[d3d11] Implement ID3D11Fence

No interop support just yet.

Co-authored-by: Derek Lesho <dlesho@codeweavers.com>
This commit is contained in:
Philip Rebohle 2021-10-22 17:22:41 +02:00 committed by Philip Rebohle
parent 3bbcacf687
commit 513a2610e1
6 changed files with 162 additions and 12 deletions

View File

@ -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;
@ -185,16 +186,41 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Signal(
ID3D11Fence* pFence,
UINT64 Value) {
Logger::err("D3D11ImmediateContext::Signal: Not implemented");
return E_NOTIMPL;
auto fence = static_cast<D3D11Fence*>(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<D3D11Fence*>(pFence);
if (!fence)
return E_INVALIDARG;
Flush();
EmitCs([
cFence = fence->GetFence(),
cValue = Value
] (DxvkContext* ctx) {
ctx->waitFence(cFence, cValue);
});
return S_OK;
}

View File

@ -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<D3D11Fence> fence = new D3D11Fence(this, InitialValue, Flags);
return fence->QueryInterface(riid, ppFence);
} catch (const DxvkError& e) {
Logger::err(e.message());
return E_FAIL;
}
}
@ -1927,6 +1929,8 @@ namespace dxvk {
enabled.shaderDrawParameters.shaderDrawParameters = VK_TRUE;
enabled.khrTimelineSemaphore.timelineSemaphore = supported.khrTimelineSemaphore.timelineSemaphore;
enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority;
enabled.extRobustness2.robustBufferAccess2 = supported.extRobustness2.robustBufferAccess2;

View File

@ -260,7 +260,7 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE CreateFence(
UINT64 InitialValue,
D3D11_FENCE_FLAG Flags,
REFIID ReturnedInterface,
REFIID riid,
void** ppFence);
void STDMETHODCALLTYPE ReadFromSubresource(

72
src/d3d11/d3d11_fence.cpp Normal file
View File

@ -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<ID3D11Fence>(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();
}
}

47
src/d3d11/d3d11_fence.h Normal file
View File

@ -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<ID3D11Fence> {
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<DxvkFence> GetFence() const {
return m_fence;
}
private:
Rc<DxvkFence> m_fence;
};
}

View File

@ -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',