mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +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_archive: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.tgz
|
||||||
trace_file: trace.trace
|
trace_file: trace.trace
|
||||||
golden: tools/trace_replay/fixtures/minecraft-1.21.4-fabric-iris-bsl-in-world.0000110725.png
|
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
|
target_call: 110725
|
||||||
width: 854
|
width: 854
|
||||||
height: 480
|
height: 480
|
||||||
|
|||||||
@@ -744,7 +744,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
backendObj->SyncToBackend(currentProgram);
|
backendObj->SyncToBackend(currentProgram);
|
||||||
} else {
|
} else {
|
||||||
if (!backendObj->GetBackendProgramId() ||
|
if (!backendObj->GetBackendProgramId() ||
|
||||||
backendObj->GetSnormFallbackClampOutputMask() != g_snormFallbackClampOutputMask) {
|
backendObj->GetSnormFallbackClampOutputMask() != g_snormFallbackClampOutputMask ||
|
||||||
|
backendObj->GetUnormFallbackClampOutputMask() != g_unormFallbackClampOutputMask) {
|
||||||
backendObj->SyncToBackend(currentProgram);
|
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(
|
static Bool IsSnormFallbackAttachment(
|
||||||
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject) {
|
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject) {
|
||||||
if (attachmentObject.IsTexture()) {
|
if (attachmentObject.IsTexture()) {
|
||||||
@@ -1348,6 +1360,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
return false;
|
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(
|
void BackendFramebufferObject::SyncToBackend(
|
||||||
const SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, FramebufferTarget asTarget) {
|
const SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject, FramebufferTarget asTarget) {
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
@@ -1399,7 +1427,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (asTarget == FramebufferTarget::Draw) {
|
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) {
|
for (Uint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS && i < 32; ++i) {
|
||||||
const auto frontendBuf = stateDrawBuffers[i];
|
const auto frontendBuf = stateDrawBuffers[i];
|
||||||
if (frontendBuf < FramebufferAttachmentType::Color0 ||
|
if (frontendBuf < FramebufferAttachmentType::Color0 ||
|
||||||
@@ -1408,10 +1437,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
}
|
}
|
||||||
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendBuf);
|
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendBuf);
|
||||||
if (IsSnormFallbackAttachment(attachmentObject)) {
|
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
|
// 2. Remap read buffer
|
||||||
@@ -1527,6 +1559,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
|
|
||||||
namespace PrgramImpl {
|
namespace PrgramImpl {
|
||||||
Uint32 g_snormFallbackClampOutputMask = 0;
|
Uint32 g_snormFallbackClampOutputMask = 0;
|
||||||
|
Uint32 g_unormFallbackClampOutputMask = 0;
|
||||||
StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> g_backendProgramObjects;
|
StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl> g_backendProgramObjects;
|
||||||
|
|
||||||
BackendProgramObjectImpl::BackendProgramObjectImpl() {
|
BackendProgramObjectImpl::BackendProgramObjectImpl() {
|
||||||
@@ -1572,6 +1605,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_snormFallbackClampOutputMask = g_snormFallbackClampOutputMask;
|
m_snormFallbackClampOutputMask = g_snormFallbackClampOutputMask;
|
||||||
|
m_unormFallbackClampOutputMask = g_unormFallbackClampOutputMask;
|
||||||
|
|
||||||
// Detach all existing shaders
|
// Detach all existing shaders
|
||||||
GLint attachedCount = 0;
|
GLint attachedCount = 0;
|
||||||
@@ -1647,8 +1681,9 @@ 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 = ClampSnormFallbackOutputs(std::move(source), glShaderType,
|
source = ClampNormFallbackOutputs(std::move(source), glShaderType,
|
||||||
m_snormFallbackClampOutputMask);
|
m_snormFallbackClampOutputMask,
|
||||||
|
m_unormFallbackClampOutputMask);
|
||||||
|
|
||||||
// Patch for Photon compiler precision issue
|
// Patch for Photon compiler precision issue
|
||||||
String findStr = "1000000.0";
|
String findStr = "1000000.0";
|
||||||
|
|||||||
@@ -285,16 +285,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
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 GetSnormFallbackClampOutputMask() const { return m_snormFallbackClampOutputMask; }
|
Uint32 GetSnormFallbackClampOutputMask() const { return m_snormFallbackClampOutputMask; }
|
||||||
|
Uint32 GetUnormFallbackClampOutputMask() const { return m_unormFallbackClampOutputMask; }
|
||||||
|
|
||||||
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_snormFallbackClampOutputMask = 0;
|
Uint32 m_snormFallbackClampOutputMask = 0;
|
||||||
|
Uint32 m_unormFallbackClampOutputMask = 0;
|
||||||
Bool m_isInitialized = false;
|
Bool m_isInitialized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Uint32 g_snormFallbackClampOutputMask;
|
extern Uint32 g_snormFallbackClampOutputMask;
|
||||||
|
extern Uint32 g_unormFallbackClampOutputMask;
|
||||||
extern StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl>
|
extern StateBackendObjectRegistry<MG_State::GLState::ProgramObject, BackendProgramObjectImpl>
|
||||||
g_backendProgramObjects;
|
g_backendProgramObjects;
|
||||||
} // namespace PrgramImpl
|
} // namespace PrgramImpl
|
||||||
|
|||||||
@@ -214,10 +214,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ClampSnormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 outputMask) {
|
String ClampNormFallbackOutputs(String glslCode, GLenum shaderType, Uint32 snormOutputMask,
|
||||||
|
Uint32 unormOutputMask) {
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||||
#endif
|
#endif
|
||||||
|
const Uint32 outputMask = snormOutputMask | unormOutputMask;
|
||||||
if (shaderType != GL_FRAGMENT_SHADER || outputMask == 0) {
|
if (shaderType != GL_FRAGMENT_SHADER || outputMask == 0) {
|
||||||
return glslCode;
|
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*;)");
|
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 outputIt(glslCode.begin(), glslCode.end(), outputPattern);
|
||||||
std::sregex_iterator outputEnd;
|
std::sregex_iterator outputEnd;
|
||||||
Vector<String> outputNames;
|
struct OutputClamp {
|
||||||
|
String Name;
|
||||||
|
Bool Signed;
|
||||||
|
};
|
||||||
|
Vector<OutputClamp> outputClamps;
|
||||||
for (; outputIt != outputEnd; ++outputIt) {
|
for (; outputIt != outputEnd; ++outputIt) {
|
||||||
const Uint location = static_cast<Uint>(std::stoul((*outputIt)[1].str()));
|
const Uint location = static_cast<Uint>(std::stoul((*outputIt)[1].str()));
|
||||||
if (location < 32 && (outputMask & (1u << location))) {
|
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;
|
return glslCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,9 +258,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
--depth;
|
--depth;
|
||||||
if (depth == 0) {
|
if (depth == 0) {
|
||||||
String clampLine;
|
String clampLine;
|
||||||
for (const String& outputName : outputNames) {
|
for (const OutputClamp& outputClamp : outputClamps) {
|
||||||
clampLine += "\n " + outputName + " = clamp(" + outputName +
|
const String minValue = outputClamp.Signed ? "-1.0" : "0.0";
|
||||||
", vec4(-1.0), vec4(1.0));";
|
clampLine += "\n " + outputClamp.Name + " = clamp(" + outputClamp.Name +
|
||||||
|
", vec4(" + minValue + "), vec4(1.0));";
|
||||||
}
|
}
|
||||||
clampLine += "\n";
|
clampLine += "\n";
|
||||||
glslCode.insert(pos, clampLine);
|
glslCode.insert(pos, clampLine);
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ 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 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 ForceFlatIntegerVaryings(const String& glslCode, GLenum shaderType);
|
||||||
String RemoveLayoutBinding(const String& glslCode);
|
String RemoveLayoutBinding(const String& glslCode);
|
||||||
} // namespace PrgramImpl
|
} // namespace PrgramImpl
|
||||||
|
|||||||
BIN
Binary file not shown.
Reference in New Issue
Block a user