From 8aa515a47a57ba6cb7719fce53987f61ca35871c Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 20 May 2019 12:24:41 +0100 Subject: [PATCH] Make drivers m_Events a direct lookup * Rather than doing an expensive iteration for looking up m_Events, just index by eventId which will be very dense. --- renderdoc/api/replay/data_types.h | 6 ++--- renderdoc/driver/d3d11/d3d11_context.cpp | 20 +++++++++------- renderdoc/driver/d3d11/d3d11_context.h | 2 +- renderdoc/driver/d3d12/d3d12_commands.cpp | 24 +++++++++---------- renderdoc/driver/gl/gl_driver.cpp | 18 ++++++++------ .../driver/gl/wrappers/gl_draw_funcs.cpp | 14 +++++------ renderdoc/driver/vulkan/vk_core.cpp | 22 +++++++---------- .../driver/vulkan/wrappers/vk_queue_funcs.cpp | 3 ++- 8 files changed, 56 insertions(+), 53 deletions(-) diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 78d9c38b6..dd3780bbd 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -558,20 +558,20 @@ Also eventIds may not correspond directly to an actual function call - sometimes a multi draw indirect will be one function call that expands to multiple events to allow inspection of results part way through the multi draw. )"); - uint32_t eventId; + uint32_t eventId = 0; DOCUMENT("A list of addresses in the CPU callstack where this function was called."); rdcarray callstack; DOCUMENT("The chunk index for this function call in the structured file."); - uint32_t chunkIndex; + uint32_t chunkIndex = 0; DOCUMENT(R"(A byte offset in the data stream where this event happens. .. note:: This should only be used as a relative measure, it is not a literal number of bytes from the start of the file on disk. )"); - uint64_t fileOffset; + uint64_t fileOffset = 0; }; DECLARE_REFLECTION_STRUCT(APIEvent); diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 712f9630c..52de928c1 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -1091,18 +1091,22 @@ void WrappedID3D11DeviceContext::AddEvent() m_CurEvents.push_back(apievent); if(IsLoading(m_State)) - m_Events.push_back(apievent); + { + m_Events.resize(apievent.eventId + 1); + m_Events[apievent.eventId] = apievent; + } } -const APIEvent &WrappedID3D11DeviceContext::GetEvent(uint32_t eventId) +const APIEvent &WrappedID3D11DeviceContext::GetEvent(uint32_t eventId) const { - for(const APIEvent &e : m_Events) - { - if(e.eventId >= eventId) - return e; - } + // start at where the requested eventId would be + size_t idx = eventId; - return m_Events.back(); + // find the next valid event (some may be skipped) + while(idx < m_Events.size() - 1 && m_Events[idx].eventId == 0) + idx++; + + return m_Events[RDCMIN(idx, m_Events.size() - 1)]; } void WrappedID3D11DeviceContext::ReplayFakeContext(ResourceId id) diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index f41d4e941..95114a5db 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -320,7 +320,7 @@ public: void ClearMaps(); uint32_t GetEventID() { return m_CurEventID; } - const APIEvent &GetEvent(uint32_t eventId); + const APIEvent &GetEvent(uint32_t eventId) const; const DrawcallDescription &GetRootDraw() { return m_ParentDrawcall; } void ThreadSafe_SetMarker(uint32_t col, const wchar_t *name); diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 8008b655a..6d44d4b35 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -391,13 +391,14 @@ std::string WrappedID3D12CommandQueue::GetChunkName(uint32_t idx) const APIEvent &WrappedID3D12CommandQueue::GetEvent(uint32_t eventId) { - for(const APIEvent &e : m_Cmd.m_Events) - { - if(e.eventId >= eventId) - return e; - } + // start at where the requested eventId would be + size_t idx = eventId; - return m_Cmd.m_Events.back(); + // find the next valid event (some may be skipped) + while(idx < m_Cmd.m_Events.size() - 1 && m_Cmd.m_Events[idx].eventId == 0) + idx++; + + return m_Cmd.m_Events[RDCMIN(idx, m_Cmd.m_Events.size() - 1)]; } bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chunk) @@ -841,11 +842,6 @@ ReplayStatus WrappedID3D12CommandQueue::ReplayLog(CaptureState readType, uint32_ m_StructuredFile = NULL; - if(IsLoading(m_State)) - { - std::sort(m_Cmd.m_Events.begin(), m_Cmd.m_Events.end()); - } - for(size_t i = 0; i < m_Cmd.m_RerecordCmdList.size(); i++) SAFE_RELEASE(m_Cmd.m_RerecordCmdList[i]); @@ -1392,7 +1388,8 @@ void D3D12CommandData::AddEvent() else { m_RootEvents.push_back(apievent); - m_Events.push_back(apievent); + m_Events.resize(apievent.eventId + 1); + m_Events[apievent.eventId] = apievent; for(auto it = m_EventMessages.begin(); it != m_EventMessages.end(); ++it) m_pDevice->AddDebugMessage(*it); @@ -1694,7 +1691,8 @@ void D3D12CommandData::InsertDrawsAndRefreshIDs(ResourceId cmd, for(APIEvent &ev : n.draw.events) { ev.eventId += m_RootEventID; - m_Events.push_back(ev); + m_Events.resize(ev.eventId + 1); + m_Events[ev.eventId] = ev; } DrawcallUse use(m_Events.back().fileOffset, n.draw.eventId, cmd, cmdBufNodes[i].draw.eventId); diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index fce4bf2ab..93d4f6722 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -4962,18 +4962,22 @@ void WrappedOpenGL::AddEvent() m_CurEvents.push_back(apievent); if(IsLoading(m_State)) - m_Events.push_back(apievent); + { + m_Events.resize(apievent.eventId + 1); + m_Events[apievent.eventId] = apievent; + } } const APIEvent &WrappedOpenGL::GetEvent(uint32_t eventId) { - for(const APIEvent &e : m_Events) - { - if(e.eventId >= eventId) - return e; - } + // start at where the requested eventId would be + size_t idx = eventId; - return m_Events.back(); + // find the next valid event (some may be skipped) + while(idx < m_Events.size() - 1 && m_Events[idx].eventId == 0) + idx++; + + return m_Events[RDCMIN(idx, m_Events.size() - 1)]; } const DrawcallDescription *WrappedOpenGL::GetDrawcall(uint32_t eventId) diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index e9ccd0ae2..0e49b461e 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -2103,7 +2103,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArrays(SerialiserType &ser, GLenum mode } else if(IsActiveReplaying(m_State)) { - size_t i = 0; + size_t i = m_CurEventID; for(; i < m_Events.size(); i++) { if(m_Events[i].eventId >= m_CurEventID) @@ -2265,7 +2265,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElements(SerialiserType &ser, GLenum mo } else if(IsActiveReplaying(m_State)) { - size_t i = 0; + size_t i = m_CurEventID; for(; i < m_Events.size(); i++) { if(m_Events[i].eventId >= m_CurEventID) @@ -2432,7 +2432,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsBaseVertex(SerialiserType &ser, } else if(IsActiveReplaying(m_State)) { - size_t i = 0; + size_t i = m_CurEventID; for(; i < m_Events.size(); i++) { if(m_Events[i].eventId >= m_CurEventID) @@ -2617,7 +2617,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(SerialiserType &ser, GLe } else if(IsActiveReplaying(m_State)) { - size_t i = 0; + size_t i = m_CurEventID; for(; i < m_Events.size(); i++) { if(m_Events[i].eventId >= m_CurEventID) @@ -2840,7 +2840,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(SerialiserType &ser, G } else if(IsActiveReplaying(m_State)) { - size_t i = 0; + size_t i = m_CurEventID; for(; i < m_Events.size(); i++) { if(m_Events[i].eventId >= m_CurEventID) @@ -3063,7 +3063,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirectCount(SerialiserType &ser } else if(IsActiveReplaying(m_State)) { - size_t i = 0; + size_t i = m_CurEventID; for(; i < m_Events.size(); i++) { if(m_Events[i].eventId >= m_CurEventID) @@ -3295,7 +3295,7 @@ bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirectCount(SerialiserType &s } else if(IsActiveReplaying(m_State)) { - size_t i = 0; + size_t i = m_CurEventID; for(; i < m_Events.size(); i++) { if(m_Events[i].eventId >= m_CurEventID) diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 44b4d9065..51f940006 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -2305,12 +2305,6 @@ ReplayStatus WrappedVulkan::ContextReplayLog(CaptureState readType, uint32_t sta SetupDrawcallPointers(m_Drawcalls, GetFrameRecord().drawcallList); - struct SortEID - { - bool operator()(const APIEvent &a, const APIEvent &b) { return a.eventId < b.eventId; } - }; - - std::sort(m_Events.begin(), m_Events.end(), SortEID()); m_ParentDrawcall.children.clear(); } @@ -3897,7 +3891,8 @@ void WrappedVulkan::AddEvent() else { m_RootEvents.push_back(apievent); - m_Events.push_back(apievent); + m_Events.resize(apievent.eventId + 1); + m_Events[apievent.eventId] = apievent; m_DebugMessages.insert(m_DebugMessages.end(), m_EventMessages.begin(), m_EventMessages.end()); } @@ -3907,13 +3902,14 @@ void WrappedVulkan::AddEvent() const APIEvent &WrappedVulkan::GetEvent(uint32_t eventId) { - for(const APIEvent &e : m_Events) - { - if(e.eventId >= eventId) - return e; - } + // start at where the requested eventId would be + size_t idx = eventId; - return m_Events.back(); + // find the next valid event (some may be skipped) + while(idx < m_Events.size() - 1 && m_Events[idx].eventId == 0) + idx++; + + return m_Events[RDCMIN(idx, m_Events.size() - 1)]; } const DrawcallDescription *WrappedVulkan::GetDrawcall(uint32_t eventId) diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index c47b78709..8b22d33b5 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -675,7 +675,8 @@ void WrappedVulkan::InsertDrawsAndRefreshIDs(BakedCmdBufferInfo &cmdBufInfo) for(APIEvent &ev : n.draw.events) { ev.eventId += m_RootEventID; - m_Events.push_back(ev); + m_Events.resize(ev.eventId + 1); + m_Events[ev.eventId] = ev; } if(!n.draw.events.empty())