diff --git a/Source/Core/VideoBackends/D3D12/D3DState.cpp b/Source/Core/VideoBackends/D3D12/D3DState.cpp index d0df14371f..5810a74536 100644 --- a/Source/Core/VideoBackends/D3D12/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D12/D3DState.cpp @@ -461,6 +461,18 @@ HRESULT StateCache::GetPipelineStateObjectFromCache(SmallPsoDesc* pso_desc, ID3D return S_OK; } +void StateCache::OnMSAASettingsChanged() +{ + for (auto& it : m_small_pso_map) + { + SAFE_RELEASE(it.second); + } + m_small_pso_map.clear(); + + // Update sample count for new PSOs being created + gx_state_cache.m_current_pso_desc.SampleDesc.Count = g_ActiveConfig.iMultisamples; +} + void StateCache::Clear() { for (auto& it : m_pso_map) diff --git a/Source/Core/VideoBackends/D3D12/D3DState.h b/Source/Core/VideoBackends/D3D12/D3DState.h index 85e83592d0..49d4fab157 100644 --- a/Source/Core/VideoBackends/D3D12/D3DState.h +++ b/Source/Core/VideoBackends/D3D12/D3DState.h @@ -95,6 +95,9 @@ public: HRESULT GetPipelineStateObjectFromCache(D3D12_GRAPHICS_PIPELINE_STATE_DESC* pso_desc, ID3D12PipelineState** pso); HRESULT GetPipelineStateObjectFromCache(SmallPsoDesc* pso_desc, ID3D12PipelineState** pso, D3D12_PRIMITIVE_TOPOLOGY_TYPE topology, const GeometryShaderUid* gs_uid, const PixelShaderUid* ps_uid, const VertexShaderUid* vs_uid); + // Called when the MSAA count/quality changes. Invalidates all small PSOs. + void OnMSAASettingsChanged(); + // Release all cached states and clear hash tables. void Clear(); @@ -126,7 +129,8 @@ private: lhs.BlendState.RenderTarget[0].DestBlend, lhs.BlendState.RenderTarget[0].SrcBlend, lhs.BlendState.RenderTarget[0].RenderTargetWriteMask, - lhs.RTVFormats[0]) == + lhs.RTVFormats[0], + lhs.SampleDesc.Count) == std::tie(rhs.PS.pShaderBytecode, rhs.VS.pShaderBytecode, rhs.GS.pShaderBytecode, rhs.RasterizerState.CullMode, rhs.DepthStencilState.DepthEnable, @@ -137,7 +141,8 @@ private: rhs.BlendState.RenderTarget[0].DestBlend, rhs.BlendState.RenderTarget[0].SrcBlend, rhs.BlendState.RenderTarget[0].RenderTargetWriteMask, - rhs.RTVFormats[0]); + rhs.RTVFormats[0], + rhs.SampleDesc.Count); } }; diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 4f763a68cb..bf80081ff5 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -984,9 +984,16 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0)) { s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; - s_last_multisamples = g_ActiveConfig.iMultisamples; - StaticShaderCache::InvalidateMSAAShaders(); + // Block on any changes until the GPU catches up, so we can free resources safely. + D3D::command_list_mgr->ExecuteQueuedWork(true); + + if (s_last_multisamples != g_ActiveConfig.iMultisamples) + { + s_last_multisamples = g_ActiveConfig.iMultisamples; + StaticShaderCache::InvalidateMSAAShaders(); + gx_state_cache.OnMSAASettingsChanged(); + } if (window_resized) {