[Fix] (MG_Backend/DirectGLES): fix Super Duper Vanilla on Adreno

- emulate RGB16 SNORM fallback writes
This commit is contained in:
2026-06-27 00:06:13 +08:00
parent 195330ccea
commit 5d6cb7dfed
8 changed files with 46 additions and 16 deletions
@@ -185,6 +185,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() { Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32; Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
options |= PixelFormatNormalizeOptionBit::NoRGBA8Snorm; options |= PixelFormatNormalizeOptionBit::NoRGBA8Snorm;
options |= PixelFormatNormalizeOptionBit::NoRGB16Snorm;
if (!g_GLESCapabilities.SupportsNorm16Texture) { if (!g_GLESCapabilities.SupportsNorm16Texture) {
options |= PixelFormatNormalizeOptionBit::NoNorm16; options |= PixelFormatNormalizeOptionBit::NoNorm16;
} }
@@ -212,6 +213,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
reasons.push_back(forced ? "RGBA8_SNORM fallback forced by backend policy" reasons.push_back(forced ? "RGBA8_SNORM fallback forced by backend policy"
: "RGBA8_SNORM render target path is not supported"); : "RGBA8_SNORM render target path is not supported");
} }
if (options & PixelFormatNormalizeOptionBit::NoRGB16Snorm) {
reasons.push_back(forced ? "RGB16_SNORM fallback forced by backend policy"
: "RGB16_SNORM render target path is not supported");
}
if (options & PixelFormatNormalizeOptionBit::NoDepthComponent32) { if (options & PixelFormatNormalizeOptionBit::NoDepthComponent32) {
reasons.push_back("GL_DEPTH_COMPONENT32 native probe failed on OpenGL ES"); reasons.push_back("GL_DEPTH_COMPONENT32 native probe failed on OpenGL ES");
} }
@@ -712,7 +712,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
backendObj->SyncToBackend(currentProgram); backendObj->SyncToBackend(currentProgram);
} else { } else {
if (!backendObj->GetBackendProgramId() || if (!backendObj->GetBackendProgramId() ||
backendObj->GetRGBA8SnormClampOutputMask() != g_rgba8SnormClampOutputMask) { backendObj->GetSnormFallbackClampOutputMask() != g_snormFallbackClampOutputMask) {
backendObj->SyncToBackend(currentProgram); backendObj->SyncToBackend(currentProgram);
} }
} }
+25 -9
View File
@@ -1316,17 +1316,33 @@ namespace MobileGL::MG_Backend::DirectGLES {
return true; return true;
} }
static Bool IsRGBA8SnormFallbackAttachment( static Bool IsSnormFormat(TextureInternalFormat format) {
switch (format) {
case TextureInternalFormat::R8Snorm:
case TextureInternalFormat::RG8Snorm:
case TextureInternalFormat::RGB8Snorm:
case TextureInternalFormat::RGBA8Snorm:
case TextureInternalFormat::R16Snorm:
case TextureInternalFormat::RG16Snorm:
case TextureInternalFormat::RGB16Snorm:
case TextureInternalFormat::RGBA16Snorm:
return true;
default:
return false;
}
}
static Bool IsSnormFallbackAttachment(
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject) { const MG_State::GLState::FramebufferAttachmentObject& attachmentObject) {
if (attachmentObject.IsTexture()) { if (attachmentObject.IsTexture()) {
const auto& textureObject = attachmentObject.GetTexture(); const auto& textureObject = attachmentObject.GetTexture();
return textureObject && textureObject->GetFormat() == TextureInternalFormat::RGBA8Snorm && return textureObject && IsSnormFormat(textureObject->GetFormat()) &&
TextureImpl::ShouldUseCaveatTextureFormat(textureObject->GetFormat(), textureObject->GetTarget()); TextureImpl::ShouldUseCaveatTextureFormat(textureObject->GetFormat(), textureObject->GetTarget());
} }
if (attachmentObject.IsRenderbuffer()) { if (attachmentObject.IsRenderbuffer()) {
const auto& renderbufferObject = attachmentObject.GetRenderbuffer(); const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
return renderbufferObject && return renderbufferObject &&
renderbufferObject->GetInternalFormat() == TextureInternalFormat::RGBA8Snorm && IsSnormFormat(renderbufferObject->GetInternalFormat()) &&
TextureImpl::ShouldUseCaveatRenderbufferFormat(renderbufferObject->GetInternalFormat()); TextureImpl::ShouldUseCaveatRenderbufferFormat(renderbufferObject->GetInternalFormat());
} }
return false; return false;
@@ -1391,11 +1407,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
continue; continue;
} }
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendBuf); const auto& attachmentObject = stateFBOObject->GetAttachment(frontendBuf);
if (IsRGBA8SnormFallbackAttachment(attachmentObject)) { if (IsSnormFallbackAttachment(attachmentObject)) {
clampOutputMask |= (1u << i); clampOutputMask |= (1u << i);
} }
} }
PrgramImpl::g_rgba8SnormClampOutputMask = clampOutputMask; PrgramImpl::g_snormFallbackClampOutputMask = clampOutputMask;
} }
// 2. Remap read buffer // 2. Remap read buffer
@@ -1510,7 +1526,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} // namespace FramebufferImpl } // namespace FramebufferImpl
namespace PrgramImpl { namespace PrgramImpl {
Uint32 g_rgba8SnormClampOutputMask = 0; Uint32 g_snormFallbackClampOutputMask = 0;
StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> g_backendProgramObjects; StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> g_backendProgramObjects;
BackendProgramObjectImpl::BackendProgramObjectImpl() { BackendProgramObjectImpl::BackendProgramObjectImpl() {
@@ -1555,7 +1571,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("Syncing program to backend. State program ID: %u, Backend ID: %u", MGLOG_D("Syncing program to backend. State program ID: %u, Backend ID: %u",
stateProgramObject->GetExternalIndex(), m_backendProgramId); stateProgramObject->GetExternalIndex(), m_backendProgramId);
m_rgba8SnormClampOutputMask = g_rgba8SnormClampOutputMask; m_snormFallbackClampOutputMask = g_snormFallbackClampOutputMask;
// Detach all existing shaders // Detach all existing shaders
GLint attachedCount = 0; GLint attachedCount = 0;
@@ -1631,8 +1647,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
source = ForceFlatIntegerVaryings(source, glShaderType); source = ForceFlatIntegerVaryings(source, glShaderType);
source = EmulateBaseInstanceInVertexShader(std::move(source), glShaderType); source = EmulateBaseInstanceInVertexShader(std::move(source), glShaderType);
source = ForceSupporterOutput(source); source = ForceSupporterOutput(source);
source = ClampRGBA8SnormFallbackOutputs(std::move(source), glShaderType, source = ClampSnormFallbackOutputs(std::move(source), glShaderType,
m_rgba8SnormClampOutputMask); m_snormFallbackClampOutputMask);
// Patch for Photon compiler precision issue // Patch for Photon compiler precision issue
String findStr = "1000000.0"; String findStr = "1000000.0";
+3 -3
View File
@@ -284,17 +284,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
void SetBaseInstance(Uint32 baseInstance) const; void SetBaseInstance(Uint32 baseInstance) const;
Uint GetBackendProgramId() const { return m_backendProgramId; } Uint GetBackendProgramId() const { return m_backendProgramId; }
Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; } Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; }
Uint32 GetRGBA8SnormClampOutputMask() const { return m_rgba8SnormClampOutputMask; } Uint32 GetSnormFallbackClampOutputMask() const { return m_snormFallbackClampOutputMask; }
private: private:
Uint m_backendProgramId = 0; Uint m_backendProgramId = 0;
Uint m_backendGlobalUBOId = 0; Uint m_backendGlobalUBOId = 0;
Int m_baseInstanceUniformLocation = -1; Int m_baseInstanceUniformLocation = -1;
Uint32 m_rgba8SnormClampOutputMask = 0; Uint32 m_snormFallbackClampOutputMask = 0;
Bool m_isInitialized = false; Bool m_isInitialized = false;
}; };
extern Uint32 g_rgba8SnormClampOutputMask; extern Uint32 g_snormFallbackClampOutputMask;
extern StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> extern StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl>
g_backendProgramObjects; g_backendProgramObjects;
} // namespace PrgramImpl } // namespace PrgramImpl
+2 -1
View File
@@ -34,6 +34,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() { Flags<PixelFormatNormalizeOptionBit> GetDriverPixelFormatNormalizeOptions() {
Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32; Flags<PixelFormatNormalizeOptionBit> options = PixelFormatNormalizeOptionBit::NoDepthComponent32;
options |= PixelFormatNormalizeOptionBit::NoRGBA8Snorm; options |= PixelFormatNormalizeOptionBit::NoRGBA8Snorm;
options |= PixelFormatNormalizeOptionBit::NoRGB16Snorm;
if (!g_GLESCapabilities.SupportsNorm16Texture) { if (!g_GLESCapabilities.SupportsNorm16Texture) {
options |= PixelFormatNormalizeOptionBit::NoNorm16; options |= PixelFormatNormalizeOptionBit::NoNorm16;
} }
@@ -213,7 +214,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return result; return result;
} }
String ClampRGBA8SnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask) { String ClampSnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask) {
#ifdef TRACY_ENABLE #ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND); ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif #endif
+1 -1
View File
@@ -48,7 +48,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace PrgramImpl { namespace PrgramImpl {
String ProcessOutColorLocations(const String& glslCode); String ProcessOutColorLocations(const String& glslCode);
String ForceSupporterOutput(const String& glslCode); String ForceSupporterOutput(const String& glslCode);
String ClampRGBA8SnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask); String ClampSnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask);
String ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType); String ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType);
String RemoveLayoutBinding(const String& glslCode); String RemoveLayoutBinding(const String& glslCode);
} // namespace PrgramImpl } // namespace PrgramImpl
@@ -27,8 +27,12 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16; applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16;
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoRgb16; applicableOptions |= options & PixelFormatNormalizeOptionBit::NoRgb16;
break; break;
case GL_RGBA16_SNORM:
case GL_RGB16_SNORM: case GL_RGB16_SNORM:
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoRGB16Snorm;
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16;
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoSnorm16;
break;
case GL_RGBA16_SNORM:
case GL_RG16_SNORM: case GL_RG16_SNORM:
case GL_R16_SNORM: case GL_R16_SNORM:
applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16; applicableOptions |= options & PixelFormatNormalizeOptionBit::NoNorm16;
@@ -103,6 +107,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
break; break;
case GL_RGB16_SNORM: case GL_RGB16_SNORM:
if ((options & PixelFormatNormalizeOptionBit::NoNorm16) || if ((options & PixelFormatNormalizeOptionBit::NoNorm16) ||
(options & PixelFormatNormalizeOptionBit::NoRGB16Snorm) ||
(options & PixelFormatNormalizeOptionBit::NoSnorm16)) { (options & PixelFormatNormalizeOptionBit::NoSnorm16)) {
*outInternalFormat = GL_RGB16F; *outInternalFormat = GL_RGB16F;
break; break;
@@ -357,6 +362,8 @@ namespace MobileGL::MG_Util::TextureFormatProcessor {
case GL_RG16_SNORM: case GL_RG16_SNORM:
case GL_R16_SNORM: case GL_R16_SNORM:
if ((options & PixelFormatNormalizeOptionBit::NoNorm16) || if ((options & PixelFormatNormalizeOptionBit::NoNorm16) ||
(internalFormat == GL_RGB16_SNORM &&
(options & PixelFormatNormalizeOptionBit::NoRGB16Snorm)) ||
(options & PixelFormatNormalizeOptionBit::NoSnorm16)) { (options & PixelFormatNormalizeOptionBit::NoSnorm16)) {
*outType = GL_FLOAT; *outType = GL_FLOAT;
break; break;
@@ -17,6 +17,7 @@ namespace MobileGL {
NoSnorm8 = 1 << 3, NoSnorm8 = 1 << 3,
NoDepthComponent32 = 1 << 4, NoDepthComponent32 = 1 << 4,
NoRGBA8Snorm = 1 << 5, NoRGBA8Snorm = 1 << 5,
NoRGB16Snorm = 1 << 6,
None = 0, None = 0,
}; };
namespace MG_Util::TextureFormatProcessor { namespace MG_Util::TextureFormatProcessor {