From dcd2c4847b95cd5732f17087f515e64a886800a8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 22 Oct 2021 17:22:41 +0200 Subject: [PATCH] [d3d11] Implement ID3D11Fence No interop support just yet. Co-authored-by: Derek Lesho --- src/d3d11/d3d11_context_imm.cpp | 34 ++++++++++++++-- src/d3d11/d3d11_device.cpp | 17 ++++---- src/d3d11/d3d11_device.h | 2 +- src/d3d11/d3d11_fence.cpp | 72 +++++++++++++++++++++++++++++++++ src/d3d11/d3d11_fence.h | 47 +++++++++++++++++++++ src/d3d11/meson.build | 1 + 6 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 src/d3d11/d3d11_fence.cpp create mode 100644 src/d3d11/d3d11_fence.h diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 0c4ea85e..cbbc2d1e 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -1,6 +1,7 @@ #include "d3d11_cmdlist.h" #include "d3d11_context_imm.h" #include "d3d11_device.h" +#include "d3d11_fence.h" #include "d3d11_texture.h" constexpr static uint32_t MinFlushIntervalUs = 750; @@ -190,16 +191,41 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Signal( ID3D11Fence* pFence, UINT64 Value) { - Logger::err("D3D11ImmediateContext::Signal: Not implemented"); - return E_NOTIMPL; + auto fence = static_cast(pFence); + + if (!fence) + return E_INVALIDARG; + + EmitCs([ + cFence = fence->GetFence(), + cValue = Value + ] (DxvkContext* ctx) { + ctx->signalFence(cFence, cValue); + }); + + Flush(); + return S_OK; } HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Wait( ID3D11Fence* pFence, UINT64 Value) { - Logger::err("D3D11ImmediateContext::Wait: Not implemented"); - return E_NOTIMPL; + auto fence = static_cast(pFence); + + if (!fence) + return E_INVALIDARG; + + Flush(); + + EmitCs([ + cFence = fence->GetFence(), + cValue = Value + ] (DxvkContext* ctx) { + ctx->waitFence(cFence, cValue); + }); + + return S_OK; } diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f71aa156..337c3127 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -12,6 +12,7 @@ #include "d3d11_context_def.h" #include "d3d11_context_imm.h" #include "d3d11_device.h" +#include "d3d11_fence.h" #include "d3d11_input_layout.h" #include "d3d11_interop.h" #include "d3d11_query.h" @@ -1347,16 +1348,17 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateFence( UINT64 InitialValue, D3D11_FENCE_FLAG Flags, - REFIID ReturnedInterface, + REFIID riid, void** ppFence) { InitReturnPtr(ppFence); - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11Device::CreateFence: Not implemented"); - - return E_NOTIMPL; + try { + Com fence = new D3D11Fence(this, InitialValue, Flags); + return fence->QueryInterface(riid, ppFence); + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; + } } @@ -1930,6 +1932,7 @@ namespace dxvk { enabled.vk11.shaderDrawParameters = VK_TRUE; enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; + enabled.vk12.timelineSemaphore = VK_TRUE; enabled.vk13.shaderDemoteToHelperInvocation = supported.vk13.shaderDemoteToHelperInvocation; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 7643f8f4..5a99bd62 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -260,7 +260,7 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE CreateFence( UINT64 InitialValue, D3D11_FENCE_FLAG Flags, - REFIID ReturnedInterface, + REFIID riid, void** ppFence); void STDMETHODCALLTYPE ReadFromSubresource( diff --git a/src/d3d11/d3d11_fence.cpp b/src/d3d11/d3d11_fence.cpp new file mode 100644 index 00000000..3c802f89 --- /dev/null +++ b/src/d3d11/d3d11_fence.cpp @@ -0,0 +1,72 @@ +#include "d3d11_fence.h" +#include "d3d11_device.h" + +namespace dxvk { + + D3D11Fence::D3D11Fence( + D3D11Device* pDevice, + UINT64 InitialValue, + D3D11_FENCE_FLAG Flags) + : D3D11DeviceChild(pDevice) { + DxvkFenceCreateInfo fenceInfo; + fenceInfo.initialValue = InitialValue; + + if (Flags) + Logger::err(str::format("Fence flags 0x", std::hex, Flags, " not supported")); + + m_fence = pDevice->GetDXVKDevice()->createFence(fenceInfo); + } + + + D3D11Fence::~D3D11Fence() { + + } + + + HRESULT STDMETHODCALLTYPE D3D11Fence::QueryInterface( + REFIID riid, + void** ppvObject) { + if (ppvObject == nullptr) + return E_POINTER; + + *ppvObject = nullptr; + + if (riid == __uuidof(IUnknown) + || riid == __uuidof(ID3D11DeviceChild) + || riid == __uuidof(ID3D11Fence)) { + *ppvObject = ref(this); + return S_OK; + } + + Logger::warn("D3D11Fence: Unknown interface query"); + Logger::warn(str::format(riid)); + return E_NOINTERFACE; + } + + + HRESULT STDMETHODCALLTYPE D3D11Fence::CreateSharedHandle( + const SECURITY_ATTRIBUTES* pAttributes, + DWORD dwAccess, + LPCWSTR lpName, + HANDLE* pHandle) { + Logger::err("D3D11Fence::CreateSharedHandle: Not implemented"); + return E_NOTIMPL; + } + + + HRESULT STDMETHODCALLTYPE D3D11Fence::SetEventOnCompletion( + UINT64 Value, + HANDLE hEvent) { + m_fence->enqueueWait(Value, [hEvent] { + SetEvent(hEvent); + }); + + return S_OK; + } + + + UINT64 STDMETHODCALLTYPE D3D11Fence::GetCompletedValue() { + return m_fence->getValue(); + } + +} diff --git a/src/d3d11/d3d11_fence.h b/src/d3d11/d3d11_fence.h new file mode 100644 index 00000000..b29c0c99 --- /dev/null +++ b/src/d3d11/d3d11_fence.h @@ -0,0 +1,47 @@ +#pragma once + +#include "../dxvk/dxvk_fence.h" +#include "../dxvk/dxvk_gpu_query.h" + +#include "d3d11_device_child.h" + +namespace dxvk { + + class D3D11Fence : public D3D11DeviceChild { + + public: + + D3D11Fence( + D3D11Device* pDevice, + UINT64 InitialValue, + D3D11_FENCE_FLAG Flags); + + ~D3D11Fence(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE CreateSharedHandle( + const SECURITY_ATTRIBUTES* pAttributes, + DWORD dwAccess, + LPCWSTR lpName, + HANDLE* pHandle); + + HRESULT STDMETHODCALLTYPE SetEventOnCompletion( + UINT64 Value, + HANDLE hEvent); + + UINT64 STDMETHODCALLTYPE GetCompletedValue(); + + Rc GetFence() const { + return m_fence; + } + + private: + + Rc m_fence; + + }; + +} diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index ad35acd8..85fe7807 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -37,6 +37,7 @@ d3d11_src = [ 'd3d11_depth_stencil.cpp', 'd3d11_device.cpp', 'd3d11_enums.cpp', + 'd3d11_fence.cpp', 'd3d11_gdi.cpp', 'd3d11_initializer.cpp', 'd3d11_input_layout.cpp',