fix(agc): skip CB metadata draws for EliminateFastClear/Fmask/DCC (#553)

CB_COLOR_CONTROL modes 2/5/6 are colour-buffer metadata ops; applying
the bound shader as a normal colour draw corrupts subsequent composites.
Decode MODE from bits [6:4] and return before translate.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
MarcelMediaDev
2026-07-23 13:37:34 +01:00
committed by GitHub
parent 82ab181861
commit 4c6cff1116
+51 -2
View File
@@ -280,6 +280,7 @@ public static partial class AgcExports
private static int _tracedVertexRangeCount;
private static long _dcbWaitRegMemTraceCount;
private static long _createShaderTraceCount;
private static long _cbMetadataSkipTraceCount;
private static long _packetPayloadTraceCount;
private static bool _tracedMissingPixelShaderBindings;
private static long _unsatisfiedWaitTraceCount;
@@ -5683,6 +5684,25 @@ public static partial class AgcExports
}
state.TranslatedDraw = null;
state.GuestDrawKind = GuestDrawKind.None;
// CB modes EliminateFastClear / FmaskDecompress / DccDecompress run
// colour-buffer metadata ops. The bound shader is only a vehicle and
// must not be applied as a normal colour draw.
if (TryGetCbColorControlMode(state.CxRegisters, out var cbMode) &&
IsCbMetadataColorMode(cbMode))
{
if (_traceAgcShader || ShouldTraceHotPath(ref _cbMetadataSkipTraceCount))
{
TraceAgcShader(
$"agc.cb_metadata_skip seq={drawSequence} mode={cbMode} " +
$"es=0x{(hasExportShader ? exportShaderAddress : 0):X16} " +
$"ps=0x{(hasPixelShader ? pixelShaderAddress : 0):X16} " +
$"vertices={vertexCount}");
}
return;
}
foreach (var target in renderTargets)
{
state.KnownRenderTargets[target.Address] = target;
@@ -7294,6 +7314,35 @@ public static partial class AgcExports
return hash;
}
private enum CbColorMode : byte
{
Disable = 0,
Normal = 1,
EliminateFastClear = 2,
Resolve = 3,
FmaskDecompress = 5,
DccDecompress = 6,
}
private static bool TryGetCbColorControlMode(
IReadOnlyDictionary<uint, uint> registers,
out uint mode)
{
mode = 0;
if (!registers.TryGetValue(CbColorControl, out var colorControl))
{
return false;
}
mode = (colorControl >> 4) & 0x7u;
return true;
}
private static bool IsCbMetadataColorMode(uint mode) =>
mode is (uint)CbColorMode.EliminateFastClear or
(uint)CbColorMode.FmaskDecompress or
(uint)CbColorMode.DccDecompress;
private static bool TryGetHardwareColorResolveTargets(
IReadOnlyDictionary<uint, uint> registers,
out RenderTargetDescriptor source,
@@ -7301,8 +7350,8 @@ public static partial class AgcExports
{
source = default;
destination = default;
if (!registers.TryGetValue(CbColorControl, out var colorControl) ||
((colorControl >> 4) & 0x7u) != 3u)
if (!TryGetCbColorControlMode(registers, out var mode) ||
mode != (uint)CbColorMode.Resolve)
{
return false;
}