#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; } bool D3D12SwapChain::Initialize(IDXGISwapChain* swapChain, uint32_t width, uint32_t height) { HRESULT hResult = swapChain->QueryInterface(IID_PPV_ARGS(&m_swapChain)); if (FAILED(hResult)) { return false; } m_width = width; m_height = height; m_backBuffers.resize(m_bufferCount); for (uint32_t i = 0; i < m_bufferCount; ++i) { ID3D12Resource* resource = nullptr; m_swapChain->GetBuffer(i, IID_PPV_ARGS(&resource)); m_backBuffers[i].InitializeFromExisting(resource); } return true; } void D3D12SwapChain::Shutdown() { m_swapChain.Reset(); } uint32_t D3D12SwapChain::GetCurrentBackBufferIndex() const { return m_swapChain->GetCurrentBackBufferIndex(); } IResource* D3D12SwapChain::GetBackBuffer(uint32_t index) const { if (index < m_backBuffers.size()) { return const_cast(&m_backBuffers[index]); } return nullptr; } 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; } void D3D12SwapChain::SetFullscreen(bool fullscreen) { m_swapChain->SetFullscreenState(fullscreen, nullptr); } bool D3D12SwapChain::IsFullscreen() const { BOOL fullscreen = FALSE; m_swapChain->GetFullscreenState(&fullscreen, nullptr); return fullscreen != FALSE; } void* D3D12SwapChain::GetNativeHandle() const { return reinterpret_cast(m_swapChain.Get()); } } // namespace RHI } // namespace XCEngine