Merge pull request #4862 from Tamalero/fix/agc-blend-bypass-leaves-blending-off

fix(agc): leave blending off for a color target with CB_COLOR_INFO.BLEND_BYPASS
This commit is contained in:
Dean 2026-10-14 14:33:39 +13:00 committed by GitHub
commit a87019d4ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 2 deletions

View File

@ -893,11 +893,10 @@ State DecodeState(const QueueState& queue, bool vertexWorkgroup) {
for (std::uint32_t component = 0; component < 4; ++component) {
if (((exportedMask >> ((mapping >> (2u * component)) & 3u)) & 1u) != 0) state.colorWriteMask |= 1u << component;
}
state.blendEnable = (blend >> 30u) & 1u;
state.blendEnable = ((blend >> 30u) & 1u) != 0 && (read(cx, 0x31c + slot * 0xfu) & 0x10000u) == 0;
if (state.blendEnable && (mapping == 0x1bu || mapping == 0x93u)) throw std::runtime_error("AGC graphics: blending into a color target with a reversed component order is not implemented");
Require(!state.blendEnable || !color.uintExport, "blending into an unsigned integer target is unsupported");
if (state.blendEnable) {
Require((read(cx, 0x31c + slot * 0xfu) & 0x10000u) == 0, "blend bypass conflicts with enabled blending");
state.srcColorBlendFactor = blendFactor(blend & 0x1fu);
state.dstColorBlendFactor = blendFactor((blend >> 8u) & 0x1fu);
state.colorBlendOp = blendOp((blend >> 5u) & 7u);

View File

@ -1030,6 +1030,16 @@ void PixelInputLayoutTests() {
Require(!readsBuiltin(read, spv::BuiltInFragCoord) && !readsBuiltin(read, spv::BuiltInBaryCoordKHR), "an ADDR-only centroid pair was loaded");
}
void BlendBypassTests() {
auto queue = makeState();
for (std::uint32_t constant = 0x105; constant < 0x109; ++constant) queue.context[constant] = 0;
queue.context[0x1e0] = (1u << 30u) | 4u | (5u << 8u);
Require(AgcDriver::Graphics::DecodeState(queue).blends.at(0).blendEnable, "enabled blending was not decoded");
queue.context[0x31c] |= 0x10000u;
const auto bypassed = AgcDriver::Graphics::DecodeState(queue);
Require(!bypassed.blends.at(0).blendEnable && bypassed.blends.at(0).colorWriteMask != 0, "a target with BLEND_BYPASS still blends");
}
void OpaqueDestinationAlphaTests() {
auto queue = makeState();
for (std::uint32_t constant = 0x105; constant < 0x109; ++constant) queue.context[constant] = 0;
@ -5710,6 +5720,7 @@ int main(int argc, char** argv) {
DisabledColorTests();
OpaqueDestinationAlphaTests();
Color1555TargetTests();
BlendBypassTests();
CompactedExportTests();
ReversedComponentOrderTests();
ShadersWriteMemoryTests();