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:
baldurk
2017-07-27 16:14:17 +01:00
parent 180947ddcb
commit 72bae9bdc9
22 changed files with 463 additions and 55 deletions
+17 -7
View File
@@ -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;
+2
View File
@@ -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;
+12 -15
View File
@@ -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,
+3
View File
@@ -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;
+4
View File
@@ -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
+47 -3
View File
@@ -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)
+11 -2
View File
@@ -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)
+23 -2
View File
@@ -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();
+11 -1
View File
@@ -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;
+3
View File
@@ -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;
};
+14 -16
View File
@@ -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");
}
+2
View File
@@ -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";
+96
View File
@@ -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)
+23
View File
@@ -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;
+9
View File
@@ -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)
+2
View File
@@ -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