summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2018-02-25 00:23:24 +1000
committerStenzek <stenzek@gmail.com>2018-03-10 15:56:24 +1000
commit1ddc4c55685d38741f95e286fad5b49537ef5399 (patch)
tree55ae07dd9ad75703096a0e7a589033399858478b /Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp
parent40845e6b8f10d1fb0d4b6d02b1994b1ebe7f8552 (diff)
D3D: Make NativeVertexFormat thread safe
Diffstat (limited to 'Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp')
-rw-r--r--Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp29
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