From 6bb6c4c398b89ecd3257393a6295bae58d8b9395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 2 Jan 2016 00:32:54 +0100 Subject: [PATCH] Add workaround for inconsistent cubemap compressed image size on NVidia. The affected test case now passes again. --- src/Magnum/CubeMapTexture.cpp | 28 +++++++++++++++++--- src/Magnum/CubeMapTexture.h | 7 ++--- src/Magnum/Implementation/TextureState.cpp | 20 +++++++++++--- src/Magnum/Implementation/TextureState.h | 2 +- src/Magnum/Implementation/driverSpecific.cpp | 6 +++++ 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/Magnum/CubeMapTexture.cpp b/src/Magnum/CubeMapTexture.cpp index 569a3dbd9..e1c7d48b8 100644 --- a/src/Magnum/CubeMapTexture.cpp +++ b/src/Magnum/CubeMapTexture.cpp @@ -362,7 +362,7 @@ void CubeMapTexture::getLevelParameterImplementationDSAEXT(const GLint level, co #endif #endif -#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) +#ifndef MAGNUM_TARGET_GLES GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDefault(const GLint level) { bindInternal(); /* Using only parameters of +X in pre-DSA code path and assuming that all @@ -374,13 +374,28 @@ GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDefault(const GLi return value*6; } -#ifndef MAGNUM_TARGET_GLES +GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDefaultImmutableWorkaround(const GLint level) { + const GLint value = getLevelCompressedImageSizeImplementationDefault(level); + + GLint immutable; + glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS, &immutable); + return immutable ? value/6 : value; +} + GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDSA(const GLint level) { GLint value; glGetTextureLevelParameteriv(_id, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &value); return value; } +GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDSANonImmutableWorkaround(const GLint level) { + const GLint value = getLevelCompressedImageSizeImplementationDSA(level); + + GLint immutable; + glGetTextureParameteriv(_id, GL_TEXTURE_IMMUTABLE_LEVELS, &immutable); + return immutable ? value : value*6; +} + GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDSAEXT(const GLint level) { _flags |= ObjectFlag::Created; /* Using only parameters of +X in pre-DSA code path and assuming that all @@ -391,7 +406,14 @@ GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDSAEXT(const GLin /* Size of all six faces */ return value*6; } -#endif + +GLint CubeMapTexture::getLevelCompressedImageSizeImplementationDSAEXTImmutableWorkaround(const GLint level) { + const GLint value = getLevelCompressedImageSizeImplementationDSAEXT(level); + + GLint immutable; + glGetTextureParameterivEXT(_id, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS, &immutable); + return immutable ? value/6 : value; +} #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index 4e4b0c4d9..f49d8966c 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -952,12 +952,13 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { #endif #endif - #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) - GLint MAGNUM_LOCAL getLevelCompressedImageSizeImplementationDefault(GLint level); #ifndef MAGNUM_TARGET_GLES + GLint MAGNUM_LOCAL getLevelCompressedImageSizeImplementationDefault(GLint level); + GLint MAGNUM_LOCAL getLevelCompressedImageSizeImplementationDefaultImmutableWorkaround(GLint level); GLint MAGNUM_LOCAL getLevelCompressedImageSizeImplementationDSA(GLint level); + GLint MAGNUM_LOCAL getLevelCompressedImageSizeImplementationDSANonImmutableWorkaround(GLint level); GLint MAGNUM_LOCAL getLevelCompressedImageSizeImplementationDSAEXT(GLint level); - #endif + GLint MAGNUM_LOCAL getLevelCompressedImageSizeImplementationDSAEXTImmutableWorkaround(GLint level); #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Implementation/TextureState.cpp b/src/Magnum/Implementation/TextureState.cpp index ec127405e..0d0491a55 100644 --- a/src/Magnum/Implementation/TextureState.cpp +++ b/src/Magnum/Implementation/TextureState.cpp @@ -136,7 +136,6 @@ TextureState::TextureState(Context& context, std::vector& extension setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA; getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDSA; - getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDSA; cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSA; cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDSA; @@ -162,7 +161,6 @@ TextureState::TextureState(Context& context, std::vector& extension setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSAEXT; getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDSAEXT; - getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDSAEXT; cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDSAEXT; cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDSAEXT; @@ -201,7 +199,6 @@ TextureState::TextureState(Context& context, std::vector& extension #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) getCubeLevelParameterivImplementation = &CubeMapTexture::getLevelParameterImplementationDefault; - getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDefault; #endif cubeSubImageImplementation = &CubeMapTexture::subImageImplementationDefault; cubeCompressedSubImageImplementation = &CubeMapTexture::compressedSubImageImplementationDefault; @@ -222,6 +219,23 @@ TextureState::TextureState(Context& context, std::vector& extension } #ifndef MAGNUM_TARGET_GLES + /* Compressed cubemap image size query implementation (extensions added + above) */ + if((context.detectedDriver() & Context::DetectedDriver::NVidia) && + !context.isDriverWorkaroundDisabled("nv-cubemap-inconsistent-compressed-image-size")) { + if(context.isExtensionSupported()) + getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDSANonImmutableWorkaround; + else if(context.isExtensionSupported()) + getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDSAEXTImmutableWorkaround; + else getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDefaultImmutableWorkaround; + } else { + if(context.isExtensionSupported()) + getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDSA; + else if(context.isExtensionSupported()) + getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDSAEXT; + else getCubeLevelCompressedImageSizeImplementation = &CubeMapTexture::getLevelCompressedImageSizeImplementationDefault; + } + /* Image retrieval implementation */ if(context.isExtensionSupported()) { /* Extension name added above */ diff --git a/src/Magnum/Implementation/TextureState.h b/src/Magnum/Implementation/TextureState.h index 85ceb0b7b..d7ff7ed15 100644 --- a/src/Magnum/Implementation/TextureState.h +++ b/src/Magnum/Implementation/TextureState.h @@ -99,9 +99,9 @@ struct TextureState { #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) void(CubeMapTexture::*getCubeLevelParameterivImplementation)(GLint, GLenum, GLint*); - GLint(CubeMapTexture::*getCubeLevelCompressedImageSizeImplementation)(GLint); #endif #ifndef MAGNUM_TARGET_GLES + GLint(CubeMapTexture::*getCubeLevelCompressedImageSizeImplementation)(GLint); void(CubeMapTexture::*getCubeImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, PixelFormat, PixelType, std::size_t, GLvoid*); void(CubeMapTexture::*getCompressedCubeImageImplementation)(CubeMapTexture::Coordinate, GLint, const Vector2i&, std::size_t, GLvoid*); #endif diff --git a/src/Magnum/Implementation/driverSpecific.cpp b/src/Magnum/Implementation/driverSpecific.cpp index 8be35d1a2..2ee50b188 100644 --- a/src/Magnum/Implementation/driverSpecific.cpp +++ b/src/Magnum/Implementation/driverSpecific.cpp @@ -51,6 +51,12 @@ namespace { 1.30 on NVidia and 1.40 on Mac OS X. Everything is fine when using newer GLSL version. */ "no-layout-qualifiers-on-old-glsl", + + /* NVidia drivers (358.16) report different compressed image size for + cubemaps based on whether the texture is immutable or not and not + based on whether I'm querying all faces (ARB_DSA) or a single face + (non-DSA, EXT_DSA) */ + "nv-cubemap-inconsistent-compressed-image-size", #endif #ifdef CORRADE_TARGET_NACL