From d4276d89f8d78c80aea921da2b929d9a5e0b6a0e Mon Sep 17 00:00:00 2001 From: ParantezTech <12572227+par274@users.noreply.github.com> Date: Sun, 11 Oct 2026 06:11:55 +0300 Subject: [PATCH] [Profile] Count DCC metadata synchronizations and their outcome --- .../Gpu/Images/GuestImageCache.Metadata.cs | 13 +++++++++++++ src/SharpEmu.Libs/VideoOut/RenderPhaseProfile.cs | 1 + 2 files changed, 14 insertions(+) diff --git a/src/SharpEmu.Libs/Gpu/Images/GuestImageCache.Metadata.cs b/src/SharpEmu.Libs/Gpu/Images/GuestImageCache.Metadata.cs index ab099e0..660acfd 100644 --- a/src/SharpEmu.Libs/Gpu/Images/GuestImageCache.Metadata.cs +++ b/src/SharpEmu.Libs/Gpu/Images/GuestImageCache.Metadata.cs @@ -11,6 +11,14 @@ namespace SharpEmu.Libs.Gpu.Images; // Surface metadata (HTile, DCC, CMask, FMask) keyed by its guest address. public sealed partial class GuestImageCache { + private static long _dccSyncs; + private static long _dccSlicesUndecodable; + private static long _dccSlicesMixed; + private static long _dccSlicesCleared; + + public static string TakeDccReport() => FormattableString.Invariant( + $"[PERF][DCC_SYNC] gpu_syncs={Interlocked.Exchange(ref _dccSyncs, 0)} cleared={Interlocked.Exchange(ref _dccSlicesCleared, 0)} mixed={Interlocked.Exchange(ref _dccSlicesMixed, 0)} undecodable={Interlocked.Exchange(ref _dccSlicesUndecodable, 0)}"); + private unsafe void MaterializeDccClear( ResourceSlotIdentifier imageIdentifier, in ImageRequest request, @@ -96,6 +104,7 @@ public sealed partial class GuestImageCache allowClearToRegister: request.Role == ImageRole.ColorTarget, out var clear)) { + Interlocked.Increment(ref _dccSlicesUndecodable); continue; } @@ -126,9 +135,12 @@ public sealed partial class GuestImageCache if (!uniform) { + Interlocked.Increment(ref _dccSlicesMixed); continue; } + Interlocked.Increment(ref _dccSlicesCleared); + using (var held = _lock.Hold()) { if (_slots.TryGet(imageIdentifier) == null) @@ -423,6 +435,7 @@ public sealed partial class GuestImageCache var size = (ulong)layerCount * sliceSize; if (IsValidRange(address, size) && _bufferCache.HasGpuDirtyBytes(address, size)) { + Interlocked.Increment(ref _dccSyncs); _ = _bufferCache.TrySynchronizeCpuRead(address, size); } } diff --git a/src/SharpEmu.Libs/VideoOut/RenderPhaseProfile.cs b/src/SharpEmu.Libs/VideoOut/RenderPhaseProfile.cs index eb5e5d5..a1f6c38 100644 --- a/src/SharpEmu.Libs/VideoOut/RenderPhaseProfile.cs +++ b/src/SharpEmu.Libs/VideoOut/RenderPhaseProfile.cs @@ -472,6 +472,7 @@ internal static class RenderPhaseProfile Console.Error.WriteLine(SharpEmu.Libs.Gpu.Buffers.GuestBufferCache.TakeAsyncReadbackReport()); Console.Error.WriteLine(SharpEmu.Libs.Gpu.Vulkan.GpuSyncProfile.TakeReport()); Console.Error.WriteLine(SharpEmu.Libs.Gpu.Images.GuestImageCache.TakeLookupReport()); + Console.Error.WriteLine(SharpEmu.Libs.Gpu.Images.GuestImageCache.TakeDccReport()); SharpEmu.ShaderCompiler.Resources.ResourceMaterializationProfile.WriteReport(); SharpEmu.Libs.Diagnostics.AgcRegisterPacketProfile.WriteReport(); SharpEmu.HLE.GpuMemory.GpuMemoryAccessProfile.WriteReport();