mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MG_Backend/DirectGLES): clamp UNORM fallback writes
This commit is contained in:
@@ -216,6 +216,7 @@ jobs:
|
||||
trace_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.tgz
|
||||
trace_file: trace.trace
|
||||
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.0000110725.png
|
||||
alternate_golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.0000110725-mali.png
|
||||
target_call: 110725
|
||||
width: 854
|
||||
height: 480
|
||||
|
||||
@@ -744,7 +744,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
backendObj->SyncToBackend(currentProgram);
|
||||
} else {
|
||||
if (!backendObj->GetBackendProgramId() ||
|
||||
backendObj->GetSnormFallbackClampOutputMask() != g_snormFallbackClampOutputMask) {
|
||||
backendObj->GetSnormFallbackClampOutputMask() != g_snormFallbackClampOutputMask ||
|
||||
backendObj->GetUnormFallbackClampOutputMask() != g_unormFallbackClampOutputMask) {
|
||||
backendObj->SyncToBackend(currentProgram);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1332,6 +1332,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
}
|
||||
|
||||
static Bool IsUnormFormat(TextureInternalFormat format) {
|
||||
switch (format) {
|
||||
case TextureInternalFormat::R16:
|
||||
case TextureInternalFormat::RG16:
|
||||
case TextureInternalFormat::RGB16:
|
||||
case TextureInternalFormat::RGBA16:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Bool IsSnormFallbackAttachment(
|
||||
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject) {
|
||||
if (attachmentObject.IsTexture()) {
|
||||
@@ -1348,6 +1360,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return false;
|
||||
}
|
||||
|
||||
static Bool IsUnormFallbackAttachment(
|
||||
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject) {
|
||||
if (attachmentObject.IsTexture()) {
|
||||
const auto& textureObject = attachmentObject.GetTexture();
|
||||
return textureObject && IsUnormFormat(textureObject->GetFormat()) &&
|
||||
TextureImpl::ShouldUseCaveatTextureFormat(textureObject->GetFormat(), textureObject->GetTarget());
|
||||
}
|
||||
if (attachmentObject.IsRenderbuffer()) {
|
||||
const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
|
||||
return renderbufferObject &&
|
||||
IsUnormFormat(renderbufferObject->GetInternalFormat()) &&
|
||||
TextureImpl::ShouldUseCaveatRenderbufferFormat(renderbufferObject->GetInternalFormat());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BackendFramebufferObject::SyncToBackend(
|
||||
const SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, FramebufferTarget asTarget) {
|
||||
#ifdef TRACY_ENABLE
|
||||
@@ -1399,7 +1427,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
|
||||
if (asTarget == FramebufferTarget::Draw) {
|
||||
Uint32 clampOutputMask = 0;
|
||||
Uint32 snormClampOutputMask = 0;
|
||||
Uint32 unormClampOutputMask = 0;
|
||||
for (Uint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS && i < 32; ++i) {
|
||||
const auto frontendBuf = stateDrawBuffers[i];
|
||||
if (frontendBuf < FramebufferAttachmentType::Color0 ||
|
||||
@@ -1408,10 +1437,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendBuf);
|
||||
if (IsSnormFallbackAttachment(attachmentObject)) {
|
||||
clampOutputMask |= (1u << i);
|
||||
snormClampOutputMask |= (1u << i);
|
||||
} else if (IsUnormFallbackAttachment(attachmentObject)) {
|
||||
unormClampOutputMask |= (1u << i);
|
||||
}
|
||||
}
|
||||
PrgramImpl::g_snormFallbackClampOutputMask = clampOutputMask;
|
||||
PrgramImpl::g_snormFallbackClampOutputMask = snormClampOutputMask;
|
||||
PrgramImpl::g_unormFallbackClampOutputMask = unormClampOutputMask;
|
||||
}
|
||||
|
||||
// 2. Remap read buffer
|
||||
@@ -1527,6 +1559,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
namespace PrgramImpl {
|
||||
Uint32 g_snormFallbackClampOutputMask = 0;
|
||||
Uint32 g_unormFallbackClampOutputMask = 0;
|
||||
StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> g_backendProgramObjects;
|
||||
|
||||
BackendProgramObjectImpl::BackendProgramObjectImpl() {
|
||||
@@ -1572,6 +1605,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MGLOG_D("Syncing program to backend. State program ID: %u, Backend ID: %u",
|
||||
stateProgramObject->GetExternalIndex(), m_backendProgramId);
|
||||
m_snormFallbackClampOutputMask = g_snormFallbackClampOutputMask;
|
||||
m_unormFallbackClampOutputMask = g_unormFallbackClampOutputMask;
|
||||
|
||||
// Detach all existing shaders
|
||||
GLint attachedCount = 0;
|
||||
@@ -1647,8 +1681,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
source = ForceFlatIntegerVaryings(source, glShaderType);
|
||||
source = EmulateBaseInstanceInVertexShader(std::move(source), glShaderType);
|
||||
source = ForceSupporterOutput(source);
|
||||
source = ClampSnormFallbackOutputs(std::move(source), glShaderType,
|
||||
m_snormFallbackClampOutputMask);
|
||||
source = ClampNormFallbackOutputs(std::move(source), glShaderType,
|
||||
m_snormFallbackClampOutputMask,
|
||||
m_unormFallbackClampOutputMask);
|
||||
|
||||
// Patch for Photon compiler precision issue
|
||||
String findStr = "1000000.0";
|
||||
|
||||
@@ -285,16 +285,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
Uint GetBackendProgramId() const { return m_backendProgramId; }
|
||||
Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; }
|
||||
Uint32 GetSnormFallbackClampOutputMask() const { return m_snormFallbackClampOutputMask; }
|
||||
Uint32 GetUnormFallbackClampOutputMask() const { return m_unormFallbackClampOutputMask; }
|
||||
|
||||
private:
|
||||
Uint m_backendProgramId = 0;
|
||||
Uint m_backendGlobalUBOId = 0;
|
||||
Int m_baseInstanceUniformLocation = -1;
|
||||
Uint32 m_snormFallbackClampOutputMask = 0;
|
||||
Uint32 m_unormFallbackClampOutputMask = 0;
|
||||
Bool m_isInitialized = false;
|
||||
};
|
||||
|
||||
extern Uint32 g_snormFallbackClampOutputMask;
|
||||
extern Uint32 g_unormFallbackClampOutputMask;
|
||||
extern StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl>
|
||||
g_backendProgramObjects;
|
||||
} // namespace PrgramImpl
|
||||
|
||||
@@ -214,10 +214,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return result;
|
||||
}
|
||||
|
||||
String ClampSnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask) {
|
||||
String ClampNormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 snormOutputMask,
|
||||
Uint32 unormOutputMask) {
|
||||
#ifdef TRACY_ENABLE
|
||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||
#endif
|
||||
const Uint32 outputMask = snormOutputMask | unormOutputMask;
|
||||
if (shaderType != GL_FRAGMENT_SHADER || outputMask == 0) {
|
||||
return glslCode;
|
||||
}
|
||||
@@ -226,14 +228,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
R"(layout\s*\(\s*location\s*=\s*([0-9]+)\s*\)\s*out\s+(?:(?:lowp|mediump|highp)\s+)?vec4\s+([A-Za-z_][A-Za-z0-9_]*)\s*;)");
|
||||
std::sregex_iterator outputIt(glslCode.begin(), glslCode.end(), outputPattern);
|
||||
std::sregex_iterator outputEnd;
|
||||
Vector<String> outputNames;
|
||||
struct OutputClamp {
|
||||
String Name;
|
||||
Bool Signed;
|
||||
};
|
||||
Vector<OutputClamp> outputClamps;
|
||||
for (; outputIt != outputEnd; ++outputIt) {
|
||||
const Uint location = static_cast<Uint>(std::stoul((*outputIt)[1].str()));
|
||||
if (location < 32 && (outputMask & (1u << location))) {
|
||||
outputNames.push_back((*outputIt)[2].str());
|
||||
outputClamps.push_back({(*outputIt)[2].str(), static_cast<Bool>(snormOutputMask & (1u << location))});
|
||||
}
|
||||
}
|
||||
if (outputNames.empty()) {
|
||||
if (outputClamps.empty()) {
|
||||
return glslCode;
|
||||
}
|
||||
|
||||
@@ -252,9 +258,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
--depth;
|
||||
if (depth == 0) {
|
||||
String clampLine;
|
||||
for (const String& outputName : outputNames) {
|
||||
clampLine += "\n " + outputName + " = clamp(" + outputName +
|
||||
", vec4(-1.0), vec4(1.0));";
|
||||
for (const OutputClamp& outputClamp : outputClamps) {
|
||||
const String minValue = outputClamp.Signed ? "-1.0" : "0.0";
|
||||
clampLine += "\n " + outputClamp.Name + " = clamp(" + outputClamp.Name +
|
||||
", vec4(" + minValue + "), vec4(1.0));";
|
||||
}
|
||||
clampLine += "\n";
|
||||
glslCode.insert(pos, clampLine);
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
namespace PrgramImpl {
|
||||
String ProcessOutColorLocations(const String& glslCode);
|
||||
String ForceSupporterOutput(const String& glslCode);
|
||||
String ClampSnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask);
|
||||
String ClampNormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 snormOutputMask,
|
||||
Uint32 unormOutputMask);
|
||||
String ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType);
|
||||
String RemoveLayoutBinding(const String& glslCode);
|
||||
} // namespace PrgramImpl
|
||||
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user