D3D12: Fix crash/errors when switching MSAA modes while running

This commit is contained in:
Stenzek 2016-02-21 18:55:55 +10:00
parent 1d909ec7a4
commit 9efe66509d
3 changed files with 28 additions and 4 deletions

View File

@ -461,6 +461,18 @@ HRESULT StateCache::GetPipelineStateObjectFromCache(SmallPsoDesc* pso_desc, ID3D
return S_OK; 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() void StateCache::Clear()
{ {
for (auto& it : m_pso_map) for (auto& it : m_pso_map)

View File

@ -95,6 +95,9 @@ public:
HRESULT GetPipelineStateObjectFromCache(D3D12_GRAPHICS_PIPELINE_STATE_DESC* pso_desc, ID3D12PipelineState** pso); 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); 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. // Release all cached states and clear hash tables.
void Clear(); void Clear();
@ -126,7 +129,8 @@ private:
lhs.BlendState.RenderTarget[0].DestBlend, lhs.BlendState.RenderTarget[0].DestBlend,
lhs.BlendState.RenderTarget[0].SrcBlend, lhs.BlendState.RenderTarget[0].SrcBlend,
lhs.BlendState.RenderTarget[0].RenderTargetWriteMask, 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, std::tie(rhs.PS.pShaderBytecode, rhs.VS.pShaderBytecode, rhs.GS.pShaderBytecode,
rhs.RasterizerState.CullMode, rhs.RasterizerState.CullMode,
rhs.DepthStencilState.DepthEnable, rhs.DepthStencilState.DepthEnable,
@ -137,7 +141,8 @@ private:
rhs.BlendState.RenderTarget[0].DestBlend, rhs.BlendState.RenderTarget[0].DestBlend,
rhs.BlendState.RenderTarget[0].SrcBlend, rhs.BlendState.RenderTarget[0].SrcBlend,
rhs.BlendState.RenderTarget[0].RenderTargetWriteMask, rhs.BlendState.RenderTarget[0].RenderTargetWriteMask,
rhs.RTVFormats[0]); rhs.RTVFormats[0],
rhs.SampleDesc.Count);
} }
}; };

View File

@ -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_stereo_mode != (g_ActiveConfig.iStereoMode > 0))
{ {
s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; s_last_xfb_mode = g_ActiveConfig.bUseRealXFB;
s_last_multisamples = g_ActiveConfig.iMultisamples;
// 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(); StaticShaderCache::InvalidateMSAAShaders();
gx_state_cache.OnMSAASettingsChanged();
}
if (window_resized) if (window_resized)
{ {