summaryrefslogtreecommitdiffstats
path: root/tools/gfx/d3d12/render-d3d12.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gfx/d3d12/render-d3d12.cpp')
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp108
1 files changed, 106 insertions, 2 deletions
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index e8dadfbbb..371d22002 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -144,6 +144,16 @@ public:
virtual SLANG_NO_THROW Result SLANG_MCALL createQueryPool(
const IQueryPool::Desc& desc, IQueryPool** outState) override;
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ createFence(const IFence::Desc& desc, IFence** outFence) override;
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL waitForFences(
+ uint32_t fenceCount,
+ IFence** fences,
+ uint64_t* fenceValues,
+ bool waitForAll,
+ uint64_t timeout) override;
+
virtual SLANG_NO_THROW SlangResult SLANG_MCALL readTextureResource(
ITextureResource* resource,
ResourceState state,
@@ -3780,6 +3790,65 @@ public:
}
};
+ class FenceImpl : public FenceBase
+ {
+ public:
+ ComPtr<ID3D12Fence> m_fence;
+ HANDLE m_waitEvent = 0;
+
+ ~FenceImpl()
+ {
+ if (m_waitEvent)
+ CloseHandle(m_waitEvent);
+ }
+
+ HANDLE getWaitEvent()
+ {
+ if (m_waitEvent)
+ return m_waitEvent;
+ m_waitEvent = CreateEventEx(
+ nullptr,
+ nullptr,
+ 0,
+ EVENT_ALL_ACCESS);
+ return m_waitEvent;
+ }
+
+ Result init(D3D12Device* device, const IFence::Desc& desc)
+ {
+ SLANG_RETURN_ON_FAIL(device->m_device->CreateFence(
+ desc.initialValue,
+ desc.isShared ? D3D12_FENCE_FLAG_SHARED : D3D12_FENCE_FLAG_NONE,
+ IID_PPV_ARGS(m_fence.writeRef())));
+ return SLANG_OK;
+ }
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL getCurrentValue(uint64_t* outValue) override
+ {
+ *outValue = m_fence->GetCompletedValue();
+ return SLANG_OK;
+ }
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL setCurrentValue(uint64_t value) override
+ {
+ SLANG_RETURN_ON_FAIL(m_fence->Signal(value));
+ return SLANG_OK;
+ }
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL getSharedHandle(InteropHandle* outHandle) override
+ {
+ outHandle->handleValue = 0;
+ return SLANG_FAIL;
+ }
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ getNativeHandle(InteropHandle* outNativeHandle) override
+ {
+ outNativeHandle->handleValue = 0;
+ return SLANG_FAIL;
+ }
+ };
+
class CommandQueueImpl
: public ICommandQueue
, public ComObject
@@ -3823,7 +3892,7 @@ public:
}
~CommandQueueImpl()
{
- wait();
+ waitOnHost();
CloseHandle(globalWaitHandle);
m_renderer->m_queueIndexAllocator.free((int)m_queueIndex, 1);
}
@@ -3861,7 +3930,7 @@ public:
ResetEvent(globalWaitHandle);
}
- virtual SLANG_NO_THROW void SLANG_MCALL wait() override
+ virtual SLANG_NO_THROW void SLANG_MCALL waitOnHost() override
{
m_fenceValue++;
m_d3dQueue->Signal(m_fence, m_fenceValue);
@@ -3871,6 +3940,17 @@ public:
}
virtual SLANG_NO_THROW Result SLANG_MCALL
+ waitForFences(uint32_t fenceCount, IFence** fences, uint64_t* waitValues) override
+ {
+ for (uint32_t i = 0; i < fenceCount; ++i)
+ {
+ auto fenceImpl = static_cast<FenceImpl*>(fences[i]);
+ m_d3dQueue->Wait(fenceImpl->m_fence.get(), waitValues[i]);
+ }
+ return SLANG_OK;
+ }
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL
getNativeHandle(NativeHandle* outHandle) override
{
*outHandle = (uint64_t)m_d3dQueue.get();
@@ -6205,6 +6285,30 @@ Result D3D12Device::createQueryPool(const IQueryPool::Desc& desc, IQueryPool** o
}
}
+Result D3D12Device::createFence(const IFence::Desc& desc, IFence** outFence)
+{
+ RefPtr<FenceImpl> fence = new FenceImpl();
+ SLANG_RETURN_ON_FAIL(fence->init(this, desc));
+ returnComPtr(outFence, fence);
+ return SLANG_OK;
+}
+
+Result D3D12Device::waitForFences(
+ uint32_t fenceCount, IFence** fences, uint64_t* fenceValues, bool waitForAll, uint64_t timeout)
+{
+ List<HANDLE> waitHandles;
+ for (uint32_t i = 0; i < fenceCount; ++i)
+ {
+ auto fenceImpl = static_cast<FenceImpl*>(fences[i]);
+ waitHandles.add(fenceImpl->getWaitEvent());
+ SLANG_RETURN_ON_FAIL(fenceImpl->m_fence->SetEventOnCompletion(fenceValues[i], fenceImpl->getWaitEvent()));
+ }
+ auto result = WaitForMultipleObjects(fenceCount, waitHandles.getBuffer(), waitForAll ? TRUE : FALSE, (DWORD)timeout);
+ if (result == WAIT_TIMEOUT)
+ return SLANG_E_TIME_OUT;
+ return result == WAIT_FAILED ? SLANG_FAIL : SLANG_OK;
+}
+
#if SLANG_GFX_HAS_DXR_SUPPORT
class D3D12AccelerationStructureImpl