From 255947b2fc3d676554d02e467267b0f3c789ac86 Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 6 Jul 2023 08:42:34 -0700 Subject: [PATCH] [GPU] Add texture surface cache eviction Implemented as a simple ring buffer evicting the oldest entry for now. --- include/renderer_gl/renderer_gl.hpp | 2 +- include/renderer_gl/surface_cache.hpp | 19 +++++++++++++++---- src/core/renderer_gl/textures.cpp | 5 +++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/include/renderer_gl/renderer_gl.hpp b/include/renderer_gl/renderer_gl.hpp index 4fe0a37c..3ede19ff 100644 --- a/include/renderer_gl/renderer_gl.hpp +++ b/include/renderer_gl/renderer_gl.hpp @@ -45,7 +45,7 @@ class Renderer { SurfaceCache depthBufferCache; SurfaceCache colourBufferCache; - SurfaceCache textureCache; + SurfaceCache textureCache; OpenGL::uvec2 fbSize; // The size of the framebuffer (ie both the colour and depth buffer)' diff --git a/include/renderer_gl/surface_cache.hpp b/include/renderer_gl/surface_cache.hpp index e6b07763..fb0a469d 100644 --- a/include/renderer_gl/surface_cache.hpp +++ b/include/renderer_gl/surface_cache.hpp @@ -5,8 +5,9 @@ #include "textures.hpp" // Surface cache class that can fit "capacity" instances of the "SurfaceType" class of surfaces -// SurfaceType *must* have all of the following -// - An "allocate" function that allocates GL resources for the surfaces +// SurfaceType *must* have all of the following. +// - An "allocate" function that allocates GL resources for the surfaces. On overflow it will panic +// if evict_on_overflow is false, or kick out the oldest item if it is true. // - A "free" function that frees up all resources the surface is taking up // - A "matches" function that, when provided with a SurfaceType object reference // Will tell us if the 2 surfaces match (Only as far as location in VRAM, format, dimensions, etc) @@ -14,7 +15,7 @@ // Including equality of the allocated OpenGL resources, which we don't want // - A "valid" member that tells us whether the function is still valid or not // - A "location" member which tells us which location in 3DS memory this surface occupies -template +template class SurfaceCache { // Vanilla std::optional can't hold actual references using OptionalRef = std::optional>; @@ -22,11 +23,13 @@ class SurfaceCache { std::is_same(), "Invalid surface type"); size_t size; + size_t eviction_index; std::array buffer; public: void reset() { size = 0; + eviction_index=0; for (auto& e : buffer) { // Free the VRAM of all surfaces e.free(); } @@ -53,7 +56,15 @@ public: // Adds a surface object to the cache and returns it SurfaceType& add(const SurfaceType& surface) { if (size >= capacity) { - Helpers::panic("Surface cache full! Add emptying!"); + if(evict_on_overflow){ + auto & e = buffer[eviction_index % size]; + eviction_index++; + e.free(); + e.valid = false; + e = surface; + e.allocate(); + return e; + }else Helpers::panic("Surface cache full! Add emptying!"); } size++; diff --git a/src/core/renderer_gl/textures.cpp b/src/core/renderer_gl/textures.cpp index a806e1eb..e05be35a 100644 --- a/src/core/renderer_gl/textures.cpp +++ b/src/core/renderer_gl/textures.cpp @@ -35,8 +35,9 @@ void Texture::setNewConfig(u32 cfg) { void Texture::free() { valid = false; - if (texture.exists()) - Helpers::panic("Make this texture free itself"); + if (texture.exists()){ + glDeleteTextures(1, &texture.m_handle); + } } u64 Texture::sizeInBytes() {