From db44d06d412da862be3ff96e6b79e08b5e26e5e4 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 29 Apr 2024 18:32:21 +0100 Subject: [PATCH] Manage internal GPU buffers as refcounted objects on D3D12 * This will enable sharing of these buffers more easily when there are multiple lifetimes that are more difficult to co-ordinate. --- .../driver/d3d12/d3d12_command_list4_wrap.cpp | 22 +- renderdoc/driver/d3d12/d3d12_commands.h | 2 +- renderdoc/driver/d3d12/d3d12_initstate.cpp | 18 +- renderdoc/driver/d3d12/d3d12_manager.cpp | 214 +++++------------- renderdoc/driver/d3d12/d3d12_manager.h | 35 ++- 5 files changed, 89 insertions(+), 202 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp index 24fd80141..de3bf1238 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list4_wrap.cpp @@ -784,7 +784,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress( resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer.Resource(); + resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource(); resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; resBarriers.push_back(resBarrier); @@ -793,8 +793,8 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress( dxrCmd->ResourceBarrier((UINT)resBarriers.size(), resBarriers.data()); } - dxrCmd->CopyBufferRegion(patchRaytracing->m_patchedInstanceBuffer.Resource(), - patchRaytracing->m_patchedInstanceBuffer.Offset(), instanceResource, + dxrCmd->CopyBufferRegion(patchRaytracing->m_patchedInstanceBuffer->Resource(), + patchRaytracing->m_patchedInstanceBuffer->Offset(), instanceResource, instanceResOffset, totalInstancesSize); D3D12AccStructPatchInfo patchInfo = rtHandler->GetAccStructPatchInfo(); @@ -806,7 +806,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress( resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer.Resource(); + resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource(); resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; resBarriers.push_back(resBarrier); @@ -840,7 +840,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress( D3D12_RESOURCE_BARRIER resBarrier; resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - resBarrier.UAV.pResource = patchRaytracing->m_patchedInstanceBuffer.Resource(); + resBarrier.UAV.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource(); dxrCmd->ResourceBarrier(1, &resBarrier); } @@ -857,14 +857,14 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress( (UINT)D3D12PatchAccStructRootParamIndices::RootAddressPairSrv, addressPairResAddress); dxrCmd->SetComputeRootUnorderedAccessView( (UINT)D3D12PatchAccStructRootParamIndices::RootPatchedAddressUav, - patchRaytracing->m_patchedInstanceBuffer.Address()); + patchRaytracing->m_patchedInstanceBuffer->Address()); dxrCmd->Dispatch(accStructInput->Inputs.NumDescs, 1, 1); { D3D12_RESOURCE_BARRIER resBarrier; resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - resBarrier.UAV.pResource = patchRaytracing->m_patchedInstanceBuffer.Resource(); + resBarrier.UAV.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource(); dxrCmd->ResourceBarrier(1, &resBarrier); } @@ -873,7 +873,7 @@ bool WrappedID3D12GraphicsCommandList::PatchAccStructBlasAddress( resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer.Resource(); + resBarrier.Transition.pResource = patchRaytracing->m_patchedInstanceBuffer->Resource(); resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; dxrCmd->ResourceBarrier(1, &resBarrier); @@ -922,7 +922,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BuildRaytracingAccelerationStru PatchAccStructBlasAddress(&AccStructDesc, dxrCmd, &patchInfo); if(patchInfo.m_patched) { - AccStructDesc.Inputs.InstanceDescs = patchInfo.m_patchedInstanceBuffer.Address(); + AccStructDesc.Inputs.InstanceDescs = patchInfo.m_patchedInstanceBuffer->Address(); } else { @@ -948,13 +948,13 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BuildRaytracingAccelerationStru if(D3D12GpuBufferAllocator::Inst()->Alloc( D3D12GpuBufferHeapType::DefaultHeapWithUav, D3D12GpuBufferHeapMemoryFlag::Default, totalInstancesSize, D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT, - patchInfo.m_patchedInstanceBuffer)) + &patchInfo.m_patchedInstanceBuffer)) { PatchAccStructBlasAddress(&AccStructDesc, dxrCmd, &patchInfo); if(patchInfo.m_patched) { - AccStructDesc.Inputs.InstanceDescs = patchInfo.m_patchedInstanceBuffer.Address(); + AccStructDesc.Inputs.InstanceDescs = patchInfo.m_patchedInstanceBuffer->Address(); } // Switch back to previous state diff --git a/renderdoc/driver/d3d12/d3d12_commands.h b/renderdoc/driver/d3d12/d3d12_commands.h index 67bd2aa1c..f0cf9c7d5 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.h +++ b/renderdoc/driver/d3d12/d3d12_commands.h @@ -205,7 +205,7 @@ struct BakedCmdListInfo struct PatchRaytracing { bool m_patched = false; - D3D12GpuBuffer m_patchedInstanceBuffer; + D3D12GpuBuffer *m_patchedInstanceBuffer; }; rdcflatmap m_patchRaytracingInfo; diff --git a/renderdoc/driver/d3d12/d3d12_initstate.cpp b/renderdoc/driver/d3d12/d3d12_initstate.cpp index 567d80873..f1e528161 100644 --- a/renderdoc/driver/d3d12/d3d12_initstate.cpp +++ b/renderdoc/driver/d3d12/d3d12_initstate.cpp @@ -409,12 +409,12 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) // get the size { - D3D12GpuBuffer ASQueryBuffer = GetRaytracingResourceAndUtilHandler()->ASQueryBuffer; + D3D12GpuBuffer *ASQueryBuffer = GetRaytracingResourceAndUtilHandler()->ASQueryBuffer; list4 = Unwrap4(m_Device->GetInitialStateList()); D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC emitDesc = {}; - emitDesc.DestBuffer = ASQueryBuffer.Address(); + emitDesc.DestBuffer = ASQueryBuffer->Address(); emitDesc.InfoType = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION; list4->EmitRaytracingAccelerationStructurePostbuildInfo(&emitDesc, 1, &asAddress); @@ -426,7 +426,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC *serSize = (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC *) - ASQueryBuffer.Map(); + ASQueryBuffer->Map(); if(!serSize) { @@ -437,7 +437,7 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) desc.Width = serSize->SerializedSizeInBytes; blasCount = serSize->NumBottomLevelAccelerationStructurePointers; - ASQueryBuffer.Unmap(); + ASQueryBuffer->Unmap(); // no other copies are in flight because of the above sync so we can resize this GetRaytracingResourceAndUtilHandler()->ResizeSerialisationBuffer(desc.Width); @@ -456,22 +456,22 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res) if(SUCCEEDED(hr)) { - D3D12GpuBuffer ASSerialiseBuffer = GetRaytracingResourceAndUtilHandler()->ASSerialiseBuffer; + D3D12GpuBuffer *ASSerialiseBuffer = GetRaytracingResourceAndUtilHandler()->ASSerialiseBuffer; list4->CopyRaytracingAccelerationStructure( - ASSerialiseBuffer.Address(), r->GetVirtualAddress(), + ASSerialiseBuffer->Address(), r->GetVirtualAddress(), D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_SERIALIZE); D3D12_RESOURCE_BARRIER b = {}; - b.Transition.pResource = ASSerialiseBuffer.Resource(); + b.Transition.pResource = ASSerialiseBuffer->Resource(); b.Transition.Subresource = 0; b.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; b.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; list4->ResourceBarrier(1, &b); - list4->CopyBufferRegion(copyDst, 0, ASSerialiseBuffer.Resource(), ASSerialiseBuffer.Offset(), - desc.Width); + list4->CopyBufferRegion(copyDst, 0, ASSerialiseBuffer->Resource(), + ASSerialiseBuffer->Offset(), desc.Width); } else { diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index e54a9d02b..8d264ed1d 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -740,7 +740,7 @@ D3D12RaytracingResourceAndUtilHandler::D3D12RaytracingResourceAndUtilHandler(Wra D3D12GpuBufferAllocator::Inst()->Alloc(D3D12GpuBufferHeapType::CustomHeapWithUavCpuAccess, D3D12GpuBufferHeapMemoryFlag::Default, 16, 256, - ASQueryBuffer); + &ASQueryBuffer); } } @@ -769,13 +769,13 @@ void D3D12RaytracingResourceAndUtilHandler::InitInternalResources() void D3D12RaytracingResourceAndUtilHandler::ResizeSerialisationBuffer(UINT64 size) { - if(size > ASSerialiseBuffer.Size()) + if(!ASSerialiseBuffer || size > ASSerialiseBuffer->Size()) { - ASSerialiseBuffer.Release(); + SAFE_RELEASE(ASSerialiseBuffer); D3D12GpuBufferAllocator::Inst()->Alloc(D3D12GpuBufferHeapType::DefaultHeapWithUav, D3D12GpuBufferHeapMemoryFlag::Default, size, 256, - ASSerialiseBuffer); + &ASSerialiseBuffer); } } @@ -911,126 +911,6 @@ void D3D12RaytracingResourceAndUtilHandler::UnregisterExportDatabase(D3D12Shader D3D12GpuBufferAllocator *D3D12GpuBufferAllocator::m_bufferAllocator = NULL; -bool D3D12GpuBufferAllocator::CopyBufferRegion(WrappedID3D12GraphicsCommandList *wrappedCmd, - const D3D12GpuBuffer &destBuffer, - D3D12_GPU_VIRTUAL_ADDRESS srcAddress, - uint64_t dataSize) -{ - if(D3D12GpuBuffer() != destBuffer && dataSize > 0) - { - ResourceId srcResourceId; - D3D12BufferOffset srcResourceOffset; - - rdcarray resBarriers; - rdcarray finalBarriers; - - { - D3D12_RESOURCE_BARRIER resBarrier; - resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; - resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; - resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - resBarrier.Transition.pResource = destBuffer.Resource(); - resBarriers.push_back(resBarrier); - - resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; - resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; - finalBarriers.push_back(resBarrier); - } - - WrappedID3D12Resource::GetResIDFromAddr(srcAddress, srcResourceId, srcResourceOffset); - - if(srcResourceId != ResourceId()) - { - D3D12_RESOURCE_STATES srResourceState = - wrappedCmd->GetWrappedDevice()->GetSubresourceStates(srcResourceId)[0].ToStates(); - - ID3D12Resource *srcResource = NULL; - srcResource = wrappedCmd->GetWrappedDevice() - ->GetResourceManager() - ->GetCurrentAs(srcResourceId) - ->GetReal(); - - if(!(srResourceState & D3D12_RESOURCE_STATE_COPY_SOURCE)) - { - D3D12_RESOURCE_BARRIER resBarrier; - resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - resBarrier.Transition.StateBefore = srResourceState; - resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - resBarrier.Transition.pResource = srcResource; - resBarriers.push_back(resBarrier); - - resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE; - resBarrier.Transition.StateAfter = srResourceState; - finalBarriers.push_back(resBarrier); - } - - wrappedCmd->GetReal()->ResourceBarrier((UINT)resBarriers.size(), resBarriers.data()); - wrappedCmd->GetReal()->CopyBufferRegion(destBuffer.Resource(), destBuffer.Offset(), - srcResource, srcResourceOffset, dataSize); - wrappedCmd->GetReal()->ResourceBarrier((UINT)finalBarriers.size(), finalBarriers.data()); - - return true; - } - } - - return false; -} - -bool D3D12GpuBufferAllocator::CopyBufferRegion(WrappedID3D12GraphicsCommandList *wrappedCmd, - const D3D12GpuBuffer &destBuffer, - const D3D12GpuBuffer &sourceBuffer, uint64_t dataSize) -{ - // This will only handle if both are on default heap - if(destBuffer.GetD3D12HeapType() != D3D12_HEAP_TYPE_DEFAULT || - sourceBuffer.GetD3D12HeapType() != D3D12_HEAP_TYPE_DEFAULT) - { - return false; - } - - rdcarray initBarriers; - rdcarray finalBarriers; - - { - D3D12_RESOURCE_BARRIER resBarrier; - resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; - resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - resBarrier.Transition.pResource = sourceBuffer.Resource(); - initBarriers.push_back(resBarrier); - - resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE; - resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; - finalBarriers.push_back(resBarrier); - } - - { - D3D12_RESOURCE_BARRIER resBarrier; - resBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; - resBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON; - resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; - resBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - resBarrier.Transition.pResource = destBuffer.Resource(); - initBarriers.push_back(resBarrier); - - resBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; - resBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; - finalBarriers.push_back(resBarrier); - } - - wrappedCmd->GetReal()->ResourceBarrier((UINT)initBarriers.size(), initBarriers.data()); - wrappedCmd->GetReal()->CopyBufferRegion(destBuffer.Resource(), destBuffer.Offset(), - sourceBuffer.Resource(), sourceBuffer.Offset(), dataSize); - wrappedCmd->GetReal()->ResourceBarrier((UINT)finalBarriers.size(), finalBarriers.data()); - return true; -} - bool D3D12GpuBufferAllocator::D3D12GpuBufferResource::CreateCommittedResourceBuffer( ID3D12Device *device, const D3D12_HEAP_PROPERTIES &heapProperty, D3D12_RESOURCE_STATES initState, uint64_t size, bool allowUav, D3D12GpuBufferResource **bufferResource) @@ -1102,7 +982,7 @@ D3D12GpuBufferAllocator::D3D12GpuBufferResource::D3D12GpuBufferResource(ID3D12Re bool D3D12GpuBufferAllocator::D3D12GpuBufferPool::Alloc(WrappedID3D12Device *wrappedDevice, D3D12GpuBufferHeapMemoryFlag heapMem, uint64_t size, uint64_t alignment, - D3D12GpuBuffer &gpuBuffer) + D3D12GpuBuffer **gpuBuffer) { if(heapMem == D3D12GpuBufferHeapMemoryFlag::Default) { @@ -1116,8 +996,8 @@ bool D3D12GpuBufferAllocator::D3D12GpuBufferPool::Alloc(WrappedID3D12Device *wra { if(bufferRes->SubAlloc(size, alignment, gpuAddress)) { - gpuBuffer = D3D12GpuBuffer(m_bufferPoolHeapType, D3D12GpuBufferHeapMemoryFlag::Default, - size, alignment, gpuAddress, bufferRes->Resource()); + *gpuBuffer = new D3D12GpuBuffer(m_bufferPoolHeapType, D3D12GpuBufferHeapMemoryFlag::Default, + size, alignment, gpuAddress, bufferRes->Resource()); return true; } } @@ -1129,8 +1009,8 @@ bool D3D12GpuBufferAllocator::D3D12GpuBufferPool::Alloc(WrappedID3D12Device *wra m_bufferResourceList.push_back(newBufferResource); if(newBufferResource->SubAlloc(size, alignment, gpuAddress)) { - gpuBuffer = D3D12GpuBuffer(m_bufferPoolHeapType, D3D12GpuBufferHeapMemoryFlag::Default, - size, alignment, gpuAddress, newBufferResource->Resource()); + *gpuBuffer = new D3D12GpuBuffer(m_bufferPoolHeapType, D3D12GpuBufferHeapMemoryFlag::Default, + size, alignment, gpuAddress, newBufferResource->Resource()); return true; } } @@ -1142,10 +1022,10 @@ bool D3D12GpuBufferAllocator::D3D12GpuBufferPool::Alloc(WrappedID3D12Device *wra &newBufferResource)) { m_bufferResourceList.push_back(newBufferResource); - gpuBuffer = D3D12GpuBuffer(m_bufferPoolHeapType, D3D12GpuBufferHeapMemoryFlag::Dedicated, - size, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, - newBufferResource->Resource()->GetGPUVirtualAddress(), - newBufferResource->Resource()); + *gpuBuffer = new D3D12GpuBuffer(m_bufferPoolHeapType, D3D12GpuBufferHeapMemoryFlag::Dedicated, + size, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, + newBufferResource->Resource()->GetGPUVirtualAddress(), + newBufferResource->Resource()); return true; } } @@ -1154,40 +1034,45 @@ bool D3D12GpuBufferAllocator::D3D12GpuBufferPool::Alloc(WrappedID3D12Device *wra return false; } -bool D3D12GpuBufferAllocator::D3D12GpuBufferPool::Free(const D3D12GpuBuffer &gpuBuffer) +void D3D12GpuBufferAllocator::D3D12GpuBufferPool::Free(const D3D12GpuBuffer &gpuBuffer) { - if(gpuBuffer != D3D12GpuBuffer()) + if(gpuBuffer.Resource() == NULL) { - for(D3D12GpuBufferResource *bufferRes : m_bufferResourceList) + RDCERR("Freeing invalid GPU buffer"); + return; + } + + for(D3D12GpuBufferResource *bufferRes : m_bufferResourceList) + { + if(bufferRes->Resource() == gpuBuffer.Resource()) { - if(bufferRes->Resource() == gpuBuffer.Resource()) + D3D12GpuBufferHeapMemoryFlag heapMem = gpuBuffer.HeapMemory(); + if(heapMem == D3D12GpuBufferHeapMemoryFlag::Default) { - D3D12GpuBufferHeapMemoryFlag heapMem = gpuBuffer.HeapMemory(); - if(heapMem == D3D12GpuBufferHeapMemoryFlag::Default) + if(bufferRes->SubAllocationInRange(gpuBuffer.Address())) { - if(bufferRes->SubAllocationInRange(gpuBuffer.Address())) + if(!bufferRes->Free(gpuBuffer.Address())) { - return bufferRes->Free(gpuBuffer.Address()); + RDCERR("Invalid address when freeing buffer"); } + return; } - else if(heapMem == D3D12GpuBufferHeapMemoryFlag::Dedicated) + } + else if(heapMem == D3D12GpuBufferHeapMemoryFlag::Dedicated) + { + if(D3D12GpuBufferResource::ReleaseGpuBufferResource(bufferRes)) { - if(D3D12GpuBufferResource::ReleaseGpuBufferResource(bufferRes)) - { - m_bufferResourceList.removeOne(bufferRes); - return true; - } + m_bufferResourceList.removeOne(bufferRes); + return; } } } } - - return false; } bool D3D12GpuBufferAllocator::Alloc(D3D12GpuBufferHeapType heapType, D3D12GpuBufferHeapMemoryFlag heapMem, uint64_t size, - uint64_t alignment, D3D12GpuBuffer &gpuBuffer) + uint64_t alignment, D3D12GpuBuffer **gpuBuffer) { SCOPED_LOCK(m_bufferAllocLock); bool success = false; @@ -1219,16 +1104,17 @@ bool D3D12GpuBufferAllocator::Alloc(D3D12GpuBufferHeapType heapType, return success; } -bool D3D12GpuBufferAllocator::Release(const D3D12GpuBuffer &gpuBuffer) +void D3D12GpuBufferAllocator::Release(const D3D12GpuBuffer &gpuBuffer) { SCOPED_LOCK(m_bufferAllocLock); size_t heap = (size_t)gpuBuffer.HeapType(); if(gpuBuffer.HeapType() < D3D12GpuBufferHeapType::Count && m_bufferPoolList[heap] != NULL) { - return m_bufferPoolList[heap]->Free(gpuBuffer); + m_bufferPoolList[heap]->Free(gpuBuffer); + return; } - return false; + RDCERR("Couldn't identify buffer heap type %zu", heap); } bool D3D12GpuBufferAllocator::CreateBufferResource(WrappedID3D12Device *wrappedDevice, @@ -1718,14 +1604,18 @@ void GPUAddressRangeTracker::GetResIDFromAddrAllowOutOfBounds(D3D12_GPU_VIRTUAL_ offs = addr - range.start; } -bool D3D12GpuBuffer::Release() +void D3D12GpuBuffer::AddRef() { - bool success = D3D12GpuBufferAllocator::Inst()->Release(*this); - - if(success) - { - *this = {}; - } - - return success; + InterlockedIncrement(&m_RefCount); +} + +void D3D12GpuBuffer::Release() +{ + unsigned int ret = InterlockedDecrement(&m_RefCount); + if(ret == 0) + { + D3D12GpuBufferAllocator::Inst()->Release(*this); + + delete this; + } } diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index fe54cf289..5f3736501 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -576,17 +576,6 @@ class D3D12GpuBufferAllocator; struct D3D12GpuBuffer { - D3D12GpuBuffer() - : m_alignedAddress(0), - m_offset(0), - m_alignment(0), - m_addressContentSize(0), - m_heapType(D3D12GpuBufferHeapType::UnInitialized), - m_heapMemory(D3D12GpuBufferHeapMemoryFlag::UnInitialized), - m_resource(NULL) - { - } - D3D12GpuBuffer(D3D12GpuBufferHeapType heapType, D3D12GpuBufferHeapMemoryFlag heapMemory, uint64_t size, uint64_t alignment, D3D12_GPU_VIRTUAL_ADDRESS alignedAddress, ID3D12Resource *resource) @@ -598,12 +587,18 @@ struct D3D12GpuBuffer m_heapMemory(heapMemory), m_resource(resource) { + m_RefCount = 1; if(m_resource) { m_offset = alignedAddress - m_resource->GetGPUVirtualAddress(); } } + // disable copying, these should be passed via pointer so the refcounting works as expected + D3D12GpuBuffer(const D3D12GpuBuffer &) = delete; + D3D12GpuBuffer(D3D12GpuBuffer &&) = delete; + D3D12GpuBuffer &operator=(const D3D12GpuBuffer &) = delete; + D3D12GpuBufferHeapType HeapType() const { return m_heapType; } D3D12_HEAP_TYPE GetD3D12HeapType() const { @@ -640,7 +635,8 @@ struct D3D12GpuBuffer uint64_t Size() const { return m_addressContentSize; } D3D12_GPU_VIRTUAL_ADDRESS Address() const { return m_alignedAddress; } uint64_t Alignment() const { return m_alignment; } - bool Release(); + void AddRef(); + void Release(); D3D12GpuBufferHeapMemoryFlag HeapMemory() const { return m_heapMemory; } void *Map(D3D12_RANGE *pReadRange = NULL) @@ -653,6 +649,7 @@ struct D3D12GpuBuffer } void Unmap(D3D12_RANGE *pWrittenRange = NULL) { m_resource->Unmap(0, pWrittenRange); } private: + unsigned int m_RefCount; D3D12_GPU_VIRTUAL_ADDRESS m_alignedAddress; uint64_t m_offset; uint64_t m_alignment; @@ -869,15 +866,15 @@ public: uint64_t dataSize); bool Alloc(D3D12GpuBufferHeapType heapType, D3D12GpuBufferHeapMemoryFlag heapMem, uint64_t size, - D3D12GpuBuffer &gpuBuffer) + D3D12GpuBuffer **gpuBuffer) { return Alloc(heapType, heapMem, size, 0, gpuBuffer); } bool Alloc(D3D12GpuBufferHeapType heapType, D3D12GpuBufferHeapMemoryFlag heapMem, uint64_t size, - uint64_t alignment, D3D12GpuBuffer &gpuBuffer); + uint64_t alignment, D3D12GpuBuffer **gpuBuffer); - bool Release(const D3D12GpuBuffer &gpuBuffer); + void Release(const D3D12GpuBuffer &gpuBuffer); uint64_t GetAllocatedMemorySize() const { return m_totalAllocatedMemoryInUse; } ~D3D12GpuBufferAllocator() @@ -1005,9 +1002,9 @@ private: } bool Alloc(WrappedID3D12Device *wrappedDevice, D3D12GpuBufferHeapMemoryFlag heapMem, - uint64_t size, uint64_t alignment, D3D12GpuBuffer &gpuBuffer); + uint64_t size, uint64_t alignment, D3D12GpuBuffer **gpuBuffer); - bool Free(const D3D12GpuBuffer &gpuBuffer); + void Free(const D3D12GpuBuffer &gpuBuffer); static constexpr uint64_t kDefaultWithUavSizeBufferInitSize = 1000ull * 8u; static constexpr uint64_t kAccStructBufferPoolInitSize = 1000ull * 256u; @@ -1080,10 +1077,10 @@ public: void ResizeSerialisationBuffer(UINT64 size); // buffer in UAV state for emitting AS queries to, CPU accessible/mappable - D3D12GpuBuffer ASQueryBuffer; + D3D12GpuBuffer *ASQueryBuffer = NULL; // temp buffer for AS serialise copies - D3D12GpuBuffer ASSerialiseBuffer; + D3D12GpuBuffer *ASSerialiseBuffer = NULL; private: void InitReplayBlasPatchingResources();