Browse Source

GL: rework Texture, TextureArray and MultisampleTexture symbol export.

This fixes a "visibility attribute ignored" warning in
MultisampleTexture.cpp on newer GCC and makes the three behave
consistently without having to perform crazy ordering between function
definitions and explicit template instantiation.

It's horrible, yes, but I had to resort to the same approach in
StringView.cpp because in general every other variant was failing in
some way in some compilers. I hate everything about this.
pull/617/head
Vladimír Vondruš 3 years ago
parent
commit
e7e6faa571
  1. 38
      src/Magnum/GL/MultisampleTexture.cpp
  2. 10
      src/Magnum/GL/MultisampleTexture.h
  3. 123
      src/Magnum/GL/Texture.cpp
  4. 9
      src/Magnum/GL/Texture.h
  5. 69
      src/Magnum/GL/TextureArray.cpp
  6. 10
      src/Magnum/GL/TextureArray.h

38
src/Magnum/GL/MultisampleTexture.cpp

@ -75,21 +75,8 @@ template<UnsignedInt dimensions> MultisampleTexture<dimensions> MultisampleTextu
return out;
}
/* Other view() overloads at the end */
template<UnsignedInt dimensions> MultisampleTexture<dimensions>& MultisampleTexture<dimensions>::setLabel(Containers::StringView label) {
AbstractTexture::setLabel(label);
return *this;
}
template class MAGNUM_GL_EXPORT MultisampleTexture<2>;
template class MAGNUM_GL_EXPORT MultisampleTexture<3>;
/* Because these refer to concrete types different than the class itself, they
have to be after the explicit type instantiations. Additionally, on Windows (MSVC, clang-cl and MinGw) these need an explicit export otherwise the
symbol doesn't get exported.
Other view() overloads above. */
/* On Windows (MSVC, clang-cl and MinGw) these need an explicit export
otherwise the symbol doesn't get exported. */
template<> template<> MAGNUM_GL_EXPORT MultisampleTexture2D MultisampleTexture2D::view(MultisampleTexture2DArray& original, const TextureFormat internalFormat, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
@ -112,5 +99,26 @@ template<> template<> MAGNUM_GL_EXPORT MultisampleTexture2DArray MultisampleText
return out;
}
template<UnsignedInt dimensions> MultisampleTexture<dimensions>& MultisampleTexture<dimensions>::setLabel(Containers::StringView label) {
AbstractTexture::setLabel(label);
return *this;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
template class
/* GCC needs the export macro on the class definition (and here it warns
that the type is already defined so the export is ignored), while Clang
and MSVC need it here (and ignore it on the declaration) */
#if defined(CORRADE_TARGET_CLANG) || defined(CORRADE_TARGET_MSVC)
MAGNUM_GL_EXPORT
#endif
MultisampleTexture<2>;
template class
#if defined(CORRADE_TARGET_CLANG) || defined(CORRADE_TARGET_MSVC)
MAGNUM_GL_EXPORT
#endif
MultisampleTexture<3>;
#endif
}}
#endif

10
src/Magnum/GL/MultisampleTexture.h

