From ac53611f07cabe2d498168e191a6766d987354b4 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 19 Oct 2016 18:52:57 +0200 Subject: [PATCH] If any list executed contains an ExecuteIndirect, ref all buffers * Since buffers can be referenced indirectly on the GPU by their GPU address, there's no feasible way to know if the buffer is actually used or not. If an ExecuteIndirect is seen at all we just have to pessimistically include all buffers. * Generally textures take up the bulk of VRAM usage, so this likely won't be too bad. --- renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp | 3 +++ renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp | 3 +++ renderdoc/driver/d3d12/d3d12_device.cpp | 5 +++++ renderdoc/driver/d3d12/d3d12_manager.h | 7 ++++++- renderdoc/driver/d3d12/d3d12_resources.cpp | 8 +++++++- renderdoc/driver/d3d12/d3d12_resources.h | 2 ++ 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 456c24ba5..2198c6846 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -263,6 +263,7 @@ HRESULT WrappedID3D12GraphicsCommandList::Reset(ID3D12CommandAllocator *pAllocat // reset for new recording m_ListRecord->DeleteChunks(); + m_ListRecord->ContainsExecuteIndirect = false; // free parents m_ListRecord->FreeParents(GetResourceManager()); @@ -2843,6 +2844,8 @@ void WrappedID3D12GraphicsCommandList::ExecuteIndirect(ID3D12CommandSignature *p m_ListRecord->AddChunk(scope.Get()); + m_ListRecord->ContainsExecuteIndirect = true; + m_ListRecord->MarkResourceFrameReferenced(GetResID(pCommandSignature), eFrameRef_Read); m_ListRecord->MarkResourceFrameReferenced(GetResID(pArgumentBuffer), eFrameRef_Read); m_ListRecord->MarkResourceFrameReferenced(GetResID(pCountBuffer), eFrameRef_Read); diff --git a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp index 5fb44fd8c..c011e54fc 100644 --- a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp @@ -340,6 +340,9 @@ void STDMETHODCALLTYPE WrappedID3D12CommandQueue::ExecuteCommandLists( { D3D12ResourceRecord *record = GetRecord(ppCommandLists[i]); + if(record->ContainsExecuteIndirect) + m_QueueRecord->ContainsExecuteIndirect = true; + m_pDevice->ApplyBarriers(record->bakedCommands->cmdInfo->barriers); // need to lock the whole section of code, not just the check on diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index fe07eca11..381cdea2f 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -1386,6 +1386,11 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd) Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser( m_FrameCounter, &m_InitParams, jpgbuf, len, thwidth, thheight); + if(m_Queue->GetResourceRecord()->ContainsExecuteIndirect) + { + WrappedID3D12Resource::RefBuffers(GetResourceManager()); + } + { CACHE_THREAD_SERIALISER(); diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index b64bc2a35..7958f88b6 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -351,7 +351,11 @@ struct D3D12ResourceRecord : public ResourceRecord }; D3D12ResourceRecord(ResourceId id) - : ResourceRecord(id, true), type(Resource_Unknown), cmdInfo(NULL), bakedCommands(NULL) + : ResourceRecord(id, true), + type(Resource_Unknown), + ContainsExecuteIndirect(false), + cmdInfo(NULL), + bakedCommands(NULL) { } ~D3D12ResourceRecord() {} @@ -384,6 +388,7 @@ struct D3D12ResourceRecord : public ResourceRecord } D3D12ResourceType type; + bool ContainsExecuteIndirect; D3D12ResourceRecord *bakedCommands; CmdListRecordingInfo *cmdInfo; diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index ae937ebdc..e1933ae76 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -29,7 +29,6 @@ std::vector WrappedID3D12Resource::m_Addresses; std::map WrappedID3D12Resource::m_List; - std::map WrappedID3D12PipelineState::m_Shaders; @@ -373,6 +372,13 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12Resource::WriteToSubresource(UINT DstSubr return m_pReal->WriteToSubresource(DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch); } +void WrappedID3D12Resource::RefBuffers(D3D12ResourceManager *rm) +{ + // only buffers go into m_Addresses + for(size_t i = 0; i < m_Addresses.size(); i++) + rm->MarkResourceFrameReferenced(m_Addresses[i].id, eFrameRef_Read); +} + WrappedID3D12DescriptorHeap::WrappedID3D12DescriptorHeap(ID3D12DescriptorHeap *real, WrappedID3D12Device *device, const D3D12_DESCRIPTOR_HEAP_DESC &desc) diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 8217a60de..a6484ec55 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -645,6 +645,8 @@ public: static std::map m_List; + static void RefBuffers(D3D12ResourceManager *rm); + static void GetResIDFromAddr(D3D12_GPU_VIRTUAL_ADDRESS addr, ResourceId &id, UINT64 &offs) { GPUAddressRange::GetResIDFromAddr(m_Addresses, addr, id, offs);