summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/TextureCacheBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/TextureCacheBase.cpp')
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.cpp62
1 files changed, 59 insertions, 3 deletions
diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index 9e8cb9387f..0bbc336a31 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -22,6 +22,7 @@
enum
{
TEXTURE_KILL_THRESHOLD = 200,
+ RENDER_TARGET_KILL_THRESHOLD = 3,
};
TextureCache *g_texture_cache;
@@ -30,6 +31,7 @@ GC_ALIGNED16(u8 *TextureCache::temp) = nullptr;
unsigned int TextureCache::temp_size;
TextureCache::TexCache TextureCache::textures;
+TextureCache::RenderTargetPool TextureCache::render_target_pool;
TextureCache::BackupConfig TextureCache::backup_config;
@@ -67,6 +69,12 @@ void TextureCache::Invalidate()
delete tex.second;
}
textures.clear();
+
+ for (auto& rt : render_target_pool)
+ {
+ delete rt;
+ }
+ render_target_pool.clear();
}
TextureCache::~TextureCache()
@@ -138,6 +146,22 @@ void TextureCache::Cleanup()
++iter;
}
}
+
+ for (size_t i = 0; i < render_target_pool.size();)
+ {
+ auto rt = render_target_pool[i];
+
+ if (frameCount > RENDER_TARGET_KILL_THRESHOLD + rt->frameCount)
+ {
+ delete rt;
+ render_target_pool[i] = render_target_pool.back();
+ render_target_pool.pop_back();
+ }
+ else
+ {
+ ++i;
+ }
+ }
}
void TextureCache::InvalidateRange(u32 start_address, u32 size)
@@ -868,8 +892,17 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
}
else if (!(entry->type == TCET_EC_VRAM && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h))
{
- // remove it and recreate it as a render target
- delete entry;
+ if (entry->type == TCET_EC_VRAM)
+ {
+ // try to re-use this render target later
+ FreeRenderTarget(entry);
+ }
+ else
+ {
+ // remove it and recreate it as a render target
+ delete entry;
+ }
+
entry = nullptr;
}
}
@@ -877,7 +910,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
if (nullptr == entry)
{
// create the texture
- textures[dstAddr] = entry = g_texture_cache->CreateRenderTargetTexture(scaled_tex_w, scaled_tex_h);
+ textures[dstAddr] = entry = AllocateRenderTarget(scaled_tex_w, scaled_tex_h);
// TODO: Using the wrong dstFormat, dumb...
entry->SetGeneralParameters(dstAddr, 0, dstFormat, 1);
@@ -890,3 +923,26 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
entry->FromRenderTarget(dstAddr, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat);
}
+
+TextureCache::TCacheEntryBase* TextureCache::AllocateRenderTarget(unsigned int width, unsigned int height)
+{
+ for (size_t i = 0; i < render_target_pool.size(); ++i)
+ {
+ auto rt = render_target_pool[i];
+
+ if (rt->virtual_width != width || rt->virtual_height != height)
+ continue;
+
+ render_target_pool[i] = render_target_pool.back();
+ render_target_pool.pop_back();
+
+ return rt;
+ }
+
+ return g_texture_cache->CreateRenderTargetTexture(width, height);
+}
+
+void TextureCache::FreeRenderTarget(TCacheEntryBase* entry)
+{
+ render_target_pool.push_back(entry);
+}