summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2018-03-10 08:22:28 +0100
committerGitHub <noreply@github.com>2018-03-10 08:22:28 +0100
commita4ef133456a18178f345d3c25195bf74c0e83750 (patch)
tree1564aa8e85c3800882466b953984a57be0bf0b0c /Source/Core/VideoBackends/D3D/NativeVertexFormat.cpp
parent63838c013bde06ed13bfc1b5e24c53594934f641 (diff)
parent93ab50c55584c416d32b5bbdf39f37e9c67f4105 (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.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