diff --git a/Source/Core/DolphinWX/Src/Debugger/DebuggerPanel.cpp b/Source/Core/DolphinWX/Src/Debugger/DebuggerPanel.cpp index af3d8256d3..7f978895b7 100644 --- a/Source/Core/DolphinWX/Src/Debugger/DebuggerPanel.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/DebuggerPanel.cpp @@ -334,7 +334,7 @@ void GFXDebuggerPanel::OnClearScreenButton(wxCommandEvent& event) void GFXDebuggerPanel::OnClearTextureCacheButton(wxCommandEvent& event) { - TextureCache::Invalidate(false); + TextureCache::Invalidate(); } void GFXDebuggerPanel::OnClearVertexShaderCacheButton(wxCommandEvent& event) diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index c42764c0bb..f5a488a7e8 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -66,8 +66,6 @@ void VideoConfigDiag::Event_Close(wxCloseEvent& ev) g_Config.Save((File::GetUserPath(D_CONFIG_IDX) + ininame + ".ini").c_str()); EndModal(wxID_OK); - - TextureCache::InvalidateDefer(); // For settings like hi-res textures/texture format/etc. } wxString backend_desc = wxTRANSLATE("Selects what graphics API to use internally.\nDirect3D 9 usually is the fastest one. OpenGL is more accurate though. Direct3D 11 is somewhere between the two.\nNote that the Direct3D backends are only available on Windows.\n\nIf unsure, use Direct3D 9."); diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index df29fef606..cb6dc7ae5b 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -203,7 +203,7 @@ void VideoBackendHardware::DoState(PointerWrap& p) // Clear all caches that touch RAM // (? these don't appear to touch any emulation state that gets saved. moved to on load only.) - TextureCache::Invalidate(false); + TextureCache::Invalidate(); VertexLoaderManager::MarkAllDirty(); } } diff --git a/Source/Core/VideoCommon/Src/RenderBase.cpp b/Source/Core/VideoCommon/Src/RenderBase.cpp index b98edf1a7d..6f1f9c411a 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.cpp +++ b/Source/Core/VideoCommon/Src/RenderBase.cpp @@ -82,9 +82,11 @@ bool Renderer::s_EnableDLCachingAfterRecording; unsigned int Renderer::prev_efb_format = (unsigned int)-1; + Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false) { UpdateActiveConfig(); + TextureCache::OnConfigChanged(g_ActiveConfig); #if defined _WIN32 || defined HAVE_LIBAV bAVIDumping = false; @@ -130,11 +132,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc,Gamma); Common::AtomicStoreRelease(s_swapRequested, false); } - - if (TextureCache::DeferredInvalidate) - { - TextureCache::Invalidate(false); - } } void Renderer::CalculateTargetScale(int x, int y, int &scaledX, int &scaledY) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index bb240d5df3..e9c2dbe9f3 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -42,7 +42,9 @@ GC_ALIGNED16(u8 *TextureCache::temp) = NULL; unsigned int TextureCache::temp_size; TextureCache::TexCache TextureCache::textures; -bool TextureCache::DeferredInvalidate; + +TextureCache::BackupConfig TextureCache::backup_config; + TextureCache::TCacheEntryBase::~TCacheEntryBase() { @@ -59,34 +61,19 @@ TextureCache::TextureCache() SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures); } -void TextureCache::Invalidate(bool shutdown) +void TextureCache::Invalidate() { TexCache::iterator iter = textures.begin(), tcend = textures.end(); for (; iter != tcend; ++iter) - { - if (shutdown) - iter->second->addr = 0; delete iter->second; - } textures.clear(); - if(g_ActiveConfig.bHiresTextures && !g_ActiveConfig.bDumpTextures) - HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures); - - DeferredInvalidate = false; -} - -void TextureCache::InvalidateDefer() -{ - DeferredInvalidate = true; } TextureCache::~TextureCache() { - Invalidate(true); if (temp) { FreeAlignedMemory(temp); @@ -94,6 +81,48 @@ TextureCache::~TextureCache() } } +void TextureCache::OnConfigChanged(VideoConfig& config) +{ + if (!g_texture_cache) + goto skip_checks; + + // 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(); + + if(g_ActiveConfig.bHiresTextures) + HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + + SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures); + TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter); + } + + // TODO: Probably shouldn't clear all render targets here, just mark them dirty or something. + if (config.bEFBCopyCacheEnable != backup_config.s_copy_cache_enable || // TODO: not sure if this is needed? + config.bCopyEFBToTexture != backup_config.s_copy_efb_to_texture || + config.bCopyEFBScaled != backup_config.s_copy_efb_scaled || + config.bEFBCopyEnable != backup_config.s_copy_efb || + config.iEFBScale != backup_config.s_efb_scale) + { + g_texture_cache->ClearRenderTargets(); + } + +skip_checks: + backup_config.s_colorsamples = config.iSafeTextureCache_ColorSamples; + backup_config.s_copy_efb_to_texture = config.bCopyEFBToTexture; + backup_config.s_copy_efb_scaled = config.bCopyEFBScaled; + backup_config.s_copy_efb = config.bEFBCopyEnable; + backup_config.s_efb_scale = config.iEFBScale; + 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_copy_cache_enable = config.bEFBCopyCacheEnable; +} + void TextureCache::Cleanup() { TexCache::iterator iter = textures.begin(); @@ -326,8 +355,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, // 2. a) For EFB copies, only the hash and the texture address need to match if (entry->IsEfbCopy() && tex_hash == entry->hash && address == entry->addr) { - if (entry->type != TCET_EC_VRAM) - entry->type = TCET_NORMAL; + entry->type = TCET_EC_VRAM; // TODO: Print a warning if the format changes! In this case, we could reinterpret the internal texture object data to the new pixel format (similiar to what is already being done in Renderer::ReinterpretPixelFormat()) goto return_entry; @@ -734,16 +762,12 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat TCacheEntryBase *entry = textures[dstAddr]; if (entry) { - if ((entry->type == TCET_EC_VRAM && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h) - || (entry->type == TCET_EC_DYNAMIC && entry->native_width == tex_w && entry->native_height == tex_h)) + if (entry->type == TCET_EC_DYNAMIC && entry->native_width == tex_w && entry->native_height == tex_h) { - if (entry->type == TCET_EC_DYNAMIC) - { - scaled_tex_w = tex_w; - scaled_tex_h = tex_h; - } + scaled_tex_w = tex_w; + scaled_tex_h = tex_h; } - else + else if (!(entry->type == TCET_EC_VRAM && entry->virtual_width == scaled_tex_w && entry->virtual_height == scaled_tex_h)) { // remove it and recreate it as a render target delete entry; diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index f67ad518c5..4ef3b8a985 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -27,6 +27,8 @@ #include "CommonTypes.h" +struct VideoConfig; + class TextureCache { public: @@ -100,10 +102,10 @@ public: virtual ~TextureCache(); // needs virtual for DX11 dtor + static void OnConfigChanged(VideoConfig& config); static void Cleanup(); - static void Invalidate(bool shutdown); - static void InvalidateDefer(); + static void Invalidate(); static void InvalidateRange(u32 start_address, u32 size); static void MakeRangeDynamic(u32 start_address, u32 size); static void ClearRenderTargets(); // currently only used by OGL @@ -118,8 +120,6 @@ public: static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); - static bool DeferredInvalidate; - protected: TextureCache(); @@ -135,6 +135,19 @@ private: typedef std::map TexCache; static TexCache textures; + + // Backup configuration values + static struct BackupConfig { + int s_colorsamples; + bool s_copy_efb_to_texture; + bool s_copy_efb_scaled; + bool s_copy_efb; + int s_efb_scale; + bool s_texfmt_overlay; + bool s_texfmt_overlay_center; + bool s_hires_textures; + bool s_copy_cache_enable; + } backup_config; }; extern TextureCache *g_texture_cache; diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index d40fbcb99a..7653972ec8 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -135,8 +135,8 @@ struct VideoConfig bool bEnablePerPixelDepth; int iLog; // CONF_ bits - int iSaveTargetId; - + int iSaveTargetId; // TODO: Should be dropped + //currently unused: int iCompileDLsLevel; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 1c204ddfe1..0dbb4ee25f 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -1111,6 +1111,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Enable configuration changes UpdateActiveConfig(); + TextureCache::OnConfigChanged(g_ActiveConfig); SetWindowSize(fbWidth, fbHeight); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index 0e43eb013d..5f82a18fc0 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -159,13 +159,15 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo u8* dst = Memory::GetPointer(dstAddr); size_t encoded_size = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf); - hash = GetHash64(dst, (int)encoded_size, g_ActiveConfig.iSafeTextureCache_ColorSamples); + u64 hash = GetHash64(dst, (int)encoded_size, g_ActiveConfig.iSafeTextureCache_ColorSamples); // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date if (!g_ActiveConfig.bEFBCopyCacheEnable) TextureCache::MakeRangeDynamic(addr, (u32)encoded_size); else if (!TextureCache::Find(addr, hash)) TextureCache::MakeRangeDynamic(addr, (u32)encoded_size); + + this->hash = hash; } } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index ba3a67108b..cb348b8684 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -230,6 +230,7 @@ void VideoBackend::Shutdown() delete g_texture_cache; delete g_renderer; g_renderer = NULL; + g_texture_cache = NULL; } } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 834867c477..a7820cce3d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -237,7 +237,7 @@ void TeardownDeviceObjects() D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); delete g_framebuffer_manager; D3D::font.Shutdown(); - TextureCache::Invalidate(false); + TextureCache::Invalidate(); VertexLoaderManager::Shutdown(); VertexShaderCache::Shutdown(); PixelShaderCache::Shutdown(); @@ -1117,6 +1117,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Enable configuration changes UpdateActiveConfig(); + TextureCache::OnConfigChanged(g_ActiveConfig); SetWindowSize(fbWidth, fbHeight); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 0d31098c17..2be29048d3 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -164,13 +164,15 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo srcRect); u8* dst = Memory::GetPointer(addr); - hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples); + u64 hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples); // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date if (!g_ActiveConfig.bEFBCopyCacheEnable) TextureCache::MakeRangeDynamic(addr,encoded_size); else if (!TextureCache::Find(addr, hash)) TextureCache::MakeRangeDynamic(addr,encoded_size); + + this->hash = hash; } D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 6c52219f97..5aeca6751d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -212,6 +212,7 @@ void VideoBackend::Shutdown() delete g_texture_cache; delete g_renderer; g_renderer = NULL; + g_texture_cache = NULL; } D3D::Shutdown(); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 49fac8b260..eb7b0168a4 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1437,11 +1437,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons GL_REPORT_ERRORD(); g_Config.iSaveTargetId = 0; - // reload textures if these settings changed - if (g_Config.bCopyEFBToTexture != g_ActiveConfig.bCopyEFBToTexture) - TextureCache::ClearRenderTargets(); - UpdateActiveConfig(); + TextureCache::OnConfigChanged(g_ActiveConfig); // For testing zbuffer targets. // Renderer::SetZBufferRender(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index bc1b1f6fc5..7a62131f90 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -330,13 +330,15 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo srcRect); u8* dst = Memory::GetPointer(addr); - hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples); + u64 hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples); // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date if (!g_ActiveConfig.bEFBCopyCacheEnable) TextureCache::MakeRangeDynamic(addr,encoded_size); else if (!TextureCache::Find(addr, hash)) TextureCache::MakeRangeDynamic(addr,encoded_size); + + this->hash = hash; } FramebufferManager::SetFramebuffer(0); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 251512fe6b..543fb9824d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -235,6 +235,7 @@ void VideoBackend::Shutdown() OpcodeDecoder_Shutdown(); delete g_renderer; g_renderer = NULL; + g_texture_cache = NULL; } OpenGL_Shutdown(); }