[Gpu] Track the extent of DCC metadata and answer overlap queries

A color target records the size of its DCC metadata, and the image cache can
tell whether a guest range overlaps registered DCC metadata.
This commit is contained in:
ParantezTech 2026-10-02 18:48:02 +03:00
parent 7085532257
commit 792953c90b
5 changed files with 28 additions and 1 deletions

View File

@ -13,6 +13,8 @@ public interface IGuestImageCache
bool ClearMetadata(ulong address);
bool OverlapsDccMetadata(ulong address, ulong size);
void InvalidateMemory(ulong address, ulong size);
void InvalidateMemoryFromGpu(ulong address, ulong size);

View File

@ -257,6 +257,12 @@ public sealed partial class GuestImageCache
metadata.ClearMask = 0;
}
internal void RegisterDccMetadataForTest(ulong address, ulong size)
{
using var held = _lock.Hold();
_surfaceMetadata[address] = new SurfaceMetadata { Kind = SurfaceMetadataKind.Dcc, Size = size };
}
internal RegionLockScope HoldLockForTest() => new(_lock);
internal readonly struct RegionLockScope : IDisposable

View File

@ -29,6 +29,21 @@ public sealed partial class GuestImageCache
public bool IsMetadataCleared(ulong address, uint slice) => IsMetadataCleared(address, slice, out _);
public bool OverlapsDccMetadata(ulong address, ulong size)
{
using var held = _lock.Hold();
foreach (var (start, metadata) in _surfaceMetadata)
{
if (metadata.Kind == SurfaceMetadataKind.Dcc && metadata.Size != 0 &&
address < start + metadata.Size && start < address + size)
{
return true;
}
}
return false;
}
// A broad clear applies to CMask, FMask and HTile; DCC needs a validated fill value.
public bool ClearMetadata(ulong address)
{

View File

@ -321,7 +321,8 @@ public sealed unsafe partial class GuestImageCache : IGuestImageCache, IGuestIma
var address = request.Description.Metadata.Range.Address;
if (!_surfaceMetadata.TryGetValue(address, out var metadata))
{
_surfaceMetadata.Add(address, new SurfaceMetadata { Kind = SurfaceMetadataKind.Dcc });
metadata = new SurfaceMetadata { Kind = SurfaceMetadataKind.Dcc };
_surfaceMetadata.Add(address, metadata);
}
else if (metadata.Kind == SurfaceMetadataKind.PendingDcc)
{
@ -331,6 +332,8 @@ public sealed unsafe partial class GuestImageCache : IGuestImageCache, IGuestIma
{
throw SubmissionScheduler.Fatal($"A color target reuses metadata that is not DCC: address=0x{address:X16} kind={metadata.Kind}.");
}
metadata.Size = Math.Max(metadata.Size, request.Description.DccSliceSize * request.Description.TransferLayers);
}
TakeGpuOwnership(image);

View File

@ -20,4 +20,5 @@ public sealed class SurfaceMetadata
public uint ClearMask;
public uint FillValue = 0xffffffff;
public ulong FillSize;
public ulong Size;
}