From e7991c07ebf53ca42298b1bfdabd9a7e5053d0e5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 11 Jan 2018 16:44:57 +0000 Subject: [PATCH] Add ability to create a mapping from RGP linear/interopId <=> eventId --- qrenderdoc/Code/CaptureContext.cpp | 101 +++++++++++++++++++++++ qrenderdoc/Code/CaptureContext.h | 19 +++++ qrenderdoc/Code/Interface/QRDInterface.h | 25 ++++++ qrenderdoc/Windows/PythonShell.cpp | 12 +++ 4 files changed, 157 insertions(+) diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 15dd464a2..74f4aa813 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -799,6 +799,9 @@ void CaptureContext::CloseCapture() if(!m_CaptureLoaded) return; + m_RGP2Event.clear(); + m_Event2RGP.clear(); + m_Config.CrashReport_LastOpenedCapture = QString(); m_CaptureTemporary = false; @@ -1080,6 +1083,104 @@ void CaptureContext::LoadNotes(const QString &data) } } +void CaptureContext::CreateRGPMapping(uint32_t version) +{ + m_RGP2Event.clear(); + m_Event2RGP.clear(); + + if(!m_CaptureLoaded) + return; + + if(!m_StructuredFile) + { + qCritical() << "Capture not loaded correctly - no structured data"; + return; + } + + if(version != 0) + { + qCritical() << "Unsupported version" << version; + return; + } + + QStringList eventNames; + + if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) + { + eventNames << lit("vkCmdDispatch") << lit("vkCmdDispatchIndirect") << lit("vkCmdDraw") + << lit("vkCmdDrawIndexed") << lit("vkCmdDrawIndirect") + << lit("vkCmdDrawIndexedIndirect") << lit("vkCmdClearColorImage") + << lit("vkCmdClearDepthStencilImage") << lit("vkCmdClearAttachments") + << lit("vkCmdPipelineBarrier") << lit("vkCmdCopyBuffer") << lit("vkCmdCopyImage") + << lit("vkCmdBlitImage") << lit("vkCmdCopyBufferToImage") + << lit("vkCmdCopyImageToBuffer") << lit("vkCmdUpdateBuffer") + << lit("vkCmdFillBuffer") << lit("vkCmdResolveImage") << lit("vkCmdResetQueryPool") + << lit("vkCmdCopyQueryPoolResults") << lit("vkCmdWaitEvents"); + } + else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) + { + // these names must match those in DoStringise(const D3D12Chunk &el) for the chunks + eventNames << lit("ID3D12GraphicsCommandList::Dispatch") + << lit("ID3D12GraphicsCommandList::DrawInstanced") + << lit("ID3D12GraphicsCommandList::DrawIndexedInstanced") + << lit("ID3D12GraphicsCommandList::ClearDepthStencilView") + << lit("ID3D12GraphicsCommandList::ClearRenderTargetView") + << lit("ID3D12GraphicsCommandList::ClearUnorderedAccessViewFloat") + << lit("ID3D12GraphicsCommandList::ClearUnorderedAccessViewUint") + << lit("ID3D12GraphicsCommandList::ResourceBarrier") + << lit("ID3D12GraphicsCommandList::CopyTextureRegion") + << lit("ID3D12GraphicsCommandList::CopyBufferRegion") + << lit("ID3D12GraphicsCommandList::CopyResource") + << lit("ID3D12GraphicsCommandList::CopyTiles") + << lit("ID3D12GraphicsCommandList::ResolveSubresource") + << lit("ID3D12GraphicsCommandList::ResolveSubresourceRegion") + << lit("ID3D12GraphicsCommandList::DiscardResource") + << lit("ID3D12GraphicsCommandList::ResolveQueryData") + << lit("ID3D12GraphicsCommandList::ExecuteIndirect") + << lit("ID3D12GraphicsCommandList::ExecuteBundle"); + } + + // if we don't have any event names, this API doesn't have a mapping. + if(eventNames.isEmpty()) + return; + + m_Event2RGP.resize(m_LastDrawcall->eventId + 1); + + // linearId 0 is invalid, so map to eventId 0. + // the first real event will be linearId 1 + m_RGP2Event.push_back(0); + + // iterate over all draws depth-first, to enumerate events + CreateRGPMapping(eventNames, m_Drawcalls); +} + +void CaptureContext::CreateRGPMapping(const QStringList &eventNames, + const rdcarray &drawcalls) +{ + const SDFile &file = *m_StructuredFile; + + for(const DrawcallDescription &draw : drawcalls) + { + for(const APIEvent &ev : draw.events) + { + if(ev.chunkIndex == 0 || ev.chunkIndex >= file.chunks.size()) + continue; + + const SDChunk *chunk = file.chunks[ev.chunkIndex]; + + if(eventNames.contains(chunk->name, Qt::CaseSensitive)) + { + m_Event2RGP[ev.eventId] = (uint32_t)m_RGP2Event.size(); + m_RGP2Event.push_back(ev.eventId); + } + } + + // if we have children, step into them first before going to our next sibling + if(!draw.children.empty()) + CreateRGPMapping(eventNames, draw.children); + } +} + rdcstr CaptureContext::GetResourceName(ResourceId id) { if(id == ResourceId()) diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index e45dd400b..9e306888a 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -114,6 +114,19 @@ public: const DrawcallDescription *CurDrawcall() override { return GetDrawcall(CurEvent()); } const DrawcallDescription *GetFirstDrawcall() override { return m_FirstDrawcall; }; const DrawcallDescription *GetLastDrawcall() override { return m_LastDrawcall; }; + void CreateRGPMapping(uint32_t version) override; + uint32_t GetRGPIdFromEventId(uint32_t eventId) override + { + if(eventId >= m_Event2RGP.size()) + return 0; + return m_Event2RGP[eventId]; + } + uint32_t GetEventIdFromRGPId(uint32_t RGPId) override + { + if(RGPId >= m_RGP2Event.size()) + return 0; + return m_RGP2Event[RGPId]; + } const rdcarray &CurDrawcalls() override { return m_Drawcalls; } ResourceDescription *GetResource(ResourceId id) override { return m_Resources[id]; } const rdcarray &GetResources() override { return m_ResourceList; } @@ -246,6 +259,9 @@ private: rdcarray m_DebugMessages; int m_UnreadMessageCount = 0; + void CreateRGPMapping(const QStringList &eventNames, + const rdcarray &drawcalls); + bool PassEquivalent(const DrawcallDescription &a, const DrawcallDescription &b); bool ContainsMarker(const rdcarray &m_Drawcalls); void AddFakeProfileMarkers(); @@ -297,6 +313,9 @@ private: DrawcallDescription *m_FirstDrawcall = NULL; DrawcallDescription *m_LastDrawcall = NULL; + rdcarray m_Event2RGP; + rdcarray m_RGP2Event; + QMap m_Textures; rdcarray m_TextureList; QMap m_Buffers; diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index 3dd697543..297b77018 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -1279,6 +1279,31 @@ considered out of date )"); virtual const DrawcallDescription *GetDrawcall(uint32_t eventId) = 0; + DOCUMENT(R"(Creates a mapping from eventId to/from RGP linearId for the current capture. + +Does nothing if no capture is loaded. + +:param int version: The version of mapping to use, determining which events are counted. +)"); + virtual void CreateRGPMapping(uint32_t version) = 0; + + DOCUMENT(R"(Get the RGP linearId from an :data:`eventId `. + +:param int eventId: The :data:`eventId ` to query for. +:return: The linearId, or ``0`` if no linearId corresponds to this event. +:rtype: int +)"); + virtual uint32_t GetRGPIdFromEventId(uint32_t eventId) = 0; + + DOCUMENT(R"(Get the :data:`eventId ` from an RGP linearId. + +:param int RGPId: The RGP linearId to query for. +:return: The :data:`eventId `, or ``0`` if no eventId can be found + corresponding to this linearId. +:rtype: int +)"); + virtual uint32_t GetEventIdFromRGPId(uint32_t RGPId) = 0; + DOCUMENT(R"(Retrieve the :class:`~renderdoc.SDFile` for the currently open capture. :return: The structured file. diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index 760214e07..ba9e55565 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -99,6 +99,18 @@ struct CaptureContextInvoker : ICaptureContext { return m_Ctx.GetDrawcall(eventId); } + virtual void CreateRGPMapping(uint32_t version) override + { + return m_Ctx.CreateRGPMapping(version); + } + virtual uint32_t GetRGPIdFromEventId(uint32_t eventId) override + { + return m_Ctx.GetRGPIdFromEventId(eventId); + } + virtual uint32_t GetEventIdFromRGPId(uint32_t RGPId) override + { + return m_Ctx.GetEventIdFromRGPId(RGPId); + } virtual const SDFile &GetStructuredFile() override { return m_Ctx.GetStructuredFile(); } virtual WindowingSystem CurWindowingSystem() override { return m_Ctx.CurWindowingSystem(); } virtual WindowingData CreateWindowingData(uintptr_t winId) override