diff options
| author | Pierre Bourdon <delroth@gmail.com> | 2018-03-10 08:22:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-03-10 08:22:28 +0100 |
| commit | a4ef133456a18178f345d3c25195bf74c0e83750 (patch) | |
| tree | 1564aa8e85c3800882466b953984a57be0bf0b0c /Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp | |
| parent | 63838c013bde06ed13bfc1b5e24c53594934f641 (diff) | |
| parent | 93ab50c55584c416d32b5bbdf39f37e9c67f4105 (diff) | |
Merge pull request #6399 from stenzek/videocommon-shader-cache
VideoCommon Shader (Pipeline) Cache
Diffstat (limited to 'Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp b/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp index 525e2b33cb..4ba64eec21 100644 --- a/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp +++ b/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp @@ -13,6 +13,8 @@ namespace DX11 { +std::mutex s_input_layout_lock; + std::unique_ptr<NativeVertexFormat> VertexManager::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) { @@ -116,23 +118,34 @@ D3DVertexFormat::D3DVertexFormat(const PortableVertexDeclaration& _vtx_decl) D3DVertexFormat::~D3DVertexFormat() { - SAFE_RELEASE(m_layout); + ID3D11InputLayout* layout = m_layout.load(); + SAFE_RELEASE(layout); } ID3D11InputLayout* D3DVertexFormat::GetInputLayout(D3DBlob* vs_bytecode) { - if (m_layout) - return m_layout; + // CreateInputLayout requires a shader input, but it only looks at the signature of the shader, + // so we don't need to recompute it if the shader changes. + ID3D11InputLayout* layout = m_layout.load(); + if (layout) + return layout; - // CreateInputLayout requires a shader input, but it only looks at the - // signature of the shader, so we don't need to recompute it if the shader - // changes. HRESULT hr = DX11::D3D::device->CreateInputLayout( - m_elems.data(), m_num_elems, vs_bytecode->Data(), vs_bytecode->Size(), &m_layout); + m_elems.data(), m_num_elems, vs_bytecode->Data(), vs_bytecode->Size(), &layout); if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); DX11::D3D::SetDebugObjectName(m_layout, "input layout used to emulate the GX pipeline"); - return m_layout; + + // This method can be called from multiple threads, so ensure that only one thread sets the + // cached input layout pointer. If another thread beats this thread, use the existing layout. + ID3D11InputLayout* expected = nullptr; + if (!m_layout.compare_exchange_strong(expected, layout)) + { + SAFE_RELEASE(layout); + layout = expected; + } + + return layout; } } // namespace DX11 |
