mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-23 06:05:45 +00:00
Re-organise debug marker handling during replay
* Where available or allowed, we replay the captured user markers. * When we're doing partial replay and we only push some of the markers then stop, we keep track of how many were pushed so we can pop them again and keep things balanced. * Also for renderdoc internal book-keeping around the frame replay itself we explicitly annotate the renderdoc internals * On vulkan since there are no queue-level markers, we fire single-shot command buffers that do nothing but push/pop/insert a marker.
This commit is contained in:
@@ -34,13 +34,12 @@ WrappedID3D11Device *D3D11MarkerRegion::device;
|
||||
|
||||
D3D11MarkerRegion::D3D11MarkerRegion(const std::string &marker)
|
||||
{
|
||||
if(device == NULL)
|
||||
return;
|
||||
D3D11MarkerRegion::Begin(marker);
|
||||
}
|
||||
|
||||
ID3DUserDefinedAnnotation *annot = device->GetAnnotations();
|
||||
|
||||
if(annot)
|
||||
annot->BeginEvent(StringFormat::UTF82Wide(marker).c_str());
|
||||
D3D11MarkerRegion::~D3D11MarkerRegion()
|
||||
{
|
||||
D3D11MarkerRegion::End();
|
||||
}
|
||||
|
||||
void D3D11MarkerRegion::Set(const std::string &marker)
|
||||
@@ -54,7 +53,18 @@ void D3D11MarkerRegion::Set(const std::string &marker)
|
||||
annot->SetMarker(StringFormat::UTF82Wide(marker).c_str());
|
||||
}
|
||||
|
||||
D3D11MarkerRegion::~D3D11MarkerRegion()
|
||||
void D3D11MarkerRegion::Begin(const std::string &marker)
|
||||
{
|
||||
if(device == NULL)
|
||||
return;
|
||||
|
||||
ID3DUserDefinedAnnotation *annot = device->GetAnnotations();
|
||||
|
||||
if(annot)
|
||||
annot->BeginEvent(StringFormat::UTF82Wide(marker).c_str());
|
||||
}
|
||||
|
||||
void D3D11MarkerRegion::End()
|
||||
{
|
||||
if(device == NULL)
|
||||
return;
|
||||
|
||||
@@ -43,6 +43,8 @@ struct D3D11MarkerRegion
|
||||
D3D11MarkerRegion(const std::string &marker);
|
||||
~D3D11MarkerRegion();
|
||||
static void Set(const std::string &marker);
|
||||
static void Begin(const std::string &marker);
|
||||
static void End();
|
||||
|
||||
static WrappedID3D11Device *device;
|
||||
};
|
||||
|
||||
@@ -53,6 +53,9 @@ bool WrappedID3D11DeviceContext::Serialise_SetMarker(uint32_t col, const wchar_t
|
||||
|
||||
m_pSerialiser->Serialise("Name", name);
|
||||
|
||||
if(m_State <= EXECUTING)
|
||||
D3D11MarkerRegion::Set(name);
|
||||
|
||||
if(m_State == READING)
|
||||
{
|
||||
DrawcallDescription draw;
|
||||
@@ -89,6 +92,12 @@ bool WrappedID3D11DeviceContext::Serialise_PushEvent(uint32_t col, const wchar_t
|
||||
|
||||
m_pSerialiser->Serialise("Name", name);
|
||||
|
||||
if(m_State <= EXECUTING)
|
||||
{
|
||||
D3D11MarkerRegion::Begin(name);
|
||||
m_pDevice->ReplayPushEvent();
|
||||
}
|
||||
|
||||
if(m_State == READING)
|
||||
{
|
||||
DrawcallDescription draw;
|
||||
@@ -113,6 +122,12 @@ bool WrappedID3D11DeviceContext::Serialise_PushEvent(uint32_t col, const wchar_t
|
||||
|
||||
bool WrappedID3D11DeviceContext::Serialise_PopEvent()
|
||||
{
|
||||
if(m_State <= EXECUTING)
|
||||
{
|
||||
D3D11MarkerRegion::End();
|
||||
m_pDevice->ReplayPopEvent();
|
||||
}
|
||||
|
||||
if(m_State == READING && !m_CurEvents.empty())
|
||||
{
|
||||
DrawcallDescription draw;
|
||||
|
||||
@@ -2469,35 +2469,32 @@ void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
|
||||
|
||||
if(!partial)
|
||||
{
|
||||
D3D11MarkerRegion apply("ApplyInitialContents");
|
||||
D3D11MarkerRegion apply("!!!!RenderDoc Internal: ApplyInitialContents");
|
||||
GetResourceManager()->ApplyInitialContents();
|
||||
GetResourceManager()->ReleaseInFrameResources();
|
||||
}
|
||||
|
||||
m_State = EXECUTING;
|
||||
|
||||
D3D11MarkerRegion::Set(StringFormat::Fmt("!!!!RenderDoc Internal: Replay %d (%d): %u->%u",
|
||||
(int)replayType, (int)partial, startEventID, endEventID));
|
||||
|
||||
m_ReplayEventCount = 0;
|
||||
|
||||
if(replayType == eReplay_Full)
|
||||
{
|
||||
D3D11MarkerRegion exec(
|
||||
StringFormat::Fmt("Replay: Full %u->%u (partial %u)", startEventID, endEventID, partial));
|
||||
m_pImmediateContext->ReplayLog(EXECUTING, startEventID, endEventID, partial);
|
||||
}
|
||||
else if(replayType == eReplay_WithoutDraw)
|
||||
{
|
||||
D3D11MarkerRegion exec(StringFormat::Fmt("Replay: W/O Draw %u->%u (partial %u)", startEventID,
|
||||
endEventID, partial));
|
||||
m_pImmediateContext->ReplayLog(EXECUTING, startEventID, RDCMAX(1U, endEventID) - 1, partial);
|
||||
}
|
||||
else if(replayType == eReplay_OnlyDraw)
|
||||
{
|
||||
D3D11MarkerRegion exec(StringFormat::Fmt("Replay: Draw Only %u->%u (partial %u)", endEventID,
|
||||
endEventID, partial));
|
||||
m_pImmediateContext->ReplayLog(EXECUTING, endEventID, endEventID, partial);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCFATAL("Unexpected replay type");
|
||||
}
|
||||
|
||||
// make sure to end any unbalanced replay events if we stopped in the middle of a frame
|
||||
for(int i = 0; i < m_ReplayEventCount; i++)
|
||||
D3D11MarkerRegion::End();
|
||||
|
||||
D3D11MarkerRegion::Set("!!!!RenderDoc Internal: Done replay");
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap, UINT QueueCount,
|
||||
|
||||
@@ -327,6 +327,7 @@ private:
|
||||
WrappedID3D11Debug m_WrappedDebug;
|
||||
|
||||
ID3DUserDefinedAnnotation *m_RealAnnotations;
|
||||
int m_ReplayEventCount;
|
||||
|
||||
unsigned int m_InternalRefcount;
|
||||
RefCounter m_RefCounter;
|
||||
@@ -434,6 +435,8 @@ public:
|
||||
FrameStatistics &GetFrameStats() { return m_FrameRecord.frameInfo.stats; }
|
||||
const DrawcallDescription *GetDrawcall(uint32_t eventID);
|
||||
|
||||
void ReplayPushEvent() { m_ReplayEventCount++; }
|
||||
void ReplayPopEvent() { m_ReplayEventCount = RDCMAX(0, m_ReplayEventCount - 1); }
|
||||
void LockForChunkFlushing();
|
||||
void UnlockForChunkFlushing();
|
||||
void LockForChunkRemoval();
|
||||
|
||||
@@ -123,7 +123,9 @@ public:
|
||||
WrappedID3D12Device *GetWrappedDevice() { return m_pDevice; }
|
||||
D3D12ResourceRecord *GetResourceRecord() { return m_ListRecord; }
|
||||
ID3D12GraphicsCommandList *GetList(ResourceId id);
|
||||
ID3D12GraphicsCommandList *GetWrappedList(ResourceId id);
|
||||
ID3D12GraphicsCommandList *GetCrackedList(ResourceId id);
|
||||
ID3D12GraphicsCommandList *GetWrappedCrackedList(ResourceId id);
|
||||
|
||||
void SetCommandData(D3D12CommandData *cmd) { m_Cmd = cmd; }
|
||||
void SetInitParams(REFIID riid, UINT nodeMask, D3D12_COMMAND_LIST_TYPE type)
|
||||
|
||||
@@ -30,11 +30,21 @@ ID3D12GraphicsCommandList *WrappedID3D12GraphicsCommandList::GetList(ResourceId
|
||||
return GetResourceManager()->GetLiveAs<WrappedID3D12GraphicsCommandList>(id)->GetReal();
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList *WrappedID3D12GraphicsCommandList::GetWrappedList(ResourceId id)
|
||||
{
|
||||
return GetResourceManager()->GetLiveAs<WrappedID3D12GraphicsCommandList>(id);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList *WrappedID3D12GraphicsCommandList::GetCrackedList(ResourceId id)
|
||||
{
|
||||
return Unwrap(m_Cmd->m_BakedCmdListInfo[id].crackedLists.back());
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList *WrappedID3D12GraphicsCommandList::GetWrappedCrackedList(ResourceId id)
|
||||
{
|
||||
return m_Cmd->m_BakedCmdListInfo[id].crackedLists.back();
|
||||
}
|
||||
|
||||
bool WrappedID3D12GraphicsCommandList::Serialise_Close()
|
||||
{
|
||||
SERIALISE_ELEMENT(ResourceId, CommandList, GetResourceID());
|
||||
@@ -63,6 +73,11 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Close()
|
||||
RDCDEBUG("Ending partial command list for %llu baked to %llu", CommandList, bakeId);
|
||||
#endif
|
||||
|
||||
int &markerCount = m_Cmd->m_BakedCmdListInfo[CommandList].markerCount;
|
||||
|
||||
for(int i = 0; i < markerCount; i++)
|
||||
D3D12MarkerRegion::End(list);
|
||||
|
||||
list->Close();
|
||||
|
||||
// erase the non-baked reference to this command list so that we don't have
|
||||
@@ -219,6 +234,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(ID3D12CommandAllocator *p
|
||||
m_Cmd->m_RenderState.pipe = GetResID(pInitialState);
|
||||
}
|
||||
|
||||
m_Cmd->m_BakedCmdListInfo[CommandList].markerCount = 0;
|
||||
m_Cmd->m_BakedCmdListInfo[CommandList].curEventID = 0;
|
||||
m_Cmd->m_BakedCmdListInfo[CommandList].executeEvents =
|
||||
m_Cmd->m_BakedCmdListInfo[bakeId].executeEvents;
|
||||
@@ -2653,8 +2669,20 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetMarker(UINT Metadata, const
|
||||
if(m_State < WRITING)
|
||||
m_Cmd->m_LastCmdListID = CommandList;
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList))
|
||||
{
|
||||
ID3D12GraphicsCommandList *list = m_Cmd->RerecordCmdList(CommandList);
|
||||
|
||||
D3D12MarkerRegion::Set(list, markerText);
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
D3D12MarkerRegion::Set(GetWrappedList(CommandList), markerText);
|
||||
D3D12MarkerRegion::Set(GetWrappedCrackedList(CommandList), markerText);
|
||||
|
||||
DrawcallDescription draw;
|
||||
draw.name = markerText;
|
||||
draw.flags |= DrawFlags::SetMarker;
|
||||
@@ -2711,8 +2739,22 @@ bool WrappedID3D12GraphicsCommandList::Serialise_BeginEvent(UINT Metadata, const
|
||||
if(m_State < WRITING)
|
||||
m_Cmd->m_LastCmdListID = CommandList;
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList))
|
||||
{
|
||||
ID3D12GraphicsCommandList *list = m_Cmd->RerecordCmdList(CommandList);
|
||||
|
||||
m_Cmd->m_BakedCmdListInfo[CommandList].markerCount++;
|
||||
|
||||
D3D12MarkerRegion::Begin(list, markerText);
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
D3D12MarkerRegion::Begin(GetWrappedList(CommandList), markerText);
|
||||
D3D12MarkerRegion::Begin(GetWrappedCrackedList(CommandList), markerText);
|
||||
|
||||
DrawcallDescription draw;
|
||||
draw.name = markerText;
|
||||
draw.flags |= DrawFlags::PushMarker;
|
||||
@@ -2752,8 +2794,23 @@ bool WrappedID3D12GraphicsCommandList::Serialise_EndEvent()
|
||||
m_Cmd->AddDrawcall(draw, true);
|
||||
}
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
if(m_Cmd->ShouldRerecordCmd(CommandList) && m_Cmd->InRerecordRange(CommandList))
|
||||
{
|
||||
ID3D12GraphicsCommandList *list = m_Cmd->RerecordCmdList(CommandList);
|
||||
|
||||
int &markerCount = m_Cmd->m_BakedCmdListInfo[CommandList].markerCount;
|
||||
markerCount = RDCMAX(0, markerCount - 1);
|
||||
|
||||
D3D12MarkerRegion::End(list);
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
D3D12MarkerRegion::End(GetWrappedList(CommandList));
|
||||
D3D12MarkerRegion::End(GetWrappedCrackedList(CommandList));
|
||||
|
||||
// dummy draw that is consumed when this command buffer
|
||||
// is being in-lined into the call stream
|
||||
DrawcallDescription draw;
|
||||
|
||||
@@ -192,6 +192,10 @@ struct BakedCmdListInfo
|
||||
|
||||
ResourceId parentList;
|
||||
|
||||
// modified during recording to ensure we end any markers that should be ended but weren't due to
|
||||
// a partial replay
|
||||
int markerCount;
|
||||
|
||||
D3D12DrawcallTreeNode *draw; // the root draw to copy from when submitting
|
||||
uint32_t eventCount; // how many events are in this cmd list, for quick skipping
|
||||
uint32_t curEventID; // current event ID while reading or executing
|
||||
|
||||
@@ -31,7 +31,29 @@
|
||||
D3D12MarkerRegion::D3D12MarkerRegion(ID3D12GraphicsCommandList *l, const std::string &marker)
|
||||
{
|
||||
list = l;
|
||||
queue = NULL;
|
||||
|
||||
D3D12MarkerRegion::Begin(list, marker);
|
||||
}
|
||||
|
||||
D3D12MarkerRegion::D3D12MarkerRegion(ID3D12CommandQueue *q, const std::string &marker)
|
||||
{
|
||||
list = NULL;
|
||||
queue = q;
|
||||
|
||||
D3D12MarkerRegion::Begin(queue, marker);
|
||||
}
|
||||
|
||||
D3D12MarkerRegion::~D3D12MarkerRegion()
|
||||
{
|
||||
if(list)
|
||||
D3D12MarkerRegion::End(list);
|
||||
if(queue)
|
||||
D3D12MarkerRegion::End(queue);
|
||||
}
|
||||
|
||||
void D3D12MarkerRegion::Begin(ID3D12GraphicsCommandList *list, const std::string &marker)
|
||||
{
|
||||
if(list)
|
||||
{
|
||||
std::wstring text = StringFormat::UTF82Wide(marker);
|
||||
@@ -39,6 +61,15 @@ D3D12MarkerRegion::D3D12MarkerRegion(ID3D12GraphicsCommandList *l, const std::st
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12MarkerRegion::Begin(ID3D12CommandQueue *queue, const std::string &marker)
|
||||
{
|
||||
if(queue)
|
||||
{
|
||||
std::wstring text = StringFormat::UTF82Wide(marker);
|
||||
queue->BeginEvent(0, text.c_str(), (UINT)text.size());
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12MarkerRegion::Set(ID3D12GraphicsCommandList *list, const std::string &marker)
|
||||
{
|
||||
if(list)
|
||||
@@ -48,10 +79,23 @@ void D3D12MarkerRegion::Set(ID3D12GraphicsCommandList *list, const std::string &
|
||||
}
|
||||
}
|
||||
|
||||
D3D12MarkerRegion::~D3D12MarkerRegion()
|
||||
void D3D12MarkerRegion::Set(ID3D12CommandQueue *queue, const std::string &marker)
|
||||
{
|
||||
if(list)
|
||||
list->EndEvent();
|
||||
if(queue)
|
||||
{
|
||||
std::wstring text = StringFormat::UTF82Wide(marker);
|
||||
queue->SetMarker(0, text.c_str(), (UINT)text.size());
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12MarkerRegion::End(ID3D12GraphicsCommandList *list)
|
||||
{
|
||||
list->EndEvent();
|
||||
}
|
||||
|
||||
void D3D12MarkerRegion::End(ID3D12CommandQueue *queue)
|
||||
{
|
||||
queue->EndEvent();
|
||||
}
|
||||
|
||||
TextureDim MakeTextureDim(D3D12_SRV_DIMENSION dim)
|
||||
|
||||
@@ -37,10 +37,19 @@
|
||||
struct D3D12MarkerRegion
|
||||
{
|
||||
D3D12MarkerRegion(ID3D12GraphicsCommandList *list, const std::string &marker);
|
||||
D3D12MarkerRegion(ID3D12CommandQueue *queue, const std::string &marker);
|
||||
~D3D12MarkerRegion();
|
||||
static void Set(ID3D12GraphicsCommandList *list, const std::string &marker);
|
||||
|
||||
ID3D12GraphicsCommandList *list;
|
||||
static void Set(ID3D12GraphicsCommandList *list, const std::string &marker);
|
||||
static void Set(ID3D12CommandQueue *queue, const std::string &marker);
|
||||
|
||||
static void Begin(ID3D12GraphicsCommandList *list, const std::string &marker);
|
||||
static void End(ID3D12GraphicsCommandList *list);
|
||||
static void Begin(ID3D12CommandQueue *queue, const std::string &marker);
|
||||
static void End(ID3D12CommandQueue *queue);
|
||||
|
||||
ID3D12GraphicsCommandList *list = NULL;
|
||||
ID3D12CommandQueue *queue = NULL;
|
||||
};
|
||||
|
||||
inline void SetObjName(ID3D12Object *obj, const std::string &utf8name)
|
||||
|
||||
@@ -589,7 +589,10 @@ void WrappedID3D12Device::ApplyInitialContents()
|
||||
|
||||
// close the final list
|
||||
if(initStateCurList)
|
||||
{
|
||||
D3D12MarkerRegion::End(initStateCurList);
|
||||
initStateCurList->Close();
|
||||
}
|
||||
|
||||
initStateCurBatch = 0;
|
||||
initStateCurList = NULL;
|
||||
@@ -2159,13 +2162,22 @@ ID3D12GraphicsCommandList *WrappedID3D12Device::GetInitialStateList()
|
||||
}
|
||||
|
||||
if(initStateCurList == NULL)
|
||||
{
|
||||
initStateCurList = GetNewList();
|
||||
|
||||
if(m_State < WRITING)
|
||||
{
|
||||
D3D12MarkerRegion::Begin(initStateCurList,
|
||||
"!!!!RenderDoc Internal: ApplyInitialContents batched list");
|
||||
}
|
||||
}
|
||||
|
||||
return initStateCurList;
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CloseInitialStateList()
|
||||
{
|
||||
D3D12MarkerRegion::End(initStateCurList);
|
||||
initStateCurList->Close();
|
||||
initStateCurList = NULL;
|
||||
initStateCurBatch = 0;
|
||||
@@ -2467,8 +2479,11 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
|
||||
|
||||
if(!partial)
|
||||
{
|
||||
ApplyInitialContents();
|
||||
GetResourceManager()->ReleaseInFrameResources();
|
||||
{
|
||||
D3D12MarkerRegion apply(GetQueue(), "!!!!RenderDoc Internal: ApplyInitialContents");
|
||||
ApplyInitialContents();
|
||||
GetResourceManager()->ReleaseInFrameResources();
|
||||
}
|
||||
|
||||
ExecuteLists();
|
||||
FlushLists(true);
|
||||
@@ -2476,6 +2491,10 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
|
||||
|
||||
m_State = EXECUTING;
|
||||
|
||||
D3D12MarkerRegion::Set(
|
||||
GetQueue(), StringFormat::Fmt("!!!!RenderDoc Internal: RenderDoc Replay %d (%d): %u->%u",
|
||||
(int)replayType, (int)partial, startEventID, endEventID));
|
||||
|
||||
{
|
||||
D3D12CommandData &cmd = *m_Queue->GetCommandData();
|
||||
|
||||
@@ -2526,6 +2545,8 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
|
||||
#endif
|
||||
}
|
||||
|
||||
D3D12MarkerRegion::Set(GetQueue(), "!!!!RenderDoc Internal: Done replay");
|
||||
|
||||
// ensure all UAV writes have finished before subsequent work
|
||||
ID3D12GraphicsCommandList *list = GetNewList();
|
||||
|
||||
|
||||
@@ -738,6 +738,16 @@ void DoVendorChecks(const GLHookSet &gl, GLPlatform &platform, GLWindowingData c
|
||||
const GLHookSet *GLMarkerRegion::gl;
|
||||
|
||||
GLMarkerRegion::GLMarkerRegion(const std::string &marker)
|
||||
{
|
||||
Begin(marker);
|
||||
}
|
||||
|
||||
GLMarkerRegion::~GLMarkerRegion()
|
||||
{
|
||||
End();
|
||||
}
|
||||
|
||||
void GLMarkerRegion::Begin(const std::string &marker)
|
||||
{
|
||||
if(gl == NULL || !HasExt[KHR_debug] || !gl->glPushDebugGroup)
|
||||
return;
|
||||
@@ -754,7 +764,7 @@ void GLMarkerRegion::Set(const std::string &marker)
|
||||
eGL_DEBUG_SEVERITY_NOTIFICATION, -1, marker.c_str());
|
||||
}
|
||||
|
||||
GLMarkerRegion::~GLMarkerRegion()
|
||||
void GLMarkerRegion::End()
|
||||
{
|
||||
if(gl == NULL || !HasExt[KHR_debug] || !gl->glPopDebugGroup)
|
||||
return;
|
||||
|
||||
@@ -250,7 +250,10 @@ struct GLMarkerRegion
|
||||
{
|
||||
GLMarkerRegion(const std::string &marker);
|
||||
~GLMarkerRegion();
|
||||
|
||||
static void Begin(const std::string &marker);
|
||||
static void Set(const std::string &marker);
|
||||
static void End();
|
||||
|
||||
static const GLHookSet *gl;
|
||||
};
|
||||
|
||||
@@ -3312,7 +3312,8 @@ bool WrappedOpenGL::RecordUpdateCheck(GLResourceRecord *record)
|
||||
void WrappedOpenGL::DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum severity,
|
||||
GLsizei length, const GLchar *message)
|
||||
{
|
||||
if(type != eGL_DEBUG_TYPE_PUSH_GROUP && type != eGL_DEBUG_TYPE_POP_GROUP)
|
||||
if(type != eGL_DEBUG_TYPE_PUSH_GROUP && type != eGL_DEBUG_TYPE_POP_GROUP &&
|
||||
type != eGL_DEBUG_TYPE_MARKER)
|
||||
{
|
||||
if(type != eGL_DEBUG_TYPE_PERFORMANCE && type != eGL_DEBUG_TYPE_OTHER)
|
||||
{
|
||||
@@ -4503,31 +4504,28 @@ void WrappedOpenGL::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
|
||||
if(!partial)
|
||||
{
|
||||
GLMarkerRegion apply("ApplyInitialContents");
|
||||
GLMarkerRegion apply("!!!!RenderDoc Internal: ApplyInitialContents");
|
||||
GetResourceManager()->ApplyInitialContents();
|
||||
GetResourceManager()->ReleaseInFrameResources();
|
||||
}
|
||||
|
||||
GLMarkerRegion::Set(StringFormat::Fmt("!!!!RenderDoc Internal: Replay %d (%d): %u->%u",
|
||||
(int)replayType, (int)partial, startEventID, endEventID));
|
||||
|
||||
m_ReplayEventCount = 0;
|
||||
|
||||
if(replayType == eReplay_Full)
|
||||
{
|
||||
GLMarkerRegion exec(
|
||||
StringFormat::Fmt("Replay: Full %u->%u (partial %u)", startEventID, endEventID, partial));
|
||||
ContextReplayLog(EXECUTING, startEventID, endEventID, partial);
|
||||
}
|
||||
else if(replayType == eReplay_WithoutDraw)
|
||||
{
|
||||
GLMarkerRegion exec(StringFormat::Fmt("Replay: W/O Draw %u->%u (partial %u)", startEventID,
|
||||
endEventID, partial));
|
||||
ContextReplayLog(EXECUTING, startEventID, RDCMAX(1U, endEventID) - 1, partial);
|
||||
}
|
||||
else if(replayType == eReplay_OnlyDraw)
|
||||
{
|
||||
GLMarkerRegion exec(StringFormat::Fmt("Replay: Draw Only %u->%u (partial %u)", endEventID,
|
||||
endEventID, partial));
|
||||
ContextReplayLog(EXECUTING, endEventID, endEventID, partial);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCFATAL("Unexpected replay type");
|
||||
}
|
||||
|
||||
// make sure to end any unbalanced replay events if we stopped in the middle of a frame
|
||||
for(int i = 0; i < m_ReplayEventCount; i++)
|
||||
GLMarkerRegion::End();
|
||||
|
||||
GLMarkerRegion::Set("!!!!RenderDoc Internal: Done replay");
|
||||
}
|
||||
|
||||
@@ -192,6 +192,8 @@ private:
|
||||
|
||||
set<ResourceId> m_HighTrafficResources;
|
||||
|
||||
int m_ReplayEventCount;
|
||||
|
||||
// we store two separate sets of maps, since for an explicit glMemoryBarrier
|
||||
// we need to flush both types of maps, but for implicit sync points we only
|
||||
// want to consider coherent maps, and since that happens often we want it to
|
||||
|
||||
@@ -158,7 +158,11 @@ bool WrappedOpenGL::Serialise_glDebugMessageInsert(GLenum source, GLenum type, G
|
||||
|
||||
m_pSerialiser->Serialise("Name", name);
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
GLMarkerRegion::Set(name);
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
DrawcallDescription draw;
|
||||
draw.name = name;
|
||||
@@ -240,7 +244,12 @@ bool WrappedOpenGL::Serialise_glPushDebugGroup(GLenum source, GLuint id, GLsizei
|
||||
|
||||
m_pSerialiser->Serialise("Name", name);
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
GLMarkerRegion::Begin(name);
|
||||
m_ReplayEventCount++;
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
DrawcallDescription draw;
|
||||
draw.name = name;
|
||||
@@ -267,7 +276,12 @@ void WrappedOpenGL::glPushDebugGroup(GLenum source, GLuint id, GLsizei length, c
|
||||
|
||||
bool WrappedOpenGL::Serialise_glPopDebugGroup()
|
||||
{
|
||||
if(m_State == READING && !m_CurEvents.empty())
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
GLMarkerRegion::End();
|
||||
m_ReplayEventCount = RDCMAX(0, m_ReplayEventCount - 1);
|
||||
}
|
||||
else if(m_State == READING && !m_CurEvents.empty())
|
||||
{
|
||||
DrawcallDescription draw;
|
||||
draw.name = "API Calls";
|
||||
|
||||
@@ -23,12 +23,108 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "vk_common.h"
|
||||
#include "vk_core.h"
|
||||
#include "vk_manager.h"
|
||||
#include "vk_resources.h"
|
||||
|
||||
const uint32_t AMD_PCI_ID = 0x1002;
|
||||
const uint32_t NV_PCI_ID = 0x10DE;
|
||||
|
||||
// utility struct for firing one-shot command buffers to begin/end markers
|
||||
struct ScopedCommandBuffer
|
||||
{
|
||||
ScopedCommandBuffer(VkCommandBuffer cmdbuf, WrappedVulkan *vk)
|
||||
{
|
||||
core = vk;
|
||||
cmd = cmdbuf;
|
||||
local = (cmd == VK_NULL_HANDLE);
|
||||
|
||||
if(local)
|
||||
{
|
||||
VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
|
||||
|
||||
cmd = vk->GetNextCmd();
|
||||
|
||||
VkResult vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
}
|
||||
~ScopedCommandBuffer()
|
||||
{
|
||||
VkResult vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
core->SubmitCmds();
|
||||
}
|
||||
|
||||
WrappedVulkan *core;
|
||||
VkCommandBuffer cmd;
|
||||
bool local;
|
||||
};
|
||||
|
||||
WrappedVulkan *VkMarkerRegion::vk = NULL;
|
||||
|
||||
VkMarkerRegion::VkMarkerRegion(const std::string &marker, VkCommandBuffer cmd)
|
||||
{
|
||||
if(cmd == VK_NULL_HANDLE)
|
||||
{
|
||||
RDCERR("Cannot auto-allocate a command buffer for a scoped VkMarkerRegion");
|
||||
return;
|
||||
}
|
||||
|
||||
cmdbuf = cmd;
|
||||
Begin(marker, cmd);
|
||||
}
|
||||
|
||||
VkMarkerRegion::~VkMarkerRegion()
|
||||
{
|
||||
if(cmdbuf)
|
||||
End(cmdbuf);
|
||||
}
|
||||
|
||||
void VkMarkerRegion::Begin(const std::string &marker, VkCommandBuffer cmd)
|
||||
{
|
||||
if(!vk)
|
||||
return;
|
||||
|
||||
// check for presence of the marker extension
|
||||
if(!ObjDisp(vk->GetDev())->CmdDebugMarkerBeginEXT)
|
||||
return;
|
||||
|
||||
ScopedCommandBuffer scope(cmd, vk);
|
||||
|
||||
VkDebugMarkerMarkerInfoEXT markerInfo = {};
|
||||
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
markerInfo.pMarkerName = marker.c_str();
|
||||
ObjDisp(scope.cmd)->CmdDebugMarkerBeginEXT(Unwrap(scope.cmd), &markerInfo);
|
||||
}
|
||||
|
||||
void VkMarkerRegion::Set(const std::string &marker, VkCommandBuffer cmd)
|
||||
{
|
||||
// check for presence of the marker extension
|
||||
if(!ObjDisp(vk->GetDev())->CmdDebugMarkerBeginEXT)
|
||||
return;
|
||||
|
||||
ScopedCommandBuffer scope(cmd, vk);
|
||||
|
||||
VkDebugMarkerMarkerInfoEXT markerInfo = {};
|
||||
markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
markerInfo.pMarkerName = marker.c_str();
|
||||
ObjDisp(scope.cmd)->CmdDebugMarkerInsertEXT(Unwrap(scope.cmd), &markerInfo);
|
||||
}
|
||||
|
||||
void VkMarkerRegion::End(VkCommandBuffer cmd)
|
||||
{
|
||||
// check for presence of the marker extension
|
||||
if(!ObjDisp(vk->GetDev())->CmdDebugMarkerBeginEXT)
|
||||
return;
|
||||
|
||||
ScopedCommandBuffer scope(cmd, vk);
|
||||
|
||||
ObjDisp(scope.cmd)->CmdDebugMarkerEndEXT(Unwrap(scope.cmd));
|
||||
}
|
||||
|
||||
VkAccessFlags MakeAccessMask(VkImageLayout layout)
|
||||
{
|
||||
switch(layout)
|
||||
|
||||
@@ -104,6 +104,29 @@ int SampleCount(VkSampleCountFlagBits countFlag);
|
||||
int SampleIndex(VkSampleCountFlagBits countFlag);
|
||||
int StageIndex(VkShaderStageFlagBits stageFlag);
|
||||
|
||||
class WrappedVulkan;
|
||||
|
||||
// replay only class for handling marker regions.
|
||||
//
|
||||
// The cmd allows you to pass in an existing command buffer to insert/add the marker to.
|
||||
// If cmd is NULL, then a new command buffer is fetched, begun, the marker is applied to, then
|
||||
// closed again. Note that when constructing a scoped marker, cmd cannot be NULL
|
||||
//
|
||||
// If VK_EXT_debug_marker isn't supported, will silently do nothing
|
||||
struct VkMarkerRegion
|
||||
{
|
||||
VkMarkerRegion(const std::string &marker, VkCommandBuffer cmd);
|
||||
~VkMarkerRegion();
|
||||
|
||||
static void Begin(const std::string &marker, VkCommandBuffer cmd = VK_NULL_HANDLE);
|
||||
static void Set(const std::string &marker, VkCommandBuffer cmd = VK_NULL_HANDLE);
|
||||
static void End(VkCommandBuffer cmd = VK_NULL_HANDLE);
|
||||
|
||||
VkCommandBuffer cmdbuf = VK_NULL_HANDLE;
|
||||
|
||||
static WrappedVulkan *vk;
|
||||
};
|
||||
|
||||
// in vk_<platform>.cpp
|
||||
extern const char *VulkanLibraryName;
|
||||
|
||||
|
||||
@@ -266,6 +266,8 @@ WrappedVulkan::WrappedVulkan(const char *logFilename) : m_RenderState(this, &m_C
|
||||
|
||||
if(RenderDoc::Inst().IsReplayApp())
|
||||
{
|
||||
VkMarkerRegion::vk = this;
|
||||
|
||||
m_State = READING;
|
||||
if(logFilename)
|
||||
{
|
||||
@@ -2352,7 +2354,9 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
|
||||
if(!partial)
|
||||
{
|
||||
VkMarkerRegion::Begin("!!!!RenderDoc Internal: ApplyInitialContents");
|
||||
ApplyInitialContents();
|
||||
VkMarkerRegion::End();
|
||||
|
||||
SubmitCmds();
|
||||
FlushQ();
|
||||
@@ -2360,6 +2364,9 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
GetResourceManager()->ReleaseInFrameResources();
|
||||
}
|
||||
|
||||
VkMarkerRegion::Set(StringFormat::Fmt("!!!!RenderDoc Internal: RenderDoc Replay %d (%d): %u->%u",
|
||||
(int)replayType, (int)partial, startEventID, endEventID));
|
||||
|
||||
{
|
||||
if(!partial)
|
||||
{
|
||||
@@ -2488,6 +2495,8 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
SubmitCmds();
|
||||
#endif
|
||||
}
|
||||
|
||||
VkMarkerRegion::Set("!!!!RenderDoc Internal: Done replay");
|
||||
}
|
||||
|
||||
void WrappedVulkan::Serialise_DebugMessages(Serialiser *localSerialiser, bool isDrawcall)
|
||||
|
||||
@@ -409,6 +409,8 @@ private:
|
||||
VkCommandBufferLevel level;
|
||||
VkCommandBufferUsageFlags beginFlags;
|
||||
|
||||
int markerCount;
|
||||
|
||||
vector<pair<ResourceId, EventUsage> > resourceUsage;
|
||||
|
||||
struct CmdBufferState
|
||||
|
||||
@@ -500,6 +500,7 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(Serialiser *localSerialiser,
|
||||
|
||||
m_BakedCmdBufferInfo[cmdId].level = m_BakedCmdBufferInfo[bakeId].level = allocInfo.level;
|
||||
m_BakedCmdBufferInfo[cmdId].beginFlags = m_BakedCmdBufferInfo[bakeId].beginFlags = info.flags;
|
||||
m_BakedCmdBufferInfo[cmdId].markerCount = 0;
|
||||
}
|
||||
|
||||
if(m_State == EXECUTING)
|
||||
@@ -737,6 +738,10 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(Serialiser *localSerialiser,
|
||||
ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer));
|
||||
}
|
||||
|
||||
if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT)
|
||||
for(int i = 0; i < m_BakedCmdBufferInfo[cmdid].markerCount; i++)
|
||||
ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer));
|
||||
|
||||
ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer));
|
||||
|
||||
// erase the non-baked reference to this command buffer so that we don't have
|
||||
@@ -2654,8 +2659,37 @@ bool WrappedVulkan::Serialise_vkCmdDebugMarkerBeginEXT(Serialiser *localSerialis
|
||||
if(m_State < WRITING)
|
||||
m_LastCmdBufferID = cmdid;
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(cmdid);
|
||||
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount++;
|
||||
|
||||
if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT)
|
||||
{
|
||||
VkDebugMarkerMarkerInfoEXT marker = {};
|
||||
marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
memcpy(marker.color, color, sizeof(color));
|
||||
marker.pMarkerName = name.c_str();
|
||||
ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), &marker);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
commandBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);
|
||||
|
||||
if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT)
|
||||
{
|
||||
VkDebugMarkerMarkerInfoEXT marker = {};
|
||||
marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
memcpy(marker.color, color, sizeof(color));
|
||||
marker.pMarkerName = name.c_str();
|
||||
ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), &marker);
|
||||
}
|
||||
|
||||
DrawcallDescription draw;
|
||||
draw.name = name;
|
||||
draw.flags |= DrawFlags::PushMarker;
|
||||
@@ -2707,8 +2741,26 @@ bool WrappedVulkan::Serialise_vkCmdDebugMarkerEndEXT(Serialiser *localSerialiser
|
||||
AddDrawcall(draw, true);
|
||||
}
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(cmdid);
|
||||
|
||||
int &markerCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount;
|
||||
markerCount = RDCMAX(0, markerCount - 1);
|
||||
|
||||
if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT)
|
||||
ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer));
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
commandBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);
|
||||
|
||||
if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT)
|
||||
ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer));
|
||||
|
||||
// dummy draw that is consumed when this command buffer
|
||||
// is being in-lined into the call stream
|
||||
DrawcallDescription draw;
|
||||
@@ -2756,8 +2808,35 @@ bool WrappedVulkan::Serialise_vkCmdDebugMarkerInsertEXT(Serialiser *localSeriali
|
||||
if(m_State < WRITING)
|
||||
m_LastCmdBufferID = cmdid;
|
||||
|
||||
if(m_State == READING)
|
||||
if(m_State == EXECUTING)
|
||||
{
|
||||
if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(cmdid);
|
||||
|
||||
if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT)
|
||||
{
|
||||
VkDebugMarkerMarkerInfoEXT marker = {};
|
||||
marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
memcpy(marker.color, color, sizeof(color));
|
||||
marker.pMarkerName = name.c_str();
|
||||
ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), &marker);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
{
|
||||
commandBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid);
|
||||
|
||||
if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT)
|
||||
{
|
||||
VkDebugMarkerMarkerInfoEXT marker = {};
|
||||
marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT;
|
||||
memcpy(marker.color, color, sizeof(color));
|
||||
marker.pMarkerName = name.c_str();
|
||||
ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), &marker);
|
||||
}
|
||||
|
||||
DrawcallDescription draw;
|
||||
draw.name = name;
|
||||
draw.flags |= DrawFlags::SetMarker;
|
||||
|
||||
@@ -934,6 +934,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(Serialiser *localSerialiser,
|
||||
|
||||
AddRequiredExtensions(false, Extensions, supportedExtensions);
|
||||
|
||||
// enable VK_EXT_debug_marker if it's available, to replay markers to the driver/any other
|
||||
// layers that might be listening
|
||||
if(supportedExtensions.find(VK_EXT_DEBUG_MARKER_EXTENSION_NAME) != supportedExtensions.end())
|
||||
{
|
||||
Extensions.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
|
||||
RDCLOG("Enabling VK_EXT_debug_marker");
|
||||
}
|
||||
|
||||
#if ENABLED(FORCE_VALIDATION_LAYERS)
|
||||
Layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user