mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-31 23:19:44 +08:00
fix(agc): skip CB metadata draws for EliminateFastClear/Fmask/DCC
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:
@@ -299,6 +299,7 @@ public static partial class AgcExports
|
|||||||
private static int _tracedVertexRangeCount;
|
private static int _tracedVertexRangeCount;
|
||||||
private static long _dcbWaitRegMemTraceCount;
|
private static long _dcbWaitRegMemTraceCount;
|
||||||
private static long _createShaderTraceCount;
|
private static long _createShaderTraceCount;
|
||||||
|
private static long _cbMetadataSkipTraceCount;
|
||||||
private static long _packetPayloadTraceCount;
|
private static long _packetPayloadTraceCount;
|
||||||
private static bool _tracedMissingPixelShaderBindings;
|
private static bool _tracedMissingPixelShaderBindings;
|
||||||
private static long _unsatisfiedWaitTraceCount;
|
private static long _unsatisfiedWaitTraceCount;
|
||||||
@@ -5670,6 +5671,25 @@ public static partial class AgcExports
|
|||||||
}
|
}
|
||||||
state.TranslatedDraw = null;
|
state.TranslatedDraw = null;
|
||||||
state.GuestDrawKind = GuestDrawKind.None;
|
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)
|
foreach (var target in renderTargets)
|
||||||
{
|
{
|
||||||
state.KnownRenderTargets[target.Address] = target;
|
state.KnownRenderTargets[target.Address] = target;
|
||||||
@@ -7281,6 +7301,35 @@ public static partial class AgcExports
|
|||||||
return hash;
|
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(
|
private static bool TryGetHardwareColorResolveTargets(
|
||||||
IReadOnlyDictionary<uint, uint> registers,
|
IReadOnlyDictionary<uint, uint> registers,
|
||||||
out RenderTargetDescriptor source,
|
out RenderTargetDescriptor source,
|
||||||
@@ -7288,8 +7337,8 @@ public static partial class AgcExports
|
|||||||
{
|
{
|
||||||
source = default;
|
source = default;
|
||||||
destination = default;
|
destination = default;
|
||||||
if (!registers.TryGetValue(CbColorControl, out var colorControl) ||
|
if (!TryGetCbColorControlMode(registers, out var mode) ||
|
||||||
((colorControl >> 4) & 0x7u) != 3u)
|
mode != (uint)CbColorMode.Resolve)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user