Shader recompiler: Add depth mapping

This commit is contained in:
wheremyfoodat 2024-07-15 04:30:04 +03:00
parent c8eb1c1128
commit 0878474e01
4 changed files with 27 additions and 4 deletions

View file

@ -16,6 +16,7 @@ namespace PICA {
// Merge the enable + compare function into 1 field to avoid duplicate shaders // Merge the enable + compare function into 1 field to avoid duplicate shaders
// enable == off means a CompareFunction of Always // enable == off means a CompareFunction of Always
BitField<0, 3, CompareFunction> alphaTestFunction; BitField<0, 3, CompareFunction> alphaTestFunction;
BitField<4, 1, u32> depthMapEnable;
}; };
}; };

View file

@ -11,6 +11,8 @@ namespace PICA {
static constexpr usize tevStageCount = 6; static constexpr usize tevStageCount = 6;
s32 alphaReference; s32 alphaReference;
float depthScale;
float depthOffset;
alignas(16) vec4 constantColors[tevStageCount]; alignas(16) vec4 constantColors[tevStageCount];
alignas(16) vec4 tevBufferColor; alignas(16) vec4 tevBufferColor;

View file

@ -113,6 +113,8 @@ std::string FragmentGenerator::generate(const PICARegs& regs) {
layout(std140) uniform FragmentUniforms { layout(std140) uniform FragmentUniforms {
int alphaReference; int alphaReference;
float depthScale;
float depthOffset;
vec4 constantColors[6]; vec4 constantColors[6];
vec4 tevBufferColor; vec4 tevBufferColor;
@ -138,6 +140,19 @@ std::string FragmentGenerator::generate(const PICARegs& regs) {
float alphaOp3 = 0.0; 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]; textureConfig = regs[InternalRegs::TexUnitCfg];
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
compileTEV(ret, i, regs); compileTEV(ret, i, regs);

View file

@ -410,12 +410,12 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
static constexpr std::array<GLenum, 8> depthModes = {GL_NEVER, GL_ALWAYS, GL_EQUAL, GL_NOTEQUAL, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL}; static constexpr std::array<GLenum, 8> 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 // Update ubershader uniforms
if (usingUbershader) { 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) { if (oldDepthScale != depthScale) {
oldDepthScale = depthScale; oldDepthScale = depthScale;
glUniform1f(ubershaderData.depthScaleLoc, depthScale); glUniform1f(ubershaderData.depthScaleLoc, depthScale);
@ -785,7 +785,9 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
auto alphaTestConfig = regs[InternalRegs::AlphaTestConfig]; auto alphaTestConfig = regs[InternalRegs::AlphaTestConfig];
auto alphaTestFunction = Helpers::getBits<4, 3>(alphaTestConfig); auto alphaTestFunction = Helpers::getBits<4, 3>(alphaTestConfig);
outConfig.alphaTestFunction = (alphaTestConfig & 1) ? static_cast<PICA::CompareFunction>(alphaTestFunction) : PICA::CompareFunction::Always; outConfig.alphaTestFunction = (alphaTestConfig & 1) ? static_cast<PICA::CompareFunction>(alphaTestFunction) : PICA::CompareFunction::Always;
outConfig.depthMapEnable = regs[InternalRegs::DepthmapEnable] & 1;
texConfig.texUnitConfig = regs[InternalRegs::TexUnitCfg]; texConfig.texUnitConfig = regs[InternalRegs::TexUnitCfg];
texConfig.texEnvUpdateBuffer = regs[InternalRegs::TexEnvUpdateBuffer]; texConfig.texEnvUpdateBuffer = regs[InternalRegs::TexEnvUpdateBuffer];
@ -840,6 +842,9 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
uniforms.tevBufferColor[2] = float((texEnvBufferColor >> 16) & 0xFF) / 255.0f; uniforms.tevBufferColor[2] = float((texEnvBufferColor >> 16) & 0xFF) / 255.0f;
uniforms.tevBufferColor[3] = float((texEnvBufferColor >> 24) & 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 // Set up the constant color for the 6 TEV stages
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
static constexpr std::array<u32, 6> ioBases = { static constexpr std::array<u32, 6> ioBases = {