feat(render): unify physical residency accounting

This commit is contained in:
Erik 2026-07-24 16:20:48 +02:00
parent 1866ea0c6d
commit 3e18fc2730
25 changed files with 642 additions and 48 deletions

View file

@ -8,6 +8,7 @@ using Silk.NET.OpenGL;
using System.Linq;
using PixelFormatId = DatReaderWriter.Enums.PixelFormat;
using SurfaceType = DatReaderWriter.Enums.SurfaceType;
using AcDream.App.Rendering.Residency;
namespace AcDream.App.Rendering;
@ -87,8 +88,10 @@ public sealed unsafe class TextureCache : Wb.IEntityTextureLifetime, IDisposable
GL gl,
IDatReaderWriter dats,
Wb.BindlessSupport? bindless,
IGpuResourceRetirementQueue retirementQueue)
IGpuResourceRetirementQueue retirementQueue,
ResidencyBudgetOptions? budgets = null)
{
budgets ??= ResidencyBudgetOptions.Default;
_gl = gl;
_dats = dats;
_bindless = bindless;
@ -103,11 +106,15 @@ public sealed unsafe class TextureCache : Wb.IEntityTextureLifetime, IDisposable
composite = new CompositeTextureArrayCache(
gl,
bindless,
retirementQueue);
retirementQueue,
budgets.CompositeUnownedBytes,
budgets.CompositePhysicalBytes);
resources.Add("composite texture cache", composite.Dispose);
particles = new StandaloneBindlessTextureCache(
new ParticleTextureBackend(this),
retirementQueue);
retirementQueue,
budgets.StandaloneUnownedBytes,
budgets.StandaloneUnownedEntries);
resources.Add("particle texture cache", particles.Dispose);
resources.TransferAll();
}
@ -123,6 +130,37 @@ public sealed unsafe class TextureCache : Wb.IEntityTextureLifetime, IDisposable
}
}
internal void RegisterResidencySources(ResidencyManager manager)
{
ArgumentNullException.ThrowIfNull(manager);
if (_compositeTextures is not null)
{
manager.RegisterDomainSource(new DelegateResidencyDomainSource(
ResidencyDomain.CompositeTextures,
_compositeTextures.CaptureResidency));
}
if (_particleTextures is not null)
{
manager.RegisterDomainSource(new DelegateResidencyDomainSource(
ResidencyDomain.StandaloneTextures,
CaptureStandaloneResidency));
}
}
private ResidencyDomainSnapshot CaptureStandaloneResidency()
{
StandaloneBindlessTextureCache textures = EnsureParticleTexturesAvailable();
return new ResidencyDomainSnapshot(
ResidencyDomain.StandaloneTextures,
EntryCount: textures.EntryCount,
OwnerCount: textures.OwnerCount,
Charges: new ResidencyCharges(
GpuResidentBytes: checked(
textures.AllocatedBytes - textures.RetiringBytes),
RetiringBytes: textures.RetiringBytes),
BudgetBytes: textures.BudgetBytes);
}
/// <summary>
/// Get or upload the GL texture handle for a Surface id. Returns a
/// 1x1 magenta fallback if the Surface or its RenderSurface chain is