@ -101,7 +101,15 @@ Note that multisample textures don't support compressed formats.
array textures.
@requires_gles Multisample textures are not available in WebGL.
*/
template<UnsignedInt dimensions> class MAGNUM_GL_EXPORT MultisampleTexture: public AbstractTexture {
template<UnsignedInt dimensions> class
#ifndef CORRADE_TARGET_MSVC
/* If it's here, MSVC complains that out-of-class inline functions have a
definition while being dllimport'd. If I remove it, GCC then complains that
the export in MultisampleTexture.cpp is ignored as the type is already
defined. */
MAGNUM_GL_EXPORT
#endif
MultisampleTexture: public AbstractTexture {
public:
enum: UnsignedInt {
Dimensions = dimensions /**< Texture dimension count */

123
src/Magnum/GL/Texture.cpp

@ -83,7 +83,53 @@ template<UnsignedInt dimensions> Texture<dimensions> Texture<dimensions>::view(T
return out;
}
/* Other view() overloads at the end */
/* On Windows (MSVC, clang-cl and MinGw) these need an explicit export
otherwise the symbol doesn't get exported. */
#ifndef MAGNUM_TARGET_GLES
template<> template<> MAGNUM_GL_EXPORT Texture1D Texture1D::view(Texture1DArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture1D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
#endif
template<> template<> MAGNUM_GL_EXPORT Texture2D Texture2D::view(Texture2DArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
template<> template<> MAGNUM_GL_EXPORT Texture2D Texture2D::view(CubeMapTexture& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
template<> template<> MAGNUM_GL_EXPORT Texture2D Texture2D::view(CubeMapTextureArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
#endif
#ifndef MAGNUM_TARGET_GLES
@ -135,66 +181,29 @@ template<UnsignedInt dimensions> Texture<dimensions>& Texture<dimensions>::setLa
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES
template class MAGNUM_GL_EXPORT Texture<1>;
template class
/* GCC needs the export macro on the class definition (and here it warns
that the type is already defined so the export is ignored), while Clang
and MSVC need it here (and ignore it on the declaration) */
#if defined(CORRADE_TARGET_CLANG) || defined(CORRADE_TARGET_MSVC)
MAGNUM_GL_EXPORT
#endif
Texture<1>;
#endif
#if !defined(MAGNUM_TARGET_GLES) || !defined(MAGNUM_TARGET_WEBGL)
template class MAGNUM_GL_EXPORT Texture<2>;
template class MAGNUM_GL_EXPORT Texture<3>;
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/* Because these refer to concrete types different than the class itself, they
have to be after the explicit type instantiations. Additionally, on Windows
(MSVC, clang-cl and MinGw) these need an explicit export otherwise the
symbol doesn't get exported.
Other view() overloads at the top. */
#ifndef MAGNUM_TARGET_GLES
template<> template<> MAGNUM_GL_EXPORT Texture1D Texture1D::view(Texture1DArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture1D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
template class
#if defined(CORRADE_TARGET_CLANG) || defined(CORRADE_TARGET_MSVC)
MAGNUM_GL_EXPORT
#endif
Texture<2>;
template class
#if defined(CORRADE_TARGET_CLANG) || defined(CORRADE_TARGET_MSVC)
MAGNUM_GL_EXPORT
#endif
Texture<3>;
#endif
template<> template<> MAGNUM_GL_EXPORT Texture2D Texture2D::view(Texture2DArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
template<> template<> MAGNUM_GL_EXPORT Texture2D Texture2D::view(CubeMapTexture& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
template<> template<> MAGNUM_GL_EXPORT Texture2D Texture2D::view(CubeMapTextureArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layer) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2D out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layer, 1);
return out;
}
#endif
}}

9
src/Magnum/GL/Texture.h

@ -98,7 +98,14 @@ shaders.
@requires_webgl20 3D textures are not available in WebGL 1.0.
@requires_gl 1D textures are not available in OpenGL ES or WebGL.
*/
template<UnsignedInt dimensions> class Texture: public AbstractTexture {
template<UnsignedInt dimensions> class
#ifndef CORRADE_TARGET_MSVC
/* If it's here, MSVC complains that out-of-class inline functions have a
definition while being dllimport'd. If I remove it, GCC then may complain
that the export in Texture.cpp is ignored as the type is already defined. */
MAGNUM_GL_EXPORT
#endif
Texture: public AbstractTexture {
public:
enum: UnsignedInt {
Dimensions = dimensions /**< Texture dimension count */

69
src/Magnum/GL/TextureArray.cpp

@ -86,7 +86,29 @@ template<UnsignedInt dimensions> TextureArray<dimensions> TextureArray<dimension
return out;
}
/* Other view() overloads at the end */
/* On Windows (MSVC, clang-cl and MinGw) these need an explicit export
otherwise the symbol doesn't get exported. */
template<> template<> MAGNUM_GL_EXPORT Texture2DArray Texture2DArray::view(CubeMapTexture& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layerOffset, const Int layerCount) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2DArray out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layerOffset, layerCount);
return out;
}
template<> template<> MAGNUM_GL_EXPORT Texture2DArray Texture2DArray::view(CubeMapTextureArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layerOffset, const Int layerCount) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2DArray out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layerOffset, layerCount);
return out;
}
#endif
#ifndef MAGNUM_TARGET_GLES
@ -138,39 +160,22 @@ template<UnsignedInt dimensions> TextureArray<dimensions>& TextureArray<dimensio
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES
template class MAGNUM_GL_EXPORT TextureArray<1>;
template class
/* GCC needs the export macro on the class definition (and here it warns
that the type is already defined so the export is ignored), while Clang
and MSVC need it here (and ignore it on the declaration) */
#if defined(CORRADE_TARGET_CLANG) || defined(CORRADE_TARGET_MSVC)
MAGNUM_GL_EXPORT
#endif
TextureArray<1>;
#endif
template class MAGNUM_GL_EXPORT TextureArray<2>;
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/* Because these refer to concrete types different than the class itself, they
have to be after the explicit type instantiations. Additionally, on Windows
(MSVC, clang-cl and MinGw) these need an explicit export otherwise the
symbol doesn't get exported.
Other view() overloads at the top. */
template<> template<> MAGNUM_GL_EXPORT Texture2DArray Texture2DArray::view(CubeMapTexture& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layerOffset, const Int layerCount) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2DArray out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layerOffset, layerCount);
return out;
}
template<> template<> MAGNUM_GL_EXPORT Texture2DArray Texture2DArray::view(CubeMapTextureArray& original, const TextureFormat internalFormat, const Int levelOffset, const Int levelCount, const Int layerOffset, const Int layerCount) {
/* glTextureView() doesn't work with glCreateTextures() as it needs an
object without a name bound, so have to construct manually. The object
is marked as Created as glTextureView() binds the name. */
GLuint id;
glGenTextures(1, &id);
Texture2DArray out{id, ObjectFlag::Created|ObjectFlag::DeleteOnDestruction};
out.viewInternal(original, internalFormat, levelOffset, levelCount, layerOffset, layerCount);
return out;
}
template class
#if defined(CORRADE_TARGET_CLANG) || defined(CORRADE_TARGET_MSVC)
MAGNUM_GL_EXPORT
#endif
TextureArray<2>;
#endif
}}

10
src/Magnum/GL/TextureArray.h

@ -91,7 +91,15 @@ in shaders.
2D ones.
@todo Fix this when @gl_extension{NV,texture_array} is in ES2 extension headers
*/
template<UnsignedInt dimensions> class TextureArray: public AbstractTexture {
template<UnsignedInt dimensions> class
#ifndef CORRADE_TARGET_MSVC
/* If it's here, MSVC complains that out-of-class inline functions have a
definition while being dllimport'd. If I remove it, GCC then may complain
that the export in TextureArray.cpp is ignored as the type is already
defined. */
MAGNUM_GL_EXPORT
#endif
TextureArray: public AbstractTexture {
public:
enum: UnsignedInt {
Dimensions = dimensions /**< Texture dimension count */

Loading…
Cancel
Save