Hello.
I'm starting to learn Direct3D 12, and am currently going through the book “Introduction to 3D Game Programming with DirectX 12”, by Frank D. Luna.
This one code snippet from the book (page 113) looks to me as if it contains a race condition:
// Advance the fence value to mark commands up to this fence point.
mCurrentFence++;
// Add an instruction to the command queue to set a new fence point. Because we
// are on the GPU timeline, the new fence point won't be set until the GPU finishes
// processing all the commands prior to this Signal().
ThrowIfFailed(mCommandQueue->Signal(mFence.Get(), mCurrentFence));
// Wait until the GPU has completed commands up to this fence point.
if(mFence->GetCompletedValue() < mCurrentFence)
{
HANDLE eventHandle = CreateEventEx(nullptr, false, false, EVENT_ALL_ACCESS);
// Fire event when GPU hits current fence.
ThrowIfFailed(mFence->SetEventOnCompletion(mCurrentFence, eventHandle));
// Wait until the GPU hits current fence event is fired.
WaitForSingleObject(eventHandle, INFINITE);
CloseHandle(eventHandle);
}
The bug (race condition) would happen if the fence (on GPU side) is hit after checking mFence->GetCompletedValue()
, but before setting up an event that listens for it (mFence->SetEventOnCompletion(mCurrentFence, eventHandle)
). Am I missing something, or is it indeed wrong? If so, is there a better way to wait for the fence on CPU side?