From f187aa3b374793f95f7d7922b8f82bb8c25cec9b Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 15 Mar 2026 18:24:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=20D3D12SwapChain=20?= =?UTF-8?q?=E4=BA=A4=E6=8D=A2=E9=93=BE=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 D3D12SwapChain.h 头文件 - 实现 IDXGISwapChain3 封装 - 实现 Initialize、Present、Resize 等方法 - 测试通过 --- engine/CMakeLists.txt | 2 + .../XCEngine/RHI/D3D12/D3D12SwapChain.h | 40 ++++++++++ engine/src/RHI/D3D12SwapChain.cpp | 75 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h create mode 100644 engine/src/RHI/D3D12SwapChain.cpp 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