#include "D3D12HostDevice.h" #include namespace XCEngine::UI::Editor::Host { using ::XCEngine::RHI::CommandListDesc; using ::XCEngine::RHI::CommandQueueDesc; using ::XCEngine::RHI::D3D12CommandList; using ::XCEngine::RHI::D3D12CommandQueue; using ::XCEngine::RHI::D3D12Device; using ::XCEngine::RHI::RHICommandList; using ::XCEngine::RHI::RHICommandQueue; using ::XCEngine::RHI::RHIDevice; using ::XCEngine::RHI::RHIDeviceDesc; using ::XCEngine::RHI::RHIFactory; using ::XCEngine::RHI::RHIType; bool D3D12HostDevice::Initialize() { Shutdown(); m_device = RHIFactory::CreateRHIDevice(RHIType::D3D12); if (m_device == nullptr) { m_lastError = "Failed to create the D3D12 RHI device."; return false; } RHIDeviceDesc deviceDesc = {}; #ifdef _DEBUG deviceDesc.enableDebugLayer = true; deviceDesc.enableGPUValidation = true; #endif if (!m_device->Initialize(deviceDesc)) { m_lastError = "Failed to initialize the D3D12 RHI device."; Shutdown(); return false; } CommandQueueDesc queueDesc = {}; queueDesc.queueType = static_cast(::XCEngine::RHI::CommandQueueType::Direct); m_commandQueue = m_device->CreateCommandQueue(queueDesc); if (m_commandQueue == nullptr || GetD3D12CommandQueue() == nullptr) { m_lastError = "Failed to create the D3D12 command queue."; Shutdown(); return false; } CommandListDesc commandListDesc = {}; commandListDesc.commandListType = static_cast(::XCEngine::RHI::CommandQueueType::Direct); for (std::uint32_t commandListIndex = 0; commandListIndex < kFrameContextCount; ++commandListIndex) { m_commandLists[commandListIndex] = m_device->CreateCommandList(commandListDesc); if (m_commandLists[commandListIndex] == nullptr || GetD3D12CommandList(commandListIndex) == nullptr) { m_lastError = "Failed to create the D3D12 command list."; Shutdown(); return false; } m_commandLists[commandListIndex]->Close(); } if (!InitializeFrameCompletionFence()) { m_lastError = "Failed to create the host frame completion fence."; Shutdown(); return false; } m_frameFenceValues.fill(0u); m_lastError.clear(); return true; } void D3D12HostDevice::Shutdown() { WaitForGpuIdle(); ReleaseFrameCompletionFence(); for (auto*& commandList : m_commandLists) { if (commandList != nullptr) { commandList->Shutdown(); delete commandList; commandList = nullptr; } } if (m_commandQueue != nullptr) { m_commandQueue->Shutdown(); delete m_commandQueue; m_commandQueue = nullptr; } if (m_device != nullptr) { m_device->Shutdown(); delete m_device; m_device = nullptr; } m_lastError.clear(); } ID3D12Device* D3D12HostDevice::GetDevice() const { const D3D12Device* device = GetD3D12Device(); return device != nullptr ? device->GetDevice() : nullptr; } ID3D12CommandQueue* D3D12HostDevice::GetCommandQueue() const { const D3D12CommandQueue* queue = GetD3D12CommandQueue(); return queue != nullptr ? queue->GetCommandQueue() : nullptr; } const std::string& D3D12HostDevice::GetLastError() const { return m_lastError; } RHIDevice* D3D12HostDevice::GetRHIDevice() const { return m_device; } RHICommandQueue* D3D12HostDevice::GetRHICommandQueue() const { return m_commandQueue; } RHICommandList* D3D12HostDevice::GetCommandList(std::uint32_t frameIndex) const { return frameIndex < m_commandLists.size() ? m_commandLists[frameIndex] : nullptr; } ::XCEngine::Rendering::RenderContext D3D12HostDevice::GetRenderContext( std::uint32_t frameIndex) const { ::XCEngine::Rendering::RenderContext context = {}; context.device = m_device; context.commandList = GetCommandList(frameIndex); context.commandQueue = m_commandQueue; context.backendType = RHIType::D3D12; return context; } D3D12Device* D3D12HostDevice::GetD3D12Device() const { return m_device != nullptr ? static_cast(m_device) : nullptr; } D3D12CommandQueue* D3D12HostDevice::GetD3D12CommandQueue() const { return m_commandQueue != nullptr ? static_cast(m_commandQueue) : nullptr; } D3D12CommandList* D3D12HostDevice::GetD3D12CommandList(std::uint32_t frameIndex) const { RHICommandList* commandList = GetCommandList(frameIndex); return commandList != nullptr ? static_cast(commandList) : nullptr; } } // namespace XCEngine::UI::Editor::Host