refactor: encapsulate frame fence synchronization in CommandQueue
- Add WaitForPreviousFrame() and GetCurrentFrame() to RHICommandQueue interface - D3D12CommandQueue now manages frame fence internally - ExecuteCommandLists automatically signals fence after command execution - OpenGLCommandQueue provides stub implementations for interface compliance - Minimal test now uses CommandQueue::WaitForPreviousFrame() instead of manual fence
This commit is contained in:
@@ -27,12 +27,27 @@ bool D3D12CommandQueue::Initialize(ID3D12Device* device, CommandQueueType type)
|
||||
return false;
|
||||
}
|
||||
|
||||
hResult = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_frameFence));
|
||||
if (FAILED(hResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_frameEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
if (!m_frameEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_type = type;
|
||||
m_commandQueue->GetTimestampFrequency(&m_timestampFrequency);
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::Shutdown() {
|
||||
if (m_frameEvent) {
|
||||
CloseHandle(m_frameEvent);
|
||||
m_frameEvent = nullptr;
|
||||
}
|
||||
m_frameFence.Reset();
|
||||
m_commandQueue.Reset();
|
||||
}
|
||||
|
||||
@@ -42,6 +57,8 @@ void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, void** lists) {
|
||||
|
||||
void D3D12CommandQueue::ExecuteCommandListsInternal(uint32_t count, ID3D12CommandList** lists) {
|
||||
m_commandQueue->ExecuteCommandLists(count, lists);
|
||||
m_currentFrame++;
|
||||
m_commandQueue->Signal(m_frameFence.Get(), m_currentFrame);
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::Signal(RHIFence* fence, uint64_t value) {
|
||||
@@ -93,5 +110,14 @@ void D3D12CommandQueue::WaitForIdle() {
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12CommandQueue::WaitForPreviousFrame() {
|
||||
if (m_currentFrame > 0 && m_frameFence) {
|
||||
if (m_frameFence->GetCompletedValue() < m_currentFrame) {
|
||||
m_frameFence->SetEventOnCompletion(m_currentFrame, m_frameEvent);
|
||||
WaitForSingleObject(m_frameEvent, INFINITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
|
||||
Reference in New Issue
Block a user