diff options
author | Joshua Ashton <joshua@froggi.es> | 2023-08-23 16:50:42 +0300 |
---|---|---|
committer | Joshua Ashton <joshua@froggi.es> | 2023-08-23 17:07:39 +0300 |
commit | 53e4ab75dec5c8c7263a25d3746b6040c04389c9 (patch) | |
tree | 0d560d2b7ce479454ade29e12e495733eee357e8 | |
parent | 2f9116aade7ad9bb98511ff8f455db8268907c3f (diff) |
[d3d11] Implement synchronization on keyed mutexeskeyed-mutex
Co-authored-by: Paul Gofman <pgofman@codeweavers.com>
-rw-r--r-- | src/d3d11/d3d11_context_imm.h | 1 | ||||
-rw-r--r-- | src/d3d11/d3d11_initializer.cpp | 12 | ||||
-rw-r--r-- | src/d3d11/d3d11_initializer.h | 2 | ||||
-rw-r--r-- | src/d3d11/d3d11_resource.cpp | 36 | ||||
-rw-r--r-- | src/d3d11/d3d11_resource.h | 2 |
5 files changed, 48 insertions, 5 deletions
diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index b1fa34eb..eb3ed88f 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -17,6 +17,7 @@ namespace dxvk { friend class D3D11CommonContext<D3D11ImmediateContext>; friend class D3D11SwapChain; friend class D3D11VideoContext; + friend class D3D11DXGIKeyedMutex; public: D3D11ImmediateContext( diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index d965921c..105485fa 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -49,6 +49,8 @@ namespace dxvk { InitHostVisibleTexture(pTexture, pInitialData); else InitDeviceLocalTexture(pTexture, pInitialData); + + SyncKeyedMutex(pTexture->GetInterface()); } @@ -284,4 +286,14 @@ namespace dxvk { m_transferMemory = 0; } + + void D3D11Initializer::SyncKeyedMutex(ID3D11Resource *pResource) { + Com<IDXGIKeyedMutex> keyedMutex; + if (pResource->QueryInterface(__uuidof(IDXGIKeyedMutex), reinterpret_cast<void**>(&keyedMutex)) != S_OK) + return; + + keyedMutex->AcquireSync(0, 0); + keyedMutex->ReleaseSync(0); + } + }
\ No newline at end of file diff --git a/src/d3d11/d3d11_initializer.h b/src/d3d11/d3d11_initializer.h index 8cfe84c6..1cd94d80 100644 --- a/src/d3d11/d3d11_initializer.h +++ b/src/d3d11/d3d11_initializer.h @@ -71,6 +71,8 @@ namespace dxvk { void FlushImplicit(); void FlushInternal(); + void SyncKeyedMutex(ID3D11Resource *pResource); + }; }
\ No newline at end of file diff --git a/src/d3d11/d3d11_resource.cpp b/src/d3d11/d3d11_resource.cpp index ba252692..92b2d658 100644 --- a/src/d3d11/d3d11_resource.cpp +++ b/src/d3d11/d3d11_resource.cpp @@ -1,6 +1,8 @@ #include "d3d11_buffer.h" #include "d3d11_texture.h" #include "d3d11_resource.h" +#include "d3d11_context_imm.h" +#include "d3d11_device.h" #include "../util/util_shared_res.h" @@ -9,7 +11,13 @@ namespace dxvk { D3D11DXGIKeyedMutex::D3D11DXGIKeyedMutex( ID3D11Resource* pResource) : m_resource(pResource) { + Com<ID3D11Device> device; + m_resource->GetDevice(&device); + m_device = static_cast<D3D11Device*>(device.ptr()); + m_supported = m_device->GetDXVKDevice()->features().khrWin32KeyedMutex + && m_device->GetDXVKDevice()->vkd()->wine_vkAcquireKeyedMutex != nullptr + && m_device->GetDXVKDevice()->vkd()->wine_vkReleaseKeyedMutex != nullptr; } @@ -77,20 +85,38 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::AcquireSync( UINT64 Key, DWORD dwMilliseconds) { + if (!m_supported) { if (!m_warned) { m_warned = true; - Logger::err("D3D11DXGIKeyedMutex::AcquireSync: Stub"); + Logger::err("D3D11DXGIKeyedMutex::AcquireSync: Not supported"); } return S_OK; + } + + D3D11CommonTexture* texture = GetCommonTexture(m_resource); + Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice(); + + VkResult vr = dxvkDevice->vkd()->wine_vkAcquireKeyedMutex(dxvkDevice->handle(), texture->GetImage()->memory().memory(), Key, dwMilliseconds); + switch (vr) { + case VK_SUCCESS: return S_OK; + case VK_TIMEOUT: return WAIT_TIMEOUT; + default: return DXGI_ERROR_INVALID_CALL; + } } HRESULT STDMETHODCALLTYPE D3D11DXGIKeyedMutex::ReleaseSync( UINT64 Key) { - if (!m_warned) { - m_warned = true; - Logger::err("D3D11DXGIKeyedMutex::AcquireSync: Stub"); - } + if (!m_supported) return S_OK; + + D3D11CommonTexture* texture = GetCommonTexture(m_resource); + Rc<DxvkDevice> dxvkDevice = m_device->GetDXVKDevice(); + + m_device->GetContext()->WaitForResource(texture->GetImage(), DxvkCsThread::SynchronizeAll, D3D11_MAP_READ_WRITE, 0); + + return dxvkDevice->vkd()->wine_vkReleaseKeyedMutex(dxvkDevice->handle(), texture->GetImage()->memory().memory(), Key) == VK_SUCCESS + ? S_OK + : DXGI_ERROR_INVALID_CALL; } D3D11DXGIResource::D3D11DXGIResource( diff --git a/src/d3d11/d3d11_resource.h b/src/d3d11/d3d11_resource.h index 0c459ca3..8dc73220 100644 --- a/src/d3d11/d3d11_resource.h +++ b/src/d3d11/d3d11_resource.h @@ -74,7 +74,9 @@ namespace dxvk { private: ID3D11Resource* m_resource; + D3D11Device* m_device; bool m_warned = false; + bool m_supported = false; }; |