From 550920a1fdafcf989b6e7be5daf756096a849e4c Mon Sep 17 00:00:00 2001 From: Scott Schuster Date: Wed, 7 Oct 2026 22:08:30 -0500 Subject: [PATCH] fix(agc): render CB_COLOR_CONTROL mode disable as a draw without color Mode 0 of CB_COLOR_CONTROL turns color writes off, but a draw with a written color target and this mode was skipped as unsupported. Count no export as written when the mode is disable, so the draw renders without a color attachment like the existing attachment-free path, and accept the mode with any ROP3, which does not apply while writes are off. Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp | 3 ++- core/libs/prx/libSceAgcDriver/tests/Graphics.cpp | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp index dbf142adb..74070b60c 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp @@ -273,7 +273,7 @@ std::uint32_t effectiveDepthControl(std::uint32_t depthControl) { bool colorControlSupported(std::uint32_t colorControl, bool hasColorTarget) { colorControl &= ~1u; - return colorControl == 0xcc0010u || (!hasColorTarget && (colorControl & ~0x70u) == 0xcc0000u); + return colorControl == 0xcc0010u || ((colorControl >> 4u) & 7u) == 0u || (!hasColorTarget && (colorControl & ~0x70u) == 0xcc0000u); } std::string colorControlMessage(std::uint32_t colorControl) { @@ -570,6 +570,7 @@ State DecodeState(const QueueState& queue) { for (std::uint32_t index = 0; index < exportSlots.size(); ++index) { if (written(exportSlots[index])) exportCount = index + 1; } + if (((read(cx, 0x202) >> 4u) & 7u) == 0u) exportCount = 0; result.hasColorTarget = exportCount != 0; APS5_LOG_OUT_DEBUG("hasColorTarget=%u exports=%u", result.hasColorTarget ? 1u : 0u, exportCount); diff --git a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp index 2b034c44e..9aeb66f42 100644 --- a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp @@ -607,6 +607,13 @@ void DisabledColorTests() { queue.context[0x00b] = std::bit_cast(1.0f); const auto depthOnly = AgcDriver::Graphics::DecodeState(queue); Require(!depthOnly.hasColorTarget && depthOnly.depth && depthOnly.depthTest && depthOnly.depthWrite && depthOnly.renderExtent.height == 64, "COLOR_INVALID discarded a depth-only draw"); + for (const auto colorControl : {0x0u, 0xcc0000u}) { + queue = makeState(); + queue.context[0x202] = colorControl; + const auto unwritten = AgcDriver::Graphics::DecodeState(queue); + Require(!unwritten.hasColorTarget && unwritten.colors.empty() && unwritten.color.address == 0, "CB_COLOR_CONTROL mode disable kept a color attachment"); + Require(unwritten.renderExtent.width == 64 && unwritten.renderExtent.height == 4, "CB_COLOR_CONTROL mode disable lost the screen scissor extent"); + } } void TuningFieldTests() {