diff --git a/src/d3d10/d3d10_device.cpp b/src/d3d10/d3d10_device.cpp index dfd0bdd0..e35e131a 100644 --- a/src/d3d10/d3d10_device.cpp +++ b/src/d3d10/d3d10_device.cpp @@ -8,7 +8,7 @@ namespace dxvk { D3D10Device::D3D10Device( D3D11Device* pDevice, D3D11ImmediateContext* pContext) - : m_device(pDevice), m_context(pContext) { + : m_device(pDevice), m_context(pContext), m_multithread(this) { // Respecting the single-threaded flag may improve performance UINT flags = pDevice->GetCreationFlags(); m_threadSafe = !(flags & D3D10_CREATE_DEVICE_SINGLETHREADED); diff --git a/src/d3d10/d3d10_device.h b/src/d3d10/d3d10_device.h index df9d50fd..bdc8e7fa 100644 --- a/src/d3d10/d3d10_device.h +++ b/src/d3d10/d3d10_device.h @@ -1,12 +1,9 @@ #pragma once -#include "d3d10_include.h" +#include "d3d10_multithread.h" namespace dxvk { - using D3D10DeviceMutex = sync::Spinlock; - using D3D10DeviceLock = std::unique_lock; - class D3D11Device; class D3D11ImmediateContext; @@ -473,6 +470,10 @@ namespace dxvk { UINT* pWidth, UINT* pHeight); + D3D10Multithread* GetMultithreadIface() { + return &m_multithread; + } + D3D10DeviceLock LockDevice() { return m_threadSafe ? D3D10DeviceLock(m_mutex) @@ -484,6 +485,7 @@ namespace dxvk { D3D10DeviceMutex m_mutex; D3D11Device* m_device; D3D11ImmediateContext* m_context; + D3D10Multithread m_multithread; bool m_threadSafe = true; diff --git a/src/d3d10/d3d10_multithread.cpp b/src/d3d10/d3d10_multithread.cpp new file mode 100644 index 00000000..9f3949fd --- /dev/null +++ b/src/d3d10/d3d10_multithread.cpp @@ -0,0 +1,42 @@ +#include "d3d10_multithread.h" +#include "d3d10_device.h" + +namespace dxvk { + + HRESULT STDMETHODCALLTYPE D3D10Multithread::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_device->QueryInterface(riid, ppvObject); + } + + + ULONG STDMETHODCALLTYPE D3D10Multithread::AddRef() { + return m_device->AddRef(); + } + + + ULONG STDMETHODCALLTYPE D3D10Multithread::Release() { + return m_device->Release(); + } + + + void STDMETHODCALLTYPE D3D10Multithread::Enter() { + m_lock = m_device->LockDevice(); + } + + + void STDMETHODCALLTYPE D3D10Multithread::Leave() { + m_lock.unlock(); + } + + + BOOL STDMETHODCALLTYPE D3D10Multithread::GetMultithreadProtected() { + return m_enabled; + } + + + BOOL STDMETHODCALLTYPE D3D10Multithread::SetMultithreadProtected(BOOL Enable) { + return std::exchange(m_enabled, Enable); + } + +} \ No newline at end of file diff --git a/src/d3d10/d3d10_multithread.h b/src/d3d10/d3d10_multithread.h new file mode 100644 index 00000000..81d5dbce --- /dev/null +++ b/src/d3d10/d3d10_multithread.h @@ -0,0 +1,43 @@ +#pragma once + +#include "d3d10_include.h" + +namespace dxvk { + + using D3D10DeviceMutex = sync::Spinlock; + using D3D10DeviceLock = std::unique_lock; + + class D3D10Device; + + class D3D10Multithread : public ID3D10Multithread { + + public: + + D3D10Multithread(D3D10Device* pDevice) + : m_device(pDevice) { } + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + void STDMETHODCALLTYPE Enter(); + + void STDMETHODCALLTYPE Leave(); + + BOOL STDMETHODCALLTYPE GetMultithreadProtected(); + + BOOL STDMETHODCALLTYPE SetMultithreadProtected(BOOL Enable); + + private: + + D3D10Device* m_device; + D3D10DeviceLock m_lock; + bool m_enabled = true; + + }; + +} \ No newline at end of file diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index b5e13a5d..175b4de8 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -61,6 +61,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D10Multithread)) { + *ppvObject = ref(m_d3d11Device->GetD3D10Interface()->GetMultithreadIface()); + return S_OK; + } + if (riid == __uuidof(ID3D11Device) || riid == __uuidof(ID3D11Device1)) { *ppvObject = ref(m_d3d11Device); diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index a8596b76..c0889b20 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -4,6 +4,7 @@ d3d10_src = [ '../d3d10/d3d10_depth_stencil.cpp', '../d3d10/d3d10_device.cpp', '../d3d10/d3d10_input_layout.cpp', + '../d3d10/d3d10_multithread.cpp', '../d3d10/d3d10_query.cpp', '../d3d10/d3d10_rasterizer.cpp', '../d3d10/d3d10_sampler.cpp',