From af9e60b690b3d3ebfcd0fc8e044ffc26f338b4a3 Mon Sep 17 00:00:00 2001 From: Scott Schuster Date: Fri, 9 Oct 2026 00:54:22 -0500 Subject: [PATCH] fix(agc): accept RADV's point and line depth bias enable on triangle draws With depth bias enabled, RADV sets POLY_OFFSET_PARA_ENABLE in PA_SU_SC_MODE_CNTL next to the front and back enables, whatever the topology; vkQuake's draws carry 0x3a46. The bit applies the offset to points and lines, so it changes nothing for triangles, and Vulkan applies depth bias only to polygons. It is now accepted with depth bias on triangle topologies; point and line draws with it are still rejected. Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp | 4 +++- core/libs/prx/libSceAgcDriver/tests/Graphics.cpp | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp index 089279da3..9b616a2dc 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp @@ -553,7 +553,9 @@ State DecodeState(const QueueState& queue) { const auto raster = read(cx, 0x205); // Bits 5-10 give the front/back polygon type (2 = filled triangles), which POLY_MODE (bit 3) turns on // explicitly; KEEP_TOGETHER_ENABLE (bit 24) only affects primitive distribution across the chip. - const auto rasterMode = raster & ~0x7u & ~(1u << 24u) & ~0x1800u; + const bool pointsOrLines = result.topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST || result.topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + const auto lineOffset = (raster & 0x1800u) != 0 && !pointsOrLines ? 0x2000u : 0u; + const auto rasterMode = raster & ~0x7u & ~(1u << 24u) & ~0x1800u & ~lineOffset; if (rasterMode != 0 && rasterMode != 0x240u && rasterMode != 0x248u) throw std::runtime_error("AGC graphics: " + zeroMessage(0x205, raster, "polygon mode, depth bias, provoking vertex or nonstandard rasterization")); result.cullMode = ((raster & 1u) != 0 ? VK_CULL_MODE_FRONT_BIT : 0u) | ((raster & 2u) != 0 ? VK_CULL_MODE_BACK_BIT : 0u); if (result.rectList) result.cullMode = VK_CULL_MODE_NONE; diff --git a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp index 597409d3f..e04c75780 100644 --- a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp @@ -878,6 +878,13 @@ void DepthBoundsBiasTests() { queue.context[0x205] = 0x00001a4au; state = AgcDriver::Graphics::DecodeState(queue); Require(state.depthBias && state.depthBiasConstant == 4.0f, "culled back faces must not constrain the front depth bias"); + queue.context[0x205] = 0x00003a46u; + state = AgcDriver::Graphics::DecodeState(queue); + Require(state.depthBias && state.depthBiasConstant == 4.0f && state.cullMode == VK_CULL_MODE_BACK_BIT, "a triangle draw with the point and line offset enable lost its depth bias"); + queue.userConfig[0x242] = 2; + expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "polygon mode, depth bias, provoking vertex"); + queue.userConfig[0x242] = 4; + queue.context[0x205] = 0x00001a4au; queue.context[0x2de] = 0x1f0u; expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "units other than the depth format"); queue.context[0x2de] = 0x1e9u;