From 1c98a43203263b73da32c19085492c94214a56cb Mon Sep 17 00:00:00 2001 From: degasus Date: Mon, 19 May 2014 18:31:38 +0200 Subject: [PATCH] TexCache: clean up frameCount handling --- Source/Core/VideoBackends/D3D/Render.cpp | 2 +- Source/Core/VideoBackends/OGL/Render.cpp | 2 +- Source/Core/VideoCommon/TextureCacheBase.cpp | 15 ++++++++++----- Source/Core/VideoCommon/TextureCacheBase.h | 5 ++++- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index fd8e406ff2..92c41bfcea 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -851,7 +851,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co OSD::DrawMessages(); D3D::EndFrame(); - TextureCache::Cleanup(); + TextureCache::Cleanup(frameCount); // Enable configuration changes UpdateActiveConfig(); diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 3fecbac10d..5a64fb3c00 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1715,7 +1715,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co } // Clean out old stuff from caches. It's not worth it to clean out the shader caches. - TextureCache::Cleanup(); + TextureCache::Cleanup(frameCount); // Render to the framebuffer. FramebufferManager::SetFramebuffer(0); diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 870e79552b..d963727232 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -22,6 +22,7 @@ static const u64 TEXHASH_INVALID = 0; static const int TEXTURE_KILL_THRESHOLD = 200; static const int RENDER_TARGET_KILL_THRESHOLD = 3; +static const u64 FRAMECOUNT_INVALID = 0; TextureCache *g_texture_cache; @@ -136,13 +137,17 @@ void TextureCache::OnConfigChanged(VideoConfig& config) backup_config.s_efb_mono_depth = config.bStereoEFBMonoDepth; } -void TextureCache::Cleanup() +void TextureCache::Cleanup(int _frameCount) { TexCache::iterator iter = textures.begin(); TexCache::iterator tcend = textures.end(); while (iter != tcend) { - if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount && + if(iter->second->frameCount == FRAMECOUNT_INVALID) + { + iter->second->frameCount = _frameCount; + } + if (_frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount && // EFB copies living on the host GPU are unrecoverable and thus shouldn't be deleted !iter->second->IsEfbCopy()) { @@ -159,7 +164,7 @@ void TextureCache::Cleanup() { auto rt = render_target_pool[i]; - if (frameCount > RENDER_TARGET_KILL_THRESHOLD + rt->frameCount) + if (_frameCount > RENDER_TARGET_KILL_THRESHOLD + rt->frameCount) { delete rt; render_target_pool[i] = render_target_pool.back(); @@ -277,7 +282,7 @@ static u32 CalculateLevelSize(u32 level_0_size, u32 level) // Used by TextureCache::Load static TextureCache::TCacheEntryBase* ReturnEntry(unsigned int stage, TextureCache::TCacheEntryBase* entry) { - entry->frameCount = frameCount; + entry->frameCount = FRAMECOUNT_INVALID; entry->Bind(stage); GFX_DEBUGGER_PAUSE_AT(NEXT_TEXTURE_CHANGE, true); @@ -873,7 +878,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat entry->type = TCET_EC_VRAM; } - entry->frameCount = frameCount; + entry->frameCount = FRAMECOUNT_INVALID; entry->FromRenderTarget(dstAddr, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat); } diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 1fbcd49356..ae5e3be1ea 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -87,7 +87,10 @@ public: virtual ~TextureCache(); // needs virtual for DX11 dtor static void OnConfigChanged(VideoConfig& config); - static void Cleanup(); + + // Removes textures which aren't used for more than TEXTURE_KILL_THRESHOLD frames, + // frameCount is the current frame number. + static void Cleanup(int frameCount); static void Invalidate(); static void InvalidateRange(u32 start_address, u32 size);