diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 8fcbb46b..64b641d7 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -89,6 +89,7 @@ add_library(XCEngine STATIC include/XCEngine/RHI/D3D12/D3D12CommandAllocator.h include/XCEngine/RHI/D3D12/D3D12CommandList.h include/XCEngine/RHI/D3D12/D3D12DescriptorHeap.h + include/XCEngine/RHI/D3D12/D3D12SwapChain.h include/XCEngine/RHI/D3D12/D3D12Fence.h include/XCEngine/RHI/D3D12/D3D12Screenshot.h src/RHI/D3D12Device.cpp @@ -96,6 +97,7 @@ add_library(XCEngine STATIC src/RHI/D3D12CommandAllocator.cpp src/RHI/D3D12CommandList.cpp src/RHI/D3D12DescriptorHeap.cpp + src/RHI/D3D12SwapChain.cpp src/RHI/D3D12Fence.cpp src/RHI/D3D12Screenshot.cpp ) diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h b/engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h new file mode 100644 index 00000000..67c93525 --- /dev/null +++ b/engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +#include "../Enums.h" +#include "D3D12Enum.h" + +using Microsoft::WRL::ComPtr; + +namespace XCEngine { +namespace RHI { + +class D3D12SwapChain { +public: + D3D12SwapChain(); + ~D3D12SwapChain(); + + bool Initialize(IDXGIFactory4* factory, ID3D12CommandQueue* commandQueue, HWND windowHandle, uint32_t width, uint32_t height, uint32_t bufferCount = 2); + void Shutdown(); + + uint32_t GetCurrentBackBufferIndex() const; + ID3D12Resource* GetBackBuffer(uint32_t index) const; + void Present(uint32_t syncInterval, uint32_t flags); + void Resize(uint32_t width, uint32_t height); + + IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); } + +private: + ComPtr m_swapChain; + ComPtr m_commandQueue; + HWND m_windowHandle; + uint32_t m_width; + uint32_t m_height; + uint32_t m_bufferCount; +}; + +} // namespace RHI +} // namespace XCEngine diff --git a/engine/src/RHI/D3D12SwapChain.cpp b/engine/src/RHI/D3D12SwapChain.cpp new file mode 100644 index 00000000..424334fc --- /dev/null +++ b/engine/src/RHI/D3D12SwapChain.cpp @@ -0,0 +1,75 @@ +#include "XCEngine/RHI/D3D12/D3D12SwapChain.h" + +namespace XCEngine { +namespace RHI { + +D3D12SwapChain::D3D12SwapChain() + : m_windowHandle(nullptr) + , m_width(0) + , m_height(0) + , m_bufferCount(2) { +} + +D3D12SwapChain::~D3D12SwapChain() { + Shutdown(); +} + +bool D3D12SwapChain::Initialize(IDXGIFactory4* factory, ID3D12CommandQueue* commandQueue, HWND windowHandle, uint32_t width, uint32_t height, uint32_t bufferCount) { + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = bufferCount; + swapChainDesc.BufferDesc.Width = width; + swapChainDesc.BufferDesc.Height = height; + swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.OutputWindow = windowHandle; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.Windowed = TRUE; + + IDXGISwapChain* swapChain = nullptr; + HRESULT hResult = factory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain); + if (FAILED(hResult)) { + return false; + } + + hResult = swapChain->QueryInterface(IID_PPV_ARGS(&m_swapChain)); + if (FAILED(hResult)) { + return false; + } + + m_commandQueue = commandQueue; + m_windowHandle = windowHandle; + m_width = width; + m_height = height; + m_bufferCount = bufferCount; + + return true; +} + +void D3D12SwapChain::Shutdown() { + m_swapChain.Reset(); +} + +uint32_t D3D12SwapChain::GetCurrentBackBufferIndex() const { + return m_swapChain->GetCurrentBackBufferIndex(); +} + +ID3D12Resource* D3D12SwapChain::GetBackBuffer(uint32_t index) const { + ID3D12Resource* resource = nullptr; + m_swapChain->GetBuffer(index, IID_PPV_ARGS(&resource)); + return resource; +} + +void D3D12SwapChain::Present(uint32_t syncInterval, uint32_t flags) { + m_swapChain->Present(syncInterval, flags); +} + +void D3D12SwapChain::Resize(uint32_t width, uint32_t height) { + m_swapChain->ResizeBuffers(m_bufferCount, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + m_width = width; + m_height = height; +} + +} // namespace RHI +} // namespace XCEngine