From 76acae9889504e9c708cba0eee92707400d4fb6e Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 26 Jun 2026 14:12:24 +0800 Subject: [PATCH] [Fix] (MG_Backend/DirectGLES): make format caveats probe-driven --- .../DirectGLES/BackendObject_DirectGLES.cpp | 209 ++++++++++++++---- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 6 +- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 10 +- MobileGL/MG_Backend/DirectGLES/Utils.cpp | 114 +++++++++- MobileGL/MG_Backend/DirectGLES/Utils.h | 5 +- .../Texture/TextureFormatProcessor.cpp | 42 +++- .../MG_Util/Texture/TextureFormatProcessor.h | 4 + 7 files changed, 330 insertions(+), 60 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp index dda4500e..f58372f8 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp @@ -136,6 +136,122 @@ namespace MobileGL::MG_Backend::DirectGLES { FormatCapability::MultisampleRenderbuffer; } + struct GLESProbeFormatInfo { + GLenum InternalFormat = GL_UNKNOWN_MGL; + GLenum ImageFormat = GL_RGBA; + GLenum ImageType = GL_UNSIGNED_BYTE; + }; + + constexpr FormatCapability kGLESProbeCapabilities[] = { + FormatCapability::Creatable, + FormatCapability::Sampled, + FormatCapability::LinearFilter, + FormatCapability::GenerateMipmap, + FormatCapability::TextureGather, + FormatCapability::TextureShadow, + FormatCapability::FramebufferRenderable, + FormatCapability::FramebufferLayered, + FormatCapability::MultisampleTexture, + FormatCapability::MultisampleRenderbuffer, + FormatCapability::ColorAttachment, + FormatCapability::DepthAttachment, + FormatCapability::StencilAttachment, + FormatCapability::TextureBuffer, + }; + + GLESProbeFormatInfo BuildNativeProbeFormatInfo(GLenum requestedInternalFormat) { + GLESProbeFormatInfo info; + info.InternalFormat = requestedInternalFormat; + MG_Util::TextureFormatProcessor::NormalizePixelFormat( + requestedInternalFormat, PixelFormatNormalizeOptionBit::None, nullptr, &info.ImageFormat, + &info.ImageType); + return info; + } + + Flags GetForcedPixelFormatNormalizeOptions() { + Flags options; + if (g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos) { + options |= PixelFormatNormalizeOptionBit::NoRgb16; + options |= PixelFormatNormalizeOptionBit::NoSnorm16; + options |= PixelFormatNormalizeOptionBit::NoSnorm8; + } + return options; + } + + Flags GetDriverPixelFormatNormalizeOptions() { + Flags options = PixelFormatNormalizeOptionBit::NoDepthComponent32; + if (!g_GLESCapabilities.SupportsNorm16Texture) { + options |= PixelFormatNormalizeOptionBit::NoNorm16; + } + return options; + } + + Bool BuildFallbackProbeFormatInfo(GLenum requestedInternalFormat, + Flags options, + GLESProbeFormatInfo& outInfo) { + const Flags applicableOptions = + MG_Util::TextureFormatProcessor::GetApplicablePixelFormatNormalizeOptions(requestedInternalFormat, + options); + if (!applicableOptions) { + return false; + } + + MG_Util::TextureFormatProcessor::NormalizePixelFormat(requestedInternalFormat, applicableOptions, + &outInfo.InternalFormat, &outInfo.ImageFormat, + &outInfo.ImageType); + return outInfo.InternalFormat != GL_UNKNOWN_MGL; + } + + FormatCapabilityFlags BuildTextureCapsFromProbe(TextureInternalFormat logicalFormat, + TextureTarget target, + Bool renderable) { + FormatCapabilityFlags caps = GetTextureFeatureCaps(logicalFormat, target); + if (renderable) { + caps |= GetAttachmentCaps(logicalFormat); + if (target == TextureTarget::Texture3D || target == TextureTarget::Texture2DArray || + target == TextureTarget::TextureCubeMapArray || + target == TextureTarget::Texture2DMultisampleArray) { + caps |= FormatCapability::FramebufferLayered; + } + } + return caps; + } + + void AddFullFormatCaps(FormatCapabilityCache& cache, + SizeT targetIndex, + SizeT formatIndex, + FormatCapabilityFlags caps) { + cache.FullCaps[targetIndex][formatIndex] |= caps; + } + + void AddCaveatFormatCaps(FormatCapabilityCache& cache, + SizeT targetIndex, + SizeT formatIndex, + FormatCapabilityFlags caps) { + for (FormatCapability capability : kGLESProbeCapabilities) { + if (HasFormatCapability(caps, capability) && + !HasFormatCapability(cache.FullCaps[targetIndex][formatIndex], capability)) { + cache.CaveatCaps[targetIndex][formatIndex] |= capability; + } + } + } + + Int GetGLESFormatMaxSamples(const DynamicBackendParameters& dynamicParameters, + TextureInternalFormat logicalFormat, + GLenum imageFormat) { + const Bool isDepth = MG_Util::IsDepthFormatInternalFormat(logicalFormat); + const Bool isStencil = MG_Util::IsStencilFormatInternalFormat(logicalFormat); + const Bool isInteger = imageFormat == GL_RED_INTEGER || imageFormat == GL_RG_INTEGER || + imageFormat == GL_RGB_INTEGER || imageFormat == GL_RGBA_INTEGER; + if (isDepth || isStencil) { + return dynamicParameters.MaxDepthTextureSamples; + } + if (isInteger) { + return dynamicParameters.MaxIntegerSamples; + } + return dynamicParameters.MaxColorTextureSamples; + } + Bool ProbeFramebufferCompletenessForTexture(const MG_External::GLESFunctionsTable& gl, TextureTarget target, GLuint texture, @@ -335,6 +451,9 @@ namespace MobileGL::MG_Backend::DirectGLES { FormatCapabilityCache& cache, const DynamicBackendParameters& dynamicParameters) { cache.Clear(); + const Flags forcedOptions = GetForcedPixelFormatNormalizeOptions(); + const Flags driverOptions = GetDriverPixelFormatNormalizeOptions(); + for (SizeT formatIndex = 0; formatIndex < kFormatCapabilityFormatCount; ++formatIndex) { const auto logicalFormat = static_cast(formatIndex); GLenum requestedInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(logicalFormat); @@ -342,55 +461,71 @@ namespace MobileGL::MG_Backend::DirectGLES { continue; } - GLenum backendInternalFormat = requestedInternalFormat; - GLenum imageFormat = GL_RGBA; - GLenum imageType = GL_UNSIGNED_BYTE; - TextureImpl::GenerateTextureFormatInfo(logicalFormat, &backendInternalFormat, &imageFormat, - &imageType); - const Bool isCaveat = backendInternalFormat != requestedInternalFormat; + const GLESProbeFormatInfo nativeInfo = BuildNativeProbeFormatInfo(requestedInternalFormat); + GLESProbeFormatInfo fallbackInfo; + const Bool hasForcedFallback = + BuildFallbackProbeFormatInfo(requestedInternalFormat, forcedOptions, fallbackInfo); + if (!hasForcedFallback) { + BuildFallbackProbeFormatInfo(requestedInternalFormat, driverOptions, fallbackInfo); + } for (SizeT targetIndex = 0; targetIndex < kFormatCapabilityTextureTargetCount; ++targetIndex) { const auto target = static_cast(targetIndex); - Bool renderable = false; - if (!ProbeTexture(gl, target, backendInternalFormat, imageFormat, imageType, logicalFormat, - &renderable)) { - continue; - } - - FormatCapabilityFlags caps = GetTextureFeatureCaps(logicalFormat, target); - if (renderable) { - caps |= GetAttachmentCaps(logicalFormat); - if (target == TextureTarget::Texture3D || target == TextureTarget::Texture2DArray || - target == TextureTarget::TextureCubeMapArray || - target == TextureTarget::Texture2DMultisampleArray) { - caps |= FormatCapability::FramebufferLayered; + Bool shouldProbeFallback = hasForcedFallback; + if (!hasForcedFallback) { + Bool nativeRenderable = false; + const Bool nativeCreated = + ProbeTexture(gl, target, nativeInfo.InternalFormat, nativeInfo.ImageFormat, + nativeInfo.ImageType, logicalFormat, &nativeRenderable); + if (nativeCreated) { + AddFullFormatCaps(cache, targetIndex, formatIndex, + BuildTextureCapsFromProbe(logicalFormat, target, nativeRenderable)); + if (IsGLESProbeMultisampleTarget(target)) { + cache.SampleCounts[targetIndex][formatIndex] = {1}; + } } + shouldProbeFallback = !nativeCreated || !nativeRenderable; } - auto& table = isCaveat ? cache.CaveatCaps : cache.FullCaps; - table[targetIndex][formatIndex] |= caps; - if (IsGLESProbeMultisampleTarget(target)) { - cache.SampleCounts[targetIndex][formatIndex] = {1}; + if (shouldProbeFallback && fallbackInfo.InternalFormat != GL_UNKNOWN_MGL) { + Bool fallbackRenderable = false; + const Bool fallbackCreated = + ProbeTexture(gl, target, fallbackInfo.InternalFormat, fallbackInfo.ImageFormat, + fallbackInfo.ImageType, logicalFormat, &fallbackRenderable); + if (fallbackCreated) { + AddCaveatFormatCaps(cache, targetIndex, formatIndex, + BuildTextureCapsFromProbe(logicalFormat, target, fallbackRenderable)); + if (IsGLESProbeMultisampleTarget(target)) { + cache.SampleCounts[targetIndex][formatIndex] = {1}; + } + } } } const SizeT renderbufferTargetIndex = GetRenderbufferFormatCapabilityTargetIndex(); - if (ProbeRenderbuffer(gl, backendInternalFormat, logicalFormat, false, 1)) { - auto& table = isCaveat ? cache.CaveatCaps : cache.FullCaps; - table[renderbufferTargetIndex][formatIndex] |= GetRenderbufferFeatureCaps(logicalFormat); - - const Bool isDepth = MG_Util::IsDepthFormatInternalFormat(logicalFormat); - const Bool isStencil = MG_Util::IsStencilFormatInternalFormat(logicalFormat); - const Bool isInteger = imageFormat == GL_RED_INTEGER || imageFormat == GL_RG_INTEGER || - imageFormat == GL_RGB_INTEGER || imageFormat == GL_RGBA_INTEGER; - Int maxSamples = dynamicParameters.MaxColorTextureSamples; - if (isDepth || isStencil) { - maxSamples = dynamicParameters.MaxDepthTextureSamples; - } else if (isInteger) { - maxSamples = dynamicParameters.MaxIntegerSamples; + Bool shouldProbeFallbackRenderbuffer = hasForcedFallback; + if (!hasForcedFallback) { + const Bool nativeRenderbufferComplete = + ProbeRenderbuffer(gl, nativeInfo.InternalFormat, logicalFormat, false, 1); + if (nativeRenderbufferComplete) { + AddFullFormatCaps(cache, renderbufferTargetIndex, formatIndex, + GetRenderbufferFeatureCaps(logicalFormat)); + const Int maxSamples = + GetGLESFormatMaxSamples(dynamicParameters, logicalFormat, nativeInfo.ImageFormat); + cache.SampleCounts[renderbufferTargetIndex][formatIndex] = + ProbeRenderbufferSampleCounts(gl, nativeInfo.InternalFormat, logicalFormat, maxSamples); + } else { + shouldProbeFallbackRenderbuffer = true; } + } + if (shouldProbeFallbackRenderbuffer && fallbackInfo.InternalFormat != GL_UNKNOWN_MGL && + ProbeRenderbuffer(gl, fallbackInfo.InternalFormat, logicalFormat, false, 1)) { + AddCaveatFormatCaps(cache, renderbufferTargetIndex, formatIndex, + GetRenderbufferFeatureCaps(logicalFormat)); + const Int maxSamples = + GetGLESFormatMaxSamples(dynamicParameters, logicalFormat, fallbackInfo.ImageFormat); cache.SampleCounts[renderbufferTargetIndex][formatIndex] = - ProbeRenderbufferSampleCounts(gl, backendInternalFormat, logicalFormat, maxSamples); + ProbeRenderbufferSampleCounts(gl, fallbackInfo.InternalFormat, logicalFormat, maxSamples); } } } diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 02a62184..fd1c2d08 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -2041,7 +2041,8 @@ namespace MobileGL::MG_Backend::DirectGLES { auto mgInternalFormat = textureObject->GetFormat(); GLenum format = GL_DEPTH_COMPONENT; GLenum type = GL_UNSIGNED_INT; - TextureImpl::GenerateTextureFormatInfo(mgInternalFormat, &internalformat, &format, &type); + TextureImpl::GenerateTextureFormatInfo(mgInternalFormat, &internalformat, &format, &type, + MG_Util::ConvertGLEnumToTextureTarget(target)); MOBILEGL_ASSERT(format != GL_NONE && type != GL_NONE, "%s: cannot GenerateTextureFormatInfo(%s): out internalformat=%s, format=%s, type=%s", MG_Util::ConvertTextureInternalFormatToString(mgInternalFormat).c_str(), @@ -2269,9 +2270,6 @@ namespace MobileGL::MG_Backend::DirectGLES { if (copyImageError == GL_NO_ERROR) { return; } - MOBILEGL_ASSERT(copyImageError == GL_INVALID_ENUM, - "glCopyImageSubData failed: %s", - MG_Util::ConvertGLEnumToString(copyImageError).c_str()); MOBILEGL_ASSERT(IsColorOnlyFormat(srcTexture->GetFormat()) && IsColorOnlyFormat(dstTexture->GetFormat()), "DirectGLES CopyImageSubData only supports color-only or depth-only copies."); MOBILEGL_ASSERT(srcTarget == GL_TEXTURE_2D && dstTarget == GL_TEXTURE_2D, diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 44452aab..77a8fc37 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -708,7 +708,7 @@ namespace MobileGL::MG_Backend::DirectGLES { GLenum glInternalFormat, glType, glFormat; TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, - &glFormat, &glType); + &glFormat, &glType, targetInternal); const auto& uploadTargets = textureMipmapObject->GetUploadTargets(); ScopedDefaultUnpackState unpackState; @@ -771,7 +771,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Regenerate all mipmap levels GLenum glInternalFormat, glType, glFormat; TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, - &glFormat, &glType); + &glFormat, &glType, targetInternal); const auto& uploadTargets = textureMipmapObject->GetUploadTargets(); if (TextureImpl::IsMultisampleTextureTarget(targetInternal)) { @@ -884,7 +884,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount(); GLenum glInternalFormat, glType, glFormat; TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, - &glFormat, &glType); + &glFormat, &glType, targetInternal); const auto& uploadTargets = textureMipmapObject->GetUploadTargets(); ScopedDefaultUnpackState unpackState; for (auto& uploadTarget : uploadTargets) { @@ -980,7 +980,7 @@ namespace MobileGL::MG_Backend::DirectGLES { GLenum glInternalFormat, glType, glFormat; TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glFormat, - &glType); + &glType, TextureTarget::TextureBuffer); if (needsRegeneration) { MGLOG_D("Texture state changed significantly or not initialized, regenerating texture buffer with " @@ -1832,7 +1832,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Int height = static_cast(stateRBOObject->GetHeight()); Int samples = static_cast(stateRBOObject->GetSamples()); GLenum glInternalFormat, glType, glFormat; - TextureImpl::GenerateTextureFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType); + TextureImpl::GenerateRenderbufferFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType); if (samples > 0) { g_GLESFuncs.glRenderbufferStorageMultisample( diff --git a/MobileGL/MG_Backend/DirectGLES/Utils.cpp b/MobileGL/MG_Backend/DirectGLES/Utils.cpp index 9f2fea81..22f321b7 100644 --- a/MobileGL/MG_Backend/DirectGLES/Utils.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Utils.cpp @@ -9,6 +9,7 @@ #include "DirectGLES.h" #include "Utils.h" #include "Managers.h" +#include "MG_Backend/BackendObjects.h" #include "MG_Util/Converters/GLToMG/FramebufferEnumConverter.h" #include "MG_Util/Texture/TextureFormatProcessor.h" @@ -19,23 +20,112 @@ #include namespace MobileGL::MG_Backend::DirectGLES { - namespace TextureImpl { - void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat, - GLenum* outFormat, GLenum* outType) { -#ifdef TRACY_ENABLE - ZoneScopedC(TRACY_ZONECOLOR_BACKEND); -#endif - using namespace MobileGL::MG_Util::TextureFormatProcessor; - Flags options = - (g_GLESCapabilities.SupportsNorm16Texture) ? PixelFormatNormalizeOptionBit::None - : PixelFormatNormalizeOptionBit::NoNorm16; + namespace { + Flags GetForcedPixelFormatNormalizeOptions() { + Flags options; if (g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos) { options |= PixelFormatNormalizeOptionBit::NoRgb16; options |= PixelFormatNormalizeOptionBit::NoSnorm16; options |= PixelFormatNormalizeOptionBit::NoSnorm8; } - NormalizePixelFormat(MG_Util::ConvertTextureInternalFormatToGLEnum(internalFormat), options, - outInternalFormat, outFormat, outType); + return options; + } + + Flags GetDriverPixelFormatNormalizeOptions() { + Flags options = PixelFormatNormalizeOptionBit::NoDepthComponent32; + if (!g_GLESCapabilities.SupportsNorm16Texture) { + options |= PixelFormatNormalizeOptionBit::NoNorm16; + } + return options; + } + + Flags GetRuntimeFallbackNormalizeOptions(GLenum requestedInternalFormat) { + using namespace MG_Util::TextureFormatProcessor; + const Flags forcedOptions = + GetApplicablePixelFormatNormalizeOptions(requestedInternalFormat, GetForcedPixelFormatNormalizeOptions()); + if (forcedOptions) { + return forcedOptions; + } + return GetApplicablePixelFormatNormalizeOptions(requestedInternalFormat, + GetDriverPixelFormatNormalizeOptions()); + } + + Bool HasCachedFormatCapability(TextureInternalFormat internalFormat, + SizeT targetIndex, + Bool caveat, + FormatCapability capability) { + if (!pActiveBackendObject || targetIndex >= kFormatCapabilityTargetCount) { + return false; + } + const SizeT formatIndex = static_cast(internalFormat); + if (formatIndex >= kFormatCapabilityFormatCount) { + return false; + } + + const FormatCapabilityCache& cache = pActiveBackendObject->GetFormatCapabilities(); + const FormatCapabilityFlags caps = + caveat ? cache.CaveatCaps[targetIndex][formatIndex] : cache.FullCaps[targetIndex][formatIndex]; + return HasFormatCapability(caps, capability); + } + + Bool HasAnyCachedFormatCapability(TextureInternalFormat internalFormat, + Bool caveat, + FormatCapability capability) { + for (SizeT targetIndex = 0; targetIndex < kFormatCapabilityTargetCount; ++targetIndex) { + if (HasCachedFormatCapability(internalFormat, targetIndex, caveat, capability)) { + return true; + } + } + return false; + } + + Bool ShouldUseCaveatFormat(TextureInternalFormat internalFormat, SizeT targetIndex) { + if (targetIndex < kFormatCapabilityTargetCount) { + if (HasCachedFormatCapability(internalFormat, targetIndex, false, FormatCapability::Creatable)) { + return false; + } + return HasCachedFormatCapability(internalFormat, targetIndex, true, FormatCapability::Creatable); + } + + if (HasAnyCachedFormatCapability(internalFormat, false, FormatCapability::Creatable)) { + return false; + } + return HasAnyCachedFormatCapability(internalFormat, true, FormatCapability::Creatable); + } + + void GenerateFormatInfo(TextureInternalFormat internalFormat, + SizeT targetIndex, + GLenum* outInternalFormat, + GLenum* outFormat, + GLenum* outType) { + using namespace MobileGL::MG_Util::TextureFormatProcessor; + const GLenum requestedInternalFormat = MG_Util::ConvertTextureInternalFormatToGLEnum(internalFormat); + Flags options; + if (!pActiveBackendObject || ShouldUseCaveatFormat(internalFormat, targetIndex)) { + options = GetRuntimeFallbackNormalizeOptions(requestedInternalFormat); + } + NormalizePixelFormat(requestedInternalFormat, options, outInternalFormat, outFormat, outType); + } + } // namespace + + namespace TextureImpl { + void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat, + GLenum* outFormat, GLenum* outType, TextureTarget target) { +#ifdef TRACY_ENABLE + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); +#endif + const SizeT targetIndex = + target == TextureTarget::Unknown ? kFormatCapabilityTargetCount : GetFormatCapabilityTargetIndex(target); + GenerateFormatInfo(internalFormat, targetIndex, outInternalFormat, outFormat, outType); + } + + void GenerateRenderbufferFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat, + GLenum* outFormat, GLenum* outType) { +#ifdef TRACY_ENABLE + ZoneScopedC(TRACY_ZONECOLOR_BACKEND); +#endif + GenerateFormatInfo(internalFormat, GetRenderbufferFormatCapabilityTargetIndex(), outInternalFormat, + outFormat, outType); } } // namespace TextureImpl namespace PrgramImpl { diff --git a/MobileGL/MG_Backend/DirectGLES/Utils.h b/MobileGL/MG_Backend/DirectGLES/Utils.h index 58c02fa3..288e185b 100644 --- a/MobileGL/MG_Backend/DirectGLES/Utils.h +++ b/MobileGL/MG_Backend/DirectGLES/Utils.h @@ -35,7 +35,10 @@ namespace MobileGL::MG_Backend::DirectGLES { namespace TextureImpl { void GenerateTextureFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat, - GLenum* outFormat, GLenum* outType); + GLenum* outFormat, GLenum* outType, + TextureTarget target = TextureTarget::Unknown); + void GenerateRenderbufferFormatInfo(TextureInternalFormat internalFormat, GLenum* outInternalFormat, + GLenum* outFormat, GLenum* outType); } // namespace TextureImpl namespace FramebufferImpl {} // namespace FramebufferImpl diff --git a/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp b/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp index ac7a9129..1bfbc810 100644 --- a/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp +++ b/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp @@ -10,6 +10,42 @@ #include "MG_Util/Converters/GLToStr/GLEnumConverter.h" namespace MobileGL::MG_Util::TextureFormatProcessor { + Flags + GetApplicablePixelFormatNormalizeOptions(GLenum internalFormat, + Flags options) { + Flags applicableOptions; + switch (internalFormat) { + case GL_DEPTH_COMPONENT32: + applicableOptions |= options & PixelFormatNormalizeOptionBit::NoDepthComponent32; + break; + case GL_RGBA16: + case GL_RG16: + case GL_R16: + applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16; + break; + case GL_RGB16: + applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16; + applicableOptions |= options & PixelFormatNormalizeOptionBit::NoRgb16; + break; + case GL_RGBA16_SNORM: + case GL_RGB16_SNORM: + case GL_RG16_SNORM: + case GL_R16_SNORM: + applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16; + applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm16; + break; + case GL_RGBA8_SNORM: + case GL_RGB8_SNORM: + case GL_RG8_SNORM: + case GL_R8_SNORM: + applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm8; + break; + default: + break; + } + return applicableOptions; + } + void NormalizePixelFormat(GLenum internalFormat, Flags options, GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType) { #ifdef TRACY_ENABLE @@ -19,7 +55,11 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { if (outInternalFormat) { switch (internalFormat) { case GL_DEPTH_COMPONENT32: - *outInternalFormat = GL_DEPTH_COMPONENT; + if (options & PixelFormatNormalizeOptionBit::NoDepthComponent32) { + *outInternalFormat = GL_DEPTH_COMPONENT; + break; + } + *outInternalFormat = internalFormat; break; case GL_RGBA16: if (options & PixelFormatNormalizeOptionBit::NoNorm16) { diff --git a/MobileGL/MG_Util/Texture/TextureFormatProcessor.h b/MobileGL/MG_Util/Texture/TextureFormatProcessor.h index 8a23d1e2..d664a4fb 100644 --- a/MobileGL/MG_Util/Texture/TextureFormatProcessor.h +++ b/MobileGL/MG_Util/Texture/TextureFormatProcessor.h @@ -15,9 +15,13 @@ namespace MobileGL { NoSnorm16 = 1 << 1, NoRgb16 = 1 << 2, NoSnorm8 = 1 << 3, + NoDepthComponent32 = 1 << 4, None = 0, }; namespace MG_Util::TextureFormatProcessor { + Flags + GetApplicablePixelFormatNormalizeOptions(GLenum internalFormat, + Flags options); void NormalizePixelFormat(GLenum internalFormat, Flags options, GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType); } // namespace MG_Util::TextureFormatProcessor