diff --git a/include/PICA/pica_frag_config.hpp b/include/PICA/pica_frag_config.hpp index 8352cba2..59f13757 100644 --- a/include/PICA/pica_frag_config.hpp +++ b/include/PICA/pica_frag_config.hpp @@ -16,6 +16,7 @@ namespace PICA { // Merge the enable + compare function into 1 field to avoid duplicate shaders // enable == off means a CompareFunction of Always BitField<0, 3, CompareFunction> alphaTestFunction; + BitField<4, 1, u32> depthMapEnable; }; }; diff --git a/include/PICA/pica_frag_uniforms.hpp b/include/PICA/pica_frag_uniforms.hpp index b151ed42..616f1882 100644 --- a/include/PICA/pica_frag_uniforms.hpp +++ b/include/PICA/pica_frag_uniforms.hpp @@ -11,6 +11,8 @@ namespace PICA { static constexpr usize tevStageCount = 6; s32 alphaReference; + float depthScale; + float depthOffset; alignas(16) vec4 constantColors[tevStageCount]; alignas(16) vec4 tevBufferColor; diff --git a/src/core/PICA/shader_gen_glsl.cpp b/src/core/PICA/shader_gen_glsl.cpp index 50e9c3de..f19c699d 100644 --- a/src/core/PICA/shader_gen_glsl.cpp +++ b/src/core/PICA/shader_gen_glsl.cpp @@ -113,6 +113,8 @@ std::string FragmentGenerator::generate(const PICARegs& regs) { layout(std140) uniform FragmentUniforms { int alphaReference; + float depthScale; + float depthOffset; vec4 constantColors[6]; vec4 tevBufferColor; @@ -138,6 +140,19 @@ std::string FragmentGenerator::generate(const PICARegs& regs) { float alphaOp3 = 0.0; )"; + ret += R"( + // Get original depth value by converting from [near, far] = [0, 1] to [-1, 1] + // We do this by converting to [0, 2] first and subtracting 1 to go to [-1, 1] + float z_over_w = gl_FragCoord.z * 2.0f - 1.0f; + float depth = z_over_w * depthScale + depthOffset; + )"; + + if ((regs[InternalRegs::DepthmapEnable] & 1) == 0) { + ret += "depth /= gl_FragCoord.w;\n"; + } + + ret += "gl_FragDepth = depth;\n"; + textureConfig = regs[InternalRegs::TexUnitCfg]; for (int i = 0; i < 6; i++) { compileTEV(ret, i, regs); diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index aa3bb61b..9c60ac5f 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -410,12 +410,12 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span v static constexpr std::array depthModes = {GL_NEVER, GL_ALWAYS, GL_EQUAL, GL_NOTEQUAL, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL}; - const float depthScale = f24::fromRaw(regs[PICA::InternalRegs::DepthScale] & 0xffffff).toFloat32(); - const float depthOffset = f24::fromRaw(regs[PICA::InternalRegs::DepthOffset] & 0xffffff).toFloat32(); - const bool depthMapEnable = regs[PICA::InternalRegs::DepthmapEnable] & 1; - // Update ubershader uniforms if (usingUbershader) { + const float depthScale = f24::fromRaw(regs[PICA::InternalRegs::DepthScale] & 0xffffff).toFloat32(); + const float depthOffset = f24::fromRaw(regs[PICA::InternalRegs::DepthOffset] & 0xffffff).toFloat32(); + const bool depthMapEnable = regs[PICA::InternalRegs::DepthmapEnable] & 1; + if (oldDepthScale != depthScale) { oldDepthScale = depthScale; glUniform1f(ubershaderData.depthScaleLoc, depthScale); @@ -785,7 +785,9 @@ OpenGL::Program& RendererGL::getSpecializedShader() { auto alphaTestConfig = regs[InternalRegs::AlphaTestConfig]; auto alphaTestFunction = Helpers::getBits<4, 3>(alphaTestConfig); + outConfig.alphaTestFunction = (alphaTestConfig & 1) ? static_cast(alphaTestFunction) : PICA::CompareFunction::Always; + outConfig.depthMapEnable = regs[InternalRegs::DepthmapEnable] & 1; texConfig.texUnitConfig = regs[InternalRegs::TexUnitCfg]; texConfig.texEnvUpdateBuffer = regs[InternalRegs::TexEnvUpdateBuffer]; @@ -840,6 +842,9 @@ OpenGL::Program& RendererGL::getSpecializedShader() { uniforms.tevBufferColor[2] = float((texEnvBufferColor >> 16) & 0xFF) / 255.0f; uniforms.tevBufferColor[3] = float((texEnvBufferColor >> 24) & 0xFF) / 255.0f; + uniforms.depthScale = f24::fromRaw(regs[PICA::InternalRegs::DepthScale] & 0xffffff).toFloat32(); + uniforms.depthOffset = f24::fromRaw(regs[PICA::InternalRegs::DepthOffset] & 0xffffff).toFloat32(); + // Set up the constant color for the 6 TEV stages for (int i = 0; i < 6; i++) { static constexpr std::array ioBases = {