Merge pull request #114 from oneandonlydean/fix/inert-depth-write

fix(agc): accept depth writes that the disabled depth test makes inert
This commit is contained in:
boykopovar 2026-09-30 17:56:37 +03:00 committed by GitHub
commit eaa47d66ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 2 deletions

View File

@ -182,6 +182,10 @@ bool depthPassThrough(std::uint32_t depthControl) {
return (stencil || depth) && passThroughDepth && passThroughStencil;
}
std::uint32_t effectiveDepthControl(std::uint32_t depthControl) {
return (depthControl & 3u) == 0 ? depthControl & ~4u : depthControl;
}
bool colorControlSupported(std::uint32_t colorControl, bool hasColorTarget) {
return colorControl == 0xcc0010u || (!hasColorTarget && (colorControl & ~0x70u) == 0xcc0000u);
}
@ -416,7 +420,7 @@ State DecodeState(const QueueState& queue) {
std::fprintf(stderr, "[gpu] depth/stencil tests are ignored (APS5_IGNORE_DEPTH_TEST; DB_DEPTH_CONTROL=0x%08x)\n", depthControl);
}
} else {
zero(cx, 0x200, DepthControlMask, "depth, stencil or conditional color writes");
if ((effectiveDepthControl(depthControl) & DepthControlMask) != 0) zero(cx, 0x200, DepthControlMask, "depth, stencil or conditional color writes");
}
Require((depthControl & 0xc0000008u) == 0, "depth bounds or depth-conditional color writes are unsupported");
}
@ -643,7 +647,7 @@ std::string DrawRejection(const QueueState& queue, bool indexed) {
if (auto reason = nonzero(cx, 0x207, ~LayerExports, "clip distances, layer, viewport or auxiliary vertex exports"); !reason.empty()) return reason;
if (value(cx, 0x200, word)) {
const bool surface = (word & 3u) != 0 && depthSurfaceBound(cx);
if (!surface && !depthPassThrough(word) && !IgnoreDepthTest() && (word & DepthControlMask) != 0) return zeroMessage(0x200, word, "depth, stencil or conditional color writes");
if (!surface && !depthPassThrough(word) && !IgnoreDepthTest() && (effectiveDepthControl(word) & DepthControlMask) != 0) return zeroMessage(0x200, word, "depth, stencil or conditional color writes");
if (auto reason = require((word & 0xc0000008u) == 0, "depth bounds or depth-conditional color writes are unsupported"); !reason.empty()) return reason;
}
if (auto reason = nonzero(cx, 0x203, ShaderControlMask, "depth export, shader coverage or ordered fragment execution"); !reason.empty()) return reason;

View File

@ -127,6 +127,15 @@ void stateTests() {
queue.context[0x200] = 2;
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "depth");
queue = makeState();
queue.context[0x200] = 0x007007b4;
queue.context[0x1b3] = 2;
queue.context[0x1b4] = 2;
(void)AgcDriver::Graphics::DecodeState(queue);
Require(AgcDriver::Graphics::DrawRejection(queue, false).empty(), "a depth write without the depth test was rejected");
queue = makeState();
queue.context[0x200] = 0x007007b6;
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "depth");
queue = makeState();
queue.context[0x10f] = 0x7fc00000;
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "non-finite");
// The register facade: every register the decoders read is in DrawKeyRegisters (a wrong hit of