diff --git a/src/SharpEmu.Libs/Agc/AgcExports.cs b/src/SharpEmu.Libs/Agc/AgcExports.cs
index f535c649..1b58a13a 100644
--- a/src/SharpEmu.Libs/Agc/AgcExports.cs
+++ b/src/SharpEmu.Libs/Agc/AgcExports.cs
@@ -11307,7 +11307,9 @@ public static partial class AgcExports
}
}
- if (evaluationHandledByCpu)
+ // Rejected/CPU-handled dispatches never hand evaluation's pooled buffers to a
+ // consumer that would return them; reclaim here to keep GuestDataPool.Shared bounded.
+ if (evaluationHandledByCpu || !gpuDispatch)
{
ReturnPooledEvaluationArrays(evaluation);
}
diff --git a/src/SharpEmu.Libs/Gpu/GuestDataPool.cs b/src/SharpEmu.Libs/Gpu/GuestDataPool.cs
index a9d395dc..af0740f7 100644
--- a/src/SharpEmu.Libs/Gpu/GuestDataPool.cs
+++ b/src/SharpEmu.Libs/Gpu/GuestDataPool.cs
@@ -23,6 +23,10 @@ internal static class GuestDataPool
public static void Trim() => ((BoundedByteArrayPool)Shared).Trim();
+ /// Outstanding lease count and idle cached bytes, for leak diagnostics.
+ public static (int LeaseCount, ulong CachedBytes) DiagnosticStats() =>
+ ((BoundedByteArrayPool)Shared).Stats();
+
private sealed class BoundedByteArrayPool : ArrayPool
{
private readonly object _gate = new();
@@ -119,6 +123,14 @@ internal static class GuestDataPool
}
}
+ public (int LeaseCount, ulong CachedBytes) Stats()
+ {
+ lock (_gate)
+ {
+ return (_leases.Count, _cachedBytes);
+ }
+ }
+
private int GetAllocationLength(int minimumLength)
{
if (minimumLength <= 16)
diff --git a/src/SharpEmu.Libs/VideoOut/VideoOutExports.cs b/src/SharpEmu.Libs/VideoOut/VideoOutExports.cs
index c5895ced..ca2689c9 100644
--- a/src/SharpEmu.Libs/VideoOut/VideoOutExports.cs
+++ b/src/SharpEmu.Libs/VideoOut/VideoOutExports.cs
@@ -1300,10 +1300,12 @@ public static class VideoOutExports
var submitted = Interlocked.Exchange(ref _submittedFrameCount, 0);
var presentedCount = Interlocked.Exchange(ref _presentedFrameCount, 0);
var (draws, drawMs, pipelines, spirvCompiles) = GuestGpu.Current.ReadAndResetPerfCounters();
+ var (poolLeases, poolCachedBytes) = SharpEmu.Libs.Gpu.GuestDataPool.DiagnosticStats();
Console.Error.WriteLine(
$"[LOADER][PERF] videoout submitted_fps={submitted / elapsedSeconds:F1} " +
$"presented_fps={presentedCount / elapsedSeconds:F1} " +
- $"draws={draws} draw_ms={drawMs:F0} pipelines={pipelines} spirv={spirvCompiles}");
+ $"draws={draws} draw_ms={drawMs:F0} pipelines={pipelines} spirv={spirvCompiles} " +
+ $"pool_leases={poolLeases} pool_cached_mb={poolCachedBytes / 1024.0 / 1024.0:F1}");
}
private static readonly bool _flipPacingDisabled = string.Equals(