diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 2316d50bae..e1ebeddb59 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -997,6 +997,11 @@ void GLES_GPU::InvalidateCacheHint(u32 addr, int size) { textureCache_.InvalidateAll(false); } +void GLES_GPU::ClearCacheNextFrame() { + textureCache_.ClearNextFrame(); +} + + void GLES_GPU::Flush() { transformDraw_.Flush(); } diff --git a/GPU/GLES/DisplayListInterpreter.h b/GPU/GLES/DisplayListInterpreter.h index ce6d7cc676..ae19f739be 100644 --- a/GPU/GLES/DisplayListInterpreter.h +++ b/GPU/GLES/DisplayListInterpreter.h @@ -46,6 +46,7 @@ public: virtual void UpdateStats(); virtual void InvalidateCache(u32 addr, int size); virtual void InvalidateCacheHint(u32 addr, int size); + virtual void ClearCacheNextFrame(); virtual void DeviceLost(); // Only happens on Android. Drop all textures and shaders. virtual void DumpNextFrame(); diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 631c167573..9bfa0d6dca 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -44,7 +44,7 @@ u32 RoundUpToPowerOf2(u32 v) return v; } -TextureCache::TextureCache() { +TextureCache::TextureCache() : clearCacheNextFrame_(false) { lastBoundTexture = -1; // This is 5MB of temporary storage. Might be possible to shrink it. tmpTexBuf32.resize(1024 * 512); // 2MB @@ -120,6 +120,11 @@ void TextureCache::InvalidateAll(bool force) { Invalidate(0, 0xFFFFFFFF, force); } +void TextureCache::ClearNextFrame() { + clearCacheNextFrame_ = true; +} + + TextureCache::TexCacheEntry *TextureCache::GetEntryAt(u32 texaddr) { // If no CLUT, as in framebuffer textures, cache key is simply texaddr. auto iter = cache.find(texaddr); @@ -654,7 +659,12 @@ static void convertColors(u8 *finalBuf, GLuint dstFmt, int numPixels) { void TextureCache::StartFrame() { lastBoundTexture = -1; - Decimate(); + if(clearCacheNextFrame_) { + Clear(true); + clearCacheNextFrame_ = false; + } else { + Decimate(); + } } static const u8 bitsPerPixel[11] = { diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 4e8949725a..66de2b3828 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -36,6 +36,7 @@ public: void StartFrame(); void Invalidate(u32 addr, int size, bool force); void InvalidateAll(bool force); + void ClearNextFrame(); // FramebufferManager keeps TextureCache updated about what regions of memory // are being rendered to. This is barebones so far. @@ -100,6 +101,8 @@ private: typedef std::map TexCache; TexCache cache; + bool clearCacheNextFrame_; + template class SimpleBuf { public: diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index 06a438cc10..21c067d9af 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -174,6 +174,9 @@ public: virtual void InvalidateCache(u32 addr, int size) = 0; virtual void InvalidateCacheHint(u32 addr, int size) = 0; + // Will cause the texture cache to be cleared at the start of the next frame. + virtual void ClearCacheNextFrame() = 0; + // Internal hack to avoid interrupts from "PPGe" drawing (utility UI, etc) virtual void EnableInterrupts(bool enable) = 0; diff --git a/GPU/Null/NullGpu.h b/GPU/Null/NullGpu.h index eea14f42cc..4dfb856d20 100644 --- a/GPU/Null/NullGpu.h +++ b/GPU/Null/NullGpu.h @@ -36,6 +36,7 @@ public: virtual void UpdateStats(); virtual void InvalidateCache(u32 addr, int size); virtual void InvalidateCacheHint(u32 addr, int size); + virtual void ClearCacheNextFrame() {}; virtual void Flush() {} virtual void DeviceLost() {} diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 788c1da8fe..883ccf722d 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -177,7 +177,7 @@ namespace MainWindow void setXbrzTexScaling(int num) { g_Config.iXBRZTexScalingLevel = num; - if(gpu) gpu->InvalidateCache(0,0); + if(gpu) gpu->ClearCacheNextFrame(); } BOOL Show(HINSTANCE hInstance, int nCmdShow)