From 816038d03fb0aca261759b6ba1bb2fb5face9487 Mon Sep 17 00:00:00 2001 From: Kaldaien Date: Tue, 18 Feb 2025 07:33:28 -0500 Subject: [PATCH] Correctly isolate command lists and command list allocators to individual frame contexts instead of sharing frame context 0's allocator for all command lists --- src/d3d12/D3D12.h | 2 +- src/d3d12/D3D12_Functions.cpp | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/d3d12/D3D12.h b/src/d3d12/D3D12.h index 87035739..3689f3be 100644 --- a/src/d3d12/D3D12.h +++ b/src/d3d12/D3D12.h @@ -35,6 +35,7 @@ struct D3D12 struct FrameContext { Microsoft::WRL::ComPtr CommandAllocator; + Microsoft::WRL::ComPtr CommandList{}; Microsoft::WRL::ComPtr BackBuffer; D3D12_CPU_DESCRIPTOR_HANDLE MainRenderTargetDescriptor{0}; }; @@ -62,7 +63,6 @@ struct D3D12 Microsoft::WRL::ComPtr m_pd3d12Device{}; Microsoft::WRL::ComPtr m_pd3dRtvDescHeap{}; Microsoft::WRL::ComPtr m_pd3dSrvDescHeap{}; - Microsoft::WRL::ComPtr m_pd3dCommandList{}; // borrowed resources from game, do not manipulate reference counts on these! Microsoft::WRL::ComPtr m_pdxgiSwapChain{nullptr}; diff --git a/src/d3d12/D3D12_Functions.cpp b/src/d3d12/D3D12_Functions.cpp index f48dc2d4..60b5d0fc 100644 --- a/src/d3d12/D3D12_Functions.cpp +++ b/src/d3d12/D3D12_Functions.cpp @@ -35,7 +35,6 @@ bool D3D12::ResetState(const bool acDestroyContext) m_pd3d12Device.Reset(); m_pd3dRtvDescHeap.Reset(); m_pd3dSrvDescHeap.Reset(); - m_pd3dCommandList.Reset(); m_pCommandQueue.Reset(); m_pdxgiSwapChain.Reset(); @@ -113,17 +112,19 @@ bool D3D12::Initialize() } for (auto& context : m_frameContexts) + { if (FAILED(m_pd3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&context.CommandAllocator)))) { Log::Error("D3D12::Initialize() - failed to create command allocator!"); return ResetState(); } - if (FAILED(m_pd3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_frameContexts[0].CommandAllocator.Get(), nullptr, IID_PPV_ARGS(&m_pd3dCommandList))) || - FAILED(m_pd3dCommandList->Close())) - { - Log::Error("D3D12::Initialize() - failed to create command list!"); - return ResetState(); + if (FAILED(m_pd3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, context.CommandAllocator.Get(), nullptr, IID_PPV_ARGS(&context.CommandList))) || + FAILED(context.CommandList->Close())) + { + Log::Error("D3D12::Initialize() - failed to create command list!"); + return ResetState(); + } } if (!InitializeImGui(buffersCounts)) @@ -404,18 +405,18 @@ void D3D12::Update() ID3D12DescriptorHeap* heaps[] = {m_pd3dSrvDescHeap.Get()}; - m_pd3dCommandList->Reset(frameContext.CommandAllocator.Get(), nullptr); - m_pd3dCommandList->ResourceBarrier(1, &barrier); - m_pd3dCommandList->SetDescriptorHeaps(1, heaps); - m_pd3dCommandList->OMSetRenderTargets(1, &frameContext.MainRenderTargetDescriptor, FALSE, nullptr); + frameContext.CommandList->Reset(frameContext.CommandAllocator.Get(), nullptr); + frameContext.CommandList->ResourceBarrier(1, &barrier); + frameContext.CommandList->SetDescriptorHeaps(1, heaps); + frameContext.CommandList->OMSetRenderTargets(1, &frameContext.MainRenderTargetDescriptor, FALSE, nullptr); - ImGui_ImplDX12_RenderDrawData(&m_imguiDrawDataBuffers[0], m_pd3dCommandList.Get()); + ImGui_ImplDX12_RenderDrawData(&m_imguiDrawDataBuffers[0], frameContext.CommandList.Get()); barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; - m_pd3dCommandList->ResourceBarrier(1, &barrier); - m_pd3dCommandList->Close(); + frameContext.CommandList->ResourceBarrier(1, &barrier); + frameContext.CommandList->Close(); - ID3D12CommandList* commandLists[] = {m_pd3dCommandList.Get()}; + ID3D12CommandList* commandLists[] = {frameContext.CommandList.Get()}; m_pCommandQueue->ExecuteCommandLists(1, commandLists); }