refactor(new_editor/app): reorganize host structure and add smoke test
This commit is contained in:
113
new_editor/app/Rendering/D3D12/D3D12HostDeviceFrame.cpp
Normal file
113
new_editor/app/Rendering/D3D12/D3D12HostDeviceFrame.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user