diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp index 32b2bc8e08..0dce8f8b2d 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp @@ -317,7 +317,8 @@ void decodeDepth(const Registers& cx, std::uint32_t depthControl, bool testValEx depth.lastSlice = (view >> 13u) & 0x7ffu; depth.address = zFormat != 0 ? base(0x012, 0x01a) : 0; depth.stencilAddress = stencil ? base(0x013, 0x01b) : 0; - Require(zFormat == 0 || depthReadOnly || base(0x014, 0x01c) == depth.address, "depth read and written at different addresses is unsupported"); + const bool depthWritten = zFormat != 0 && !depthReadOnly && (depthClear || (depthControl & 6u) == 6u || (read(cx, 0x000) & 0x60u) != 0); + Require(!depthWritten || base(0x014, 0x01c) == depth.address, "depth read and written at different addresses is unsupported"); Require(!stencil || stencilReadOnly || base(0x015, 0x01d) == depth.stencilAddress, "stencil read and written at different addresses is unsupported"); if (depth.samples != 1u) { depth.pipeBankXor = static_cast(depth.address & 65535u); diff --git a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp index f6b15bbc10..69e85bb7d7 100644 --- a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp @@ -2134,6 +2134,23 @@ void DepthStencilTests() { const auto rejection = AgcDriver::Graphics::DrawRejection(queue, false); Require(rejection.empty(), "precheck rejected a stencil draw with a surface: " + rejection); Require(state.depth && state.depth->address == 0x10000 && state.depth->stencilAddress == 0x20000 && state.depth->format == VK_FORMAT_D32_SFLOAT_S8_UINT && state.depth->clearStencil == 7 && state.depth->htileAddress == 0x10000030000ull && !state.depth->htileStencil, "depth surface decode changed"); + { + auto split = queue; + split.context[0x014] = 0; + for (const auto control : {0x00700711u, 0x00700715u, 0x00700713u}) { + split.context[0x200] = control; + const auto splitState = AgcDriver::Graphics::DecodeState(split); + Require(splitState.depth && splitState.depth->address == 0x10000 && !splitState.depthWrite, "a depth plane the draw does not write rejected another write address"); + Require(AgcDriver::Graphics::DrawRejection(split, false).empty(), "precheck rejected a depth plane the draw does not write at another write address"); + } + split.context[0x200] = 0x00700717u; + expectFailure([&] { AgcDriver::Graphics::DecodeState(split); }, "depth read and written at different addresses"); + split.context[0x200] = 0x00700711u; + for (const auto control : {0x01u, 0x20u, 0x40u, 0x60u}) { + split.context[0x000] = control; + expectFailure([&] { AgcDriver::Graphics::DecodeState(split); }, "depth read and written at different addresses"); + } + } for (const auto clear : {0u, 1u, 2u, 3u}) { auto retained = queue; retained.context[0x8e] = retained.context[0x8f] = retained.context[0x203] = 0;