diff options
| author | Stenzek <stenzek@gmail.com> | 2018-02-25 00:23:24 +1000 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2018-03-10 15:56:24 +1000 |
| commit | 1ddc4c55685d38741f95e286fad5b49537ef5399 (patch) | |
| tree | 55ae07dd9ad75703096a0e7a589033399858478b /Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp | |
| parent | 40845e6b8f10d1fb0d4b6d02b1994b1ebe7f8552 (diff) | |
D3D: Make NativeVertexFormat thread safe
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 |
