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 <noreply@anthropic.com>
This commit is contained in:
Scott Schuster 2026-10-09 00:54:22 -05:00
parent 88cc2ea477
commit af9e60b690
2 changed files with 10 additions and 1 deletions

View File

@ -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;

View File

@ -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;