Merge pull request #1915 from TheAggie/fix/agc-radv-raster-defaults

fix(agc): accept RADV's disabled conservative rasterization and out-of-order watermark
This commit is contained in:
Dean 2026-10-10 17:42:34 +13:00 committed by GitHub
commit 8002d11f67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 5 deletions

View File

@ -58,7 +58,7 @@ std::string vteMessage(std::uint32_t viewportControl) {
std::string conservativeMessage(std::uint32_t control) {
std::ostringstream message;
message << "AGC graphics: PA_SC_CONSERVATIVE_RASTERIZATION_CNTL=0x" << std::hex << control << ": only 0x6000 (off) and 0x6001 (overestimation) are supported";
message << "AGC graphics: PA_SC_CONSERVATIVE_RASTERIZATION_CNTL=0x" << std::hex << control << ": only off (0x6000, or RADV's 0x100000) and 0x6001 (overestimation) are supported";
return message.str();
}
@ -72,7 +72,7 @@ void requireConservativeTriangles(bool triangles, const char* primitive, const c
VkConservativeRasterizationModeEXT decodeConservativeRasterization(const QueueState& queue) {
const auto& cx = queue.context;
const auto control = read(cx, 0x313);
if (control == 0x6000u) return VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
if ((control & ~0x00106000u) == 0) return VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
if (control != 0x6001u) throw std::runtime_error(conservativeMessage(control));
const auto stages = read(cx, 0x2d5);
if ((stages & 0x20u) != 0) {
@ -105,7 +105,7 @@ constexpr std::uint32_t ShaderControlMask = ~(0x0000f870u | 0x00020600u | 0x0001
constexpr std::uint32_t PixelStageRunsMask = 0x00020747u;
constexpr std::uint32_t AlphaToCoverageMask = ~0x0001ff00u;
constexpr std::uint32_t ScanModeMask = ~0x22u;
constexpr std::uint32_t ScanControlMask = ~0x06023fffu;
constexpr std::uint32_t ScanControlMask = ~0x76023fffu;
constexpr std::uint32_t ScreenOffsetMask = ~0x01ff01ffu;
// Bits 26/27 (ZCLIP_NEAR/FAR_DISABLE) become depth clamping; bit 19 selects the [0, 1] clip space.
constexpr std::uint32_t ClipControlMask = ~(0x80000u | 0x01000000u | 0x0c000000u);
@ -586,7 +586,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;
@ -911,7 +913,7 @@ std::string DrawRejection(const QueueState& queue, bool indexed) {
if (value(cx, 0x83, word) && word != 0xffffu) return require(false, "clip rectangles are unsupported");
if (value(cx, 0x8c, word) && (word & 0xfu) != 0xau) return require(false, "nonstandard triangle edge rules are unsupported");
if (value(cx, 0x2f9, word) && word != 0x2du) return require(false, "nonstandard pixel center or vertex quantization is unsupported");
if (value(cx, 0x313, word) && word != 0x6000u && word != 0x6001u) return conservativeMessage(word);
if (value(cx, 0x313, word) && (word & ~0x00106000u) != 0 && word != 0x6001u) return conservativeMessage(word);
std::uint32_t other = 0;
if (value(cx, 0x30e, word) && value(cx, 0x30f, other) && (word != 0xffffffffu || other != 0xffffffffu)) return require(false, "sample masks are unsupported");
if (value(cx, 0x206, word) && word != 0x43fu) return vteMessage(word);

View File

@ -123,9 +123,26 @@ void stateTests() {
queue.context[0x293] = 0x06020000u;
(void)AgcDriver::Graphics::DecodeState(queue);
Require(AgcDriver::Graphics::DrawRejection(queue, false).find("sample iteration") == std::string::npos, "per-engine primitive discard was rejected");
queue.context[0x293] = 0x760201bcu;
(void)AgcDriver::Graphics::DecodeState(queue);
Require(AgcDriver::Graphics::DrawRejection(queue, false).find("sample iteration") == std::string::npos, "an out-of-order watermark without out-of-order rasterization was rejected");
queue.context[0x293] = 0x7e0201bcu;
Require(AgcDriver::Graphics::DrawRejection(queue, false).find("sample iteration") != std::string::npos, "out-of-order rasterization was accepted");
queue.context[0x293] = 0x06030000u;
Require(AgcDriver::Graphics::DrawRejection(queue, false).find("sample iteration") != std::string::npos, "per-sample shading was accepted");
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "sample iteration");
queue.context[0x293] = 0;
for (const auto disabled : {0x6000u, 0x00100000u, 0u}) {
queue.context[0x313] = disabled;
Require(AgcDriver::Graphics::DecodeState(queue).conservativeRasterization == VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, "disabled conservative rasterization decoded as enabled");
Require(AgcDriver::Graphics::DrawRejection(queue, false).find("PA_SC_CONSERVATIVE") == std::string::npos, "disabled conservative rasterization was rejected");
}
for (const auto enabled : {0x00e00001u, 0x01e00022u}) {
queue.context[0x313] = enabled;
Require(AgcDriver::Graphics::DrawRejection(queue, false).find("PA_SC_CONSERVATIVE") != std::string::npos, "conservative rasterization was accepted");
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "PA_SC_CONSERVATIVE");
}
queue.context[0x313] = 0x6000u;
queue = makeState();
queue.userConfig.erase(0x24b);
queue.context[0x2a5] = 0;
@ -930,6 +947,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;