diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2022-01-03 17:20:17 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2022-01-06 14:56:32 +0100 |
commit | 0d98a1faf7fa0b943c7513b8ef56c4e9db007b4b (patch) | |
tree | f71008f2c70209a68e3c978f41976089d70a0f1b /src | |
parent | 0a59101495634a02e7b893682904f4cfc5898624 (diff) |
rhi: gl: Do not just rely on GL_COMPRESSED_TEXTURE_FORMATS
Pick-to: 6.3 6.2
Task-number: QTBUG-98937
Change-Id: I64f2783ae64ad3ef77a389999ded4c9ba2c46ee5
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/opengl/qopenglextensions_p.h | 2 | ||||
-rw-r--r-- | src/gui/opengl/qopenglfunctions.cpp | 10 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 158 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 2 |
4 files changed, 115 insertions, 57 deletions
diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 0d58b5f301..972a92aac6 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -93,6 +93,8 @@ public: Sized16Formats = 0x00800000, TextureSwizzle = 0x01000000, StandardDerivatives = 0x02000000, + ASTCTextureCompression = 0x04000000, + ETC2TextureCompression = 0x08000000 }; Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension) diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index bc1bad2831..6192a49685 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -364,6 +364,8 @@ static int qt_gl_resolve_extensions() extensions |= QOpenGLExtensions::ETC1TextureCompression; if (extensionMatcher.match("GL_IMG_texture_compression_pvrtc")) extensions |= QOpenGLExtensions::PVRTCTextureCompression; + if (extensionMatcher.match("GL_KHR_texture_compression_astc_ldr")) + extensions |= QOpenGLExtensions::ASTCTextureCompression; if (extensionMatcher.match("GL_ARB_texture_mirrored_repeat")) extensions |= QOpenGLExtensions::MirroredRepeat; if (extensionMatcher.match("GL_EXT_stencil_two_side")) @@ -391,7 +393,8 @@ static int qt_gl_resolve_extensions() | QOpenGLExtensions::FramebufferBlit | QOpenGLExtensions::FramebufferMultisample | QOpenGLExtensions::Sized8Formats - | QOpenGLExtensions::StandardDerivatives; + | QOpenGLExtensions::StandardDerivatives + | QOpenGLExtensions::ETC2TextureCompression; #ifndef Q_OS_WASM // WebGL 2.0 specification explicitly does not support texture swizzles // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.19 @@ -413,6 +416,8 @@ static int qt_gl_resolve_extensions() extensions |= QOpenGLExtensions::FramebufferMultisample; if (extensionMatcher.match("GL_OES_rgb8_rgba8")) extensions |= QOpenGLExtensions::Sized8Formats; + if (extensionMatcher.match("GL_OES_compressed_ETC2_RGB8_texture")) + extensions |= QOpenGLExtensions::ETC2TextureCompression; } if (extensionMatcher.match("GL_OES_mapbuffer")) @@ -481,6 +486,9 @@ static int qt_gl_resolve_extensions() if (srgbCapableFramebuffers) extensions |= QOpenGLExtensions::SRGBFrameBuffer; } + + if (extensionMatcher.match("GL_ARB_ES3_compatibility")) + extensions |= QOpenGLExtensions::ETC2TextureCompression; } return extensions; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 6788942db8..02fbb5ec40 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -543,6 +543,58 @@ bool QRhiGles2::ensureContext(QSurface *surface) const return true; } +static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags) +{ + const bool srgb = flags.testFlag(QRhiTexture::sRGB); + switch (format) { + case QRhiTexture::BC1: + return srgb ? 0x8C4C : 0x83F0; + case QRhiTexture::BC2: + return srgb ? 0x8C4E : 0x83F2; + case QRhiTexture::BC3: + return srgb ? 0x8C4F : 0x83F3; + + case QRhiTexture::ETC2_RGB8: + return srgb ? 0x9275 : 0x9274; + case QRhiTexture::ETC2_RGB8A1: + return srgb ? 0x9277 : 0x9276; + case QRhiTexture::ETC2_RGBA8: + return srgb ? 0x9279 : 0x9278; + + case QRhiTexture::ASTC_4x4: + return srgb ? 0x93D0 : 0x93B0; + case QRhiTexture::ASTC_5x4: + return srgb ? 0x93D1 : 0x93B1; + case QRhiTexture::ASTC_5x5: + return srgb ? 0x93D2 : 0x93B2; + case QRhiTexture::ASTC_6x5: + return srgb ? 0x93D3 : 0x93B3; + case QRhiTexture::ASTC_6x6: + return srgb ? 0x93D4 : 0x93B4; + case QRhiTexture::ASTC_8x5: + return srgb ? 0x93D5 : 0x93B5; + case QRhiTexture::ASTC_8x6: + return srgb ? 0x93D6 : 0x93B6; + case QRhiTexture::ASTC_8x8: + return srgb ? 0x93D7 : 0x93B7; + case QRhiTexture::ASTC_10x5: + return srgb ? 0x93D8 : 0x93B8; + case QRhiTexture::ASTC_10x6: + return srgb ? 0x93D9 : 0x93B9; + case QRhiTexture::ASTC_10x8: + return srgb ? 0x93DA : 0x93BA; + case QRhiTexture::ASTC_10x10: + return srgb ? 0x93DB : 0x93BB; + case QRhiTexture::ASTC_12x10: + return srgb ? 0x93DC : 0x93BC; + case QRhiTexture::ASTC_12x12: + return srgb ? 0x93DD : 0x93BD; + + default: + return 0; // this is reachable, just return an invalid format + } +} + bool QRhiGles2::create(QRhi::Flags flags) { Q_ASSERT(fallbackSurface); @@ -598,9 +650,57 @@ bool QRhiGles2::create(QRhi::Flags flags) GLint n = 0; f->glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &n); - supportedCompressedFormats.resize(n); - if (n > 0) - f->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, supportedCompressedFormats.data()); + if (n > 0) { + QVarLengthArray<GLint, 16> compressedTextureFormats(n); + f->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, compressedTextureFormats.data()); + for (GLint format : compressedTextureFormats) + supportedCompressedFormats.insert(format); + + } + // The above looks nice, if only it worked always. With GLES the list we + // query is likely the full list of compressed formats (mostly anything + // that can be decoded). With OpenGL however the list is not required to + // include all formats due to the way the spec is worded. For instance, we + // cannot rely on ASTC formats being present in the list on non-ES. Some + // drivers do include them (Intel, NVIDIA), some don't (Mesa). On the other + // hand, relying on extension strings only is not ok: for example, Intel + // reports GL_KHR_texture_compression_astc_ldr whereas NVIDIA doesn't. So + // the only reasonable thing to do is to query the list always and then see + // if there is something we can add - if not already in there. + std::array<QRhiTexture::Flags, 2> textureVariantFlags; + textureVariantFlags[0] = {}; + textureVariantFlags[1] = QRhiTexture::sRGB; + if (f->hasOpenGLExtension(QOpenGLExtensions::DDSTextureCompression)) { + for (QRhiTexture::Flags f : textureVariantFlags) { + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::BC1, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::BC2, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::BC3, f)); + } + } + if (f->hasOpenGLExtension(QOpenGLExtensions::ETC2TextureCompression)) { + for (QRhiTexture::Flags f : textureVariantFlags) { + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ETC2_RGB8, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ETC2_RGB8A1, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ETC2_RGBA8, f)); + } + } + if (f->hasOpenGLExtension(QOpenGLExtensions::ASTCTextureCompression)) { + for (QRhiTexture::Flags f : textureVariantFlags) { + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_4x4, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_5x4, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_5x5, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_6x5, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_6x6, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_8x5, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_8x6, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_8x8, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_10x5, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_10x8, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_10x10, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_12x10, f)); + supportedCompressedFormats.insert(toGlCompressedTextureFormat(QRhiTexture::ASTC_12x12, f)); + } + } f->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.maxTextureSize); @@ -870,58 +970,6 @@ QMatrix4x4 QRhiGles2::clipSpaceCorrMatrix() const return QMatrix4x4(); // identity } -static inline GLenum toGlCompressedTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags) -{ - const bool srgb = flags.testFlag(QRhiTexture::sRGB); - switch (format) { - case QRhiTexture::BC1: - return srgb ? 0x8C4C : 0x83F0; - case QRhiTexture::BC2: - return srgb ? 0x8C4E : 0x83F2; - case QRhiTexture::BC3: - return srgb ? 0x8C4F : 0x83F3; - - case QRhiTexture::ETC2_RGB8: - return srgb ? 0x9275 : 0x9274; - case QRhiTexture::ETC2_RGB8A1: - return srgb ? 0x9277 : 0x9276; - case QRhiTexture::ETC2_RGBA8: - return srgb ? 0x9279 : 0x9278; - - case QRhiTexture::ASTC_4x4: - return srgb ? 0x93D0 : 0x93B0; - case QRhiTexture::ASTC_5x4: - return srgb ? 0x93D1 : 0x93B1; - case QRhiTexture::ASTC_5x5: - return srgb ? 0x93D2 : 0x93B2; - case QRhiTexture::ASTC_6x5: - return srgb ? 0x93D3 : 0x93B3; - case QRhiTexture::ASTC_6x6: - return srgb ? 0x93D4 : 0x93B4; - case QRhiTexture::ASTC_8x5: - return srgb ? 0x93D5 : 0x93B5; - case QRhiTexture::ASTC_8x6: - return srgb ? 0x93D6 : 0x93B6; - case QRhiTexture::ASTC_8x8: - return srgb ? 0x93D7 : 0x93B7; - case QRhiTexture::ASTC_10x5: - return srgb ? 0x93D8 : 0x93B8; - case QRhiTexture::ASTC_10x6: - return srgb ? 0x93D9 : 0x93B9; - case QRhiTexture::ASTC_10x8: - return srgb ? 0x93DA : 0x93BA; - case QRhiTexture::ASTC_10x10: - return srgb ? 0x93DB : 0x93BB; - case QRhiTexture::ASTC_12x10: - return srgb ? 0x93DC : 0x93BC; - case QRhiTexture::ASTC_12x12: - return srgb ? 0x93DD : 0x93BD; - - default: - return 0; // this is reachable, just return an invalid format - } -} - static inline void toGlTextureFormat(QRhiTexture::Format format, const QRhiGles2::Caps &caps, GLenum *glintformat, GLenum *glsizedintformat, GLenum *glformat, GLenum *gltype) diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index 1e9ffc911f..dd0728cfc0 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -1007,7 +1007,7 @@ public: uint texture3D : 1; } caps; QGles2SwapChain *currentSwapChain = nullptr; - QList<GLint> supportedCompressedFormats; + QSet<GLint> supportedCompressedFormats; mutable QList<int> supportedSampleCountList; QRhiGles2NativeHandles nativeHandlesStruct; QRhiDriverInfo driverInfoStruct; |