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