#include "D3D12WindowRenderer.h" namespace XCEngine::UI::Editor::Host { using ::XCEngine::RHI::RHIDevice; using ::XCEngine::RHI::RHISwapChain; using ::XCEngine::RHI::D3D12Texture; bool D3D12WindowRenderer::Initialize(HWND hwnd, int width, int height) { Shutdown(); if (hwnd == nullptr || width <= 0 || height <= 0) { m_lastError = "Initialize rejected an invalid hwnd or size."; return false; } if (!m_hostDevice.Initialize()) { m_lastError = m_hostDevice.GetLastError(); return false; } if (!m_presenter.Initialize(m_hostDevice, hwnd, width, height)) { m_lastError = m_presenter.GetLastError(); Shutdown(); return false; } m_lastError.clear(); return true; } void D3D12WindowRenderer::Shutdown() { m_presenter.Shutdown(); m_hostDevice.Shutdown(); m_activeBackBufferIndex = 0u; m_lastError.clear(); } bool D3D12WindowRenderer::Resize(int width, int height) { if (!m_presenter.Resize(width, height)) { m_lastError = m_presenter.GetLastError(); return false; } m_activeBackBufferIndex = m_presenter.GetCurrentBackBufferIndex(); m_lastError = m_presenter.GetLastError(); if (!m_lastError.empty()) { return true; } m_lastError.clear(); return true; } bool D3D12WindowRenderer::BeginFrame() { if (m_presenter.GetSwapChain() == nullptr) { m_lastError = "BeginFrame requires an initialized swap chain."; return false; } m_activeBackBufferIndex = m_presenter.GetCurrentBackBufferIndex(); if (!m_hostDevice.BeginFrame(m_activeBackBufferIndex)) { m_lastError = m_hostDevice.GetLastError(); return false; } m_lastError.clear(); return true; } bool D3D12WindowRenderer::PreparePresentSurface() { ::XCEngine::Rendering::RenderContext renderContext = GetRenderContext(); if (!renderContext.IsValid() || renderContext.commandList == nullptr) { m_lastError = "PreparePresentSurface requires a valid render context."; return false; } const bool prepared = m_presenter.PreparePresentSurface(renderContext); m_lastError = prepared ? std::string() : m_presenter.GetLastError(); return prepared; } bool D3D12WindowRenderer::SubmitFrame(bool presentSwapChain) { if (presentSwapChain && m_presenter.GetSwapChain() == nullptr) { m_lastError = "SubmitFrame requested present without a swap chain."; return false; } if (!m_hostDevice.SubmitFrame(m_activeBackBufferIndex)) { m_lastError = m_hostDevice.GetLastError(); return false; } if (presentSwapChain) { if (!m_presenter.PresentFrame()) { m_lastError = m_presenter.GetLastError(); return false; } } m_lastError.clear(); return true; } bool D3D12WindowRenderer::SignalFrameCompletion() { if (!m_hostDevice.SignalFrameCompletion(m_activeBackBufferIndex)) { m_lastError = m_hostDevice.GetLastError(); return false; } m_lastError.clear(); return true; } bool D3D12WindowRenderer::PresentFrame() { const bool presented = m_presenter.PresentFrame(); m_lastError = presented ? std::string() : m_presenter.GetLastError(); return presented; } ID3D12Device* D3D12WindowRenderer::GetDevice() const { return m_hostDevice.GetDevice(); } ID3D12CommandQueue* D3D12WindowRenderer::GetCommandQueue() const { return m_hostDevice.GetCommandQueue(); } const std::string& D3D12WindowRenderer::GetLastError() const { return m_lastError; } RHIDevice* D3D12WindowRenderer::GetRHIDevice() const { return m_hostDevice.GetRHIDevice(); } RHISwapChain* D3D12WindowRenderer::GetSwapChain() const { return m_presenter.GetSwapChain(); } const ::XCEngine::Rendering::RenderSurface* D3D12WindowRenderer::GetCurrentRenderSurface() const { return m_presenter.GetCurrentRenderSurface(); } const D3D12Texture* D3D12WindowRenderer::GetCurrentBackBufferTexture() const { return m_presenter.GetCurrentBackBufferTexture(); } const D3D12Texture* D3D12WindowRenderer::GetBackBufferTexture(std::uint32_t index) const { return m_presenter.GetBackBufferTexture(index); } std::uint32_t D3D12WindowRenderer::GetBackBufferCount() const { return m_presenter.GetBackBufferCount(); } ::XCEngine::Rendering::RenderContext D3D12WindowRenderer::GetRenderContext() const { return m_hostDevice.GetRenderContext(m_activeBackBufferIndex); } } // namespace XCEngine::UI::Editor::Host