From 228ddb8abab02105e02233647834bde2528d9ba9 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 24 Jun 2017 19:29:03 +1000 Subject: [PATCH] D3D11: Reload shader cache when relevant config changes --- .../VideoBackends/D3D/GeometryShaderCache.cpp | 32 +++++++++++++------ .../VideoBackends/D3D/GeometryShaderCache.h | 3 ++ .../VideoBackends/D3D/PixelShaderCache.cpp | 32 +++++++++++++------ .../Core/VideoBackends/D3D/PixelShaderCache.h | 3 ++ Source/Core/VideoBackends/D3D/Render.cpp | 11 +++++++ Source/Core/VideoBackends/D3D/Render.h | 2 ++ .../VideoBackends/D3D/VertexShaderCache.cpp | 32 +++++++++++++------ .../VideoBackends/D3D/VertexShaderCache.h | 3 ++ 8 files changed, 88 insertions(+), 30 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp index 6dbd3d3dde..951b4287da 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp @@ -158,18 +158,29 @@ void GeometryShaderCache::Init() Clear(); if (g_ActiveConfig.bShaderCache) - { - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); + LoadShaderCache(); +} - std::string cache_filename = - StringFromFormat("%sdx11-%s-gs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().GetGameID().c_str()); - GeometryShaderCacheInserter inserter; - g_gs_disk_cache.OpenAndRead(cache_filename, inserter); - } +void GeometryShaderCache::LoadShaderCache() +{ + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); - last_entry = nullptr; + std::string cache_filename = StringFromFormat( + "%sdx11-%s-%s-gs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().GetGameID().c_str(), g_ActiveConfig.GetHostConfigFilename().c_str()); + GeometryShaderCacheInserter inserter; + g_gs_disk_cache.OpenAndRead(cache_filename, inserter); +} + +void GeometryShaderCache::Reload() +{ + g_gs_disk_cache.Sync(); + g_gs_disk_cache.Close(); + Clear(); + + if (g_ActiveConfig.bShaderCache) + LoadShaderCache(); } // ONLY to be used during shutdown. @@ -180,6 +191,7 @@ void GeometryShaderCache::Clear() GeometryShaders.clear(); last_entry = nullptr; + last_uid = {}; } void GeometryShaderCache::Shutdown() diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.h b/Source/Core/VideoBackends/D3D/GeometryShaderCache.h index 72024e52f5..e6eca3b2e0 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.h +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.h @@ -15,6 +15,7 @@ class GeometryShaderCache { public: static void Init(); + static void Reload(); static void Clear(); static void Shutdown(); static bool SetShader(u32 primitive_type); // TODO: Should be renamed to LoadShader @@ -38,6 +39,8 @@ private: typedef std::map GSCache; + static void LoadShaderCache(); + static GSCache GeometryShaders; static const GSCacheEntry* last_entry; static GeometryShaderUid last_uid; diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp index 289e9a32f9..d3bdce59f1 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp @@ -498,18 +498,29 @@ void PixelShaderCache::Init() SETSTAT(stats.numPixelShadersAlive, 0); if (g_ActiveConfig.bShaderCache) - { - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); + LoadShaderCache(); +} - std::string cache_filename = - StringFromFormat("%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().GetGameID().c_str()); - PixelShaderCacheInserter inserter; - g_ps_disk_cache.OpenAndRead(cache_filename, inserter); - } +void PixelShaderCache::LoadShaderCache() +{ + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); - last_entry = nullptr; + std::string cache_filename = StringFromFormat( + "%sdx11-%s-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().GetGameID().c_str(), g_ActiveConfig.GetHostConfigFilename().c_str()); + PixelShaderCacheInserter inserter; + g_ps_disk_cache.OpenAndRead(cache_filename, inserter); +} + +void PixelShaderCache::Reload() +{ + g_ps_disk_cache.Sync(); + g_ps_disk_cache.Close(); + Clear(); + + if (g_ActiveConfig.bShaderCache) + LoadShaderCache(); } // ONLY to be used during shutdown. @@ -520,6 +531,7 @@ void PixelShaderCache::Clear() PixelShaders.clear(); last_entry = nullptr; + last_uid = {}; } // Used in Swap() when AA mode has changed diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.h b/Source/Core/VideoBackends/D3D/PixelShaderCache.h index d3d4106a53..fb1b79ad6c 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.h +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.h @@ -15,6 +15,7 @@ class PixelShaderCache { public: static void Init(); + static void Reload(); static void Clear(); static void Shutdown(); static bool SetShader(); // TODO: Should be renamed to LoadShader @@ -46,6 +47,8 @@ private: typedef std::map PSCache; + static void LoadShaderCache(); + static PSCache PixelShaders; static const PSCacheEntry* last_entry; static PixelShaderUid last_uid; diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index df4aad0e28..31bd6a82bb 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -242,6 +242,7 @@ Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferH s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0; s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; s_last_fullscreen_mode = D3D::GetFullscreenState(); + m_last_host_config_bits = g_ActiveConfig.GetHostConfigBits(); g_framebuffer_manager = std::make_unique(m_target_width, m_target_height); SetupDeviceObjects(); @@ -894,6 +895,16 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, D3D11_CLEAR_DEPTH, 0.f, 0); } + u32 new_host_config_bits = g_ActiveConfig.GetHostConfigBits(); + if (new_host_config_bits != m_last_host_config_bits) + { + OSD::AddMessage("Video config changed, reloading shaders.", OSD::Duration::NORMAL); + VertexShaderCache::Reload(); + GeometryShaderCache::Reload(); + PixelShaderCache::Reload(); + m_last_host_config_bits = new_host_config_bits; + } + // begin next frame RestoreAPIState(); D3D::BeginFrame(); diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index e5b429f2ab..a72c9308a2 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -64,5 +64,7 @@ public: private: void BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture, u32 src_width, u32 src_height, float Gamma); + + u32 m_last_host_config_bits = 0; }; } diff --git a/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp b/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp index 1ca0982e6f..77aa06b2f4 100644 --- a/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp @@ -159,18 +159,29 @@ void VertexShaderCache::Init() SETSTAT(stats.numVertexShadersAlive, 0); if (g_ActiveConfig.bShaderCache) - { - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); + LoadShaderCache(); +} - std::string cache_filename = - StringFromFormat("%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().GetGameID().c_str()); - VertexShaderCacheInserter inserter; - g_vs_disk_cache.OpenAndRead(cache_filename, inserter); - } +void VertexShaderCache::LoadShaderCache() +{ + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); - last_entry = nullptr; + std::string cache_filename = StringFromFormat( + "%sdx11-%s-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().GetGameID().c_str(), g_ActiveConfig.GetHostConfigFilename().c_str()); + VertexShaderCacheInserter inserter; + g_vs_disk_cache.OpenAndRead(cache_filename, inserter); +} + +void VertexShaderCache::Reload() +{ + g_vs_disk_cache.Sync(); + g_vs_disk_cache.Close(); + Clear(); + + if (g_ActiveConfig.bShaderCache) + LoadShaderCache(); } void VertexShaderCache::Clear() @@ -180,6 +191,7 @@ void VertexShaderCache::Clear() vshaders.clear(); last_entry = nullptr; + last_uid = {}; } void VertexShaderCache::Shutdown() diff --git a/Source/Core/VideoBackends/D3D/VertexShaderCache.h b/Source/Core/VideoBackends/D3D/VertexShaderCache.h index ba006bb954..514e807192 100644 --- a/Source/Core/VideoBackends/D3D/VertexShaderCache.h +++ b/Source/Core/VideoBackends/D3D/VertexShaderCache.h @@ -17,6 +17,7 @@ class VertexShaderCache { public: static void Init(); + static void Reload(); static void Clear(); static void Shutdown(); static bool SetShader(); // TODO: Should be renamed to LoadShader @@ -53,6 +54,8 @@ private: }; typedef std::map VSCache; + static void LoadShaderCache(); + static VSCache vshaders; static const VSCacheEntry* last_entry; static VertexShaderUid last_uid;