diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 5bfb984e7..a212c93e4 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -1018,6 +1018,38 @@ void WrappedID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable( m_ListRecord->AddChunk(scope.Get()); m_ListRecord->MarkResourceFrameReferenced(GetResID(GetWrapped(BaseDescriptor)->nonsamp.heap), eFrameRef_Read); + + vector &ranges = + GetWrapped(m_CurRootSig)->sig.params[RootParameterIndex].ranges; + + D3D12Descriptor *base = GetWrapped(BaseDescriptor); + + UINT prevTableOffset = 0; + + for(size_t i = 0; i < ranges.size(); i++) + { + D3D12Descriptor *rangeStart = base; + + UINT offset = ranges[i].OffsetInDescriptorsFromTableStart; + + if(ranges[i].OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + offset = prevTableOffset; + + rangeStart += offset; + + UINT num = ranges[i].NumDescriptors; + + if(num == UINT_MAX) + { + // find out how many descriptors are left after rangeStart + num = base->samp.heap->GetNumDescriptors() - offset; + } + + for(UINT d = 0; d < num; d++) + m_ListRecord->cmdInfo->boundDescs.insert(rangeStart + d); + + prevTableOffset = offset + num; + } } } diff --git a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp index 5ca26fb28..59f47ca0b 100644 --- a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp @@ -336,6 +336,45 @@ void STDMETHODCALLTYPE WrappedID3D12CommandQueue::ExecuteCommandLists( if(capframe) { + // for each bound descriptor table, mark it referenced as well as all resources currently + // bound to it + for(auto it = record->bakedCommands->cmdInfo->boundDescs.begin(); + it != record->bakedCommands->cmdInfo->boundDescs.end(); ++it) + { + D3D12Descriptor &desc = **it; + + switch(desc.GetType()) + { + case D3D12Descriptor::TypeUndefined: + case D3D12Descriptor::TypeSampler: + // nothing to do - no resource here + break; + case D3D12Descriptor::TypeCBV: + GetResourceManager()->MarkResourceFrameReferenced( + WrappedID3D12Resource::GetResIDFromAddr(desc.nonsamp.cbv.BufferLocation), + eFrameRef_Read); + break; + case D3D12Descriptor::TypeSRV: + GetResourceManager()->MarkResourceFrameReferenced(GetResID(desc.nonsamp.resource), + eFrameRef_Read); + break; + case D3D12Descriptor::TypeUAV: + GetResourceManager()->MarkResourceFrameReferenced(GetResID(desc.nonsamp.resource), + eFrameRef_Write); + GetResourceManager()->MarkResourceFrameReferenced( + GetResID(desc.nonsamp.uav.counterResource), eFrameRef_Write); + break; + case D3D12Descriptor::TypeRTV: + GetResourceManager()->MarkResourceFrameReferenced(GetResID(desc.nonsamp.resource), + eFrameRef_Write); + break; + case D3D12Descriptor::TypeDSV: + GetResourceManager()->MarkResourceFrameReferenced(GetResID(desc.nonsamp.resource), + eFrameRef_Write); + break; + } + } + // pull in frame refs from this baked command list record->bakedCommands->AddResourceReferences(GetResourceManager()); record->bakedCommands->AddReferencedIDs(refdIDs); diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index f25c258e2..01fe632ab 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -231,6 +231,11 @@ struct CmdListRecordingInfo // a list of all resources dirtied by this command list set dirtied; + // a list of descriptors that are bound at any point in this command list + // used to look up all the frame refs per-descriptor and apply them on queue + // submit with latest binding refs. + set boundDescs; + // bundles executed vector bundles; }; @@ -253,6 +258,7 @@ struct D3D12ResourceRecord : public ResourceRecord SwapChunks(bakedCommands); cmdInfo->barriers.swap(bakedCommands->cmdInfo->barriers); cmdInfo->dirtied.swap(bakedCommands->cmdInfo->dirtied); + cmdInfo->boundDescs.swap(bakedCommands->cmdInfo->boundDescs); cmdInfo->bundles.swap(bakedCommands->cmdInfo->bundles); } diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index b123c57cd..f7997b817 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -149,11 +149,12 @@ WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *r realGPUBase = real->GetGPUDescriptorHandleForHeapStart(); increment = device->GetUnwrappedDescriptorIncrement(desc.Type); + numDescriptors = desc.NumDescriptors; - descriptors = new D3D12Descriptor[desc.NumDescriptors]; + descriptors = new D3D12Descriptor[numDescriptors]; - RDCEraseMem(descriptors, sizeof(D3D12Descriptor) * desc.NumDescriptors); - for(UINT i = 0; i < desc.NumDescriptors; i++) + RDCEraseMem(descriptors, sizeof(D3D12Descriptor) * numDescriptors); + for(UINT i = 0; i < numDescriptors; i++) { // only need to set this once, it's aliased between samp and nonsamp descriptors[i].samp.heap = this; diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 2f14de847..1a89c59b1 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -312,6 +312,7 @@ class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12