add fences to prevent resetting a ID3D12CommandAllocator before commands have completed

This commit is contained in:
Austin Eng 2017-06-07 16:38:11 -04:00 committed by Corentin Wallez
parent 81bc3ad23b
commit 2b055c38fd
2 changed files with 18 additions and 0 deletions

View File

@ -32,9 +32,24 @@ namespace d3d12 {
IID_PPV_ARGS(&commandList) IID_PPV_ARGS(&commandList)
)); ));
ASSERT_SUCCESS(commandList->Close()); 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) { 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(commandAllocator->Reset());
ASSERT_SUCCESS(commandList->Reset(commandAllocator.Get(), NULL)); ASSERT_SUCCESS(commandList->Reset(commandAllocator.Get(), NULL));

View File

@ -37,6 +37,9 @@ namespace d3d12 {
ComPtr<ID3D12CommandAllocator> commandAllocator; ComPtr<ID3D12CommandAllocator> commandAllocator;
ComPtr<ID3D12GraphicsCommandList> commandList; ComPtr<ID3D12GraphicsCommandList> commandList;
ComPtr<ID3D12Fence> fence;
uint64_t fenceValue = 0;
HANDLE fenceEvent;
}; };
} }