From c0c058937f6b70b0d9550d3f9a7a9137d37ca4a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 13 Jun 2014 22:07:26 +0200 Subject: [PATCH 1/3] Limit the amount of texture scaling done per frame, to reduce stutters Scaling causes really bad stutters in some games on some hardware. This should also reduce the impact of pathological cases like the first boss of FF Type-0 to be more bearable. --- GPU/GLES/TextureCache.cpp | 25 +++++++++++++++++++++++-- GPU/GLES/TextureCache.h | 6 +++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 75c6ec397a..197a3cf8b7 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -55,13 +55,15 @@ #define TEXCACHE_NAME_CACHE_SIZE 16 +#define TEXCACHE_MAX_TEXELS_SCALED (256*256) // Per frame + #ifndef GL_UNPACK_ROW_LENGTH #define GL_UNPACK_ROW_LENGTH 0x0CF2 #endif extern int g_iNumVideos; -TextureCache::TextureCache() : clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL) { +TextureCache::TextureCache() : clearCacheNextFrame_(false), lowMemoryMode_(false), clutBuf_(NULL), texelsScaledThisFrame_(0) { lastBoundTexture = -1; decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL; // This is 5MB of temporary storage. Might be possible to shrink it. @@ -770,6 +772,10 @@ static void ConvertColors(void *dstBuf, const void *srcBuf, GLuint dstFmt, int n void TextureCache::StartFrame() { lastBoundTexture = -1; + + if (texelsScaledThisFrame_) + INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); + texelsScaledThisFrame_ = 0; if (clearCacheNextFrame_) { Clear(true); clearCacheNextFrame_ = false; @@ -1232,6 +1238,12 @@ void TextureCache::SetTexture(bool force) { } } + if (match && (entry->status & TexCacheEntry::STATUS_TO_SCALE) && g_Config.iTexScalingLevel != 1 && texelsScaledThisFrame_ < TEXCACHE_MAX_TEXELS_SCALED) { + INFO_LOG(G3D, "Reloading texture to do the scaling we skipped.."); + entry->status &= ~TexCacheEntry::STATUS_TO_SCALE; + match = false; + } + if (match) { // TODO: Mark the entry reliable if it's been safe for long enough? //got one! @@ -1381,7 +1393,6 @@ void TextureCache::SetTexture(bool force) { // If GLES3 is available, we can preallocate the storage, which makes texture loading more efficient. GLenum dstFmt = GetDestFormat(format, gstate.getClutPaletteFormat()); - int scaleFactor; // Auto-texture scale upto 5x rendering resolution if (g_Config.iTexScalingLevel == 0) { @@ -1406,6 +1417,16 @@ void TextureCache::SetTexture(bool force) { if (entry->addr > 0x05000000 && entry->addr < 0x08800000) scaleFactor = 1; + if (scaleFactor != 1) { + if (texelsScaledThisFrame_ >= TEXCACHE_MAX_TEXELS_SCALED) { + entry->status |= TexCacheEntry::STATUS_TO_SCALE; + scaleFactor = 1; + INFO_LOG(G3D, "Skipped scaling for now.."); + } else { + texelsScaledThisFrame_ += w * h; + } + } + // Disabled this due to issue #6075: https://github.com/hrydgard/ppsspp/issues/6075 // This breaks Dangan Ronpa 2 with mipmapping enabled. Why? No idea, it shouldn't. // glTexStorage2D probably has few benefits for us anyway. diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 587a491d55..904fe80109 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -115,7 +115,9 @@ public: STATUS_CLUT_RECHECK = 0x20, // Another texture with same addr had a hashfail. STATUS_DEPALETTIZE = 0x40, STATUS_DEPALETTIZE_DIRTY = 0x80, - STATUS_TEXPARAM_DIRTY = 0x100 + STATUS_TEXPARAM_DIRTY = 0x100, + + STATUS_TO_SCALE = 0x200, }; // Status, but int so we can zero initialize. @@ -227,6 +229,8 @@ private: float maxAnisotropyLevel; int decimationCounter_; + int texelsScaledThisFrame_; + FramebufferManager *framebufferManager_; DepalShaderCache *depalShaderCache_; ShaderManager *shaderManager_; From ea9f8d8bf34f9a5283174393b7fb29480818cf3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 13 Jun 2014 22:11:25 +0200 Subject: [PATCH 2/3] Comment out the deferred scaling logs. --- GPU/GLES/TextureCache.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 197a3cf8b7..461b498deb 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -773,8 +773,9 @@ static void ConvertColors(void *dstBuf, const void *srcBuf, GLuint dstFmt, int n void TextureCache::StartFrame() { lastBoundTexture = -1; - if (texelsScaledThisFrame_) - INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); + if (texelsScaledThisFrame_) { + // INFO_LOG(G3D, "Scaled %i texels", texelsScaledThisFrame_); + } texelsScaledThisFrame_ = 0; if (clearCacheNextFrame_) { Clear(true); @@ -1239,7 +1240,7 @@ void TextureCache::SetTexture(bool force) { } if (match && (entry->status & TexCacheEntry::STATUS_TO_SCALE) && g_Config.iTexScalingLevel != 1 && texelsScaledThisFrame_ < TEXCACHE_MAX_TEXELS_SCALED) { - INFO_LOG(G3D, "Reloading texture to do the scaling we skipped.."); + // INFO_LOG(G3D, "Reloading texture to do the scaling we skipped.."); entry->status &= ~TexCacheEntry::STATUS_TO_SCALE; match = false; } @@ -1421,7 +1422,7 @@ void TextureCache::SetTexture(bool force) { if (texelsScaledThisFrame_ >= TEXCACHE_MAX_TEXELS_SCALED) { entry->status |= TexCacheEntry::STATUS_TO_SCALE; scaleFactor = 1; - INFO_LOG(G3D, "Skipped scaling for now.."); + // INFO_LOG(G3D, "Skipped scaling for now.."); } else { texelsScaledThisFrame_ += w * h; } From 2f86e3e0217faf18d577d3b457d5a9a7920bed52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 13 Jun 2014 23:01:40 +0200 Subject: [PATCH 3/3] Clear STATUS_TO_SCALE at a better place --- GPU/GLES/TextureCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 461b498deb..5048f61544 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -1241,7 +1241,6 @@ void TextureCache::SetTexture(bool force) { if (match && (entry->status & TexCacheEntry::STATUS_TO_SCALE) && g_Config.iTexScalingLevel != 1 && texelsScaledThisFrame_ < TEXCACHE_MAX_TEXELS_SCALED) { // INFO_LOG(G3D, "Reloading texture to do the scaling we skipped.."); - entry->status &= ~TexCacheEntry::STATUS_TO_SCALE; match = false; } @@ -1424,6 +1423,7 @@ void TextureCache::SetTexture(bool force) { scaleFactor = 1; // INFO_LOG(G3D, "Skipped scaling for now.."); } else { + entry->status &= ~TexCacheEntry::STATUS_TO_SCALE; texelsScaledThisFrame_ += w * h; } }