diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index a3d6c62740..ba54adbac5 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -119,8 +119,12 @@ void TextureCache::InvalidateRange(u32 start_address, u32 size) void TextureCache::MakeRangeDynamic(u32 start_address, u32 size) { TexCache::iterator - iter = textures.begin(), - tcend = textures.end(); + iter = textures.lower_bound(start_address), + tcend = textures.upper_bound(start_address + size); + + if (iter != textures.begin()) + iter--; + for (; iter != tcend; ++iter) { const int rangePosition = iter->second->IntersectsMemoryRange(start_address, size); @@ -131,6 +135,18 @@ void TextureCache::MakeRangeDynamic(u32 start_address, u32 size) } } +bool TextureCache::Find(u32 start_address, u64 hash) +{ + TexCache::iterator + iter = textures.lower_bound(start_address), + tcend = textures.upper_bound(start_address); + + if (iter->second->hash == hash) + return true; + + return false; +} + int TextureCache::TCacheEntryBase::IntersectsMemoryRange(u32 range_address, u32 range_size) const { if (addr + size_in_bytes < range_address) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index 24ca3dd761..d434bec5f6 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -77,6 +77,7 @@ public: static void InvalidateRange(u32 start_address, u32 size); static void MakeRangeDynamic(u32 start_address, u32 size); static void ClearRenderTargets(); // currently only used by OGL + static bool Find(u32 start_address, u64 hash); virtual TCacheEntryBase* CreateTexture(unsigned int width, unsigned int height, unsigned int expanded_width, unsigned int tex_levels, PC_TexFormat pcfmt) = 0; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp index 3e9d25c476..05514d1919 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp @@ -406,6 +406,12 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format); + u64 hash = GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); + + // If the texture in RAM is already in the texture cache, do not copy it again as it has not changed. + if (TextureCache::Find(address, hash)) + return hash; + u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1; u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1; u16 samples = TextureConversionShader::GetEncodedSampleCount(format); @@ -439,7 +445,7 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); TextureCache::MakeRangeDynamic(address,size_in_bytes); - return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); + return hash; } void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index 9236f2a627..ee1236b8d1 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -345,6 +345,12 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format); + u64 hash = GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); + + // If the texture in RAM is already in the texture cache, do not copy it again as it has not changed. + if (TextureCache::Find(address, hash)) + return hash; + u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1; u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1; u16 samples = TextureConversionShader::GetEncodedSampleCount(format); @@ -375,7 +381,7 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer); TextureCache::MakeRangeDynamic(address,size_in_bytes); - return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); + return hash; } void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)