diff --git a/renderdoc/driver/d3d12/d3d12_command_list.h b/renderdoc/driver/d3d12/d3d12_command_list.h index 0e5d07515..3a5f2d7ec 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list.h +++ b/renderdoc/driver/d3d12/d3d12_command_list.h @@ -89,7 +89,7 @@ class WrappedID3D12GraphicsCommandList : public RefCounter12DeleteChunks(); + // free parents + m_ListRecord->FreeParents(GetResourceManager()); + SCOPED_SERIALISE_CONTEXT(RESET_LIST); Serialise_Reset(pAllocator, pInitialState); m_ListRecord->AddChunk(scope.Get()); + + // add allocator and initial state (if there is one) as parents + m_ListRecord->AddParent(GetRecord(pAllocator)); + if(pInitialState) + m_ListRecord->AddParent(GetRecord(pInitialState)); } return m_pReal->Reset(Unwrap(pAllocator), Unwrap(pInitialState)); diff --git a/renderdoc/driver/d3d12/d3d12_command_queue.h b/renderdoc/driver/d3d12/d3d12_command_queue.h index 58ad15dc4..31f20c51d 100644 --- a/renderdoc/driver/d3d12/d3d12_command_queue.h +++ b/renderdoc/driver/d3d12/d3d12_command_queue.h @@ -76,7 +76,7 @@ class WrappedID3D12CommandQueue : public ID3D12CommandQueue, D3D12ResourceRecord *m_QueueRecord; Serialiser *m_pSerialiser; - LogState m_State; + LogState &m_State; DummyID3D12DebugCommandQueue m_DummyDebug; @@ -86,12 +86,13 @@ public: ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12CommandQueue); WrappedID3D12CommandQueue(ID3D12CommandQueue *real, WrappedID3D12Device *device, - Serialiser *serialiser); + Serialiser *serialiser, LogState &state); virtual ~WrappedID3D12CommandQueue(); Serialiser *GetSerialiser() { return m_pSerialiser; } ResourceId GetResourceID() { return m_ResourceID; } ID3D12CommandQueue *GetReal() { return m_pReal; } + D3D12ResourceRecord *GetRecord() { return m_QueueRecord; } WrappedID3D12Device *GetWrappedDevice() { return m_pDevice; } // interface for DXGI virtual IUnknown *GetRealIUnknown() { return GetReal(); } @@ -226,4 +227,10 @@ public: }; template <> -ID3D12CommandQueue *Unwrap(ID3D12CommandQueue *obj); \ No newline at end of file +ID3D12CommandQueue *Unwrap(ID3D12CommandQueue *obj); + +template <> +ResourceId GetResID(ID3D12CommandQueue *obj); + +template <> +D3D12ResourceRecord *GetRecord(ID3D12CommandQueue *obj); \ No newline at end of file diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 22c1950a0..f50b2ff19 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -73,6 +73,24 @@ ID3D12CommandQueue *Unwrap(ID3D12CommandQueue *obj) return ((WrappedID3D12CommandQueue *)obj)->GetReal(); } +template <> +ResourceId GetResID(ID3D12CommandQueue *obj) +{ + if(obj == NULL) + return ResourceId(); + + return ((WrappedID3D12CommandQueue *)obj)->GetResourceID(); +} + +template <> +D3D12ResourceRecord *GetRecord(ID3D12CommandQueue *obj) +{ + if(obj == NULL) + return NULL; + + return ((WrappedID3D12CommandQueue *)obj)->GetRecord(); +} + ULONG STDMETHODCALLTYPE DummyID3D12DebugCommandQueue::AddRef() { m_pQueue->AddRef(); @@ -99,8 +117,8 @@ ULONG STDMETHODCALLTYPE DummyID3D12DebugCommandList::Release() WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real, WrappedID3D12Device *device, - Serialiser *serialiser) - : RefCounter12(real), m_pDevice(device) + Serialiser *serialiser, LogState &state) + : RefCounter12(real), m_pDevice(device), m_State(state) { if(RenderDoc::Inst().GetCrashHandler()) RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, @@ -110,13 +128,11 @@ WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real, if(RenderDoc::Inst().IsReplayApp()) { - m_State = READING; m_pSerialiser = serialiser; } else { m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, true); - m_State = WRITING_IDLE; m_pSerialiser->SetDebugText(true); } @@ -134,8 +150,6 @@ WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real, m_QueueRecord->DataInSerialiser = false; m_QueueRecord->SpecialResource = true; m_QueueRecord->Length = 0; - m_QueueRecord->NumSubResources = 0; - m_QueueRecord->SubResources = NULL; m_QueueRecord->ignoreSerialise = true; } @@ -189,8 +203,9 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12CommandQueue::QueryInterface(REFIID riid, WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12GraphicsCommandList *real, WrappedID3D12Device *device, - Serialiser *serialiser) - : RefCounter12(real), m_pDevice(device) + Serialiser *serialiser, + LogState &state) + : RefCounter12(real), m_pDevice(device), m_State(state) { if(RenderDoc::Inst().GetCrashHandler()) RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion( @@ -200,13 +215,11 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic if(RenderDoc::Inst().IsReplayApp()) { - m_State = READING; m_pSerialiser = serialiser; } else { m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, true); - m_State = WRITING_IDLE; m_pSerialiser->SetDebugText(true); } @@ -224,8 +237,6 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic m_ListRecord->DataInSerialiser = false; m_ListRecord->SpecialResource = true; m_ListRecord->Length = 0; - m_ListRecord->NumSubResources = 0; - m_ListRecord->SubResources = NULL; m_ListRecord->ignoreSerialise = true; } diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 05225ae29..e4102bfc4 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -185,11 +185,15 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; + m_HeaderChunk = NULL; + if(RenderDoc::Inst().IsReplayApp()) { m_State = READING; m_pSerialiser = NULL; + m_FrameCaptureRecord = NULL; + ResourceIDGen::SetReplayResourceIDs(); } else @@ -212,14 +216,19 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara m_DeviceRecord = NULL; + m_Queue = NULL; + if(!RenderDoc::Inst().IsReplayApp()) { m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_ResourceID); m_DeviceRecord->DataInSerialiser = false; m_DeviceRecord->SpecialResource = true; m_DeviceRecord->Length = 0; - m_DeviceRecord->NumSubResources = 0; - m_DeviceRecord->SubResources = NULL; + + m_FrameCaptureRecord = GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); + m_FrameCaptureRecord->DataInSerialiser = false; + m_FrameCaptureRecord->Length = 0; + m_FrameCaptureRecord->SpecialResource = true; RenderDoc::Inst().AddDeviceFrameCapturer((ID3D12Device *)this, this); } @@ -541,8 +550,6 @@ IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap, record->DataInSerialiser = false; record->SpecialResource = true; record->Length = 0; - record->NumSubResources = 0; - record->SubResources = NULL; SCOPED_LOCK(m_D3DLock); @@ -734,7 +741,7 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInte if(!activeWindow) return S_OK; - RenderDoc::Inst().SetCurrentDriver(RDC_D3D11); + RenderDoc::Inst().SetCurrentDriver(RDC_D3D12); // kill any current capture that isn't application defined if(m_State == WRITING_CAPFRAME && !m_AppControlledCapture) @@ -750,10 +757,117 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInte return S_OK; } +bool WrappedID3D12Device::Serialise_BeginCaptureFrame(bool applyInitialState) +{ + if(m_State < WRITING && !applyInitialState) + { + m_pSerialiser->SkipCurrentChunk(); + return true; + } + + // TODO save initial resources + + if(applyInitialState) + { + // apply initial resources + } + + return true; +} + +void WrappedID3D12Device::Serialise_CaptureScope(uint64_t offset) +{ + uint32_t FrameNumber = m_FrameCounter; + m_pSerialiser->Serialise("FrameNumber", FrameNumber); + + if(m_State >= WRITING) + { + GetResourceManager()->Serialise_InitialContentsNeeded(); + } + else + { + m_FrameRecord.frameInfo.fileOffset = offset; + m_FrameRecord.frameInfo.firstEvent = 1; + m_FrameRecord.frameInfo.frameNumber = FrameNumber; + m_FrameRecord.frameInfo.immContextId = ResourceId(); + RDCEraseEl(m_FrameRecord.frameInfo.stats); + + GetResourceManager()->CreateInitialContents(); + } +} + +void WrappedID3D12Device::EndCaptureFrame(ID3D12Resource *presentImage) +{ + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); + + SERIALISE_ELEMENT(ResourceId, bbid, GetResID(presentImage)); + + bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; + m_pSerialiser->Serialise("HasCallstack", HasCallstack); + + if(HasCallstack) + { + Callstack::Stackwalk *call = Callstack::Collect(); + + RDCASSERT(call->NumLevels() < 0xff); + + size_t numLevels = call->NumLevels(); + uint64_t *stack = (uint64_t *)call->GetAddrs(); + + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + + delete call; + } + + m_FrameCaptureRecord->AddChunk(scope.Get()); +} + void WrappedID3D12Device::StartFrameCapture(void *dev, void *wnd) { if(m_State != WRITING_IDLE) return; + + RenderDoc::Inst().SetCurrentDriver(RDC_D3D12); + + m_AppControlledCapture = true; + + m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); + + FetchFrameInfo frame; + frame.frameNumber = m_FrameCounter + 1; + frame.captureTime = Timing::GetUnixTimestamp(); + RDCEraseEl(frame.stats); + m_CapturedFrames.push_back(frame); + + GetResourceManager()->ClearReferencedResources(); + + GetResourceManager()->MarkResourceFrameReferenced(m_ResourceID, eFrameRef_Read); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_Queue), eFrameRef_Read); + + // need to do all this atomically so that no other commands + // will check to see if they need to markdirty or markpendingdirty + // and go into the frame record. + { + SCOPED_LOCK(m_CapTransitionLock); + GetResourceManager()->PrepareInitialContents(); + + RDCDEBUG("Attempting capture"); + m_FrameCaptureRecord->DeleteChunks(); + + { + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); + + Serialise_BeginCaptureFrame(false); + + // need to hold onto this as it must come right after the capture chunk, + // before any command buffers + m_HeaderChunk = scope.Get(); + } + + m_State = WRITING_CAPFRAME; + } + + RDCLOG("Starting capture, frame %u", m_FrameCounter); } bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd) @@ -761,8 +875,173 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd) if(m_State != WRITING_CAPFRAME) return true; - return false; + WrappedIDXGISwapChain3 *swap = NULL; + + if(wnd) + { + for(auto it = m_SwapChains.begin(); it != m_SwapChains.end(); ++it) + { + DXGI_SWAP_CHAIN_DESC swapDesc; + it->first->GetDesc(&swapDesc); + + if(swapDesc.OutputWindow == wnd) + { + swap = it->first; + break; + } + } + + if(swap == NULL) + { + RDCERR("Output window %p provided for frame capture corresponds with no known swap chain", wnd); + return false; + } + } + + RDCLOG("Finished capture, Frame %u", m_FrameCounter); + + // TODO either get the swapchain associated with this window, or the last swapchain + // to be presented. + // Get the last buffer presented on that swapchain as backbuffer + ID3D12Resource *backbuffer = NULL; + + // transition back to IDLE atomically + { + SCOPED_LOCK(m_CapTransitionLock); + EndCaptureFrame(backbuffer); + + m_State = WRITING_IDLE; + + // TOD wait for idle + + // TODO free coherent map capture ref-data + } + + byte *thpixels = NULL; + uint32_t thwidth = 0; + uint32_t thheight = 0; + + const uint32_t maxSize = 1024; + + // gather backbuffer screenshot + (void)maxSize; + + byte *jpgbuf = NULL; + int len = thwidth * thheight; + + if(wnd && thpixels) + { + jpgbuf = new byte[len]; + + jpge::params p; + + p.m_quality = 40; + + bool success = + jpge::compress_image_to_jpeg_file_in_memory(jpgbuf, len, thwidth, thheight, 3, thpixels, p); + + if(!success) + { + RDCERR("Failed to compress to jpg"); + SAFE_DELETE_ARRAY(jpgbuf); + thwidth = 0; + thheight = 0; + } + } + + Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser( + m_FrameCounter, &m_InitParams, jpgbuf, len, thwidth, thheight); + + { + SCOPED_SERIALISE_CONTEXT(DEVICE_INIT); + + m_pFileSerialiser->Insert(scope.Get(true)); + } + + RDCDEBUG("Inserting Resource Serialisers"); + + GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser); + + GetResourceManager()->InsertInitialContentsChunks(m_pFileSerialiser); + + RDCDEBUG("Creating Capture Scope"); + + { + SCOPED_SERIALISE_CONTEXT(CAPTURE_SCOPE); + + Serialise_CaptureScope(0); + + m_pFileSerialiser->Insert(scope.Get(true)); + + m_pFileSerialiser->Insert(m_HeaderChunk); + } + + // don't need to lock access to m_CmdListRecords as we are no longer + // in capframe (the transition is thread-protected) so nothing will be + // pushed to the vector + + { + RDCDEBUG("Flushing %u command buffer records to file serialiser", + (uint32_t)m_CmdListRecords.size()); + + map recordlist; + + // ensure all command buffer records within the frame evne if recorded before, but + // otherwise order must be preserved (vs. queue submits and desc set updates) + for(size_t i = 0; i < m_CmdListRecords.size(); i++) + { + /* + SCOPED_SERIALISE_CONTEXT(BEGIN_CMD_LIST); + Serialise_BeginCmdList(m_CmdListRecords[i]->GetResourceID()); + Chunk *beginCmdList = scope.Get(); + + */ + + m_CmdListRecords[i]->Insert(recordlist); + + RDCDEBUG("Adding %u chunks to file serialiser from command buffer %llu", + (uint32_t)recordlist.size(), m_CmdListRecords[i]->GetResourceID()); + } + + GetRecord(m_Queue)->Insert(recordlist); + + m_FrameCaptureRecord->Insert(recordlist); + + RDCDEBUG("Flushing %u chunks to file serialiser from context record", + (uint32_t)recordlist.size()); + + for(auto it = recordlist.begin(); it != recordlist.end(); ++it) + m_pFileSerialiser->Insert(it->second); + + RDCDEBUG("Done"); + } + + m_pFileSerialiser->FlushToDisk(); + + RenderDoc::Inst().SuccessfullyWrittenLog(); + + SAFE_DELETE(m_pFileSerialiser); + SAFE_DELETE(m_HeaderChunk); + + m_State = WRITING_IDLE; + + // delete cmd buffers now - had to keep them alive until after serialiser flush. + for(size_t i = 0; i < m_CmdListRecords.size(); i++) + m_CmdListRecords[i]->Delete(GetResourceManager()); + + m_CmdListRecords.clear(); + + GetResourceManager()->MarkUnwrittenResources(); + + GetResourceManager()->ClearReferencedResources(); + + GetResourceManager()->FreeInitialContents(); + + GetResourceManager()->FlushPendingDirty(); + + return true; } + bool WrappedID3D12Device::Serialise_ReleaseResource(ID3D12DeviceChild *res) { return true; @@ -868,3 +1147,11 @@ void WrappedID3D12Device::SetResourceName(ID3D12DeviceChild *res, const char *na } } } + +// need to create this dummy here so that we can record D3D12. +ReplayCreateStatus D3D12_CreateReplayDevice(const char *logfile, IReplayDriver **driver) +{ + return eReplayCreate_APIUnsupported; +} + +static DriverRegistration D3D12DriverRegistration(RDC_D3D12, "D3D12", &D3D12_CreateReplayDevice); diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 1c9004f6b..92bd13097 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -32,6 +32,7 @@ #include "common/wrapped_pool.h" #include "core/core.h" #include "driver/dxgi/dxgi_wrapped.h" +#include "replay/replay_driver.h" #include "d3d12_common.h" #include "d3d12_manager.h" @@ -214,6 +215,8 @@ class WrappedID3D12Device : public IFrameCapturer, public ID3DDevice, public ID3 private: ID3D12Device *m_pDevice; + ID3D12CommandQueue *m_Queue; + D3D12ResourceManager *m_ResourceManager; DummyID3D12InfoQueue m_DummyInfoQueue; DummyID3D12DebugDevice m_DummyDebug; @@ -226,15 +229,18 @@ private: uint32_t m_FrameCounter; vector m_CapturedFrames; + FetchFrameRecord m_FrameRecord; PerformanceTimer m_FrameTimer; vector m_FrameTimes; double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; Serialiser *m_pSerialiser; - LogState m_State; bool m_AppControlledCapture; + Threading::CriticalSection m_CapTransitionLock; + LogState m_State; + D3D12InitParams m_InitParams; ID3D12InfoQueue *m_pInfoQueue; @@ -242,6 +248,18 @@ private: // protects wrapped resource creation and serialiser access Threading::CriticalSection m_D3DLock; + D3D12ResourceRecord *m_FrameCaptureRecord; + Chunk *m_HeaderChunk; + + // we record the command buffer records so we can insert them + // individually, that means even if they were recorded locklessly + // in parallel, on replay they are disjoint and it makes things + // much easier to process (we will enforce/display ordering + // by queue submit order anyway, so it's OK to lose the record + // order). + Threading::CriticalSection m_CmdListRecordsLock; + vector m_CmdListRecords; + ResourceId m_ResourceID; D3D12ResourceRecord *m_DeviceRecord; @@ -249,6 +267,10 @@ private: UINT m_DescriptorIncrements[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; + void Serialise_CaptureScope(uint64_t offset); + bool Serialise_BeginCaptureFrame(bool applyInitialState); + void EndCaptureFrame(ID3D12Resource *presentImage); + public: static const int AllocPoolCount = 4; ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Device, AllocPoolCount); diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index 8b3f40ef4..78f6a62ed 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -46,7 +46,7 @@ bool WrappedID3D12Device::Serialise_CreateCommandQueue(const D3D12_COMMAND_QUEUE } else { - ret = new WrappedID3D12CommandQueue(ret, this, m_pSerialiser); + ret = new WrappedID3D12CommandQueue(ret, this, m_pSerialiser, m_State); GetResourceManager()->AddLiveResource(Queue, ret); } @@ -71,7 +71,8 @@ HRESULT WrappedID3D12Device::CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC * { SCOPED_LOCK(m_D3DLock); - WrappedID3D12CommandQueue *wrapped = new WrappedID3D12CommandQueue(real, this, m_pSerialiser); + WrappedID3D12CommandQueue *wrapped = + new WrappedID3D12CommandQueue(real, this, m_pSerialiser, m_State); if(m_State >= WRITING) { @@ -81,6 +82,11 @@ HRESULT WrappedID3D12Device::CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC * m_DeviceRecord->AddChunk(scope.Get()); } + if(m_Queue != NULL) + RDCERR("Don't support multiple queues yet!"); + + m_Queue = (ID3D12CommandQueue *)wrapped; + *ppCommandQueue = (ID3D12CommandQueue *)wrapped; } @@ -138,7 +144,11 @@ HRESULT WrappedID3D12Device::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type SCOPED_SERIALISE_CONTEXT(CREATE_COMMAND_ALLOCATOR); Serialise_CreateCommandAllocator(type, riid, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); } *ppCommandAllocator = (ID3D12CommandAllocator *)wrapped; @@ -175,7 +185,7 @@ bool WrappedID3D12Device::Serialise_CreateCommandList(UINT nodeMask, D3D12_COMMA } else { - ret = new WrappedID3D12GraphicsCommandList(ret, this, m_pSerialiser); + ret = new WrappedID3D12GraphicsCommandList(ret, this, m_pSerialiser, m_State); GetResourceManager()->AddLiveResource(List, ret); } @@ -205,7 +215,7 @@ HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST SCOPED_LOCK(m_D3DLock); WrappedID3D12GraphicsCommandList *wrapped = - new WrappedID3D12GraphicsCommandList(real, this, m_pSerialiser); + new WrappedID3D12GraphicsCommandList(real, this, m_pSerialiser, m_State); if(m_State >= WRITING) { @@ -213,7 +223,14 @@ HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST Serialise_CreateCommandList(nodeMask, type, pCommandAllocator, pInitialState, riid, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = wrapped->GetResourceRecord(); + + // we can add these parents - if the list is reset later, it will free all of its parents + record->AddParent(GetRecord(pCommandAllocator)); + if(pInitialState) + record->AddParent(GetRecord(pInitialState)); + + record->AddChunk(scope.Get()); } *ppCommandList = (ID3D12GraphicsCommandList *)wrapped; @@ -276,7 +293,11 @@ HRESULT WrappedID3D12Device::CreateGraphicsPipelineState(const D3D12_GRAPHICS_PI SCOPED_SERIALISE_CONTEXT(CREATE_GRAPHICS_PIPE); Serialise_CreateGraphicsPipelineState(pDesc, riid, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); } *ppPipelineState = (ID3D12PipelineState *)wrapped; @@ -336,7 +357,11 @@ HRESULT WrappedID3D12Device::CreateComputePipelineState(const D3D12_COMPUTE_PIPE SCOPED_SERIALISE_CONTEXT(CREATE_COMPUTE_PIPE); Serialise_CreateComputePipelineState(pDesc, riid, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); } *ppPipelineState = (ID3D12PipelineState *)wrapped; @@ -396,7 +421,11 @@ HRESULT WrappedID3D12Device::CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DE SCOPED_SERIALISE_CONTEXT(CREATE_DESCRIPTOR_HEAP); Serialise_CreateDescriptorHeap(pDescriptorHeapDesc, riid, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); } *ppvHeap = (ID3D12DescriptorHeap *)wrapped; @@ -465,7 +494,11 @@ HRESULT WrappedID3D12Device::CreateRootSignature(UINT nodeMask, const void *pBlo Serialise_CreateRootSignature(nodeMask, pBlobWithRootSignature, blobLengthInBytes, riid, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); } *ppvRootSignature = (ID3D12RootSignature *)wrapped; @@ -602,7 +635,11 @@ HRESULT WrappedID3D12Device::CreateCommittedResource(const D3D12_HEAP_PROPERTIES InitialResourceState, pOptimizedClearValue, riidResource, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); } *ppvResource = (ID3D12Resource *)wrapped; @@ -686,7 +723,11 @@ HRESULT WrappedID3D12Device::CreateFence(UINT64 InitialValue, D3D12_FENCE_FLAGS SCOPED_SERIALISE_CONTEXT(CREATE_FENCE); Serialise_CreateFence(InitialValue, Flags, riid, (void **)&wrapped); - m_DeviceRecord->AddChunk(scope.Get()); + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); } *ppFence = (ID3D12Fence *)wrapped; diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index f45a93f29..6b7f3e6d6 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -50,6 +50,7 @@ public: TrackedResource() { m_ID = ResourceIDGen::GetNewUniqueID(); } ResourceId GetResourceID() { return m_ID; } D3D12ResourceRecord *GetResourceRecord() { return m_pRecord; } + void SetResourceRecord(D3D12ResourceRecord *record) { m_pRecord = record; } private: TrackedResource(const TrackedResource &); TrackedResource &operator=(const TrackedResource &);