Files
XCEngine/new_editor/app/Rendering/D3D12/D3D12HostDeviceFrame.cpp

114 lines
3.3 KiB
C++
Raw Normal View History

#include "D3D12HostDevice.h"
namespace XCEngine::UI::Editor::Host {
using ::XCEngine::RHI::D3D12CommandList;
using ::XCEngine::RHI::RHICommandList;
bool D3D12HostDevice::BeginFrame(std::uint32_t frameIndex) {
WaitForFrame(frameIndex);
RHICommandList* commandList = GetCommandList(frameIndex);
D3D12CommandList* d3d12CommandList = GetD3D12CommandList(frameIndex);
if (commandList == nullptr || d3d12CommandList == nullptr) {
m_lastError = "BeginFrame could not resolve the active command list.";
return false;
}
commandList->Reset();
m_lastError.clear();
return true;
}
bool D3D12HostDevice::SubmitFrame(std::uint32_t frameIndex) {
RHICommandList* commandList = GetCommandList(frameIndex);
if (commandList == nullptr || m_commandQueue == nullptr) {
m_lastError = "SubmitFrame requires an initialized command list and queue.";
return false;
}
commandList->Close();
void* commandLists[] = { commandList };
m_commandQueue->ExecuteCommandLists(1, commandLists);
m_lastError.clear();
return true;
}
bool D3D12HostDevice::SignalFrameCompletion(std::uint32_t frameIndex) {
ID3D12CommandQueue* commandQueue = GetCommandQueue();
if (commandQueue == nullptr ||
m_frameCompletionFence == nullptr ||
frameIndex >= m_frameFenceValues.size()) {
return false;
}
++m_lastSubmittedFrameValue;
const HRESULT hr = commandQueue->Signal(
m_frameCompletionFence.Get(),
m_lastSubmittedFrameValue);
if (SUCCEEDED(hr)) {
m_frameFenceValues[frameIndex] = m_lastSubmittedFrameValue;
m_lastError.clear();
}
return SUCCEEDED(hr);
}
void D3D12HostDevice::WaitForFrame(std::uint32_t frameIndex) {
if (m_frameCompletionFence == nullptr ||
m_frameCompletionEvent == nullptr ||
frameIndex >= m_frameFenceValues.size()) {
return;
}
const std::uint64_t fenceValue = m_frameFenceValues[frameIndex];
if (fenceValue == 0u ||
m_frameCompletionFence->GetCompletedValue() >= fenceValue) {
return;
}
const HRESULT hr = m_frameCompletionFence->SetEventOnCompletion(
fenceValue,
m_frameCompletionEvent);
if (SUCCEEDED(hr)) {
WaitForSingleObject(m_frameCompletionEvent, INFINITE);
}
}
void D3D12HostDevice::WaitForGpuIdle() {
ID3D12CommandQueue* commandQueue = GetCommandQueue();
if (commandQueue == nullptr ||
m_frameCompletionFence == nullptr ||
m_frameCompletionEvent == nullptr) {
if (m_commandQueue != nullptr) {
m_commandQueue->WaitForIdle();
}
return;
}
++m_lastSubmittedFrameValue;
const std::uint64_t fenceValue = m_lastSubmittedFrameValue;
const HRESULT signalHr = commandQueue->Signal(
m_frameCompletionFence.Get(),
fenceValue);
if (FAILED(signalHr)) {
return;
}
if (m_frameCompletionFence->GetCompletedValue() >= fenceValue) {
return;
}
const HRESULT waitHr = m_frameCompletionFence->SetEventOnCompletion(
fenceValue,
m_frameCompletionEvent);
if (SUCCEEDED(waitHr)) {
WaitForSingleObject(m_frameCompletionEvent, INFINITE);
}
}
void D3D12HostDevice::ResetFrameTracking() {
m_frameFenceValues.fill(0u);
}
} // namespace XCEngine::UI::Editor::Host