From 2b055c38fde3f7690920b31e6fbdabb2498f14fb Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Wed, 7 Jun 2017 16:38:11 -0400 Subject: [PATCH] add fences to prevent resetting a ID3D12CommandAllocator before commands have completed --- src/backend/d3d12/QueueD3D12.cpp | 15 +++++++++++++++ src/backend/d3d12/QueueD3D12.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/src/backend/d3d12/QueueD3D12.cpp b/src/backend/d3d12/QueueD3D12.cpp index aaa1c3cf79..7e8582fddb 100644 --- a/src/backend/d3d12/QueueD3D12.cpp +++ b/src/backend/d3d12/QueueD3D12.cpp @@ -32,9 +32,24 @@ namespace d3d12 { IID_PPV_ARGS(&commandList) )); ASSERT_SUCCESS(commandList->Close()); + + ASSERT_SUCCESS(device->GetD3D12Device()->CreateFence(fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence))); + fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + ASSERT(fenceEvent != nullptr); } void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) { + // TODO(enga@google.com): This will stall on the previous submit because + // the commands must finish exeuting before the ID3D12CommandAllocator is reset. + // This should be fixed / optimized by using multiple command allocators. + const uint64_t currentFence = fenceValue++; + ASSERT_SUCCESS(device->GetCommandQueue()->Signal(fence.Get(), fenceValue)); + + if (fence->GetCompletedValue() < currentFence) { + ASSERT_SUCCESS(fence->SetEventOnCompletion(currentFence, fenceEvent)); + WaitForSingleObject(fenceEvent, INFINITE); + } + ASSERT_SUCCESS(commandAllocator->Reset()); ASSERT_SUCCESS(commandList->Reset(commandAllocator.Get(), NULL)); diff --git a/src/backend/d3d12/QueueD3D12.h b/src/backend/d3d12/QueueD3D12.h index 4c36230259..72a823c604 100644 --- a/src/backend/d3d12/QueueD3D12.h +++ b/src/backend/d3d12/QueueD3D12.h @@ -37,6 +37,9 @@ namespace d3d12 { ComPtr commandAllocator; ComPtr commandList; + ComPtr fence; + uint64_t fenceValue = 0; + HANDLE fenceEvent; }; }