From e05614c6bf1ea06d87ae2b3af182a28c8f74e6a5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 20 Dec 2015 17:33:56 +0100 Subject: [PATCH] Set up drawcall previous/next/parent IDs in replay drivers --- renderdoc/api/replay/basic_types.h | 3 ++ renderdoc/driver/d3d11/d3d11_device.cpp | 44 +++---------------------- renderdoc/driver/d3d11/d3d11_device.h | 2 +- renderdoc/driver/d3d11/d3d11_replay.cpp | 2 +- renderdoc/driver/gl/gl_driver.cpp | 44 +++---------------------- renderdoc/driver/gl/gl_driver.h | 3 +- renderdoc/driver/gl/gl_replay.cpp | 2 +- renderdoc/driver/vulkan/vk_core.cpp | 44 +++---------------------- renderdoc/driver/vulkan/vk_core.h | 2 +- renderdoc/driver/vulkan/vk_replay.cpp | 2 +- renderdoc/replay/replay_driver.h | 41 +++++++++++++++++++++++ renderdoc/replay/replay_renderer.cpp | 37 +-------------------- renderdoc/replay/replay_renderer.h | 1 - 13 files changed, 63 insertions(+), 164 deletions(-) diff --git a/renderdoc/api/replay/basic_types.h b/renderdoc/api/replay/basic_types.h index 9c245ea6b..8a670502e 100644 --- a/renderdoc/api/replay/basic_types.h +++ b/renderdoc/api/replay/basic_types.h @@ -72,6 +72,9 @@ struct array T &operator [](size_t i) { return elems[i]; } const T &operator [](size_t i) const { return elems[i]; } + + // to help simple template specializations for vector/rdctype::array + size_t size() { return (size_t)count; } array(const T *const in) { elems = 0; count = 0; *this = in; } array &operator =(const T *const in); diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index 8df72a72c..9ccc9abea 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -1068,6 +1068,8 @@ void WrappedID3D11Device::ReadLogInitialisation() break; } + SetupDrawcallPointers(&m_Drawcalls, m_FrameRecord.back().frameInfo.immContextId, m_FrameRecord.back().drawcallList, NULL, NULL); + for(auto it=chunkInfos.begin(); it != chunkInfos.end(); ++it) { double dcount = double(it->second.count); @@ -3411,48 +3413,10 @@ WrappedID3D11DeviceContext *WrappedID3D11Device::GetDeferredContext( size_t idx return *it; } -const FetchDrawcall *WrappedID3D11Device::GetDrawcall(const FetchDrawcall *draw, uint32_t eventID) -{ - if(draw == NULL) return NULL; - if(draw->eventID == eventID) return draw; - - int32_t count = draw->children.count; - for(int32_t i=0; i < count; i++) - { - const FetchDrawcall *cur = &draw->children.elems[i]; - const FetchDrawcall *next = i+1 < count ? &draw->children.elems[i+1] : NULL; - - if(next && next->eventID <= eventID) - continue; - - cur = GetDrawcall(cur, eventID); - - if(cur) - return cur; - } - - return NULL; -} - const FetchDrawcall *WrappedID3D11Device::GetDrawcall(uint32_t frameID, uint32_t eventID) { - if(frameID >= m_FrameRecord.size()) + if(eventID >= m_Drawcalls.size()) return NULL; - size_t count = m_FrameRecord[frameID].drawcallList.size(); - for(size_t i=0; i < count; i++) - { - const FetchDrawcall *cur = &m_FrameRecord[frameID].drawcallList[i]; - const FetchDrawcall *next = i+1 < count ? &m_FrameRecord[frameID].drawcallList[i+1] : NULL; - - if(next && next->eventID <= eventID) - continue; - - cur = GetDrawcall(cur, eventID); - - if(cur) - return cur; - } - - return NULL; + return m_Drawcalls[eventID]; } \ No newline at end of file diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index bcf1b1a3a..471ec28f6 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -267,7 +267,7 @@ private: vector m_DebugMessages; vector m_FrameRecord; - const FetchDrawcall *GetDrawcall(const FetchDrawcall *draw, uint32_t eventID); + vector m_Drawcalls; public: static const int AllocPoolCount = 4; ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Device, AllocPoolCount); diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 043affd75..52069546a 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1268,7 +1268,7 @@ vector D3D11Replay::GetPassEvents(uint32_t frameID, uint32_t eventID) if(start->flags & eDraw_Drawcall) passEvents.push_back(start->eventID); - start = m_pDevice->GetDrawcall((uint32_t)start->next, 0); + start = m_pDevice->GetDrawcall(frameID, (uint32_t)start->next); } return passEvents; diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 14e0ca726..415a7b382 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -3978,6 +3978,8 @@ void WrappedOpenGL::ContextReplayLog(LogState readType, uint32_t startEventID, u { GetFrameRecord().back().drawcallList = m_ParentDrawcall.Bake(); GetFrameRecord().back().frameInfo.debugMessages = GetDebugMessages(); + + SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().back().frameInfo.immContextId, GetFrameRecord().back().drawcallList, NULL, NULL); // it's easier to remove duplicate usages here than check it as we go. // this means if textures are bound in multiple places in the same draw @@ -4431,50 +4433,12 @@ FetchAPIEvent WrappedOpenGL::GetEvent(uint32_t eventID) return m_Events[0]; } -const FetchDrawcall *WrappedOpenGL::GetDrawcall(const FetchDrawcall *draw, uint32_t eventID) -{ - if(draw == NULL) return NULL; - if(draw->eventID == eventID) return draw; - - int32_t count = draw->children.count; - for(int32_t i=0; i < count; i++) - { - const FetchDrawcall *cur = &draw->children.elems[i]; - const FetchDrawcall *next = i+1 < count ? &draw->children.elems[i+1] : NULL; - - if(next && next->eventID <= eventID) - continue; - - cur = GetDrawcall(cur, eventID); - - if(cur) - return cur; - } - - return NULL; -} - const FetchDrawcall *WrappedOpenGL::GetDrawcall(uint32_t frameID, uint32_t eventID) { - if(frameID >= m_FrameRecord.size()) + if(eventID >= m_Drawcalls.size()) return NULL; - size_t count = m_FrameRecord[frameID].drawcallList.size(); - for(size_t i=0; i < count; i++) - { - const FetchDrawcall *cur = &m_FrameRecord[frameID].drawcallList[i]; - const FetchDrawcall *next = i+1 < count ? &m_FrameRecord[frameID].drawcallList[i+1] : NULL; - - if(next && next->eventID <= eventID) - continue; - - cur = GetDrawcall(cur, eventID); - - if(cur) - return cur; - } - - return NULL; + return m_Drawcalls[eventID]; } void WrappedOpenGL::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType) diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index fd5c6a03f..c48d48543 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -189,8 +189,7 @@ class WrappedOpenGL : public IFrameCapturer { if(!m_CoherentMaps.empty()) PersistentMapMemoryBarrier(m_CoherentMaps); } vector m_FrameRecord; - - const FetchDrawcall *GetDrawcall(const FetchDrawcall *draw, uint32_t eventID); + vector m_Drawcalls; static const char *GetChunkName(uint32_t idx); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 8d7bdf481..c8155a47b 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -96,7 +96,7 @@ vector GLReplay::GetPassEvents(uint32_t frameID, uint32_t eventID) if(start->flags & eDraw_Drawcall) passEvents.push_back(start->eventID); - start = m_pDriver->GetDrawcall((uint32_t)start->next, 0); + start = m_pDriver->GetDrawcall(frameID, (uint32_t)start->next); } return passEvents; diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 66c08406a..b0069d18f 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1293,6 +1293,8 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u { GetFrameRecord().back().drawcallList = m_ParentDrawcall.Bake(); + SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().back().frameInfo.immContextId, GetFrameRecord().back().drawcallList, NULL, NULL); + struct SortEID { bool operator() (const FetchAPIEvent &a, const FetchAPIEvent &b) { return a.eventID < b.eventID; } @@ -1913,48 +1915,10 @@ FetchAPIEvent WrappedVulkan::GetEvent(uint32_t eventID) return m_Events[0]; } -const FetchDrawcall *WrappedVulkan::GetDrawcall(const FetchDrawcall *draw, uint32_t eventID) -{ - if(draw == NULL) return NULL; - if(draw->eventID == eventID) return draw; - - int32_t count = draw->children.count; - for(int32_t i=0; i < count; i++) - { - const FetchDrawcall *cur = &draw->children.elems[i]; - const FetchDrawcall *next = i+1 < count ? &draw->children.elems[i+1] : NULL; - - if(next && next->eventID <= eventID) - continue; - - cur = GetDrawcall(cur, eventID); - - if(cur) - return cur; - } - - return NULL; -} - const FetchDrawcall *WrappedVulkan::GetDrawcall(uint32_t frameID, uint32_t eventID) { - if(frameID >= m_FrameRecord.size()) + if(eventID >= m_Drawcalls.size()) return NULL; - size_t count = m_FrameRecord[frameID].drawcallList.size(); - for(size_t i=0; i < count; i++) - { - const FetchDrawcall *cur = &m_FrameRecord[frameID].drawcallList[i]; - const FetchDrawcall *next = i+1 < count ? &m_FrameRecord[frameID].drawcallList[i+1] : NULL; - - if(next && next->eventID <= eventID) - continue; - - cur = GetDrawcall(cur, eventID); - - if(cur) - return cur; - } - - return NULL; + return m_Drawcalls[eventID]; } diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 38268a1b5..925835866 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -155,7 +155,7 @@ private: double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; vector m_FrameRecord; - const FetchDrawcall *GetDrawcall(const FetchDrawcall *draw, uint32_t eventID); + vector m_Drawcalls; struct PhysicalDeviceData { diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 87d79dde1..17d31877d 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -586,7 +586,7 @@ vector VulkanReplay::GetPassEvents(uint32_t frameID, uint32_t eventID) if(start->flags & eDraw_Drawcall) passEvents.push_back(start->eventID); - start = m_pDriver->GetDrawcall((uint32_t)start->next, 0); + start = m_pDriver->GetDrawcall(frameID, (uint32_t)start->next); } return passEvents; diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index df6547464..11113e9ab 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -155,3 +155,44 @@ class IReplayDriver : public IRemoteDriver virtual void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) = 0; virtual uint32_t PickVertex(uint32_t frameID, uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) = 0; }; + +// utility function useful in any driver implementation +template +FetchDrawcall *SetupDrawcallPointers(vector *drawcallTable, ResourceId contextID, FetchDrawcallContainer &draws, + FetchDrawcall *parent, FetchDrawcall *previous) +{ + FetchDrawcall *ret = NULL; + + for(size_t i=0; i < draws.size(); i++) + { + FetchDrawcall *draw = &draws[i]; + + draw->parent = parent ? parent->eventID : 0; + + if(draw->children.count > 0) + { + ret = previous = SetupDrawcallPointers(drawcallTable, contextID, draw->children, draw, previous); + } + else if(draw->flags & (eDraw_PushMarker|eDraw_SetMarker|eDraw_Present|eDraw_MultiDraw)) + { + // don't want to set up previous/next links for markers + } + else + { + if(previous != NULL) + previous->next = draw->eventID; + draw->previous = previous ? previous->eventID : 0; + + if(drawcallTable) + { + RDCASSERT(drawcallTable->empty() || draw->eventID > drawcallTable->back()->eventID || draw->context != contextID); + drawcallTable->resize(RDCMAX(drawcallTable->size(), size_t(draw->eventID+1))); + (*drawcallTable)[draw->eventID] = draw; + } + + ret = previous = draw; + } + } + + return ret; +} diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index 123ac47ec..9d47dac68 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -1487,47 +1487,12 @@ ReplayCreateStatus ReplayRenderer::PostCreateInit(IReplayDriver *device) m_FrameRecord.back().frameInfo = fr[i].frameInfo; m_FrameRecord.back().m_DrawCallList = fr[i].drawcallList; - SetupDrawcallPointers(fr[i].frameInfo, m_FrameRecord.back().m_DrawCallList, NULL, NULL); + SetupDrawcallPointers(&m_Drawcalls, fr[i].frameInfo.immContextId, m_FrameRecord.back().m_DrawCallList, NULL, NULL); } return eReplayCreate_Success; } -FetchDrawcall *ReplayRenderer::SetupDrawcallPointers(FetchFrameInfo frame, rdctype::array &draws, FetchDrawcall *parent, FetchDrawcall *previous) -{ - FetchDrawcall *ret = NULL; - - for(int32_t i=0; i < draws.count; i++) - { - FetchDrawcall *draw = &draws[i]; - - draw->parent = parent ? parent->eventID : 0; - - if(draw->children.count > 0) - { - ret = previous = SetupDrawcallPointers(frame, draw->children, draw, previous); - } - else if(draw->flags & (eDraw_PushMarker|eDraw_SetMarker|eDraw_Present|eDraw_MultiDraw)) - { - // don't want to set up previous/next links for markers - } - else - { - if(previous != NULL) - previous->next = draw->eventID; - draw->previous = previous ? previous->eventID : 0; - - RDCASSERT(m_Drawcalls.empty() || draw->eventID > m_Drawcalls.back()->eventID || draw->context != frame.immContextId); - m_Drawcalls.resize(RDCMAX(m_Drawcalls.size(), size_t(draw->eventID+1))); - m_Drawcalls[draw->eventID] = draw; - - ret = previous = draw; - } - } - - return ret; -} - void ReplayRenderer::FileChanged() { m_pDevice->FileChanged(); diff --git a/renderdoc/replay/replay_renderer.h b/renderdoc/replay/replay_renderer.h index 11aa0dd87..248ffd7ff 100644 --- a/renderdoc/replay/replay_renderer.h +++ b/renderdoc/replay/replay_renderer.h @@ -197,7 +197,6 @@ struct ReplayRenderer : public IReplayRenderer ReplayCreateStatus PostCreateInit(IReplayDriver *device); FetchDrawcall *GetDrawcallByEID(uint32_t eventID, uint32_t defEventID); - FetchDrawcall *SetupDrawcallPointers(FetchFrameInfo frame, rdctype::array &draws, FetchDrawcall *parent, FetchDrawcall *previous); IReplayDriver *GetDevice() { return m_pDevice; }