Merge pull request #3702 from oneandonlydean/up4/depth-tests-without-planes
fix(agc): leave the depth surface out when no enabled test has its plane
This commit is contained in:
commit
4bde70b4e2
|
|
@ -138,6 +138,14 @@ bool depthSurfaceBound(const Registers& cx) {
|
|||
return (z != cx.end() && (z->second & 3u) != 0) || (stencil != cx.end() && (stencil->second & 1u) != 0);
|
||||
}
|
||||
|
||||
std::uint32_t planeTests(const Registers& cx, std::uint32_t depthControl) {
|
||||
const auto z = find(cx, 0x010);
|
||||
const auto stencil = find(cx, 0x011);
|
||||
if (z != cx.end() && (z->second & 3u) == 0) depthControl &= ~2u;
|
||||
if (stencil != cx.end() && (stencil->second & 1u) == 0) depthControl &= ~1u;
|
||||
return depthControl & 0xbu;
|
||||
}
|
||||
|
||||
bool depthPlanesAbsent(const Registers& cx) {
|
||||
const auto z = find(cx, 0x010);
|
||||
const auto stencil = find(cx, 0x011);
|
||||
|
|
@ -583,9 +591,10 @@ State DecodeState(const QueueState& queue, bool vertexWorkgroup) {
|
|||
const auto depthControl = read(cx, 0x200);
|
||||
const auto renderControl = find(cx, 0x000);
|
||||
const bool clear = renderControl != cx.end() && (renderControl->second & 3u) != 0;
|
||||
if (clear || ((depthControl & 0xbu) != 0 && depthSurfaceBound(cx))) {
|
||||
const auto tests = planeTests(cx, depthControl);
|
||||
if (clear || (tests != 0 && depthSurfaceBound(cx))) {
|
||||
decodeDepth(cx, depthControl, result);
|
||||
} else if (depthPassThrough(depthControl) || ((depthControl & 0xbu) != 0 && depthPlanesAbsent(cx))) {
|
||||
} else if (depthPassThrough(depthControl) || ((depthControl & 0xbu) != 0 && (tests == 0 || depthPlanesAbsent(cx)))) {
|
||||
static bool reported = false;
|
||||
if (!reported) {
|
||||
reported = true;
|
||||
|
|
@ -1013,8 +1022,9 @@ std::string DrawRejection(const QueueState& queue, bool indexed) {
|
|||
std::uint32_t z = 0, view = 0;
|
||||
if ((value(cx, 0x010, z) && (z & 3u) == 0) || (value(cx, 0x002, view) && (view & 0x01000000u) != 0)) return require(false, "depth clear requires a writable depth plane");
|
||||
}
|
||||
const bool surface = ((word & 0xbu) != 0 || depthClear || stencilClear) && depthSurfaceBound(cx);
|
||||
if (!surface && !((word & 0xbu) != 0 && depthPlanesAbsent(cx)) && !depthPassThrough(word) && !IgnoreDepthTest() && (effectiveDepthControl(word) & DepthControlMask) != 0) return zeroMessage(0x200, word, "depth, stencil or conditional color writes");
|
||||
const auto tests = planeTests(cx, word);
|
||||
const bool surface = (tests != 0 || depthClear || stencilClear) && depthSurfaceBound(cx);
|
||||
if (!surface && !((word & 0xbu) != 0 && (tests == 0 || depthPlanesAbsent(cx))) && !depthPassThrough(word) && !IgnoreDepthTest() && (effectiveDepthControl(word) & DepthControlMask) != 0) return zeroMessage(0x200, word, "depth, stencil or conditional color writes");
|
||||
if (auto reason = require((word & 8u) == 0 || surface || depthPlanesAbsent(cx), "depth bounds without a depth surface"); !reason.empty()) return reason;
|
||||
if (auto reason = require((word & 0xc0000000u) == 0, "depth-conditional color writes are unsupported"); !reason.empty()) return reason;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,6 +275,29 @@ void stateTests() {
|
|||
queue.context[0x200] = 0x007007bbu;
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "depth bounds without a depth plane");
|
||||
queue = makeState();
|
||||
queue.context[0x010] = 0x80000183;
|
||||
queue.context[0x011] = 0x20000180;
|
||||
queue.context[0x012] = 0x00001000;
|
||||
queue.context[0x014] = 0x00001000;
|
||||
queue.context[0x007] = 0x0001001f;
|
||||
queue.context[0x000] = 0;
|
||||
queue.context[0x002] = 0;
|
||||
queue.context[0x00a] = 0;
|
||||
queue.context[0x00b] = 0x3f800000;
|
||||
queue.context[0x200] = 0x007007b1;
|
||||
queue.context[0x1b3] = 2;
|
||||
queue.context[0x1b4] = 2;
|
||||
state = AgcDriver::Graphics::DecodeState(queue);
|
||||
Require(!state.depth.has_value() && !state.stencilTest && state.renderExtent.width == state.color.extent.width && state.renderExtent.height == state.color.extent.height, "a stencil test without a stencil plane bound the depth plane it does not test");
|
||||
Require(AgcDriver::Graphics::DrawRejection(queue, false).empty(), "a stencil test without a stencil plane beside an untested depth plane was rejected");
|
||||
queue.context[0x200] = 0x00700231;
|
||||
state = AgcDriver::Graphics::DecodeState(queue);
|
||||
Require(!state.depth.has_value() && !state.stencilTest && state.renderExtent.width == state.color.extent.width && state.renderExtent.height == state.color.extent.height, "a failing stencil test without a stencil plane bound the depth plane it does not test");
|
||||
Require(AgcDriver::Graphics::DrawRejection(queue, false).empty(), "a failing stencil test without a stencil plane beside an untested depth plane was rejected");
|
||||
queue.context[0x200] = 0x007007b3;
|
||||
state = AgcDriver::Graphics::DecodeState(queue);
|
||||
Require(state.depth.has_value() && state.depthTest && !state.stencilTest && state.renderExtent.width == 32 && state.renderExtent.height == 2, "a depth test on a bound depth plane lost its surface");
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue