D3D12: Fix texture ownership semantics and remove GetSwapChain() exposure

This commit fixes the D3D12 texture architecture issues:

1. D3D12Texture ownership semantics:
   - Add m_ownsResource member to track resource ownership
   - InitializeFromExisting() now takes ownsResource parameter (default false)
   - Shutdown() only releases resource if ownsResource is true
   - Initialize() sets m_ownsResource = true for created resources

2. D3D12SwapChain changes:
   - Remove GetSwapChain() method (was exposing native D3D12 API)
   - Change GetBackBuffer() to return reference instead of pointer
   - Back buffers initialized with ownsResource = false

3. minimal/main.cpp updates:
   - Remove gColorRTs[2] array (was duplicating back buffer wrapping)
   - Direct use of gSwapChain.GetBackBuffer(i) instead
   - All references updated to use encapsulated API

4. Documentation:
   - Update TEST_SPEC.md v1.3
   - Remove known limitation 7.2 (minimal GetBuffer issue fixed)
   - Add D3D12_Texture_Architecture_Fix_Plan.md design document
This commit is contained in:
2026-03-20 17:58:27 +08:00
parent 0017388498
commit 34c04af6cb
7 changed files with 433 additions and 38 deletions

View File

@@ -48,7 +48,7 @@ bool D3D12SwapChain::Initialize(IDXGIFactory4* factory, ID3D12CommandQueue* comm
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);
m_backBuffers[i].InitializeFromExisting(resource, false);
}
return true;
@@ -67,7 +67,7 @@ bool D3D12SwapChain::Initialize(IDXGISwapChain* swapChain, uint32_t width, uint3
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);
m_backBuffers[i].InitializeFromExisting(resource, false);
}
return true;
@@ -81,11 +81,12 @@ uint32_t D3D12SwapChain::GetCurrentBackBufferIndex() const {
return m_swapChain->GetCurrentBackBufferIndex();
}
D3D12Texture* D3D12SwapChain::GetBackBuffer(uint32_t index) const {
if (index < m_backBuffers.size()) {
return const_cast<D3D12Texture*>(&m_backBuffers[index]);
}
return nullptr;
D3D12Texture& D3D12SwapChain::GetBackBuffer(uint32_t index) {
return m_backBuffers[index];
}
const D3D12Texture& D3D12SwapChain::GetBackBuffer(uint32_t index) const {
return m_backBuffers[index];
}
void D3D12SwapChain::Present(uint32_t syncInterval, uint32_t flags) {
@@ -113,7 +114,7 @@ void* D3D12SwapChain::GetNativeHandle() {
}
RHITexture* D3D12SwapChain::GetCurrentBackBuffer() {
return GetBackBuffer(GetCurrentBackBufferIndex());
return &GetBackBuffer(GetCurrentBackBufferIndex());
}
bool D3D12SwapChain::ShouldClose() const {

View File

@@ -33,11 +33,13 @@ bool D3D12Texture::Initialize(ID3D12Device* device, const D3D12_RESOURCE_DESC& d
return false;
}
m_ownsResource = true;
return true;
}
bool D3D12Texture::InitializeFromExisting(ID3D12Resource* resource) {
bool D3D12Texture::InitializeFromExisting(ID3D12Resource* resource, bool ownsResource) {
m_resource = resource;
m_ownsResource = ownsResource;
return true;
}
@@ -178,6 +180,9 @@ bool D3D12Texture::InitializeDepthStencil(ID3D12Device* device, uint32_t width,
}
void D3D12Texture::Shutdown() {
if (m_ownsResource) {
m_resource.Reset();
}
m_resource.Reset();
}