diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 257af33ddf..fb5bb17fb3 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -193,16 +193,19 @@ void TextureCacheCommon::NotifyFramebuffer(u32 address, VirtualFramebuffer *fram } } void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) { + const u64 cachekey = entry->CacheKey(); const bool hasInvalidFramebuffer = entry->framebuffer == nullptr || entry->invalidHint == -1; const bool hasOlderFramebuffer = entry->framebuffer != nullptr && entry->framebuffer->last_frame_render < framebuffer->last_frame_render; bool hasFartherFramebuffer = false; + if (!hasInvalidFramebuffer && !hasOlderFramebuffer) { // If it's valid, but the offset is greater, then we still win. - if (fbTexInfo_[entry->addr].yOffset == fbInfo.yOffset) - hasFartherFramebuffer = fbTexInfo_[entry->addr].xOffset > fbInfo.xOffset; + if (fbTexInfo_[cachekey].yOffset == fbInfo.yOffset) + hasFartherFramebuffer = fbTexInfo_[cachekey].xOffset > fbInfo.xOffset; else - hasFartherFramebuffer = fbTexInfo_[entry->addr].yOffset > fbInfo.yOffset; + hasFartherFramebuffer = fbTexInfo_[cachekey].yOffset > fbInfo.yOffset; } + if (hasInvalidFramebuffer || hasOlderFramebuffer || hasFartherFramebuffer) { if (entry->framebuffer == nullptr) { cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry); @@ -211,7 +214,7 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra entry->invalidHint = 0; entry->status &= ~TextureCacheCommon::TexCacheEntry::STATUS_DEPALETTIZE; entry->maxLevel = 0; - fbTexInfo_[entry->addr] = fbInfo; + fbTexInfo_[cachekey] = fbInfo; framebuffer->last_frame_attached = gpuStats.numFlips; host->GPUNotifyTextureAttachment(entry->addr); } else if (entry->framebuffer == framebuffer) { @@ -220,6 +223,8 @@ void TextureCacheCommon::AttachFramebufferValid(TexCacheEntry *entry, VirtualFra } void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) { + const u64 cachekey = entry->CacheKey(); + if (entry->framebuffer == nullptr || entry->framebuffer == framebuffer) { if (entry->framebuffer == nullptr) { cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry); @@ -228,15 +233,18 @@ void TextureCacheCommon::AttachFramebufferInvalid(TexCacheEntry *entry, VirtualF entry->invalidHint = -1; entry->status &= ~TextureCacheCommon::TexCacheEntry::STATUS_DEPALETTIZE; entry->maxLevel = 0; - fbTexInfo_[entry->addr] = fbInfo; + fbTexInfo_[cachekey] = fbInfo; host->GPUNotifyTextureAttachment(entry->addr); } } void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer) { + const u64 cachekey = entry->CacheKey(); + if (entry->framebuffer == framebuffer) { cacheSizeEstimate_ += EstimateTexMemoryUsage(entry); entry->framebuffer = 0; + fbTexInfo_.erase(cachekey); host->GPUNotifyTextureAttachment(entry->addr); } } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 9dd5abe3f3..fe621242b1 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -133,9 +133,9 @@ public: SetAlphaStatus(STATUS_ALPHA_SIMPLE); } } - bool Matches(u16 dim2, u8 format2, u8 maxLevel2); - u64 CacheKey(); + bool Matches(u16 dim2, u8 format2, u8 maxLevel2) const; + u64 CacheKey() const; static u64 CacheKey(u32 addr, u8 format, u16 dim, u32 cluthash); }; @@ -163,7 +163,7 @@ protected: u32 yOffset; }; std::vector fbCache_; - std::map fbTexInfo_; + std::map fbTexInfo_; void AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo); void AttachFramebufferInvalid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo); void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer); @@ -185,11 +185,11 @@ protected: int standardScaleFactor_; }; -inline bool TextureCacheCommon::TexCacheEntry::Matches(u16 dim2, u8 format2, u8 maxLevel2) { +inline bool TextureCacheCommon::TexCacheEntry::Matches(u16 dim2, u8 format2, u8 maxLevel2) const { return dim == dim2 && format == format2 && maxLevel == maxLevel2; } -inline u64 TextureCacheCommon::TexCacheEntry::CacheKey() { +inline u64 TextureCacheCommon::TexCacheEntry::CacheKey() const { return CacheKey(addr, format, dim, cluthash); } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 34d2a55c4b..35288483cc 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -116,7 +116,7 @@ void TextureCacheDX9::Clear(bool delete_them) { void TextureCacheDX9::DeleteTexture(TexCache::iterator it) { ReleaseTexture(&it->second); - auto fbInfo = fbTexInfo_.find(it->second.addr); + auto fbInfo = fbTexInfo_.find(it->first); if (fbInfo != fbTexInfo_.end()) { fbTexInfo_.erase(fbInfo); } @@ -645,6 +645,8 @@ void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebu bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; if (useBufferedRendering) { const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); + const u64 cachekey = entry->CacheKey(); + const auto &fbInfo = fbTexInfo_[cachekey]; LPDIRECT3DPIXELSHADER9 pshader = nullptr; if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { @@ -671,8 +673,8 @@ void TextureCacheDX9::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebu gstate_c.curTextureWidth = framebuffer->bufferWidth; gstate_c.curTextureHeight = framebuffer->bufferHeight; gstate_c.bgraTexture = false; - gstate_c.curTextureXOffset = fbTexInfo_[entry->addr].xOffset; - gstate_c.curTextureYOffset = fbTexInfo_[entry->addr].yOffset; + gstate_c.curTextureXOffset = fbInfo.xOffset; + gstate_c.curTextureYOffset = fbInfo.yOffset; gstate_c.needShaderTexClamp = gstate_c.curTextureWidth != (u32)gstate.getTextureWidth(0) || gstate_c.curTextureHeight != (u32)gstate.getTextureHeight(0); if (gstate_c.curTextureXOffset != 0 || gstate_c.curTextureYOffset != 0) { gstate_c.needShaderTexClamp = true; diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 3c6a61d389..16c88531a8 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -118,7 +118,7 @@ void TextureCache::Clear(bool delete_them) { void TextureCache::DeleteTexture(TexCache::iterator it) { glDeleteTextures(1, &it->second.textureName); - auto fbInfo = fbTexInfo_.find(it->second.addr); + auto fbInfo = fbTexInfo_.find(it->first); if (fbInfo != fbTexInfo_.end()) { fbTexInfo_.erase(fbInfo); } @@ -716,6 +716,9 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; if (useBufferedRendering) { const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); + const u64 cachekey = entry->CacheKey(); + const auto &fbInfo = fbTexInfo_[cachekey]; + DepalShader *depal = nullptr; if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { depal = depalShaderCache_->GetDepalettizeShader(clutFormat, framebuffer->drawnFormat); @@ -740,8 +743,8 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe // We need to force it, since we may have set it on a texture before attaching. gstate_c.curTextureWidth = framebuffer->bufferWidth; gstate_c.curTextureHeight = framebuffer->bufferHeight; - gstate_c.curTextureXOffset = fbTexInfo_[entry->addr].xOffset; - gstate_c.curTextureYOffset = fbTexInfo_[entry->addr].yOffset; + gstate_c.curTextureXOffset = fbInfo.xOffset; + gstate_c.curTextureYOffset = fbInfo.yOffset; gstate_c.needShaderTexClamp = gstate_c.curTextureWidth != (u32)gstate.getTextureWidth(0) || gstate_c.curTextureHeight != (u32)gstate.getTextureHeight(0); if (gstate_c.curTextureXOffset != 0 || gstate_c.curTextureYOffset != 0) { gstate_c.needShaderTexClamp = true; diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index ae6c5174ac..9672c8efbc 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -203,7 +203,7 @@ void TextureCacheVulkan::Clear(bool delete_them) { void TextureCacheVulkan::DeleteTexture(TexCache::iterator it) { delete it->second.vkTex; - auto fbInfo = fbTexInfo_.find(it->second.addr); + auto fbInfo = fbTexInfo_.find(it->first); if (fbInfo != fbTexInfo_.end()) { fbTexInfo_.erase(fbInfo); } @@ -767,6 +767,9 @@ void TextureCacheVulkan::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; if (useBufferedRendering) { const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); + const u64 cachekey = entry->CacheKey(); + const auto &fbInfo = fbTexInfo_[cachekey]; + DepalShaderVulkan *depal = nullptr; if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) { // depal = depalShaderCache_->GetDepalettizeShader(clutFormat, framebuffer->drawnFormat); @@ -791,8 +794,8 @@ void TextureCacheVulkan::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFram // We need to force it, since we may have set it on a texture before attaching. gstate_c.curTextureWidth = framebuffer->bufferWidth; gstate_c.curTextureHeight = framebuffer->bufferHeight; - gstate_c.curTextureXOffset = fbTexInfo_[entry->addr].xOffset; - gstate_c.curTextureYOffset = fbTexInfo_[entry->addr].yOffset; + gstate_c.curTextureXOffset = fbInfo.xOffset; + gstate_c.curTextureYOffset = fbInfo.yOffset; gstate_c.needShaderTexClamp = gstate_c.curTextureWidth != (u32)gstate.getTextureWidth(0) || gstate_c.curTextureHeight != (u32)gstate.getTextureHeight(0); if (gstate_c.curTextureXOffset != 0 || gstate_c.curTextureYOffset != 0) { gstate_c.needShaderTexClamp = true;