Make the MaxZ test a bit more lenient to fix Taiko no Tatsujin. Debugger improvement

Fixes #21797
This commit is contained in:
Henrik Rydgård committed 2026-06-07 13:47:42 +02:00
1 parent d19f8b72f9
commit a7f62d763a
5 files changed
+25 -12

No files matched your search

+6 -4
View File
@@ -1178,10 +1178,12 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
}
if (fsMinmaxDiscard) {
// See the vertex shader generator for the explanation for this.
WRITE(p, " float clipZ = floor(projZ * 0.5 + 0.5) * 2.0;\n");
WRITE(p, " if (u_minZmaxZ.x > 0.0 && clipZ < u_minZmaxZ.x) DISCARD;\n");
WRITE(p, " if (u_minZmaxZ.y < 65535.0 && clipZ > u_minZmaxZ.y) DISCARD;\n");
// See the vertex shader generator for the explanation for this - and don't forget to update both
// places if you change this.
WRITE(p, " float clipZNear = floor(projZ * 0.5 + 0.5) * 2.0;\n");
WRITE(p, " float clipZFar = floor(projZ * 0.5) * 2.0;\n");
WRITE(p, " if (u_minZmaxZ.x > 0.0 && clipZNear < u_minZmaxZ.x) DISCARD;\n");
WRITE(p, " if (u_minZmaxZ.y < 65535.0 && clipZFar > u_minZmaxZ.y) DISCARD;\n");
}
if (writeDepth) {
+9 -3
View File
@@ -1248,6 +1248,8 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
// I think we should use min/max clipping for through-mode as well, right?
if (clipMinMax) {
// NOTE: When changing this test, don't forget to change the test in the fragment shader fallback too.
// We use clipping, where available, to implement min/max Z.
// 1.0 is used to disable the clip plane (should we generate more shaders instead? how costly are they?)
@@ -1256,10 +1258,14 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
// We round to nearest 15-bit value for the check - this seems to match some of [Unknown]'s test, and PSP GPU floats
// often have a 15-bit mantissa. TODO: should we truncate or nearest?
WRITE(p, " float clipZ = floor(outPos.z * 0.5 + 0.5) * 2.0;\n");
// Due to us having a bit too much precision, we round the value up for the min check and down for the max check.
// Will test this on hardware more carefully soon.
// The min check rounded down fixes the Test Drive map problem, and the max check rounded down fixes Taiko no Tatsujin.
WRITE(p, " float clipZNear = floor(outPos.z * 0.5 + 0.5) * 2.0;\n");
WRITE(p, " float clipZFar = floor(outPos.z * 0.5) * 2.0;\n");
WRITE(p, " %sgl_ClipDistance%s = u_minZmaxZ.x > 0.0 ? (clipZ - u_minZmaxZ.x) * outPos.w : 1.0;\n", compat.vsOutPrefix, minZClipPlaneSuffix);
WRITE(p, " %sgl_ClipDistance%s = u_minZmaxZ.y < 65535.0 ? (u_minZmaxZ.y - clipZ) * outPos.w : 1.0;\n", compat.vsOutPrefix, maxZClipPlaneSuffix);
WRITE(p, " %sgl_ClipDistance%s = u_minZmaxZ.x > 0.0 ? (clipZNear - u_minZmaxZ.x) * outPos.w : 1.0;\n", compat.vsOutPrefix, minZClipPlaneSuffix);
WRITE(p, " %sgl_ClipDistance%s = u_minZmaxZ.y < 65535.0 ? (u_minZmaxZ.y - clipZFar) * outPos.w : 1.0;\n", compat.vsOutPrefix, maxZClipPlaneSuffix);
}
// Convert to NDC space, using the framebuffer offset and size stored in u_xywh.
+5 -5
View File
@@ -43,7 +43,7 @@ static constexpr GECmdInfo geCmdInfo[] = {
{ GE_CMD_BJUMP, "bjump", GECmdFormat::JUMP, "BJump" },
{ GE_CMD_CALL, "call", GECmdFormat::JUMP, "Call" },
{ GE_CMD_RET, "ret", GECmdFormat::NONE, "Return" },
{ GE_CMD_END, "end", GECmdFormat::DATA16, "End", CMD_FMT_HEX },
{ GE_CMD_END, "end", GECmdFormat::DATA16, "End", CMD_FMT_HEX_AND_INT },
{ GE_CMD_UNKNOWN_0D, "unknown0d", GECmdFormat::NONE, "Unknown0D" },
{ GE_CMD_SIGNAL, "signal", GECmdFormat::SIGNAL, "Signal" },
{ GE_CMD_FINISH, "finish", GECmdFormat::NONE, "Finish" },
@@ -85,7 +85,7 @@ static constexpr GECmdInfo geCmdInfo[] = {
{ GE_CMD_MORPHWEIGHT7, "morph7", GECmdFormat::FLOAT, "Morph weight 7", CMD_FMT_FLOAT24 },
{ GE_CMD_UNKNOWN_34, "unknown34", GECmdFormat::NONE, "Unknown34" },
{ GE_CMD_UNKNOWN_35, "unknown35", GECmdFormat::NONE, "Unknown35" },
{ GE_CMD_PATCHDIVISION, "patchdivision", GECmdFormat::PATCH_DIVISION, "Patch division", CMD_FMT_HEX },
{ GE_CMD_PATCHDIVISION, "patchdivision", GECmdFormat::PATCH_DIVISION, "Patch division", CMD_FMT_HEX_AND_INT },
{ GE_CMD_PATCHPRIMITIVE, "patchprim", GECmdFormat::PATCH_PRIM, "Patch primitive", CMD_FMT_PATCHPRIMITIVE },
{ GE_CMD_PATCHFACING, "patchreversenormals", GECmdFormat::FLAG, "Patch facing", CMD_FMT_HEX, GE_CMD_PATCHCULLENABLE },
{ GE_CMD_UNKNOWN_39, "unknown39", GECmdFormat::NONE, "Unknown39" },
@@ -248,8 +248,8 @@ static constexpr GECmdInfo geCmdInfo[] = {
{ GE_CMD_CLEARMODE, "clearmode", GECmdFormat::CLEAR_MODE, "Clear mode", CMD_FMT_CLEARMODE},
{ GE_CMD_SCISSOR1, "scissor1", GECmdFormat::X10_Y10, "Scissor rectangle", CMD_FMT_XYXY, 0, GE_CMD_SCISSOR2},
{ GE_CMD_SCISSOR2, "scissor2", GECmdFormat::X10_Y10, "Scissor2", },
{ GE_CMD_MINZ, "minz", GECmdFormat::DATA16, "Min Z", CMD_FMT_HEX},
{ GE_CMD_MAXZ, "maxz", GECmdFormat::DATA16, "Max Z", CMD_FMT_HEX},
{ GE_CMD_MINZ, "minz", GECmdFormat::DATA16, "Min Z", CMD_FMT_HEX_AND_INT},
{ GE_CMD_MAXZ, "maxz", GECmdFormat::DATA16, "Max Z", CMD_FMT_HEX_AND_INT},
{ GE_CMD_COLORTEST, "ctestfunc", GECmdFormat::COLOR_TEST_FUNC, "Color test", CMD_FMT_COLORTEST, GE_CMD_COLORTESTENABLE, GE_CMD_COLORREF, GE_CMD_COLORTESTMASK},
{ GE_CMD_COLORREF, "ctestref", GECmdFormat::RGB, "Color test ref", CMD_FMT_HEX, },
{ GE_CMD_COLORTESTMASK, "ctestmask", GECmdFormat::RGB, "Color test mask", CMD_FMT_HEX, GE_CMD_COLORTESTENABLE},
@@ -276,7 +276,7 @@ static constexpr GECmdInfo geCmdInfo[] = {
{ GE_CMD_UNKNOWN_EF, "unknownef", GECmdFormat::NONE, "UnknownEF" },
{ GE_CMD_VSCX, "immx", GECmdFormat::SUBPIXEL_COORD, "Imm vertex XY", CMD_FMT_F16_XY, 0, GE_CMD_VSCY},
{ GE_CMD_VSCY, "immy", GECmdFormat::SUBPIXEL_COORD, "Imm vertex Y" },
{ GE_CMD_VSCZ, "immz", GECmdFormat::DATA16, "Imm vertex Z", CMD_FMT_HEX},
{ GE_CMD_VSCZ, "immz", GECmdFormat::DATA16, "Imm vertex Z", CMD_FMT_HEX_AND_INT},
{ GE_CMD_VTCS, "imms", GECmdFormat::FLOAT, "Imm vertex STQ", CMD_FMT_XYZ, 0, GE_CMD_VTCT, GE_CMD_VTCQ},
{ GE_CMD_VTCT, "immt", GECmdFormat::FLOAT, "Imm vertex T", CMD_FMT_FLOAT24 },
{ GE_CMD_VTCQ, "immq", GECmdFormat::FLOAT, "Imm vertex Q", CMD_FMT_FLOAT24 },
+1
View File
@@ -76,6 +76,7 @@ enum class GECmdFormat {
// TODO: Merge with the above.
enum CmdFormatType {
CMD_FMT_HEX = 0,
CMD_FMT_HEX_AND_INT,
CMD_FMT_NUM,
CMD_FMT_FLOAT24,
CMD_FMT_PTRWIDTH,
+4
View File
@@ -53,6 +53,10 @@ void FormatStateRow(char *dest, size_t destSize, CmdFormatType fmt, u32 value, b
snprintf(dest, destSize, "%06x", value);
break;
case CMD_FMT_HEX_AND_INT:
snprintf(dest, destSize, "%06x (%d)", value, value);
break;
case CMD_FMT_NUM:
snprintf(dest, destSize, "%d", value);
break;