#pragma once #ifndef NOMINMAX #define NOMINMAX #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace XCEngine::UI::Editor::Host { class D3D12WindowRenderer { public: static constexpr UINT kSrvDescriptorCount = 64; static constexpr std::uint32_t kSwapChainBufferCount = 3; bool Initialize(HWND hwnd, int width, int height); void Shutdown(); bool Resize(int width, int height); bool BeginFrame(); bool PreparePresentSurface(); bool SubmitFrame(bool presentSwapChain); bool SignalFrameCompletion(); bool PresentFrame(); ID3D12Device* GetDevice() const; ID3D12DescriptorHeap* GetSrvHeap() const; ID3D12CommandQueue* GetCommandQueue() const; const std::string& GetLastError() const; void AllocateShaderResourceDescriptor( D3D12_CPU_DESCRIPTOR_HANDLE* outCpuHandle, D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle); bool CreateShaderResourceTextureDescriptor( ::XCEngine::RHI::RHIDevice* device, ::XCEngine::RHI::RHITexture* texture, D3D12_CPU_DESCRIPTOR_HANDLE* outCpuHandle, D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle); void FreeShaderResourceDescriptor( D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle, D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle); UINT GetSrvDescriptorSize() const; UINT GetSrvDescriptorCount() const; ::XCEngine::RHI::RHIDevice* GetRHIDevice() const; ::XCEngine::RHI::RHISwapChain* GetSwapChain() const; const ::XCEngine::Rendering::RenderSurface* GetCurrentRenderSurface() const; const ::XCEngine::RHI::D3D12Texture* GetCurrentBackBufferTexture() const; const ::XCEngine::RHI::D3D12Texture* GetBackBufferTexture(std::uint32_t index) const; std::uint32_t GetBackBufferCount() const; ::XCEngine::Rendering::RenderContext GetRenderContext() const; private: ::XCEngine::RHI::D3D12Device* GetD3D12Device() const; ::XCEngine::RHI::D3D12CommandQueue* GetD3D12CommandQueue() const; ::XCEngine::RHI::D3D12CommandList* GetD3D12CommandList() const; ::XCEngine::RHI::D3D12SwapChain* GetD3D12SwapChain() const; ::XCEngine::RHI::RHICommandList* GetCurrentCommandList() const; void AllocateShaderResourceDescriptorInternal( D3D12_CPU_DESCRIPTOR_HANDLE* outCpuHandle, D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle); void FreeShaderResourceDescriptorInternal( D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle, D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle); bool InitializeFrameCompletionFence(); void ReleaseFrameCompletionFence(); void WaitForBackBufferFrame(std::uint32_t backBufferIndex); void WaitForGpuIdle(); void ReleaseBackBufferCommandReferences(); void ReleaseBackBufferViews(); bool RecreateBackBufferViews(); HWND m_hwnd = nullptr; int m_width = 0; int m_height = 0; ::XCEngine::RHI::RHIDevice* m_device = nullptr; ::XCEngine::RHI::RHICommandQueue* m_commandQueue = nullptr; std::array<::XCEngine::RHI::RHICommandList*, kSwapChainBufferCount> m_commandLists = {}; ::XCEngine::RHI::RHISwapChain* m_swapChain = nullptr; ::XCEngine::RHI::RHIDescriptorPool* m_srvPool = nullptr; ::XCEngine::RHI::D3D12DescriptorHeap* m_srvHeap = nullptr; std::vector m_srvUsage = {}; std::vector<::XCEngine::RHI::RHIResourceView*> m_backBufferViews = {}; std::vector<::XCEngine::Rendering::RenderSurface> m_backBufferSurfaces = {}; Microsoft::WRL::ComPtr m_frameCompletionFence = {}; HANDLE m_frameCompletionEvent = nullptr; std::array m_backBufferFenceValues = {}; std::uint32_t m_activeBackBufferIndex = 0u; std::uint64_t m_lastSubmittedFrameValue = 0; std::string m_lastError = {}; UINT m_srvDescriptorSize = 0; }; } // namespace XCEngine::UI::Editor::Host