Do image/texture caching better

also don't try to cache the sampler / avoid set sampler calls (the sampler is not pipeline specific, so it's affected by other pipelines setting the sampler)
This commit is contained in:
CasualPokePlayer 2024-08-03 23:59:20 -07:00
parent 2b371e2752
commit 91de8608af
6 changed files with 34 additions and 30 deletions

View File

@ -10,11 +10,10 @@ namespace BizHawk.Bizware.Graphics
public sealed class ImGuiResourceCache
{
private readonly IGL _igl;
private ITexture2D _lastTexture;
internal readonly IPipeline Pipeline;
internal readonly Dictionary<Bitmap, ITexture2D> TextureCache = new();
internal readonly Dictionary<Color, SolidBrush> BrushCache = new();
internal readonly Dictionary<Bitmap, ITexture2D> TextureCache = [ ];
internal readonly Dictionary<Color, SolidBrush> BrushCache = [ ];
public ImGuiResourceCache(IGL igl)
{
@ -51,8 +50,7 @@ namespace BizHawk.Bizware.Graphics
Pipeline = igl.CreatePipeline(compileArgs);
igl.BindPipeline(Pipeline);
Pipeline.SetUniform("uSamplerEnable", false);
Pipeline.SetUniformSampler("uSampler0", null);
SetTexture(null);
igl.BindPipeline(null);
}
}
@ -65,20 +63,15 @@ namespace BizHawk.Bizware.Graphics
internal void SetTexture(ITexture2D texture2D)
{
if (_lastTexture != texture2D)
{
Pipeline.SetUniform("uSamplerEnable", texture2D != null);
Pipeline.SetUniformSampler("uSampler0", texture2D);
_lastTexture = texture2D;
}
Pipeline.SetUniform("uSamplerEnable", texture2D != null);
Pipeline.SetUniformSampler("uSampler0", texture2D);
}
public void Dispose()
{
foreach (var cache in TextureCache)
foreach (var cachedTex in TextureCache.Values)
{
cache.Key.Dispose();
cache.Value.Dispose();
cachedTex.Dispose();
}
foreach (var cachedBrush in BrushCache.Values)
@ -91,6 +84,16 @@ namespace BizHawk.Bizware.Graphics
Pipeline?.Dispose();
}
public void ClearTextureCache()
{
foreach (var cachedTex in TextureCache.Values)
{
cachedTex.Dispose();
}
TextureCache.Clear();
}
public const string ImGuiVertexShader_d3d11 = @"
//vertex shader uniforms
float4x4 um44Projection;

View File

@ -94,9 +94,6 @@ namespace BizHawk.Bizware.Graphics
Flush();
CurrPipeline = pipeline;
// clobber state cache
sTexture = null;
// save the modulate color? user beware, I guess, for now.
}
@ -164,8 +161,7 @@ namespace BizHawk.Bizware.Graphics
Owner.BindPipeline(CurrPipeline);
Owner.DisableBlending();
//clear state cache
sTexture = null;
// clear state cache
CurrPipeline.SetUniform("uSamplerEnable", false);
ModelView.Clear();
Projection.Clear();
@ -201,12 +197,8 @@ namespace BizHawk.Bizware.Graphics
private void PrepDrawSubrectInternal(ITexture2D tex)
{
if (sTexture != tex)
{
sTexture = tex;
CurrPipeline.SetUniformSampler("uSampler0", tex);
CurrPipeline.SetUniform("uSamplerEnable", tex != null);
}
CurrPipeline.SetUniformSampler("uSampler0", tex);
CurrPipeline.SetUniform("uSamplerEnable", tex != null);
if (_projection.IsDirty)
{
@ -267,9 +259,6 @@ namespace BizHawk.Bizware.Graphics
private IPipeline CurrPipeline;
private readonly IPipeline DefaultPipeline;
// state cache
private ITexture2D sTexture;
// shaders are hand-coded for each platform to make sure they stay as fast as possible
public const string DefaultVertexShader_d3d11 = @"

View File

@ -52,7 +52,7 @@ namespace BizHawk.Bizware.Graphics
}
}
private readonly HashSet<GCHandle> _gcHandles = new();
private readonly HashSet<GCHandle> _gcHandles = [ ];
protected virtual float RenderThickness => 1;
@ -105,6 +105,9 @@ namespace BizHawk.Bizware.Graphics
{
switch (gcHandle.Target)
{
// we can't actually dispose this, as the bitmap might still be cached within GuiApi
// it doesn't matter too much, as the finalizer would also dispose this, so no memory leaks will occur
#if false
case ImGuiUserTexture userTexture:
// only dispose anything not cached somewhere
if (userTexture.Bitmap != _stringOutput
@ -113,6 +116,7 @@ namespace BizHawk.Bizware.Graphics
userTexture.Bitmap.Dispose();
}
break;
#endif
case DrawStringArgs args:
args.Font.Dispose();
break;

View File

@ -291,7 +291,10 @@ namespace BizHawk.Client.Common
}
public void ClearImageCache()
=> _imageCache.Clear();
{
_imageCache.Clear();
_displayManager.ClearApiHawkTextureCache();
}
public void DrawImageRegion(Image img, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int? dest_width = null, int? dest_height = null, DisplaySurfaceID? surfaceID = null)
{

View File

@ -947,5 +947,8 @@ namespace BizHawk.Client.Common
renderer.Discard();
}
}
public void ClearApiHawkTextureCache()
=> _imGuiResourceCache.ClearTextureCache();
}
}

View File

@ -131,6 +131,7 @@ namespace BizHawk.Client.EmuHawk
Settings.Columns = LuaListView.AllColumns;
DisplayManager.ClearApiHawkSurfaces();
DisplayManager.ClearApiHawkTextureCache();
ResetDrawSurfacePadding();
ClearFileWatches();
LuaImp?.Close();
@ -948,6 +949,7 @@ namespace BizHawk.Client.EmuHawk
UpdateDialog();
DisplayManager.ClearApiHawkSurfaces();
DisplayManager.ClearApiHawkTextureCache();
DisplayManager.OSD.ClearGuiText();
if (!LuaImp.ScriptList.Any(static lf => !lf.IsSeparator)) ResetDrawSurfacePadding(); // just removed last script, reset padding
}