fix: refresh d3d12 swapchain backbuffers on resize

This commit is contained in:
2026-03-28 16:26:31 +08:00
parent 1fa97dc246
commit ec1535ad25
3 changed files with 78 additions and 18 deletions

View File

@@ -33,6 +33,9 @@ public:
void* GetNativeHandle() override;
private:
bool RefreshBackBuffers();
void ReleaseBackBuffers();
ComPtr<IDXGISwapChain3> m_swapChain;
ComPtr<ID3D12CommandQueue> m_commandQueue;
uint32_t m_width;

View File

@@ -43,14 +43,7 @@ bool D3D12SwapChain::Initialize(IDXGIFactory4* factory, ID3D12CommandQueue* comm
m_height = height;
m_bufferCount = bufferCount;
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, false);
}
return true;
return RefreshBackBuffers();
}
bool D3D12SwapChain::Initialize(IDXGISwapChain* swapChain, uint32_t width, uint32_t height) {
@@ -59,21 +52,25 @@ bool D3D12SwapChain::Initialize(IDXGISwapChain* swapChain, uint32_t width, uint3
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, false);
DXGI_SWAP_CHAIN_DESC desc = {};
hResult = m_swapChain->GetDesc(&desc);
if (FAILED(hResult) || desc.BufferCount == 0) {
return false;
}
return true;
m_width = width;
m_height = height;
m_bufferCount = desc.BufferCount;
return RefreshBackBuffers();
}
void D3D12SwapChain::Shutdown() {
ReleaseBackBuffers();
m_commandQueue.Reset();
m_swapChain.Reset();
m_width = 0;
m_height = 0;
}
uint32_t D3D12SwapChain::GetCurrentBackBufferIndex() const {
@@ -95,9 +92,16 @@ void D3D12SwapChain::Present(uint32_t syncInterval, uint32_t flags) {
}
void D3D12SwapChain::Resize(uint32_t width, uint32_t height) {
m_swapChain->ResizeBuffers(m_bufferCount, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
ReleaseBackBuffers();
const HRESULT hResult = m_swapChain->ResizeBuffers(m_bufferCount, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
if (FAILED(hResult)) {
return;
}
m_width = width;
m_height = height;
RefreshBackBuffers();
}
void* D3D12SwapChain::GetNativeHandle() {
@@ -108,5 +112,34 @@ RHITexture* D3D12SwapChain::GetCurrentBackBuffer() {
return &GetBackBuffer(GetCurrentBackBufferIndex());
}
bool D3D12SwapChain::RefreshBackBuffers() {
if (!m_swapChain || m_bufferCount == 0) {
return false;
}
m_backBuffers.clear();
m_backBuffers.resize(m_bufferCount);
for (uint32_t i = 0; i < m_bufferCount; ++i) {
ComPtr<ID3D12Resource> resource;
const HRESULT hResult = m_swapChain->GetBuffer(i, IID_PPV_ARGS(&resource));
if (FAILED(hResult) || resource == nullptr) {
ReleaseBackBuffers();
return false;
}
m_backBuffers[i].InitializeFromExisting(resource.Get(), false);
}
return true;
}
void D3D12SwapChain::ReleaseBackBuffers() {
for (D3D12Texture& backBuffer : m_backBuffers) {
backBuffer.Shutdown();
}
m_backBuffers.clear();
}
} // namespace RHI
} // namespace XCEngine