diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index becebc962..29c8044cc 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -758,6 +758,12 @@ void WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context) { m_pImmediateContext->AddRef(); m_ResourceManager->AddLiveResource(ImmediateContext, m_pImmediateContext); + + AddResource(ImmediateContext, ResourceType::Queue, ""); + ResourceDescription &desc = GetReplay()->GetResourceDesc(ImmediateContext); + desc.autogeneratedName = false; + desc.name = "Immediate Context"; + desc.initialisationChunks.clear(); } break; } @@ -1152,6 +1158,8 @@ bool WrappedID3D11Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser, HRESULT hr = m_pDevice->CreateTexture2D(&BackbufferDescriptor, NULL, &fakeBB); + AddResource(SwapbufferID, ResourceType::SwapchainImage, "Swapchain Image"); + if(FAILED(hr)) { RDCERR("Failed to create fake back buffer, HRESULT: %s", ToStr(hr).c_str()); @@ -2043,6 +2051,36 @@ void WrappedID3D11Device::RemoveDeferredContext(WrappedID3D11DeviceContext *defc m_DeferredContexts.erase(defctx); } +void WrappedID3D11Device::AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix) +{ + ResourceDescription &descr = GetReplay()->GetResourceDesc(id); + + uint64_t num; + memcpy(&num, &id, sizeof(uint64_t)); + descr.name = defaultNamePrefix + (" " + ToStr(num)); + descr.autogeneratedName = true; + descr.type = type; + AddResourceCurChunk(descr); +} + +void WrappedID3D11Device::AddResourceCurChunk(ResourceDescription &descr) +{ + descr.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 1); +} + +void WrappedID3D11Device::AddResourceCurChunk(ResourceId id) +{ + AddResourceCurChunk(GetReplay()->GetResourceDesc(id)); +} + +void WrappedID3D11Device::DerivedResource(ID3D11DeviceChild *parent, ResourceId child) +{ + ResourceId parentId = GetResourceManager()->GetOriginalID(GetIDForResource(parent)); + + GetReplay()->GetResourceDesc(parentId).derivedResources.push_back(child); + GetReplay()->GetResourceDesc(child).parentResources.push_back(parentId); +} + template bool WrappedID3D11Device::Serialise_SetShaderDebugPath(SerialiserType &ser, ID3D11DeviceChild *pResource, const char *Path) @@ -2052,6 +2090,10 @@ bool WrappedID3D11Device::Serialise_SetShaderDebugPath(SerialiserType &ser, if(IsReplayingAndReading() && pResource) { + ResourceId resId = GetResourceManager()->GetOriginalID(GetIDForResource(pResource)); + + AddResourceCurChunk(resId); + auto it = WrappedShader::m_ShaderList.find(GetIDForResource(pResource)); if(it != WrappedShader::m_ShaderList.end()) @@ -2099,6 +2141,11 @@ bool WrappedID3D11Device::Serialise_SetResourceName(SerialiserType &ser, if(IsReplayingAndReading() && pResource) { + ResourceDescription &descr = GetReplay()->GetResourceDesc( + GetResourceManager()->GetOriginalID(GetIDForResource(pResource))); + descr.SetCustomName(Name); + AddResourceCurChunk(descr); + SetDebugName(pResource, Name); } diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index 85a611dbb..63d20c304 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -396,6 +396,11 @@ private: SDFile *m_StructuredFile = NULL; SDFile m_StoredStructuredData; + void AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix); + void DerivedResource(ID3D11DeviceChild *parent, ResourceId child); + void AddResourceCurChunk(ResourceDescription &descr); + void AddResourceCurChunk(ResourceId id); + vector m_DebugMessages; vector m_CapturedFrames; diff --git a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp index eb66922b9..938aad8ca 100644 --- a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp @@ -106,6 +106,8 @@ bool WrappedID3D11Device::Serialise_CreateBlendState1(SerialiserType &ser, GetResourceManager()->AddLiveResource(pState, ret); } } + + AddResource(pState, ResourceType::StateObject, "Blend State"); } return true; @@ -200,6 +202,8 @@ bool WrappedID3D11Device::Serialise_CreateRasterizerState1( GetResourceManager()->AddLiveResource(pState, ret); } } + + AddResource(pState, ResourceType::StateObject, "Rasterizer State"); } return true; diff --git a/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp index 988a39f39..727a148b4 100644 --- a/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp @@ -86,6 +86,15 @@ bool WrappedID3D11Device::Serialise_CreateTexture2D1(SerialiserType &ser, GetResourceManager()->AddLiveResource(pTexture, ret); } + const char *prefix = Descriptor.ArraySize > 1 ? "2D TextureArray" : "2D Texture"; + + if(Descriptor.BindFlags & D3D11_BIND_RENDER_TARGET) + prefix = "2D Render Target"; + else if(Descriptor.BindFlags & D3D11_BIND_DEPTH_STENCIL) + prefix = "2D Depth Target"; + + AddResource(pTexture, ResourceType::Texture, prefix); + // free the serialised buffers we stole in Serialise_CreateTextureData for(size_t i = 0; i < descs.size(); i++) FreeAlignedBuffer((byte *)descs[i].pSysMem); @@ -204,6 +213,15 @@ bool WrappedID3D11Device::Serialise_CreateTexture3D1(SerialiserType &ser, GetResourceManager()->AddLiveResource(pTexture, ret); } + const char *prefix = "3D Texture"; + + if(Descriptor.BindFlags & D3D11_BIND_RENDER_TARGET) + prefix = "3D Render Target"; + else if(Descriptor.BindFlags & D3D11_BIND_DEPTH_STENCIL) + prefix = "3D Depth Target"; + + AddResource(pTexture, ResourceType::Texture, prefix); + // free the serialised buffers we stole in Serialise_CreateTextureData for(size_t i = 0; i < descs.size(); i++) FreeAlignedBuffer((byte *)descs[i].pSysMem); @@ -335,6 +353,9 @@ bool WrappedID3D11Device::Serialise_CreateShaderResourceView1( GetResourceManager()->AddLiveResource(pView, ret); } + + AddResource(pView, ResourceType::View, "Shader Resource View"); + DerivedResource(pResource, pView); } return true; @@ -473,6 +494,9 @@ bool WrappedID3D11Device::Serialise_CreateRenderTargetView1(SerialiserType &ser, GetResourceManager()->AddLiveResource(pView, ret); } + + AddResource(pView, ResourceType::View, "Render Target View"); + DerivedResource(pResource, pView); } return true; @@ -580,6 +604,9 @@ bool WrappedID3D11Device::Serialise_CreateUnorderedAccessView1( GetResourceManager()->AddLiveResource(pView, ret); } + + AddResource(pView, ResourceType::View, "Unordered Access View"); + DerivedResource(pResource, pView); } return true; @@ -690,6 +717,8 @@ bool WrappedID3D11Device::Serialise_CreateRasterizerState2( GetResourceManager()->AddLiveResource(pState, ret); } } + + AddResource(pState, ResourceType::StateObject, "Rasterizer State"); } return true; @@ -774,6 +803,8 @@ bool WrappedID3D11Device::Serialise_CreateQuery1(SerialiserType &ser, GetResourceManager()->AddLiveResource(pQuery, ret); } + + AddResource(pQuery, ResourceType::Query, "Query"); } return true; diff --git a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp index 1ff5da35b..11f051014 100644 --- a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp @@ -119,6 +119,8 @@ bool WrappedID3D11Device::Serialise_CreateBuffer(SerialiserType &ser, const D3D1 GetResourceManager()->AddLiveResource(pBuffer, ret); } + AddResource(pBuffer, ResourceType::Buffer, "Buffer"); + if(Descriptor.Usage != D3D11_USAGE_IMMUTABLE) { ID3D11Buffer *stage = NULL; @@ -373,6 +375,15 @@ bool WrappedID3D11Device::Serialise_CreateTexture1D(SerialiserType &ser, GetResourceManager()->AddLiveResource(pTexture, ret); } + const char *prefix = Descriptor.ArraySize > 1 ? "1D TextureArray" : "1D Texture"; + + if(Descriptor.BindFlags & D3D11_BIND_RENDER_TARGET) + prefix = "1D Render Target"; + else if(Descriptor.BindFlags & D3D11_BIND_DEPTH_STENCIL) + prefix = "1D Depth Target"; + + AddResource(pTexture, ResourceType::Texture, prefix); + // free the serialised buffers we stole in Serialise_CreateTextureData for(size_t i = 0; i < descs.size(); i++) FreeAlignedBuffer((byte *)descs[i].pSysMem); @@ -481,6 +492,15 @@ bool WrappedID3D11Device::Serialise_CreateTexture2D(SerialiserType &ser, GetResourceManager()->AddLiveResource(pTexture, ret); } + const char *prefix = Descriptor.ArraySize > 1 ? "2D TextureArray" : "2D Texture"; + + if(Descriptor.BindFlags & D3D11_BIND_RENDER_TARGET) + prefix = "2D Render Target"; + else if(Descriptor.BindFlags & D3D11_BIND_DEPTH_STENCIL) + prefix = "2D Depth Target"; + + AddResource(pTexture, ResourceType::Texture, prefix); + // free the serialised buffers we stole in Serialise_CreateTextureData for(size_t i = 0; i < descs.size(); i++) FreeAlignedBuffer((byte *)descs[i].pSysMem); @@ -589,6 +609,15 @@ bool WrappedID3D11Device::Serialise_CreateTexture3D(SerialiserType &ser, GetResourceManager()->AddLiveResource(pTexture, ret); } + const char *prefix = "3D Texture"; + + if(Descriptor.BindFlags & D3D11_BIND_RENDER_TARGET) + prefix = "3D Render Target"; + else if(Descriptor.BindFlags & D3D11_BIND_DEPTH_STENCIL) + prefix = "3D Depth Target"; + + AddResource(pTexture, ResourceType::Texture, prefix); + // free the serialised buffers we stole in Serialise_CreateTextureData for(size_t i = 0; i < descs.size(); i++) FreeAlignedBuffer((byte *)descs[i].pSysMem); @@ -707,6 +736,9 @@ bool WrappedID3D11Device::Serialise_CreateShaderResourceView( GetResourceManager()->AddLiveResource(pView, ret); } + + AddResource(pView, ResourceType::View, "Shader Resource View"); + DerivedResource(pResource, pView); } return true; @@ -802,6 +834,9 @@ bool WrappedID3D11Device::Serialise_CreateUnorderedAccessView( GetResourceManager()->AddLiveResource(pView, ret); } + + AddResource(pView, ResourceType::View, "Unordered Access View"); + DerivedResource(pResource, pView); } return true; @@ -927,6 +962,9 @@ bool WrappedID3D11Device::Serialise_CreateRenderTargetView(SerialiserType &ser, GetResourceManager()->AddLiveResource(pView, ret); } + + AddResource(pView, ResourceType::View, "Render Target View"); + DerivedResource(pResource, pView); } return true; @@ -1022,6 +1060,9 @@ bool WrappedID3D11Device::Serialise_CreateDepthStencilView( GetResourceManager()->AddLiveResource(pView, ret); } + + AddResource(pView, ResourceType::View, "Depth Stencil View"); + DerivedResource(pResource, pView); } return true; @@ -1118,6 +1159,8 @@ bool WrappedID3D11Device::Serialise_CreateInputLayout( GetResourceManager()->AddLiveResource(pInputLayout, ret); } + AddResource(pInputLayout, ResourceType::StateObject, "Input Layout"); + m_LayoutDescs[ret] = std::vector(pInputElementDescs, pInputElementDescs + NumElements); @@ -1204,6 +1247,8 @@ bool WrappedID3D11Device::Serialise_CreateVertexShader(SerialiserType &ser, GetResourceManager()->AddLiveResource(pShader, ret); } + + AddResource(pShader, ResourceType::Shader, "Vertex Shader"); } return true; @@ -1289,6 +1334,8 @@ bool WrappedID3D11Device::Serialise_CreateGeometryShader(SerialiserType &ser, GetResourceManager()->AddLiveResource(pShader, ret); } + + AddResource(pShader, ResourceType::Shader, "Geometry Shader"); } return true; @@ -1379,6 +1426,8 @@ bool WrappedID3D11Device::Serialise_CreateGeometryShaderWithStreamOutput( GetResourceManager()->AddLiveResource(pShader, ret); } + + AddResource(pShader, ResourceType::Shader, "Geometry Shader"); } return true; @@ -1470,6 +1519,8 @@ bool WrappedID3D11Device::Serialise_CreatePixelShader(SerialiserType &ser, GetResourceManager()->AddLiveResource(pShader, ret); } + + AddResource(pShader, ResourceType::Shader, "Pixel Shader"); } return true; @@ -1553,6 +1604,8 @@ bool WrappedID3D11Device::Serialise_CreateHullShader(SerialiserType &ser, const GetResourceManager()->AddLiveResource(pShader, ret); } + + AddResource(pShader, ResourceType::Shader, "Hull Shader"); } return true; @@ -1637,6 +1690,8 @@ bool WrappedID3D11Device::Serialise_CreateDomainShader(SerialiserType &ser, GetResourceManager()->AddLiveResource(pShader, ret); } + + AddResource(pShader, ResourceType::Shader, "Domain Shader"); } return true; @@ -1722,6 +1777,8 @@ bool WrappedID3D11Device::Serialise_CreateComputeShader(SerialiserType &ser, GetResourceManager()->AddLiveResource(pShader, ret); } + + AddResource(pShader, ResourceType::Shader, "Compute Shader"); } return true; @@ -1815,6 +1872,9 @@ bool WrappedID3D11Device::Serialise_CreateClassInstance(SerialiserType &ser, LPC GetResourceManager()->AddLiveResource(pInstance, wrapped); } + + AddResource(pInstance, ResourceType::ShaderBinding, "Class Instance"); + DerivedResource(pClassLinkage, pInstance); } return true; @@ -1877,6 +1937,9 @@ bool WrappedID3D11Device::Serialise_GetClassInstance(SerialiserType &ser, LPCSTR GetResourceManager()->AddLiveResource(pInstance, wrapped); } + + AddResource(pInstance, ResourceType::ShaderBinding, "Class Instance"); + DerivedResource(pClassLinkage, pInstance); } return true; @@ -1932,6 +1995,8 @@ bool WrappedID3D11Device::Serialise_CreateClassLinkage(SerialiserType &ser, GetResourceManager()->AddLiveResource(pLinkage, ret); } + + AddResource(pLinkage, ResourceType::ShaderBinding, "Class Linkage"); } return true; @@ -2002,6 +2067,8 @@ bool WrappedID3D11Device::Serialise_CreateBlendState(SerialiserType &ser, GetResourceManager()->AddLiveResource(pState, ret); } } + + AddResource(pState, ResourceType::StateObject, "Blend State"); } return true; @@ -2090,6 +2157,8 @@ bool WrappedID3D11Device::Serialise_CreateDepthStencilState( GetResourceManager()->AddLiveResource(pState, ret); } } + + AddResource(pState, ResourceType::StateObject, "Depth-Stencil State"); } return true; @@ -2178,6 +2247,8 @@ bool WrappedID3D11Device::Serialise_CreateRasterizerState(SerialiserType &ser, GetResourceManager()->AddLiveResource(pState, ret); } } + + AddResource(pState, ResourceType::StateObject, "Rasterizer State"); } return true; @@ -2266,6 +2337,8 @@ bool WrappedID3D11Device::Serialise_CreateSamplerState(SerialiserType &ser, GetResourceManager()->AddLiveResource(pState, ret); } } + + AddResource(pState, ResourceType::Sampler, "Sampler State"); } return true; @@ -2343,6 +2416,8 @@ bool WrappedID3D11Device::Serialise_CreateQuery(SerialiserType &ser, GetResourceManager()->AddLiveResource(pQuery, ret); } + + AddResource(pQuery, ResourceType::Query, "Query"); } return true; @@ -2402,6 +2477,8 @@ bool WrappedID3D11Device::Serialise_CreatePredicate(SerialiserType &ser, GetResourceManager()->AddLiveResource(pPredicate, ret); } + + AddResource(pPredicate, ResourceType::Query, "Predicate"); } return true; @@ -2462,6 +2539,8 @@ bool WrappedID3D11Device::Serialise_CreateCounter(SerialiserType &ser, GetResourceManager()->AddLiveResource(pCounter, ret); } + + AddResource(pCounter, ResourceType::Query, "Counter"); } return true; @@ -2524,6 +2603,8 @@ bool WrappedID3D11Device::Serialise_CreateDeferredContext(SerialiserType &ser, GetResourceManager()->AddLiveResource(pDeferredContext, ret); } + + AddResource(pDeferredContext, ResourceType::CommandBuffer, "Deferred Context"); } return true; @@ -2640,6 +2721,8 @@ bool WrappedID3D11Device::Serialise_OpenSharedResource(SerialiserType &ser, HAND GetResourceManager()->AddLiveResource(pResource, ret); } + AddResource(pResource, ResourceType::Buffer, "Shared Buffer"); + if(Descriptor.Usage != D3D11_USAGE_IMMUTABLE) { ID3D11Buffer *stage = NULL; @@ -2709,6 +2792,8 @@ bool WrappedID3D11Device::Serialise_OpenSharedResource(SerialiserType &ser, HAND GetResourceManager()->AddLiveResource(pResource, ret); } + + AddResource(pResource, ResourceType::Texture, "Shared 1D Texture"); } } else if(Type == Resource_Texture2D) @@ -2750,6 +2835,8 @@ bool WrappedID3D11Device::Serialise_OpenSharedResource(SerialiserType &ser, HAND GetResourceManager()->AddLiveResource(pResource, ret); } + + AddResource(pResource, ResourceType::Texture, "Shared 2D Texture"); } } else if(Type == Resource_Texture3D) @@ -2791,6 +2878,8 @@ bool WrappedID3D11Device::Serialise_OpenSharedResource(SerialiserType &ser, HAND GetResourceManager()->AddLiveResource(pResource, ret); } + + AddResource(pResource, ResourceType::Texture, "Shared 3D Texture"); } } else diff --git a/renderdoc/driver/d3d11/d3d11_initstate.cpp b/renderdoc/driver/d3d11/d3d11_initstate.cpp index e622c3379..3593e8837 100644 --- a/renderdoc/driver/d3d11/d3d11_initstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_initstate.cpp @@ -416,6 +416,11 @@ bool WrappedID3D11Device::Serialise_InitialState(SerialiserType &ser, ResourceId SERIALISE_ELEMENT(Id); } + if(IsReplayingAndReading()) + { + AddResourceCurChunk(Id); + } + { RDCDEBUG("Serialise_InitialState(%llu)", Id); diff --git a/renderdoc/driver/d3d12/d3d12_command_list.h b/renderdoc/driver/d3d12/d3d12_command_list.h index cd1dbb01c..9637b8035 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list.h +++ b/renderdoc/driver/d3d12/d3d12_command_list.h @@ -96,6 +96,7 @@ class WrappedID3D12GraphicsCommandList : public RefCounter12CreateCommandList(nodeMask, type, pAllocator, pInitialState, riid, (void **)&list); + m_pDevice->AddResource(BakedCommandList, ResourceType::CommandBuffer, "Baked Command List"); + m_pDevice->GetReplay()->GetResourceDesc(BakedCommandList).initialisationChunks.clear(); + m_pDevice->DerivedResource(CommandList, BakedCommandList); + m_pDevice->DerivedResource(pAllocator, BakedCommandList); + if(pInitialState) + m_pDevice->DerivedResource(pInitialState, BakedCommandList); + GetResourceManager()->AddLiveResource(BakedCommandList, list); // whenever a command-building chunk asks for the command list, it @@ -331,9 +338,6 @@ HRESULT WrappedID3D12GraphicsCommandList::Reset(ID3D12CommandAllocator *pAllocat m_ListRecord->DeleteChunks(); m_ListRecord->ContainsExecuteIndirect = false; - // free parents - m_ListRecord->FreeParents(GetResourceManager()); - // free any baked commands. If we don't have any, this is the creation reset // so we return before actually doing the 'real' reset. if(m_ListRecord->bakedCommands) diff --git a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp index 796a3c02b..b0ca849ca 100644 --- a/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_queue_wrap.cpp @@ -402,6 +402,8 @@ void STDMETHODCALLTYPE WrappedID3D12CommandQueue::ExecuteCommandLists( for(UINT i = 0; i < NumCommandLists; i++) { + WrappedID3D12GraphicsCommandList *wrapped = + (WrappedID3D12GraphicsCommandList *)ppCommandLists[i]; D3D12ResourceRecord *record = GetRecord(ppCommandLists[i]); if(record->ContainsExecuteIndirect) @@ -487,6 +489,10 @@ void STDMETHODCALLTYPE WrappedID3D12CommandQueue::ExecuteCommandLists( record->bakedCommands->AddResourceReferences(GetResourceManager()); record->bakedCommands->AddReferencedIDs(refdIDs); + // mark the creation record as referenced so it gets pulled in. + GetResourceManager()->MarkResourceFrameReferenced( + wrapped->GetCreationRecord()->GetResourceID(), eFrameRef_Read); + // reference all executed bundles as well for(size_t b = 0; b < record->bakedCommands->cmdInfo->bundles.size(); b++) { diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index e412af307..6cd555d46 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -668,6 +668,7 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic RDCEraseEl(m_Init); m_ListRecord = NULL; + m_CreationRecord = NULL; m_Cmd = NULL; m_CurGfxRootSig = NULL; @@ -684,6 +685,17 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic // this is set up in the implicit Reset() right after creation m_ListRecord->bakedCommands = NULL; + + // a bit of a hack, we make a parallel resource record with the same lifetime as the command + // list and make it a parent, so it will hold onto our create chunk and not try to + // record it (and throw it away with baked commands that are unused), then it'll be pulled + // into the capture. + m_CreationRecord = + m_pDevice->GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); + m_CreationRecord->type = Resource_GraphicsCommandList; + m_CreationRecord->SpecialResource = true; + + m_ListRecord->AddParent(m_CreationRecord); } else { @@ -709,6 +721,9 @@ WrappedID3D12GraphicsCommandList::~WrappedID3D12GraphicsCommandList() if(m_pReal) m_pDevice->GetResourceManager()->RemoveWrapper(m_pReal); + if(m_CreationRecord) + m_CreationRecord->Delete(m_pDevice->GetResourceManager()); + if(m_ListRecord && m_ListRecord->bakedCommands) m_ListRecord->bakedCommands->Delete(m_pDevice->GetResourceManager()); diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index a974e6d06..4331ed410 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -456,6 +456,7 @@ enum class D3D12Chunk : uint32_t CreateSwapBuffer, Device_CreateCommandQueue, Device_CreateCommandAllocator, + Device_CreateCommandList, Device_CreateGraphicsPipeline, Device_CreateComputePipeline, Device_CreateDescriptorHeap, diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 9fd1a95cd..aabe5c370 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -683,6 +683,8 @@ bool WrappedID3D12Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser, D3D12_RESOURCE_STATE_COMMON, NULL, __uuidof(ID3D12Resource), (void **)&fakeBB); + AddResource(SwapbufferID, ResourceType::SwapchainImage, "Swapchain Image"); + if(FAILED(hr)) { RDCERR("Failed to create fake back buffer, HRESULT: 0x%08x", hr); @@ -1900,7 +1902,12 @@ bool WrappedID3D12Device::Serialise_SetName(SerialiserType &ser, ID3D12DeviceChi if(IsReplayingAndReading() && pResource) { - m_ResourceNames[GetResourceManager()->GetOriginalID(GetResID(pResource))] = Name; + ResourceId origId = GetResourceManager()->GetOriginalID(GetResID(pResource)); + m_ResourceNames[origId] = Name; + + ResourceDescription &descr = GetReplay()->GetResourceDesc(origId); + descr.SetCustomName(Name); + AddResourceCurChunk(descr); pResource->SetName(StringFormat::UTF82Wide(Name).c_str()); } @@ -2028,6 +2035,9 @@ void WrappedID3D12Device::CreateInternalResources() } } + // we don't want replay-only shaders added in WrappedID3D12Shader to pollute the list of resources + WrappedID3D12Shader::InternalResources(true); + CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void **)&m_Alloc); CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void **)&m_GPUSyncFence); @@ -2047,6 +2057,8 @@ void WrappedID3D12Device::CreateInternalResources() if(m_DebugManager == NULL) m_DebugManager = new D3D12DebugManager(this); + + WrappedID3D12Shader::InternalResources(false); } void WrappedID3D12Device::DestroyInternalResources() @@ -2236,6 +2248,9 @@ void WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context) case D3D12Chunk::Device_CreateCommandAllocator: Serialise_CreateCommandAllocator(ser, D3D12_COMMAND_LIST_TYPE_DIRECT, IID(), NULL); break; + case D3D12Chunk::Device_CreateCommandList: + Serialise_CreateCommandList(ser, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, NULL, NULL, IID(), NULL); + break; case D3D12Chunk::Device_CreateGraphicsPipeline: Serialise_CreateGraphicsPipelineState(ser, NULL, IID(), NULL); @@ -2308,6 +2323,41 @@ void WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context) } } +void WrappedID3D12Device::AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix) +{ + ResourceDescription &descr = GetReplay()->GetResourceDesc(id); + + uint64_t num; + memcpy(&num, &id, sizeof(uint64_t)); + descr.name = defaultNamePrefix + (" " + ToStr(num)); + descr.autogeneratedName = true; + descr.type = type; + AddResourceCurChunk(descr); +} + +void WrappedID3D12Device::DerivedResource(ID3D12DeviceChild *parent, ResourceId child) +{ + ResourceId parentId = GetResourceManager()->GetOriginalID(GetResID(parent)); + + DerivedResource(parentId, child); +} + +void WrappedID3D12Device::DerivedResource(ResourceId parent, ResourceId child) +{ + GetReplay()->GetResourceDesc(parent).derivedResources.push_back(child); + GetReplay()->GetResourceDesc(child).parentResources.push_back(parent); +} + +void WrappedID3D12Device::AddResourceCurChunk(ResourceDescription &descr) +{ + descr.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 1); +} + +void WrappedID3D12Device::AddResourceCurChunk(ResourceId id) +{ + AddResourceCurChunk(GetReplay()->GetResourceDesc(id)); +} + void WrappedID3D12Device::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) { int sectionIdx = rdc->SectionIndex(SectionType::FrameCapture); diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 6b936c0d2..5b3dbf73c 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -382,6 +382,12 @@ public: void AddDebugMessage(const DebugMessage &msg); vector GetDebugMessages(); + void AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix); + void DerivedResource(ResourceId parent, ResourceId child); + void DerivedResource(ID3D12DeviceChild *parent, ResourceId child); + void AddResourceCurChunk(ResourceDescription &descr); + void AddResourceCurChunk(ResourceId id); + const string &GetResourceName(ResourceId id) { return m_ResourceNames[id]; } vector &GetSubresourceStates(ResourceId id) { diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index ba44364e2..e444eedcf 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -60,6 +60,8 @@ bool WrappedID3D12Device::Serialise_CreateCommandQueue(SerialiserType &ser, GetResourceManager()->AddLiveResource(pCommandQueue, ret); + AddResource(pCommandQueue, ResourceType::Queue, "Command Queue"); + WrappedID3D12CommandQueue *wrapped = (WrappedID3D12CommandQueue *)ret; if(Descriptor.Type == D3D12_COMMAND_LIST_TYPE_DIRECT && m_Queue == NULL) @@ -151,6 +153,8 @@ bool WrappedID3D12Device::Serialise_CreateCommandAllocator(SerialiserType &ser, ret = new WrappedID3D12CommandAllocator(ret, this); GetResourceManager()->AddLiveResource(pCommandAllocator, ret); + + AddResource(pCommandAllocator, ResourceType::Pool, "Command Queue"); } } @@ -198,6 +202,51 @@ HRESULT WrappedID3D12Device::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type return ret; } +template +bool WrappedID3D12Device::Serialise_CreateCommandList(SerialiserType &ser, UINT nodeMask, + D3D12_COMMAND_LIST_TYPE type, + ID3D12CommandAllocator *pCommandAllocator, + ID3D12PipelineState *pInitialState, + REFIID riid, void **ppCommandList) +{ + SERIALISE_ELEMENT(nodeMask); + SERIALISE_ELEMENT(type); + SERIALISE_ELEMENT(pCommandAllocator); + SERIALISE_ELEMENT(pInitialState); + SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"); + SERIALISE_ELEMENT_LOCAL(pCommandList, + ((WrappedID3D12GraphicsCommandList *)*ppCommandList)->GetResourceID()); + + // this chunk is purely for user information and consistency, the command buffer we allocate is + // a dummy and is not used for anything. + + if(IsReplayingAndReading()) + { + ID3D12GraphicsCommandList *list = NULL; + HRESULT hr = + CreateCommandList(nodeMask, type, pCommandAllocator, pInitialState, guid, (void **)&list); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: %s", ToStr(hr).c_str()); + } + else if(list) + { + // close it immediately, we don't want to tie up the allocator + list->Close(); + + GetResourceManager()->AddLiveResource(pCommandList, list); + } + + AddResource(pCommandList, ResourceType::CommandBuffer, "Command List"); + DerivedResource(pCommandAllocator, pCommandList); + if(pInitialState) + DerivedResource(pInitialState, pCommandList); + } + + return true; +} + HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *pCommandAllocator, ID3D12PipelineState *pInitialState, REFIID riid, @@ -232,6 +281,22 @@ HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST // we just serialise out command allocator creation as a reset, since it's equivalent. wrapped->SetInitParams(riid, nodeMask, type); wrapped->Reset(pCommandAllocator, pInitialState); + + { + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreateCommandList); + Serialise_CreateCommandList(ser, nodeMask, type, pCommandAllocator, pInitialState, riid, + (void **)&wrapped); + + wrapped->GetCreationRecord()->AddChunk(scope.Get()); + } + + // add parents so these are always in the capture. They won't necessarily be used for replay + // but we want them to be available so the creation chunk is fully realised + wrapped->GetCreationRecord()->AddParent(GetRecord(pCommandAllocator)); + if(pInitialState) + wrapped->GetCreationRecord()->AddParent(GetRecord(pInitialState)); } // during replay, the caller is responsible for calling AddLiveResource as this function @@ -278,12 +343,25 @@ bool WrappedID3D12Device::Serialise_CreateGraphicsPipelineState( &wrapped->graphics->GS, &wrapped->graphics->PS, }; + AddResource(pPipelineState, ResourceType::PipelineState, "Graphics Pipeline State"); + DerivedResource(Descriptor.pRootSignature, pPipelineState); + for(size_t i = 0; i < ARRAY_COUNT(shaders); i++) { if(shaders[i]->BytecodeLength == 0) + { shaders[i]->pShaderBytecode = NULL; + } else - shaders[i]->pShaderBytecode = WrappedID3D12Shader::AddShader(*shaders[i], this, wrapped); + { + WrappedID3D12Shader *entry = WrappedID3D12Shader::AddShader(*shaders[i], this, wrapped); + + shaders[i]->pShaderBytecode = entry; + + AddResourceCurChunk(entry->GetResourceID()); + + DerivedResource(entry->GetResourceID(), pPipelineState); + } } if(wrapped->graphics->InputLayout.NumElements) @@ -461,9 +539,17 @@ bool WrappedID3D12Device::Serialise_CreateComputePipelineState( wrapped->compute = new D3D12_COMPUTE_PIPELINE_STATE_DESC(Descriptor); - wrapped->compute->CS.pShaderBytecode = + WrappedID3D12Shader *entry = WrappedID3D12Shader::AddShader(wrapped->compute->CS, this, wrapped); + AddResourceCurChunk(entry->GetResourceID()); + + AddResource(pPipelineState, ResourceType::PipelineState, "Compute Pipeline State"); + DerivedResource(Descriptor.pRootSignature, pPipelineState); + DerivedResource(entry->GetResourceID(), pPipelineState); + + wrapped->compute->CS.pShaderBytecode = entry; + GetResourceManager()->AddLiveResource(pPipelineState, ret); } } @@ -559,6 +645,8 @@ bool WrappedID3D12Device::Serialise_CreateDescriptorHeap( ret = new WrappedID3D12DescriptorHeap(ret, this, Descriptor); GetResourceManager()->AddLiveResource(pHeap, ret); + + AddResource(pHeap, ResourceType::ShaderBinding, "Descriptor Heap"); } } @@ -656,6 +744,8 @@ bool WrappedID3D12Device::Serialise_CreateRootSignature(SerialiserType &ser, UIN GetResourceManager()->AddLiveResource(pRootSignature, ret); } + + AddResource(pRootSignature, ResourceType::ShaderBinding, "Root Signature"); } } @@ -1078,6 +1168,44 @@ bool WrappedID3D12Device::Serialise_CreateCommittedResource( SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; states.resize(GetNumSubresources(m_pDevice, &desc), InitialResourceState); + + ResourceType type = ResourceType::Texture; + const char *prefix = "Texture"; + + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + type = ResourceType::Buffer; + prefix = "Buffer"; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) + { + prefix = desc.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; + + if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "1D Render Target"; + else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "1D Depth Target"; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) + { + prefix = desc.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; + + if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "2D Render Target"; + else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "2D Depth Target"; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + prefix = "3D Texture"; + + if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "3D Render Target"; + else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "3D Depth Target"; + } + + AddResource(pResource, type, prefix); } } @@ -1171,6 +1299,8 @@ bool WrappedID3D12Device::Serialise_CreateHeap(SerialiserType &ser, const D3D12_ GetResourceManager()->AddLiveResource(pHeap, ret); } + + AddResource(pHeap, ResourceType::Pool, "Heap"); } return true; @@ -1268,6 +1398,45 @@ bool WrappedID3D12Device::Serialise_CreatePlacedResource( SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; states.resize(GetNumSubresources(m_pDevice, &Descriptor), InitialState); } + + ResourceType type = ResourceType::Texture; + const char *prefix = "Texture"; + + if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + type = ResourceType::Buffer; + prefix = "Buffer"; + } + else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) + { + prefix = Descriptor.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; + + if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "1D Render Target"; + else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "1D Depth Target"; + } + else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) + { + prefix = Descriptor.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; + + if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "2D Render Target"; + else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "2D Depth Target"; + } + else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + prefix = "3D Texture"; + + if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "3D Render Target"; + else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "3D Depth Target"; + } + + AddResource(pResource, type, prefix); + DerivedResource(pHeap, pResource); } return true; @@ -1381,6 +1550,8 @@ bool WrappedID3D12Device::Serialise_CreateFence(SerialiserType &ser, UINT64 Init GetResourceManager()->AddLiveResource(pFence, ret); } + + AddResource(pFence, ResourceType::Sync, "Fence"); } return true; @@ -1451,6 +1622,8 @@ bool WrappedID3D12Device::Serialise_CreateQueryHeap(SerialiserType &ser, GetResourceManager()->AddLiveResource(pQueryHeap, ret); } + + AddResource(pQueryHeap, ResourceType::Query, "Query Heap"); } return true; @@ -1549,6 +1722,10 @@ bool WrappedID3D12Device::Serialise_CreateCommandSignature(SerialiserType &ser, ret = wrapped; GetResourceManager()->AddLiveResource(pCommandSignature, ret); + + AddResource(pCommandSignature, ResourceType::ShaderBinding, "Command Signature"); + if(pRootSignature) + DerivedResource(pRootSignature, pCommandSignature); } } @@ -2070,6 +2247,11 @@ INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommandQueue, void **ppCommandQueue); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommandAllocator, D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **ppCommandAllocator); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommandList, UINT nodeMask, + D3D12_COMMAND_LIST_TYPE type, + ID3D12CommandAllocator *pCommandAllocator, + ID3D12PipelineState *pInitialState, REFIID riid, + void **ppCommandList); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateGraphicsPipelineState, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState); diff --git a/renderdoc/driver/d3d12/d3d12_initstate.cpp b/renderdoc/driver/d3d12/d3d12_initstate.cpp index 647aa6805..66c577ca6 100644 --- a/renderdoc/driver/d3d12/d3d12_initstate.cpp +++ b/renderdoc/driver/d3d12/d3d12_initstate.cpp @@ -310,6 +310,8 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI { liveRes = GetLiveResource(id); RDCASSERT(liveRes); + + m_Device->AddResourceCurChunk(id); } if(type == Resource_DescriptorHeap) diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index 118feb914..9295fc0c6 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -31,6 +31,7 @@ GPUAddressRangeTracker WrappedID3D12Resource::m_Addresses; std::map *WrappedID3D12Resource::m_List = NULL; std::map WrappedID3D12Shader::m_Shaders; +bool WrappedID3D12Shader::m_InternalResources = false; const GUID RENDERDOC_ID3D12ShaderGUID_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_struct; diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index fabbe712c..222d7c2af 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -516,6 +516,13 @@ public: static const int AllocMaxByteSize = 8 * 1024 * 1024; ALLOCATE_WITH_WRAPPED_POOL(ShaderEntry, AllocPoolCount, AllocMaxByteSize); + static bool m_InternalResources; + + static void InternalResources(bool internalResources) + { + m_InternalResources = internalResources; + } + ShaderEntry(const D3D12_SHADER_BYTECODE &byteCode, WrappedID3D12Device *device) : WrappedDeviceChild12(NULL, device), m_Key(byteCode) { @@ -526,6 +533,19 @@ public: device->GetResourceManager()->AddLiveResource(GetResourceID(), this); + if(!m_InternalResources) + { + device->AddResource(GetResourceID(), ResourceType::Shader, "Shader"); + + ResourceDescription &desc = device->GetReplay()->GetResourceDesc(GetResourceID()); + // this will be appended to in the function above. + desc.initialisationChunks.clear(); + + // since these don't have live IDs, let's use the first uint of the hash as the name. Slight + // chance of collision but not that bad. + desc.name = StringFormat::Fmt("Shader {%08x}", m_Key.hash[0]); + } + m_Built = false; } diff --git a/renderdoc/driver/d3d12/d3d12_stringise.cpp b/renderdoc/driver/d3d12/d3d12_stringise.cpp index 61a7c38cf..77c91ed69 100644 --- a/renderdoc/driver/d3d12/d3d12_stringise.cpp +++ b/renderdoc/driver/d3d12/d3d12_stringise.cpp @@ -28,7 +28,7 @@ template <> std::string DoStringise(const D3D12Chunk &el) { - RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1084, "Chunks changed without updating names"); + RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1085, "Chunks changed without updating names"); BEGIN_ENUM_STRINGISE(D3D12Chunk) { @@ -44,6 +44,7 @@ std::string DoStringise(const D3D12Chunk &el) STRINGISE_ENUM_CLASS_NAMED(Device_CreateCommandQueue, "ID3D12Device::CreateCommandQueue"); STRINGISE_ENUM_CLASS_NAMED(Device_CreateCommandAllocator, "ID3D12Device::CreateCommandAllocator"); + STRINGISE_ENUM_CLASS_NAMED(Device_CreateCommandList, "ID3D12Device::CreateCommandList"); STRINGISE_ENUM_CLASS_NAMED(Device_CreateGraphicsPipeline, "ID3D12Device::CreateGraphicsPipeline"); STRINGISE_ENUM_CLASS_NAMED(Device_CreateComputePipeline, "ID3D12Device::CreateComputePipeline"); diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 7a8e036c7..e491cb608 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -644,8 +644,15 @@ void WrappedOpenGL::Initialise(GLInitParams ¶ms, uint64_t sectionVersion) gl.glGenTextures(1, &m_FakeBB_Color); gl.glBindTexture(target, m_FakeBB_Color); - GetResourceManager()->SetName(GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_Color)), - "Backbuffer Color"); + ResourceId colorId = GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_Color)); + const char *name = "Backbuffer Color"; + + GetResourceManager()->SetName(colorId, name); + + // we'll add the chunk later when we re-process it. + AddResource(colorId, ResourceType::SwapchainImage, name); + GetReplay()->GetResourceDesc(colorId).initialisationChunks.clear(); + GetReplay()->GetResourceDesc(colorId).SetCustomName(name); if(params.multiSamples > 1) { @@ -701,9 +708,15 @@ void WrappedOpenGL::Initialise(GLInitParams ¶ms, uint64_t sectionVersion) else RDCERR("Unexpected # stencil bits: %d", params.stencilBits); - GetResourceManager()->SetName( - GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_DepthStencil)), - stencil ? "Backbuffer Depth-stencil" : "Backbuffer Depth"); + ResourceId depthId = GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_DepthStencil)); + name = stencil ? "Backbuffer Depth-stencil" : "Backbuffer Depth"; + + GetResourceManager()->SetName(depthId, name); + + // we'll add the chunk later when we re-process it. + AddResource(depthId, ResourceType::SwapchainImage, name); + GetReplay()->GetResourceDesc(depthId).initialisationChunks.clear(); + GetReplay()->GetResourceDesc(depthId).SetCustomName(name); if(params.multiSamples > 1) { @@ -2995,6 +3008,46 @@ void WrappedOpenGL::DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum sev m_RealDebugFunc(source, type, id, severity, length, message, m_RealDebugFuncParam); } +void WrappedOpenGL::AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix) +{ + ResourceDescription &descr = GetReplay()->GetResourceDesc(id); + + uint64_t num; + memcpy(&num, &id, sizeof(uint64_t)); + descr.name = defaultNamePrefix + (" " + ToStr(num)); + descr.autogeneratedName = true; + descr.type = type; + AddResourceCurChunk(descr); +} + +void WrappedOpenGL::DerivedResource(GLResource parent, ResourceId child) +{ + ResourceId parentId = GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(parent)); + + GetReplay()->GetResourceDesc(parentId).derivedResources.push_back(child); + GetReplay()->GetResourceDesc(child).parentResources.push_back(parentId); +} + +void WrappedOpenGL::AddResourceCurChunk(ResourceDescription &descr) +{ + descr.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 1); +} + +void WrappedOpenGL::AddResourceCurChunk(ResourceId id) +{ + AddResourceCurChunk(GetReplay()->GetResourceDesc(id)); +} + +void WrappedOpenGL::AddResourceInitChunk(GLResource res) +{ + // don't add chunks that were recorded (some chunks are ambiguous) + if(m_CurEventID == 0) + { + GLResourceManager *rm = GetResourceManager(); + AddResourceCurChunk(rm->GetOriginalID(rm->GetID(res))); + } +} + void WrappedOpenGL::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) { int sectionIdx = rdc->SectionIndex(SectionType::FrameCapture); @@ -3122,6 +3175,14 @@ void WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) { GLInitParams InitParams; SERIALISE_ELEMENT(InitParams); + + ResourceId colorId = GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_Color)); + ResourceId depthId; + if(m_FakeBB_DepthStencil) + depthId = GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_DepthStencil)); + + AddResourceCurChunk(colorId); + AddResourceCurChunk(depthId); } else if(system == SystemChunk::InitialContentsList) { @@ -3145,6 +3206,9 @@ void WrappedOpenGL::ProcessChunk(ReadSerialiser &ser, GLChunk chunk) SERIALISE_ELEMENT(m_FakeVAOID).Named("VAO 0 ID"); GetResourceManager()->AddLiveResource(m_FakeVAOID, VertexArrayRes(NULL, 0)); + + AddResource(m_FakeVAOID, ResourceType::StateObject, ""); + GetReplay()->GetResourceDesc(m_FakeVAOID).SetCustomName("Special VAO 0"); break; } diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 83a569d29..a54bcb855 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -156,6 +156,12 @@ private: SDFile *m_StructuredFile; SDFile m_StoredStructuredData; + void AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix); + void DerivedResource(GLResource parent, ResourceId child); + void AddResourceCurChunk(ResourceDescription &descr); + void AddResourceCurChunk(ResourceId id); + void AddResourceInitChunk(GLResource res); + uint32_t m_FrameCounter; uint32_t m_NoCtxFrames; uint32_t m_FailedFrame; diff --git a/renderdoc/driver/gl/gl_initstate.cpp b/renderdoc/driver/gl/gl_initstate.cpp index 2059c3711..64a0b313e 100644 --- a/renderdoc/driver/gl/gl_initstate.cpp +++ b/renderdoc/driver/gl/gl_initstate.cpp @@ -1120,6 +1120,8 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId r res = GetLiveResource(Id); else res = GLResource(MakeNullResource); + + m_GL->AddResourceCurChunk(Id); } const GLHookSet &gl = m_GL->GetHookset(); diff --git a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp index 02c71ee87..225421c19 100644 --- a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp @@ -70,6 +70,8 @@ bool WrappedOpenGL::Serialise_glGenBuffers(SerialiserType &ser, GLsizei n, GLuin ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(buffer, res); + AddResource(buffer, ResourceType::Buffer, "Buffer"); + m_Buffers[live].resource = res; m_Buffers[live].curType = eGL_NONE; m_Buffers[live].creationFlags = BufferCategory::NoFlags; @@ -129,6 +131,8 @@ bool WrappedOpenGL::Serialise_glCreateBuffers(SerialiserType &ser, GLsizei n, GL ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(buffer, res); + AddResource(buffer, ResourceType::Buffer, "Buffer"); + m_Buffers[live].resource = res; m_Buffers[live].curType = eGL_NONE; m_Buffers[live].creationFlags = BufferCategory::NoFlags; @@ -205,6 +209,8 @@ bool WrappedOpenGL::Serialise_glBindBuffer(SerialiserType &ser, GLenum target, G if(IsLoading(m_State) && m_CurEventID == 0 && target != eGL_NONE) m_Real.glBindBuffer(target, prevbuf); } + + AddResourceInitChunk(buffer); } return true; @@ -395,6 +401,8 @@ bool WrappedOpenGL::Serialise_glNamedBufferStorageEXT(SerialiserType &ser, GLuin m_Real.glNamedBufferStorageEXT(buffer.name, (GLsizeiptr)bytesize, data, flags); m_Buffers[GetResourceManager()->GetID(buffer)].size = bytesize; + + AddResourceInitChunk(buffer); } return true; @@ -528,6 +536,8 @@ bool WrappedOpenGL::Serialise_glNamedBufferDataEXT(SerialiserType &ser, GLuint b m_Real.glNamedBufferDataEXT(buffer.name, (GLsizeiptr)bytesize, data, usage); m_Buffers[GetResourceManager()->GetID(buffer)].size = bytesize; + + AddResourceInitChunk(buffer); } return true; @@ -1072,6 +1082,8 @@ bool WrappedOpenGL::Serialise_glBindBufferBase(SerialiserType &ser, GLenum targe if(IsReplayingAndReading()) { m_Real.glBindBufferBase(target, index, buffer.name); + + AddResourceInitChunk(buffer); } return true; @@ -1177,6 +1189,8 @@ bool WrappedOpenGL::Serialise_glBindBufferRange(SerialiserType &ser, GLenum targ if(IsReplayingAndReading()) { m_Real.glBindBufferRange(target, index, buffer.name, (GLintptr)offset, (GLsizeiptr)size); + + AddResourceInitChunk(buffer); } return true; @@ -1294,8 +1308,12 @@ bool WrappedOpenGL::Serialise_glBindBuffersBase(SerialiserType &ser, GLenum targ std::vector bufs; bufs.reserve(count); for(GLsizei i = 0; i < count; i++) + { bufs.push_back(buffers[i].name); + AddResourceInitChunk(buffers[i]); + } + m_Real.glBindBuffersBase(target, first, count, bufs.data()); } @@ -1455,7 +1473,11 @@ bool WrappedOpenGL::Serialise_glBindBuffersRange(SerialiserType &ser, GLenum tar { bufs.reserve(count); for(GLsizei i = 0; i < count; i++) + { bufs.push_back(buffers[i].name); + + AddResourceInitChunk(buffers[i]); + } } if(!offsets.empty()) { @@ -2575,6 +2597,8 @@ bool WrappedOpenGL::Serialise_glGenTransformFeedbacks(SerialiserType &ser, GLsiz m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(feedback, res); + + AddResource(feedback, ResourceType::StateObject, "Transform Feedback"); } return true; @@ -2627,6 +2651,8 @@ bool WrappedOpenGL::Serialise_glCreateTransformFeedbacks(SerialiserType &ser, GL m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(feedback, res); + + AddResource(feedback, ResourceType::StateObject, "Transform Feedback"); } return true; @@ -3924,6 +3950,8 @@ bool WrappedOpenGL::Serialise_glGenVertexArrays(SerialiserType &ser, GLsizei n, m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(array, res); + + AddResource(array, ResourceType::StateObject, "Vertex Array"); } return true; @@ -3976,6 +4004,8 @@ bool WrappedOpenGL::Serialise_glCreateVertexArrays(SerialiserType &ser, GLsizei m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(array, res); + + AddResource(array, ResourceType::StateObject, "Vertex Array"); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp index 174ab3723..98df0e70e 100644 --- a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp @@ -70,8 +70,13 @@ bool WrappedOpenGL::Serialise_glObjectLabel(SerialiserType &ser, GLenum identifi if(IsReplayingAndReading() && Resource.name) { - GetResourceManager()->SetName( - GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(Resource)), Label); + ResourceId origId = GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(Resource)); + + GetResourceManager()->SetName(origId, Label); + + ResourceDescription &descr = GetReplay()->GetResourceDesc(origId); + descr.SetCustomName(Label); + AddResourceCurChunk(descr); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index 086cd18b5..8f5f31e24 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -44,6 +44,8 @@ bool WrappedOpenGL::Serialise_glGenFramebuffers(SerialiserType &ser, GLsizei n, ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(framebuffer, res); + + AddResource(framebuffer, ResourceType::RenderPass, "Framebuffer"); } return true; @@ -98,6 +100,8 @@ bool WrappedOpenGL::Serialise_glCreateFramebuffers(SerialiserType &ser, GLsizei ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(framebuffer, res); + + AddResource(framebuffer, ResourceType::RenderPass, "Framebuffer"); } return true; @@ -1960,6 +1964,8 @@ bool WrappedOpenGL::Serialise_glGenRenderbuffers(SerialiserType &ser, GLsizei n, ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(renderbuffer, res); + AddResource(renderbuffer, ResourceType::Texture, "Renderbuffer"); + m_Textures[live].resource = res; m_Textures[live].curType = eGL_RENDERBUFFER; } @@ -2018,6 +2024,8 @@ bool WrappedOpenGL::Serialise_glCreateRenderbuffers(SerialiserType &ser, GLsizei ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(renderbuffer, res); + AddResource(renderbuffer, ResourceType::Texture, "Renderbuffer"); + m_Textures[live].resource = res; m_Textures[live].curType = eGL_RENDERBUFFER; } @@ -2136,6 +2144,8 @@ bool WrappedOpenGL::Serialise_glNamedRenderbufferStorageEXT(SerialiserType &ser, eGL_RENDERBUFFER, renderbuffer.name); m_Real.glNamedFramebufferTexture2DEXT(texDetails.renderbufferFBOs[1], attach, eGL_TEXTURE_2D, texDetails.renderbufferReadTex, 0); + + AddResourceInitChunk(renderbuffer); } return true; @@ -2267,6 +2277,8 @@ bool WrappedOpenGL::Serialise_glNamedRenderbufferStorageMultisampleEXT(Serialise m_Real.glNamedFramebufferTexture2DEXT(texDetails.renderbufferFBOs[1], attach, eGL_TEXTURE_2D_MULTISAMPLE, texDetails.renderbufferReadTex, 0); + + AddResourceInitChunk(renderbuffer); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp index ccc3ac1b7..aae0c2a6d 100644 --- a/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_interop_funcs.cpp @@ -335,6 +335,8 @@ bool WrappedOpenGL::Serialise_wglDXRegisterObjectNV(SerialiserType &ser, GLResou m_Textures[liveId].internalFormat = internalFormat; } + + AddResourceInitChunk(Resource); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp index 5ccc77d9c..347062d70 100644 --- a/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp @@ -67,6 +67,8 @@ bool WrappedOpenGL::Serialise_glFenceSync(SerialiserType &ser, GLsync real, GLen ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(sync, res); + + AddResource(sync, ResourceType::Sync, "Sync"); } return true; @@ -191,6 +193,8 @@ bool WrappedOpenGL::Serialise_glGenQueries(SerialiserType &ser, GLsizei n, GLuin ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(query, res); + + AddResource(query, ResourceType::Query, "Query"); } return true; @@ -245,6 +249,8 @@ bool WrappedOpenGL::Serialise_glCreateQueries(SerialiserType &ser, GLenum target ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(query, res); + + AddResource(query, ResourceType::Query, "Query"); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp index 9adb614cd..68ef52ab5 100644 --- a/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp @@ -48,6 +48,8 @@ bool WrappedOpenGL::Serialise_glGenSamplers(SerialiserType &ser, GLsizei n, GLui ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(sampler, res); + + AddResource(sampler, ResourceType::Sampler, "Sampler"); } return true; @@ -100,6 +102,8 @@ bool WrappedOpenGL::Serialise_glCreateSamplers(SerialiserType &ser, GLsizei n, G ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(sampler, res); + + AddResource(sampler, ResourceType::Sampler, "Sampler"); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index 61b9251f4..6a1e0e3be 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -146,6 +146,8 @@ bool WrappedOpenGL::Serialise_glCreateShader(SerialiserType &ser, GLuint shader, m_Shaders[liveId].type = type; GetResourceManager()->AddLiveResource(Shader, res); + + AddResource(Shader, ResourceType::Shader, "Shader"); } return true; @@ -233,6 +235,8 @@ bool WrappedOpenGL::Serialise_glShaderSource(SerialiserType &ser, GLuint shaderH m_Shaders[liveId].spirv = SPVModule(); m_Shaders[liveId].reflection = ShaderReflection(); } + + AddResourceInitChunk(shader); } return true; @@ -280,6 +284,8 @@ bool WrappedOpenGL::Serialise_glCompileShader(SerialiserType &ser, GLuint shader m_Real.glCompileShader(shader.name); m_Shaders[liveId].Compile(*this, GetResourceManager()->GetOriginalID(liveId), shader.name); + + AddResourceInitChunk(shader); } return true; @@ -343,6 +349,9 @@ bool WrappedOpenGL::Serialise_glAttachShader(SerialiserType &ser, GLuint program m_Programs[liveProgId].shaders.push_back(liveShadId); m_Real.glAttachShader(program.name, shader.name); + + AddResourceInitChunk(program); + DerivedResource(program, GetResourceManager()->GetOriginalID(liveShadId)); } return true; @@ -501,6 +510,8 @@ bool WrappedOpenGL::Serialise_glCreateShaderProgramv(SerialiserType &ser, GLuint shadDetails.Compile(*this, Program, 0); GetResourceManager()->AddLiveResource(Program, res); + + AddResource(Program, ResourceType::StateObject, "Program"); } return true; @@ -581,6 +592,8 @@ bool WrappedOpenGL::Serialise_glCreateProgram(SerialiserType &ser, GLuint progra m_Programs[liveId].linked = false; GetResourceManager()->AddLiveResource(Program, res); + + AddResource(Program, ResourceType::StateObject, "Program"); } return true; @@ -647,6 +660,8 @@ bool WrappedOpenGL::Serialise_glLinkProgram(SerialiserType &ser, GLuint programH } m_Real.glLinkProgram(program.name); + + AddResourceInitChunk(program); } return true; @@ -1226,6 +1241,8 @@ bool WrappedOpenGL::Serialise_glGenProgramPipelines(SerialiserType &ser, GLsizei ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(pipeline, res); + + AddResource(pipeline, ResourceType::StateObject, "Pipeline"); } return true; @@ -1280,6 +1297,8 @@ bool WrappedOpenGL::Serialise_glCreateProgramPipelines(SerialiserType &ser, GLsi ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(pipeline, res); + + AddResource(pipeline, ResourceType::StateObject, "Pipeline"); } return true; @@ -1427,6 +1446,8 @@ bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(SerialiserType &ser, GLu m_Real.glCompileShaderIncludeARB(shader.name, count, path, NULL); shadDetails.Compile(*this, GetResourceManager()->GetOriginalID(liveId), shader.name); + + AddResourceInitChunk(shader); } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index f4973ca21..c4d66bd4b 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -78,6 +78,8 @@ bool WrappedOpenGL::Serialise_glGenTextures(SerialiserType &ser, GLsizei n, GLui ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(texture, res); + AddResource(texture, ResourceType::Texture, "Texture"); + m_Textures[live].resource = res; m_Textures[live].curType = eGL_NONE; } @@ -137,6 +139,8 @@ bool WrappedOpenGL::Serialise_glCreateTextures(SerialiserType &ser, GLenum targe ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(texture, res); + AddResource(texture, ResourceType::Texture, "Texture"); + m_Textures[live].resource = res; m_Textures[live].curType = TextureTarget(target); m_Textures[live].creationFlags |= TextureCategory::ShaderRead; @@ -625,6 +629,9 @@ bool WrappedOpenGL::Serialise_glTextureView(SerialiserType &ser, GLuint textureH m_Textures[liveTexId].width = m_Textures[liveOrigId].width; m_Textures[liveTexId].height = m_Textures[liveOrigId].height; m_Textures[liveTexId].depth = m_Textures[liveOrigId].depth; + + AddResourceInitChunk(texture); + DerivedResource(origtexture, GetResourceManager()->GetOriginalID(liveTexId)); } return true; @@ -717,6 +724,8 @@ bool WrappedOpenGL::Serialise_glGenerateTextureMipmapEXT(SerialiserType &ser, GL m_ResourceUses[GetResourceManager()->GetID(texture)].push_back( EventUsage(m_CurEventID, ResourceUsage::GenMips)); } + + AddResourceInitChunk(texture); } return true; @@ -2002,6 +2011,8 @@ bool WrappedOpenGL::Serialise_glTextureImage1DEXT(SerialiserType &ser, GLuint te if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + AddResourceInitChunk(texture); } return true; @@ -2234,6 +2245,8 @@ bool WrappedOpenGL::Serialise_glTextureImage2DEXT(SerialiserType &ser, GLuint te if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + AddResourceInitChunk(texture); } return true; @@ -2450,6 +2463,8 @@ bool WrappedOpenGL::Serialise_glTextureImage3DEXT(SerialiserType &ser, GLuint te if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + AddResourceInitChunk(texture); } return true; @@ -2673,6 +2688,8 @@ bool WrappedOpenGL::Serialise_glCompressedTextureImage1DEXT(SerialiserType &ser, if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + AddResourceInitChunk(texture); } return true; @@ -3015,6 +3032,8 @@ bool WrappedOpenGL::Serialise_glCompressedTextureImage2DEXT(SerialiserType &ser, if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + AddResourceInitChunk(texture); } return true; @@ -3249,6 +3268,8 @@ bool WrappedOpenGL::Serialise_glCompressedTextureImage3DEXT(SerialiserType &ser, if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + AddResourceInitChunk(texture); } return true; @@ -3437,6 +3458,8 @@ bool WrappedOpenGL::Serialise_glCopyTextureImage1DEXT(SerialiserType &ser, GLuin } m_Real.glCopyTextureImage1DEXT(texture.name, target, level, internalformat, x, y, width, border); + + AddResourceInitChunk(texture); } return true; @@ -3587,6 +3610,8 @@ bool WrappedOpenGL::Serialise_glCopyTextureImage2DEXT(SerialiserType &ser, GLuin m_Real.glCopyTextureImage2DEXT(texture.name, target, level, internalformat, x, y, width, height, border); + + AddResourceInitChunk(texture); } return true; } @@ -3741,6 +3766,8 @@ bool WrappedOpenGL::Serialise_glTextureStorage1DEXT(SerialiserType &ser, GLuint m_Real.glTextureStorage1DEXT(texture.name, target, levels, internalformat, width); else m_Real.glTextureStorage1D(texture.name, levels, internalformat, width); + + AddResourceInitChunk(texture); } return true; @@ -3868,6 +3895,8 @@ bool WrappedOpenGL::Serialise_glTextureStorage2DEXT(SerialiserType &ser, GLuint m_Real.glTextureStorage2DEXT(texture.name, target, levels, internalformat, width, height); else m_Real.glTextureStorage2D(texture.name, levels, internalformat, width, height); + + AddResourceInitChunk(texture); } return true; @@ -3999,6 +4028,8 @@ bool WrappedOpenGL::Serialise_glTextureStorage3DEXT(SerialiserType &ser, GLuint depth); else m_Real.glTextureStorage3D(texture.name, levels, internalformat, width, height, depth); + + AddResourceInitChunk(texture); } return true; @@ -4135,6 +4166,8 @@ bool WrappedOpenGL::Serialise_glTextureStorage2DMultisampleEXT(SerialiserType &s else m_Real.glTextureStorage2DMultisample(texture.name, samples, internalformat, width, height, fixedsamplelocations); + + AddResourceInitChunk(texture); } return true; @@ -4310,6 +4343,8 @@ bool WrappedOpenGL::Serialise_glTextureStorage3DMultisampleEXT(SerialiserType &s else m_Real.glTextureStorage3DMultisample(texture.name, samples, internalformat, width, height, depth, fixedsamplelocations); + + AddResourceInitChunk(texture); } return true; @@ -5732,9 +5767,9 @@ bool WrappedOpenGL::Serialise_glTextureBufferRangeEXT(SerialiserType &ser, GLuin if(IsReplayingAndReading()) { + ResourceId liveId = GetResourceManager()->GetID(texture); if(IsLoading(m_State) && m_CurEventID == 0) { - ResourceId liveId = GetResourceManager()->GetID(texture); m_Textures[liveId].width = uint32_t(size) / uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(internalformat), GetDataType(internalformat))); @@ -5751,6 +5786,9 @@ bool WrappedOpenGL::Serialise_glTextureBufferRangeEXT(SerialiserType &ser, GLuin else m_Real.glTextureBufferRange(texture.name, internalformat, buffer.name, (GLintptr)offs, (GLsizei)size); + + AddResourceInitChunk(texture); + DerivedResource(buffer, GetResourceManager()->GetOriginalID(liveId)); } return true; @@ -5901,9 +5939,9 @@ bool WrappedOpenGL::Serialise_glTextureBufferEXT(SerialiserType &ser, GLuint tex if(IsReplayingAndReading()) { + ResourceId liveId = GetResourceManager()->GetID(texture); if(IsLoading(m_State) && m_CurEventID == 0) { - ResourceId liveId = GetResourceManager()->GetID(texture); uint32_t Size = 1; m_Real.glGetNamedBufferParameterivEXT(buffer.name, eGL_BUFFER_SIZE, (GLint *)&Size); m_Textures[liveId].width = Size / uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(internalformat), @@ -5919,6 +5957,9 @@ bool WrappedOpenGL::Serialise_glTextureBufferEXT(SerialiserType &ser, GLuint tex m_Real.glTextureBufferEXT(texture.name, target, internalformat, buffer.name); else m_Real.glTextureBuffer(texture.name, internalformat, buffer.name); + + AddResourceInitChunk(texture); + DerivedResource(buffer, GetResourceManager()->GetOriginalID(liveId)); } return true; diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 632105746..ed6131acc 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -290,6 +290,7 @@ enum class VulkanChunk : uint32_t vkFlushMappedMemoryRanges, vkCreateCommandPool, vkResetCommandPool, + vkAllocateCommandBuffers, vkCreateFramebuffer, vkCreateRenderPass, vkCreateDescriptorPool, diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 5bb281b41..87da0e7fa 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1385,6 +1385,36 @@ bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) return true; } +void WrappedVulkan::AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix) +{ + ResourceDescription &descr = GetReplay()->GetResourceDesc(id); + + uint64_t num; + memcpy(&num, &id, sizeof(uint64_t)); + descr.name = defaultNamePrefix + (" " + ToStr(num)); + descr.autogeneratedName = true; + descr.type = type; + AddResourceCurChunk(descr); +} + +void WrappedVulkan::DerivedResource(ResourceId parentLive, ResourceId child) +{ + ResourceId parentId = GetResourceManager()->GetOriginalID(parentLive); + + GetReplay()->GetResourceDesc(parentId).derivedResources.push_back(child); + GetReplay()->GetResourceDesc(child).parentResources.push_back(parentId); +} + +void WrappedVulkan::AddResourceCurChunk(ResourceDescription &descr) +{ + descr.initialisationChunks.push_back((uint32_t)m_StructuredFile->chunks.size() - 1); +} + +void WrappedVulkan::AddResourceCurChunk(ResourceId id) +{ + AddResourceCurChunk(GetReplay()->GetResourceDesc(id)); +} + void WrappedVulkan::ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) { int sectionIdx = rdc->SectionIndex(SectionType::FrameCapture); @@ -1785,6 +1815,9 @@ void WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk) case VulkanChunk::vkCreateCommandPool: Serialise_vkCreateCommandPool(ser, VK_NULL_HANDLE, NULL, NULL, NULL); break; + case VulkanChunk::vkAllocateCommandBuffers: + Serialise_vkAllocateCommandBuffers(ser, VK_NULL_HANDLE, NULL, NULL); + break; case VulkanChunk::vkCreateFramebuffer: Serialise_vkCreateFramebuffer(ser, VK_NULL_HANDLE, NULL, NULL, NULL); break; @@ -2082,6 +2115,8 @@ void WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk) { VkInitParams InitParams; SERIALISE_ELEMENT(InitParams); + + AddResourceCurChunk(InitParams.InstanceID); } else if(system == SystemChunk::InitialContentsList) { diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index ef388548d..00bba02df 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -262,6 +262,16 @@ private: SDFile *m_StructuredFile; SDFile m_StoredStructuredData; + void AddResource(ResourceId id, ResourceType type, const char *defaultNamePrefix); + void DerivedResource(ResourceId parentLive, ResourceId child); + template + void DerivedResource(VulkanType parent, ResourceId child) + { + DerivedResource(GetResID(parent), child); + } + void AddResourceCurChunk(ResourceDescription &descr); + void AddResourceCurChunk(ResourceId id); + // util function to handle fetching the right eventID, calling any // aliases then calling PreDraw/PreDispatch. uint32_t HandlePreCallback(VkCommandBuffer commandBuffer, DrawFlags type = DrawFlags::Drawcall, diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 0e934d6b7..137afd589 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -531,6 +531,11 @@ bool WrappedVulkan::Serialise_InitialState(SerialiserType &ser, ResourceId id, W SERIALISE_ELEMENT(type); SERIALISE_ELEMENT(id); + if(IsReplayingAndReading()) + { + AddResourceCurChunk(id); + } + if(type == eResDescriptorSet) { DescriptorSetSlot *Bindings = NULL; diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index 838159724..e9379ebc6 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -178,7 +178,14 @@ public: // either allocation or freeing happens, so we only need to // lock against concurrent allocs or deletes of children. - if(record && record->bakedCommands) + if(ToTypedHandle(obj).type == eResCommandBuffer && record->cmdInfo && + record->cmdInfo->allocRecord) + { + record->cmdInfo->allocRecord->Delete(this); + record->cmdInfo->allocRecord = NULL; + } + + if(record->bakedCommands) { record->bakedCommands->Delete(this); record->bakedCommands = NULL; diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 359248bba..45fe26c34 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -872,7 +872,8 @@ struct CmdBufferRecordingInfo VkDevice device; VkCommandBufferAllocateInfo allocInfo; - VkResourceRecord *framebuffer; + VkResourceRecord *framebuffer = NULL; + VkResourceRecord *allocRecord = NULL; vector > imgbarriers; diff --git a/renderdoc/driver/vulkan/vk_stringise.cpp b/renderdoc/driver/vulkan/vk_stringise.cpp index 194c6712a..e48ff5b43 100644 --- a/renderdoc/driver/vulkan/vk_stringise.cpp +++ b/renderdoc/driver/vulkan/vk_stringise.cpp @@ -28,7 +28,7 @@ template <> std::string DoStringise(const VulkanChunk &el) { - RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1099, "Chunks changed without updating names"); + RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1100, "Chunks changed without updating names"); BEGIN_ENUM_STRINGISE(VulkanChunk) { @@ -40,6 +40,7 @@ std::string DoStringise(const VulkanChunk &el) STRINGISE_ENUM_CLASS(vkFlushMappedMemoryRanges); STRINGISE_ENUM_CLASS(vkCreateCommandPool); STRINGISE_ENUM_CLASS(vkResetCommandPool); + STRINGISE_ENUM_CLASS(vkAllocateCommandBuffers); STRINGISE_ENUM_CLASS(vkCreateFramebuffer); STRINGISE_ENUM_CLASS(vkCreateRenderPass); STRINGISE_ENUM_CLASS(vkCreateDescriptorPool); diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 4f05e859f..b70c8bf0a 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -341,6 +341,9 @@ bool WrappedVulkan::Serialise_vkCreateCommandPool(SerialiserType &ser, VkDevice ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); GetResourceManager()->AddLiveResource(CmdPool, pool); } + + AddResource(CmdPool, ResourceType::Pool, "Command Pool"); + DerivedResource(device, CmdPool); } return true; @@ -397,6 +400,45 @@ void WrappedVulkan::vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandP // Command buffer functions +template +bool WrappedVulkan::Serialise_vkAllocateCommandBuffers(SerialiserType &ser, VkDevice device, + const VkCommandBufferAllocateInfo *pAllocateInfo, + VkCommandBuffer *pCommandBuffers) +{ + SERIALISE_ELEMENT(device); + SERIALISE_ELEMENT_LOCAL(AllocateInfo, *pAllocateInfo); + SERIALISE_ELEMENT_LOCAL(CommandBuffer, GetResID(*pCommandBuffers)); + + // this chunk is purely for user information and consistency, the command buffer we allocate is + // a dummy and is not used for anything. + + if(IsReplayingAndReading()) + { + VkCommandBuffer cmd = VK_NULL_HANDLE; + + VkCommandBufferAllocateInfo unwrappedInfo = AllocateInfo; + unwrappedInfo.commandBufferCount = 1; + unwrappedInfo.commandPool = Unwrap(unwrappedInfo.commandPool); + VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &unwrappedInfo, &cmd); + + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cmd); + GetResourceManager()->AddLiveResource(CommandBuffer, cmd); + } + + AddResource(CommandBuffer, ResourceType::CommandBuffer, "Command Buffer"); + DerivedResource(device, CommandBuffer); + DerivedResource(AllocateInfo.commandPool, CommandBuffer); + } + + return true; +} + VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers) @@ -426,6 +468,27 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device, { VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pCommandBuffers[i]); + Chunk *chunk = NULL; + + { + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkAllocateCommandBuffers); + Serialise_vkAllocateCommandBuffers(ser, device, pAllocateInfo, pCommandBuffers + i); + + chunk = scope.Get(); + } + + // a bit of a hack, we make a parallel resource record with the same lifetime as the command + // buffer and make it a parent, so it will hold onto our allocation chunk and not try to + // record it (and throw it away with baked commands that are unused), then it'll be pulled + // into the capture. + VkResourceRecord *allocRecord = + GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); + allocRecord->SpecialResource = true; + allocRecord->AddChunk(chunk); + record->AddParent(allocRecord); + record->bakedCommands = NULL; record->pool = GetRecord(pAllocateInfo->commandPool); @@ -449,6 +512,7 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device, record->cmdInfo->device = device; record->cmdInfo->allocInfo = *pAllocateInfo; record->cmdInfo->allocInfo.commandBufferCount = 1; + record->cmdInfo->allocRecord = allocRecord; } else { @@ -618,6 +682,16 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman GetResourceManager()->AddLiveResource(BakedCommandBuffer, cmd); } + AddResource(BakedCommandBuffer, ResourceType::CommandBuffer, "Baked Command Buffer"); + GetReplay()->GetResourceDesc(BakedCommandBuffer).initialisationChunks.clear(); + DerivedResource(device, BakedCommandBuffer); + DerivedResource(AllocateInfo.commandPool, BakedCommandBuffer); + + // do this one manually since there's no live version of the swapchain, and + // DerivedResource() assumes we're passing it a live ID (or live resource) + GetReplay()->GetResourceDesc(CommandBuffer).derivedResources.push_back(BakedCommandBuffer); + GetReplay()->GetResourceDesc(BakedCommandBuffer).parentResources.push_back(CommandBuffer); + // whenever a vkCmd command-building chunk asks for the command buffer, it // will get our baked version. if(GetResourceManager()->HasReplacement(m_LastCmdBufferID)) @@ -2725,6 +2799,10 @@ INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateCommandPool, VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool); +INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkAllocateCommandBuffers, VkDevice device, + const VkCommandBufferAllocateInfo *pAllocateInfo, + VkCommandBuffer *pCommandBuffers); + INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkBeginCommandBuffer, VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo); diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index c3362502b..1c86c3af9 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -180,6 +180,9 @@ bool WrappedVulkan::Serialise_vkCreateDescriptorPool(SerialiserType &ser, VkDevi ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); GetResourceManager()->AddLiveResource(DescriptorPool, pool); } + + AddResource(DescriptorPool, ResourceType::Pool, "Descriptor Pool"); + DerivedResource(device, DescriptorPool); } return true; @@ -265,6 +268,22 @@ bool WrappedVulkan::Serialise_vkCreateDescriptorSetLayout( m_CreationInfo.m_DescSetLayout[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } + + AddResource(SetLayout, ResourceType::ShaderBinding, "Descriptor Layout"); + DerivedResource(device, SetLayout); + + for(uint32_t i = 0; i < CreateInfo.bindingCount; i++) + { + bool usesSampler = + CreateInfo.pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + CreateInfo.pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + + if(usesSampler && CreateInfo.pBindings[i].pImmutableSamplers != NULL) + { + for(uint32_t d = 0; d < CreateInfo.pBindings[i].descriptorCount; d++) + DerivedResource(CreateInfo.pBindings[i].pImmutableSamplers[d], SetLayout); + } + } } } @@ -360,6 +379,10 @@ bool WrappedVulkan::Serialise_vkAllocateDescriptorSets(SerialiserType &ser, VkDe m_CreationInfo.m_DescSetLayout[layoutId].CreateBindingsArray( m_DescriptorSetState[live].currentBindings); } + + AddResource(DescriptorSet, ResourceType::ShaderBinding, "Descriptor Set"); + DerivedResource(device, DescriptorSet); + DerivedResource(AllocateInfo.pSetLayouts[0], DescriptorSet); } return true; diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index c382e6037..3405fe7d5 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -239,6 +239,10 @@ ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVer GetResourceManager()->WrapResource(m_Instance, m_Instance); GetResourceManager()->AddLiveResource(params.InstanceID, m_Instance); + // we'll add the chunk later when we re-process it. + AddResource(params.InstanceID, ResourceType::Device, "Instance"); + GetReplay()->GetResourceDesc(params.InstanceID).initialisationChunks.clear(); + InitInstanceExtensionTables(m_Instance, &extInfo); m_DbgMsgCallback = VK_NULL_HANDLE; @@ -667,6 +671,9 @@ bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(SerialiserType &ser, Vk GetResourceManager()->ReplaceResource(PhysicalDevice, GetResourceManager()->GetOriginalID(GetResID(pd))); + AddResource(PhysicalDevice, ResourceType::Device, "Physical Device"); + DerivedResource(m_Instance, PhysicalDevice); + if(PhysicalDeviceIndex >= m_PhysicalDevices.size()) m_PhysicalDevices.resize(PhysicalDeviceIndex + 1); m_PhysicalDevices[PhysicalDeviceIndex] = pd; @@ -1125,6 +1132,9 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi GetResourceManager()->WrapResource(device, device); GetResourceManager()->AddLiveResource(Device, device); + AddResource(Device, ResourceType::Device, "Device"); + DerivedResource(physicalDevice, Device); + InstanceDeviceInfo extInfo; #undef CheckExt diff --git a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp index 64d16da97..aa5aacbf6 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp @@ -431,6 +431,9 @@ bool WrappedVulkan::Serialise_vkCreateSampler(SerialiserType &ser, VkDevice devi m_CreationInfo.m_Sampler[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } } + + AddResource(Sampler, ResourceType::Sampler, "Sampler"); + DerivedResource(device, Sampler); } return true; @@ -556,6 +559,13 @@ bool WrappedVulkan::Serialise_vkCreateFramebuffer(SerialiserType &ser, VkDevice m_CreationInfo.m_Framebuffer[live] = fbinfo; } } + + AddResource(Framebuffer, ResourceType::RenderPass, "Framebuffer"); + DerivedResource(device, Framebuffer); + DerivedResource(CreateInfo.renderPass, Framebuffer); + + for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++) + DerivedResource(CreateInfo.pAttachments[i], Framebuffer); } return true; @@ -758,6 +768,9 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass(SerialiserType &ser, VkDevice d m_CreationInfo.m_RenderPass[live] = rpinfo; } } + + AddResource(RenderPass, ResourceType::RenderPass, "Render Pass"); + DerivedResource(device, RenderPass); } return true; @@ -916,6 +929,9 @@ bool WrappedVulkan::Serialise_vkCreateQueryPool(SerialiserType &ser, VkDevice de vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERTEQUAL(vkr, VK_SUCCESS); } + + AddResource(QueryPool, ResourceType::Query, "Query Pool"); + DerivedResource(device, QueryPool); } return true; @@ -1139,6 +1155,8 @@ bool WrappedVulkan::Serialise_SetShaderDebugPath(SerialiserType &ser, VkDevice d { m_CreationInfo.m_ShaderModule[GetResourceManager()->GetLiveID(ShaderObject)].unstrippedPath = DebugPath; + + AddResourceCurChunk(ShaderObject); } return true; @@ -1218,6 +1236,11 @@ bool WrappedVulkan::Serialise_vkDebugMarkerSetObjectNameEXT( m_CreationInfo.m_Names[Object] = ObjectName; else m_CreationInfo.m_Names[GetResourceManager()->GetLiveID(Object)] = ObjectName; + + ResourceDescription &descr = GetReplay()->GetResourceDesc(Object); + + AddResourceCurChunk(descr); + descr.SetCustomName(ObjectName); } return true; diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index e3779d5f0..4cdb565ff 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -51,6 +51,9 @@ bool WrappedVulkan::Serialise_vkGetDeviceQueue(SerialiserType &ser, VkDevice dev // manager on vkCreateDevice) SubmitCmds(); } + + AddResource(Queue, ResourceType::Queue, "Queue"); + DerivedResource(device, Queue); } return true; diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index c19f5e62f..90dda9104 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -204,6 +204,9 @@ bool WrappedVulkan::Serialise_vkAllocateMemory(SerialiserType &ser, VkDevice dev m_CreationInfo.m_Memory[live].wholeMemBuf = buf; } + + AddResource(Memory, ResourceType::Memory, "Memory"); + DerivedResource(device, Memory); } return true; @@ -843,8 +846,19 @@ bool WrappedVulkan::Serialise_vkBindBufferMemory(SerialiserType &ser, VkDevice d SERIALISE_ELEMENT(memoryOffset); if(IsReplayingAndReading()) + { ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buffer), Unwrap(memory), memoryOffset); + ResourceId resOrigId = GetResourceManager()->GetOriginalID(GetResID(buffer)); + ResourceId memOrigId = GetResourceManager()->GetOriginalID(GetResID(memory)); + + GetReplay()->GetResourceDesc(memOrigId).derivedResources.push_back(resOrigId); + GetReplay()->GetResourceDesc(resOrigId).parentResources.push_back(memOrigId); + + AddResourceCurChunk(memOrigId); + AddResourceCurChunk(resOrigId); + } + return true; } @@ -889,8 +903,19 @@ bool WrappedVulkan::Serialise_vkBindImageMemory(SerialiserType &ser, VkDevice de SERIALISE_ELEMENT(memoryOffset); if(IsReplayingAndReading()) + { ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(image), Unwrap(memory), memoryOffset); + ResourceId resOrigId = GetResourceManager()->GetOriginalID(GetResID(image)); + ResourceId memOrigId = GetResourceManager()->GetOriginalID(GetResID(memory)); + + GetReplay()->GetResourceDesc(memOrigId).derivedResources.push_back(resOrigId); + GetReplay()->GetResourceDesc(resOrigId).parentResources.push_back(memOrigId); + + AddResourceCurChunk(memOrigId); + AddResourceCurChunk(resOrigId); + } + return true; } @@ -962,6 +987,9 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } + + AddResource(Buffer, ResourceType::Buffer, "Buffer"); + DerivedResource(device, Buffer); } return true; @@ -1078,6 +1106,10 @@ bool WrappedVulkan::Serialise_vkCreateBufferView(SerialiserType &ser, VkDevice d m_CreationInfo.m_BufferView[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } } + + AddResource(View, ResourceType::View, "Buffer View"); + DerivedResource(device, View); + DerivedResource(CreateInfo.buffer, View); } return true; @@ -1210,6 +1242,39 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device layouts.subresourceStates.push_back( ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); } + + const char *prefix = "Image"; + + if(CreateInfo.imageType == VK_IMAGE_TYPE_1D) + { + prefix = CreateInfo.arrayLayers > 1 ? "1D Array Image" : "1D Image"; + + if(CreateInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + prefix = "1D Color Attachment"; + else if(CreateInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) + prefix = "1D Depth Attachment"; + } + else if(CreateInfo.imageType == VK_IMAGE_TYPE_2D) + { + prefix = CreateInfo.arrayLayers > 1 ? "2D Array Image" : "2D Image"; + + if(CreateInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + prefix = "2D Color Attachment"; + else if(CreateInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) + prefix = "2D Depth Attachment"; + } + else if(CreateInfo.imageType == VK_IMAGE_TYPE_3D) + { + prefix = "3D Image"; + + if(CreateInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + prefix = "3D Color Attachment"; + else if(CreateInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) + prefix = "3D Depth Attachment"; + } + + AddResource(Image, ResourceType::Texture, prefix); + DerivedResource(device, Image); } return true; @@ -1448,6 +1513,10 @@ bool WrappedVulkan::Serialise_vkCreateImageView(SerialiserType &ser, VkDevice de m_CreationInfo.m_ImageView[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } } + + AddResource(View, ResourceType::View, "Image View"); + DerivedResource(device, View); + DerivedResource(CreateInfo.image, View); } return true; diff --git a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp index e6e47405d..a5c5f9455 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp @@ -136,6 +136,11 @@ bool WrappedVulkan::Serialise_vkCreatePipelineLayout(SerialiserType &ser, VkDevi m_CreationInfo.m_PipelineLayout[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } } + + AddResource(PipelineLayout, ResourceType::ShaderBinding, "Pipeline Layout"); + DerivedResource(device, PipelineLayout); + for(uint32_t i = 0; i < CreateInfo.setLayoutCount; i++) + DerivedResource(CreateInfo.pSetLayouts[i], PipelineLayout); } return true; @@ -231,6 +236,9 @@ bool WrappedVulkan::Serialise_vkCreateShaderModule(SerialiserType &ser, VkDevice m_CreationInfo.m_ShaderModule[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } } + + AddResource(ShaderModule, ResourceType::Shader, "Shader Module"); + DerivedResource(device, ShaderModule); } return true; @@ -302,6 +310,9 @@ bool WrappedVulkan::Serialise_vkCreatePipelineCache(SerialiserType &ser, VkDevic ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cache); GetResourceManager()->AddLiveResource(PipelineCache, cache); } + + AddResource(PipelineCache, ResourceType::Pool, "Pipeline Cache"); + DerivedResource(device, PipelineCache); } return true; @@ -372,6 +383,9 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines( { VkPipeline pipe = VK_NULL_HANDLE; + VkRenderPass origRP = CreateInfo.renderPass; + VkPipelineCache origCache = pipelineCache; + // don't use pipeline caches on replay pipelineCache = VK_NULL_HANDLE; @@ -424,6 +438,16 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines( GetResourceManager()->AddLiveResource(subpass0id, pipeInfo.subpass0pipe); } } + + AddResource(Pipeline, ResourceType::PipelineState, "Graphics Pipeline"); + DerivedResource(device, Pipeline); + DerivedResource(origCache, Pipeline); + if(CreateInfo.basePipelineHandle != VK_NULL_HANDLE) + DerivedResource(CreateInfo.basePipelineHandle, Pipeline); + DerivedResource(origRP, Pipeline); + DerivedResource(CreateInfo.layout, Pipeline); + for(uint32_t i = 0; i < CreateInfo.stageCount; i++) + DerivedResource(CreateInfo.pStages[i].module, Pipeline); } return true; @@ -534,6 +558,9 @@ bool WrappedVulkan::Serialise_vkCreateComputePipelines(SerialiserType &ser, VkDe { VkPipeline pipe = VK_NULL_HANDLE; + VkPipelineCache origCache = pipelineCache; + + // don't use pipeline caches on replay pipelineCache = VK_NULL_HANDLE; VkComputePipelineCreateInfo *unwrapped = UnwrapInfos(&CreateInfo, 1); @@ -567,6 +594,14 @@ bool WrappedVulkan::Serialise_vkCreateComputePipelines(SerialiserType &ser, VkDe m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &CreateInfo); } } + + AddResource(Pipeline, ResourceType::PipelineState, "Graphics Pipeline"); + DerivedResource(device, Pipeline); + DerivedResource(origCache, Pipeline); + if(CreateInfo.basePipelineHandle != VK_NULL_HANDLE) + DerivedResource(CreateInfo.basePipelineHandle, Pipeline); + DerivedResource(CreateInfo.layout, Pipeline); + DerivedResource(CreateInfo.stage.module, Pipeline); } return true; diff --git a/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp index d94cf1186..8b57ca662 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp @@ -95,6 +95,9 @@ bool WrappedVulkan::Serialise_vkCreateFence(SerialiserType &ser, VkDevice device ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), fence); GetResourceManager()->AddLiveResource(Fence, fence); } + + AddResource(Fence, ResourceType::Sync, "Fence"); + DerivedResource(device, Fence); } return true; @@ -279,6 +282,9 @@ bool WrappedVulkan::Serialise_vkCreateEvent(SerialiserType &ser, VkDevice device ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), ev); GetResourceManager()->AddLiveResource(Event, ev); } + + AddResource(Event, ResourceType::Sync, "Event"); + DerivedResource(device, Event); } return true; @@ -468,6 +474,9 @@ bool WrappedVulkan::Serialise_vkCreateSemaphore(SerialiserType &ser, VkDevice de GetResourceManager()->AddLiveResource(Semaphore, sem); } } + + AddResource(Semaphore, ResourceType::Sync, "Semaphore"); + DerivedResource(device, Semaphore); } return true; diff --git a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp index 006d72be0..5ab02c6cd 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp @@ -196,6 +196,14 @@ bool WrappedVulkan::Serialise_vkGetSwapchainImagesKHR(SerialiserType &ser, VkDev swapInfo.images.size()); GetResourceManager()->AddLiveResource(SwapchainImage, swapInfo.images[SwapchainImageIndex].im); + AddResource(SwapchainImage, ResourceType::SwapchainImage, "Swapchain Image"); + DerivedResource(device, SwapchainImage); + + // do this one manually since there's no live version of the swapchain, and DerivedResource() + // assumes we're passing it a live ID (or live resource) + GetReplay()->GetResourceDesc(Swapchain).derivedResources.push_back(SwapchainImage); + GetReplay()->GetResourceDesc(SwapchainImage).parentResources.push_back(Swapchain); + m_CreationInfo.m_Image[GetResID(swapInfo.images[SwapchainImageIndex].im)] = m_CreationInfo.m_Image[Swapchain]; } @@ -299,6 +307,9 @@ bool WrappedVulkan::Serialise_vkCreateSwapchainKHR(SerialiserType &ser, VkDevice // use original ID because we don't create a live version of the swapchain SwapchainInfo &swapinfo = m_CreationInfo.m_SwapChain[SwapChain]; + AddResource(SwapChain, ResourceType::SwapchainImage, "Swapchain"); + DerivedResource(device, SwapChain); + swapinfo.format = CreateInfo.imageFormat; swapinfo.extent = CreateInfo.imageExtent; swapinfo.arraySize = CreateInfo.imageArrayLayers;