diff --git a/Source/Core/DolphinWX/Debugger/DebuggerPanel.cpp b/Source/Core/DolphinWX/Debugger/DebuggerPanel.cpp index 5326212275..2b1e8b1513 100644 --- a/Source/Core/DolphinWX/Debugger/DebuggerPanel.cpp +++ b/Source/Core/DolphinWX/Debugger/DebuggerPanel.cpp @@ -304,7 +304,7 @@ void GFXDebuggerPanel::OnClearScreenButton(wxCommandEvent& event) void GFXDebuggerPanel::OnClearTextureCacheButton(wxCommandEvent& event) { - TextureCacheBase::Invalidate(); + g_texture_cache->Invalidate(); } void GFXDebuggerPanel::OnClearVertexShaderCacheButton(wxCommandEvent& event) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index aa9a4501e7..df9335265a 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -841,11 +841,11 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, OSD::DrawMessages(); D3D::EndFrame(); - TextureCacheBase::Cleanup(frameCount); + g_texture_cache->Cleanup(frameCount); // Enable configuration changes UpdateActiveConfig(); - TextureCacheBase::OnConfigChanged(g_ActiveConfig); + g_texture_cache->OnConfigChanged(g_ActiveConfig); SetWindowSize(fbStride, fbHeight); diff --git a/Source/Core/VideoBackends/D3D/TextureCache.cpp b/Source/Core/VideoBackends/D3D/TextureCache.cpp index 0fa7ec873c..55694dd1b8 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D/TextureCache.cpp @@ -127,12 +127,11 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase* g_renderer->RestoreAPIState(); } -void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level) +void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, + u32 level) { unsigned int src_pitch = 4 * expanded_width; - D3D::ReplaceRGBATexture2D(texture->GetTex(), TextureCache::temp, width, height, src_pitch, level, - usage); + D3D::ReplaceRGBATexture2D(texture->GetTex(), buffer, width, height, src_pitch, level, usage); } TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config) diff --git a/Source/Core/VideoBackends/D3D/TextureCache.h b/Source/Core/VideoBackends/D3D/TextureCache.h index 9fc5d0876c..90e20ea0c3 100644 --- a/Source/Core/VideoBackends/D3D/TextureCache.h +++ b/Source/Core/VideoBackends/D3D/TextureCache.h @@ -32,8 +32,7 @@ private: const MathUtil::Rectangle& srcrect, const MathUtil::Rectangle& dstrect) override; - void Load(unsigned int width, unsigned int height, unsigned int expanded_width, - unsigned int levels) override; + void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override; void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool scaleByHalf, unsigned int cbufid, const float* colmat) override; diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index be65d04f4b..d5a2baa661 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -794,11 +794,11 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height OSD::DrawMessages(); D3D::EndFrame(); - TextureCacheBase::Cleanup(frameCount); + g_texture_cache->Cleanup(frameCount); // Enable configuration changes UpdateActiveConfig(); - TextureCacheBase::OnConfigChanged(g_ActiveConfig); + g_texture_cache->OnConfigChanged(g_ActiveConfig); SetWindowSize(fb_stride, fb_height); diff --git a/Source/Core/VideoBackends/D3D12/TextureCache.cpp b/Source/Core/VideoBackends/D3D12/TextureCache.cpp index 322cec9b1d..deb3bab6e7 100644 --- a/Source/Core/VideoBackends/D3D12/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D12/TextureCache.cpp @@ -172,12 +172,12 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase* g_renderer->RestoreAPIState(); } -void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level) +void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, + u32 level) { unsigned int src_pitch = 4 * expanded_width; - D3D::ReplaceRGBATexture2D(m_texture->GetTex12(), TextureCache::temp, width, height, src_pitch, - level, m_texture->GetResourceUsageState()); + D3D::ReplaceRGBATexture2D(m_texture->GetTex12(), buffer, width, height, src_pitch, level, + m_texture->GetResourceUsageState()); } TextureCacheBase::TCacheEntryBase* TextureCache::CreateTexture(const TCacheEntryConfig& config) diff --git a/Source/Core/VideoBackends/D3D12/TextureCache.h b/Source/Core/VideoBackends/D3D12/TextureCache.h index d8b20a4911..6a5fbcd2cc 100644 --- a/Source/Core/VideoBackends/D3D12/TextureCache.h +++ b/Source/Core/VideoBackends/D3D12/TextureCache.h @@ -39,8 +39,7 @@ private: const MathUtil::Rectangle& src_rect, const MathUtil::Rectangle& dst_rect) override; - void Load(unsigned int width, unsigned int height, unsigned int expanded_width, - unsigned int levels) override; + void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 levels) override; void FromRenderTarget(u8* dst, PEControl::PixelFormat src_format, const EFBRectangle& src_rect, bool scale_by_half, unsigned int cbuf_id, const float* colmat) override; diff --git a/Source/Core/VideoBackends/Null/TextureCache.h b/Source/Core/VideoBackends/Null/TextureCache.h index 7c51133c6a..886217e91f 100644 --- a/Source/Core/VideoBackends/Null/TextureCache.h +++ b/Source/Core/VideoBackends/Null/TextureCache.h @@ -31,11 +31,7 @@ private: { TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {} ~TCacheEntry() {} - void Load(unsigned int width, unsigned int height, unsigned int expanded_width, - unsigned int level) override - { - } - + void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {} void FromRenderTarget(u8* dst, PEControl::PixelFormat src_format, const EFBRectangle& src_rect, bool scale_by_half, unsigned int cbufid, const float* colmat) override { diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 70fc43a981..c3416f2b4d 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1506,7 +1506,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, } // Clean out old stuff from caches. It's not worth it to clean out the shader caches. - TextureCache::Cleanup(frameCount); + g_texture_cache->Cleanup(frameCount); // Render to the framebuffer. FramebufferManager::SetFramebuffer(0); @@ -1516,7 +1516,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, g_Config.iSaveTargetId = 0; UpdateActiveConfig(); - TextureCache::OnConfigChanged(g_ActiveConfig); + g_texture_cache->OnConfigChanged(g_ActiveConfig); // For testing zbuffer targets. // Renderer::SetZBufferRender(); diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp index 50c729d45e..20c3f488cc 100644 --- a/Source/Core/VideoBackends/OGL/TextureCache.cpp +++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp @@ -178,8 +178,8 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture(const TCacheEntryBase* g_renderer->RestoreAPIState(); } -void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, - unsigned int expanded_width, unsigned int level) +void TextureCache::TCacheEntry::Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, + u32 level) { if (level >= config.levels) PanicAlert("Texture only has %d levels, can't update level %d", config.levels, level); @@ -196,7 +196,7 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, glPixelStorei(GL_UNPACK_ROW_LENGTH, expanded_width); glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGBA, width, height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, - temp); + buffer); if (expanded_width != width) glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); diff --git a/Source/Core/VideoBackends/OGL/TextureCache.h b/Source/Core/VideoBackends/OGL/TextureCache.h index 0007cf1deb..ae4d15ad0a 100644 --- a/Source/Core/VideoBackends/OGL/TextureCache.h +++ b/Source/Core/VideoBackends/OGL/TextureCache.h @@ -39,8 +39,7 @@ private: const MathUtil::Rectangle& srcrect, const MathUtil::Rectangle& dstrect) override; - void Load(unsigned int width, unsigned int height, unsigned int expanded_width, - unsigned int level) override; + void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override; void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool scaleByHalf, unsigned int cbufid, const float* colmat) override; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 1ecd9517c8..44d0475ca9 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -64,11 +64,7 @@ private: { TCacheEntry(const TCacheEntryConfig& _config) : TCacheEntryBase(_config) {} ~TCacheEntry() {} - void Load(unsigned int width, unsigned int height, unsigned int expanded_width, - unsigned int level) override - { - } - + void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) override {} void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool scaleByHalf, unsigned int cbufid, const float* colmat) override { diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 2fe7f56687..9c558aa9f9 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -559,7 +559,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height CheckForTargetResize(fb_width, fb_stride, fb_height); // Clean up stale textures. - TextureCacheBase::Cleanup(frameCount); + TextureCache::GetInstance()->Cleanup(frameCount); } void Renderer::DrawFrame(VkRenderPass render_pass, const TargetRectangle& target_rect, @@ -1112,7 +1112,7 @@ void Renderer::CheckForConfigChanges() bool aspect_changed = old_aspect_ratio != g_ActiveConfig.iAspectRatio; // Update texture cache settings with any changed options. - TextureCache::OnConfigChanged(g_ActiveConfig); + TextureCache::GetInstance()->OnConfigChanged(g_ActiveConfig); // Handle internal resolution changes. if (efb_scale_changed) diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp index a860e8601d..984aa95db9 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.cpp @@ -328,7 +328,7 @@ TextureCache::TCacheEntry::~TCacheEntry() g_command_buffer_mgr->DeferFramebufferDestruction(m_framebuffer); } -void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, +void TextureCache::TCacheEntry::Load(const u8* buffer, unsigned int width, unsigned int height, unsigned int expanded_width, unsigned int level) { // Can't copy data larger than the texture extents. @@ -383,7 +383,7 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, u8* image_upload_buffer_pointer = upload_buffer->GetCurrentHostPointer(); // Copy to the buffer using the stride from the subresource layout - const u8* source_ptr = TextureCache::temp; + const u8* source_ptr = buffer; if (upload_pitch != source_pitch) { VkDeviceSize copy_pitch = std::min(source_pitch, upload_pitch); @@ -429,7 +429,7 @@ void TextureCache::TCacheEntry::Load(unsigned int width, unsigned int height, } // Copy data to staging texture first, then to the "real" texture. - staging_texture->WriteTexels(0, 0, width, height, TextureCache::temp, source_pitch); + staging_texture->WriteTexels(0, 0, width, height, buffer, source_pitch); staging_texture->CopyToImage(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), m_texture->GetImage(), VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, width, height, level, 0); diff --git a/Source/Core/VideoBackends/Vulkan/TextureCache.h b/Source/Core/VideoBackends/Vulkan/TextureCache.h index 4b60d39272..399632c1b2 100644 --- a/Source/Core/VideoBackends/Vulkan/TextureCache.h +++ b/Source/Core/VideoBackends/Vulkan/TextureCache.h @@ -27,8 +27,8 @@ public: Texture2D* GetTexture() const { return m_texture.get(); } VkFramebuffer GetFramebuffer() const { return m_framebuffer; } - void Load(unsigned int width, unsigned int height, unsigned int expanded_width, - unsigned int level) override; + void Load(const u8* buffer, unsigned int width, unsigned int height, + unsigned int expanded_width, unsigned int level) override; void FromRenderTarget(u8* dst, PEControl::PixelFormat src_format, const EFBRectangle& src_rect, bool scale_by_half, unsigned int cbufid, const float* colmat) override; void CopyRectangleFromTexture(const TCacheEntryBase* source, diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index f9bd1908de..75227a0433 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -227,9 +227,9 @@ static void BPWritten(const BPCmd& bp) { // bpmem.zcontrol.pixel_format to PEControl::Z24 is when the game wants to copy from ZBuffer // (Zbuffer uses 24-bit Format) - TextureCacheBase::CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride, - bpmem.zcontrol.pixel_format, srcRect, - !!PE_copy.intensity_fmt, !!PE_copy.half_scale); + g_texture_cache->CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride, + bpmem.zcontrol.pixel_format, srcRect, + !!PE_copy.intensity_fmt, !!PE_copy.half_scale); } else { diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp index 575fb29709..659eec31b3 100644 --- a/Source/Core/VideoCommon/MainBase.cpp +++ b/Source/Core/VideoCommon/MainBase.cpp @@ -243,6 +243,6 @@ void VideoBackendBase::CheckInvalidState() m_invalid = false; BPReload(); - TextureCacheBase::Invalidate(); + g_texture_cache->Invalidate(); } } diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 113358d35f..e3096a770f 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -108,7 +108,6 @@ static float AspectToWidescreen(float aspect) Renderer::Renderer() { UpdateActiveConfig(); - TextureCacheBase::OnConfigChanged(g_ActiveConfig); OSDChoice = 0; OSDTime = 0; diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 47ecc4f528..4cbdae9435 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -45,16 +45,6 @@ static const u64 MAX_TEXTURE_BINARY_SIZE = std::unique_ptr g_texture_cache; -alignas(16) u8* TextureCacheBase::temp = nullptr; -size_t TextureCacheBase::temp_size; - -TextureCacheBase::TexCache TextureCacheBase::textures_by_address; -TextureCacheBase::TexCache TextureCacheBase::textures_by_hash; -TextureCacheBase::TexPool TextureCacheBase::texture_pool; -TextureCacheBase::TCacheEntryBase* TextureCacheBase::bound_textures[8]; - -TextureCacheBase::BackupConfig TextureCacheBase::backup_config; - TextureCacheBase::TCacheEntryBase::~TCacheEntryBase() { } @@ -71,12 +61,13 @@ void TextureCacheBase::CheckTempSize(size_t required_size) TextureCacheBase::TextureCacheBase() { - temp_size = 2048 * 2048 * 4; - if (!temp) - temp = static_cast(Common::AllocateAlignedMemory(temp_size, 16)); + SetBackupConfig(g_ActiveConfig); - TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, - g_ActiveConfig.bTexFmtOverlayCenter); + temp_size = 2048 * 2048 * 4; + temp = static_cast(Common::AllocateAlignedMemory(temp_size, 16)); + + TexDecoder_SetTexFmtOverlayOptions(backup_config.texfmt_overlay, + backup_config.texfmt_overlay_center); HiresTexture::Init(); @@ -111,42 +102,33 @@ TextureCacheBase::~TextureCacheBase() void TextureCacheBase::OnConfigChanged(VideoConfig& config) { - if (g_texture_cache) + if (config.bHiresTextures != backup_config.hires_textures || + config.bCacheHiresTextures != backup_config.cache_hires_textures) { - if (config.bHiresTextures != backup_config.s_hires_textures || - config.bCacheHiresTextures != backup_config.s_cache_hires_textures) - { - HiresTexture::Update(); - } - - // TODO: Invalidating texcache is really stupid in some of these cases - if (config.iSafeTextureCache_ColorSamples != backup_config.s_colorsamples || - config.bTexFmtOverlayEnable != backup_config.s_texfmt_overlay || - config.bTexFmtOverlayCenter != backup_config.s_texfmt_overlay_center || - config.bHiresTextures != backup_config.s_hires_textures) - { - g_texture_cache->Invalidate(); - - TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, - g_ActiveConfig.bTexFmtOverlayCenter); - } - - if ((config.iStereoMode > 0) != backup_config.s_stereo_3d || - config.bStereoEFBMonoDepth != backup_config.s_efb_mono_depth) - { - g_texture_cache->DeleteShaders(); - if (!g_texture_cache->CompileShaders()) - PanicAlert("Failed to recompile one or more texture conversion shaders."); - } + HiresTexture::Update(); } - backup_config.s_colorsamples = config.iSafeTextureCache_ColorSamples; - backup_config.s_texfmt_overlay = config.bTexFmtOverlayEnable; - backup_config.s_texfmt_overlay_center = config.bTexFmtOverlayCenter; - backup_config.s_hires_textures = config.bHiresTextures; - backup_config.s_cache_hires_textures = config.bCacheHiresTextures; - backup_config.s_stereo_3d = config.iStereoMode > 0; - backup_config.s_efb_mono_depth = config.bStereoEFBMonoDepth; + // TODO: Invalidating texcache is really stupid in some of these cases + if (config.iSafeTextureCache_ColorSamples != backup_config.color_samples || + config.bTexFmtOverlayEnable != backup_config.texfmt_overlay || + config.bTexFmtOverlayCenter != backup_config.texfmt_overlay_center || + config.bHiresTextures != backup_config.hires_textures) + { + Invalidate(); + + TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, + g_ActiveConfig.bTexFmtOverlayCenter); + } + + if ((config.iStereoMode > 0) != backup_config.stereo_3d || + config.bStereoEFBMonoDepth != backup_config.efb_mono_depth) + { + g_texture_cache->DeleteShaders(); + if (!g_texture_cache->CompileShaders()) + PanicAlert("Failed to recompile one or more texture conversion shaders."); + } + + SetBackupConfig(config); } void TextureCacheBase::Cleanup(int _frameCount) @@ -220,31 +202,38 @@ bool TextureCacheBase::TCacheEntryBase::OverlapsMemoryRange(u32 range_address, u return true; } -TextureCacheBase::TCacheEntryBase* TextureCacheBase::TCacheEntryBase::ApplyPalette(u8* palette, - u32 tlutfmt) +void TextureCacheBase::SetBackupConfig(const VideoConfig& config) { - TCacheEntryConfig newconfig; - newconfig.rendertarget = true; - newconfig.width = config.width; - newconfig.height = config.height; - newconfig.layers = config.layers; - TCacheEntryBase* decoded_entry = AllocateTexture(newconfig); + backup_config.color_samples = config.iSafeTextureCache_ColorSamples; + backup_config.texfmt_overlay = config.bTexFmtOverlayEnable; + backup_config.texfmt_overlay_center = config.bTexFmtOverlayCenter; + backup_config.hires_textures = config.bHiresTextures; + backup_config.cache_hires_textures = config.bCacheHiresTextures; + backup_config.stereo_3d = config.iStereoMode > 0; + backup_config.efb_mono_depth = config.bStereoEFBMonoDepth; +} - if (decoded_entry) - { - decoded_entry->SetGeneralParameters(addr, size_in_bytes, format); - decoded_entry->SetDimensions(native_width, native_height, 1); - decoded_entry->SetHashes(base_hash, hash); - decoded_entry->frameCount = FRAMECOUNT_INVALID; - decoded_entry->is_efb_copy = false; +TextureCacheBase::TCacheEntryBase* TextureCacheBase::ApplyPaletteToEntry(TCacheEntryBase* entry, + u8* palette, u32 tlutfmt) +{ + TCacheEntryConfig new_config = entry->config; + new_config.levels = 1; + new_config.rendertarget = true; - g_texture_cache->ConvertTexture(decoded_entry, this, palette, static_cast(tlutfmt)); - textures_by_address.emplace(addr, decoded_entry); + TCacheEntryBase* decoded_entry = AllocateTexture(new_config); + if (!decoded_entry) + return nullptr; - return decoded_entry; - } + decoded_entry->SetGeneralParameters(entry->addr, entry->size_in_bytes, entry->format); + decoded_entry->SetDimensions(entry->native_width, entry->native_height, 1); + decoded_entry->SetHashes(entry->base_hash, entry->hash); + decoded_entry->frameCount = FRAMECOUNT_INVALID; + decoded_entry->is_efb_copy = false; - return nullptr; + ConvertTexture(decoded_entry, entry, palette, static_cast(tlutfmt)); + textures_by_address.emplace(entry->addr, decoded_entry); + + return decoded_entry; } void TextureCacheBase::ScaleTextureCacheEntryTo(TextureCacheBase::TCacheEntryBase** entry, @@ -342,7 +331,7 @@ TextureCacheBase::DoPartialTextureUpdates(TexCache::iterator iter_t, u8* palette { if (isPaletteTexture) { - TCacheEntryBase* decoded_entry = entry->ApplyPalette(palette, tlutfmt); + TCacheEntryBase* decoded_entry = ApplyPaletteToEntry(entry, palette, tlutfmt); if (decoded_entry) { // Link the efb copy with the partially updated texture, so we won't apply this partial @@ -701,7 +690,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) if (unconverted_copy != textures_by_address.end()) { TCacheEntryBase* decoded_entry = - unconverted_copy->second->ApplyPalette(&texMem[tlutaddr], tlutfmt); + ApplyPaletteToEntry(unconverted_copy->second, &texMem[tlutaddr], tlutfmt); if (decoded_entry) { @@ -810,7 +799,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) entry->is_custom_tex = hires_tex != nullptr; // load texture - entry->Load(width, height, expandedWidth, 0); + entry->Load(temp, width, height, expandedWidth, 0); std::string basename = ""; if (g_ActiveConfig.bDumpTextures && !hires_tex) @@ -827,7 +816,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) const auto& level = hires_tex->m_levels[level_index]; CheckTempSize(level.data_size); memcpy(temp, level.data.get(), level.data_size); - entry->Load(level.width, level.height, level.width, level_index); + entry->Load(temp, level.width, level.height, level.width, level_index); } } else @@ -858,7 +847,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) mip_src_data += TexDecoder_GetTextureSizeInBytes(expanded_mip_width, expanded_mip_height, texformat); - entry->Load(mip_width, mip_height, expanded_mip_width, level); + entry->Load(temp, mip_width, mip_height, expanded_mip_width, level); if (g_ActiveConfig.bDumpTextures) DumpTexture(entry, basename, level); @@ -1253,8 +1242,8 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo if (copy_to_ram) { - g_texture_cache->CopyEFB(dst, dstFormat, tex_w, bytes_per_row, num_blocks_y, dstStride, - srcFormat, srcRect, isIntensity, scaleByHalf); + CopyEFB(dst, dstFormat, tex_w, bytes_per_row, num_blocks_y, dstStride, srcFormat, srcRect, + isIntensity, scaleByHalf); } else { @@ -1364,7 +1353,7 @@ TextureCacheBase::AllocateTexture(const TCacheEntryConfig& config) } else { - entry = g_texture_cache->CreateTexture(config); + entry = CreateTexture(config); if (!entry) return nullptr; diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 437392569f..f097037fa2 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -127,16 +127,13 @@ public: const MathUtil::Rectangle& srcrect, const MathUtil::Rectangle& dstrect) = 0; - virtual void Load(unsigned int width, unsigned int height, unsigned int expanded_width, - unsigned int level) = 0; + virtual void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) = 0; virtual void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, bool scaleByHalf, unsigned int cbufid, const float* colmat) = 0; bool OverlapsMemoryRange(u32 range_address, u32 range_size) const; - TextureCacheBase::TCacheEntryBase* ApplyPalette(u8* palette, u32 tlutfmt); - bool IsEfbCopy() const { return is_efb_copy; } u32 NumBlocksY() const; u32 BytesPerRow() const; @@ -146,13 +143,13 @@ public: virtual ~TextureCacheBase(); // needs virtual for DX11 dtor - static void OnConfigChanged(VideoConfig& config); + void OnConfigChanged(VideoConfig& config); // Removes textures which aren't used for more than TEXTURE_KILL_THRESHOLD frames, // frameCount is the current frame number. - static void Cleanup(int _frameCount); + void Cleanup(int _frameCount); - static void Invalidate(); + void Invalidate(); virtual TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) = 0; @@ -163,13 +160,12 @@ public: virtual bool CompileShaders() = 0; virtual void DeleteShaders() = 0; - static TCacheEntryBase* Load(const u32 stage); - static void UnbindTextures(); + TCacheEntryBase* Load(const u32 stage); + void UnbindTextures(); virtual void BindTextures(); - static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride, - PEControl::PixelFormat srcFormat, - const EFBRectangle& srcRect, bool isIntensity, - bool scaleByHalf); + void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride, + PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect, + bool isIntensity, bool scaleByHalf); virtual void ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette, TlutFormat format) = 0; @@ -177,46 +173,52 @@ public: protected: TextureCacheBase(); - alignas(16) static u8* temp; - static size_t temp_size; + alignas(16) u8* temp = nullptr; + size_t temp_size = 0; - static TCacheEntryBase* bound_textures[8]; + TCacheEntryBase* bound_textures[8] = {}; private: typedef std::multimap TexCache; typedef std::unordered_multimap TexPool; - static void ScaleTextureCacheEntryTo(TCacheEntryBase** entry, u32 new_width, u32 new_height); - static TCacheEntryBase* DoPartialTextureUpdates(TexCache::iterator iter, u8* palette, - u32 tlutfmt); - static void DumpTexture(TCacheEntryBase* entry, std::string basename, unsigned int level); - static void CheckTempSize(size_t required_size); - static TCacheEntryBase* AllocateTexture(const TCacheEntryConfig& config); - static TexPool::iterator FindMatchingTextureFromPool(const TCacheEntryConfig& config); - static TexCache::iterator GetTexCacheIter(TCacheEntryBase* entry); + void SetBackupConfig(const VideoConfig& config); + + TCacheEntryBase* ApplyPaletteToEntry(TCacheEntryBase* entry, u8* palette, u32 tlutfmt); + + void ScaleTextureCacheEntryTo(TCacheEntryBase** entry, u32 new_width, u32 new_height); + TCacheEntryBase* DoPartialTextureUpdates(TexCache::iterator iter, u8* palette, u32 tlutfmt); + + void DumpTexture(TCacheEntryBase* entry, std::string basename, unsigned int level); + void CheckTempSize(size_t required_size); + + TCacheEntryBase* AllocateTexture(const TCacheEntryConfig& config); + TexPool::iterator FindMatchingTextureFromPool(const TCacheEntryConfig& config); + TexCache::iterator GetTexCacheIter(TCacheEntryBase* entry); // Removes and unlinks texture from texture cache and returns it to the pool - static TexCache::iterator InvalidateTexture(TexCache::iterator t_iter); + TexCache::iterator InvalidateTexture(TexCache::iterator t_iter); - static TCacheEntryBase* ReturnEntry(unsigned int stage, TCacheEntryBase* entry); + TCacheEntryBase* ReturnEntry(unsigned int stage, TCacheEntryBase* entry); - static TexCache textures_by_address; - static TexCache textures_by_hash; - static TexPool texture_pool; + TexCache textures_by_address; + TexCache textures_by_hash; + TexPool texture_pool; // Backup configuration values - static struct BackupConfig + struct BackupConfig { - int s_colorsamples; - bool s_texfmt_overlay; - bool s_texfmt_overlay_center; - bool s_hires_textures; - bool s_cache_hires_textures; - bool s_copy_cache_enable; - bool s_stereo_3d; - bool s_efb_mono_depth; - } backup_config; + int color_samples; + bool texfmt_overlay; + bool texfmt_overlay_center; + bool hires_textures; + bool cache_hires_textures; + bool copy_cache_enable; + bool stereo_3d; + bool efb_mono_depth; + }; + BackupConfig backup_config = {}; }; extern std::unique_ptr g_texture_cache; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index ab4dced0e9..4ff4c2c528 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -214,10 +214,10 @@ void VertexManagerBase::Flush() if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) usedtextures[bpmem.tevindref.getTexMap(bpmem.tevind[i].bt)] = true; - TextureCacheBase::UnbindTextures(); + g_texture_cache->UnbindTextures(); for (unsigned int i : usedtextures) { - const TextureCacheBase::TCacheEntryBase* tentry = TextureCacheBase::Load(i); + const auto* tentry = g_texture_cache->Load(i); if (tentry) {