diff options
Diffstat (limited to 'tools/gfx/d3d12/render-d3d12.cpp')
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 108 |
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 |
