mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-24 06:36:08 +00:00
Support initing postvs for a whole pass via a per-draw callback
This commit is contained in:
@@ -283,11 +283,13 @@ WrappedVulkan::WrappedVulkan(const char *logFilename)
|
||||
m_FirstEventID = 0;
|
||||
m_LastEventID = ~0U;
|
||||
|
||||
m_DrawcallCallback = NULL;
|
||||
|
||||
m_LastCmdBufferID = ResourceId();
|
||||
|
||||
m_PartialReplayData.renderPassActive = false;
|
||||
m_PartialReplayData.resultPartialCmdBuffer = VK_NULL_HANDLE;
|
||||
m_PartialReplayData.singleDrawCmdBuffer = VK_NULL_HANDLE;
|
||||
m_PartialReplayData.outsideCmdBuffer = VK_NULL_HANDLE;
|
||||
m_PartialReplayData.partialParent = ResourceId();
|
||||
m_PartialReplayData.baseEvent = 0;
|
||||
|
||||
@@ -1277,16 +1279,21 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
|
||||
if(m_State == EXECUTING && startEventID == endEventID)
|
||||
break;
|
||||
|
||||
if(m_LastCmdBufferID != ResourceId())
|
||||
// increment root event ID either if we didn't just replay a cmd
|
||||
// buffer event, OR if we are doing a frame sub-section replay,
|
||||
// in which case it's up to the calling code to make sure we only
|
||||
// replay inside a command buffer (if we crossed command buffer
|
||||
// boundaries, the event IDs would no longer match up).
|
||||
if(m_LastCmdBufferID == ResourceId() || startEventID > 1)
|
||||
{
|
||||
m_RootEventID++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// these events are completely omitted, so don't increment the curEventID
|
||||
if(context != BEGIN_CMD_BUFFER && context != END_CMD_BUFFER)
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RootEventID++;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_State == READING)
|
||||
@@ -1766,6 +1773,22 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
|
||||
m_RenderState.m_ResourceManager = GetResourceManager();
|
||||
}
|
||||
|
||||
VkResult vkr = VK_SUCCESS;
|
||||
|
||||
// we'll need our own command buffer if we're replaying just a subsection
|
||||
// of events within a single command buffer record - always if it's only
|
||||
// one drawcall, or if start event ID is > 0 we assume the outside code
|
||||
// has chosen a subsection that lies within a command buffer
|
||||
if(partial)
|
||||
{
|
||||
VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer = GetNextCmd();
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT };
|
||||
|
||||
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
}
|
||||
|
||||
if(replayType == eReplay_Full)
|
||||
{
|
||||
ContextReplayLog(EXECUTING, startEventID, endEventID, partial);
|
||||
@@ -1776,13 +1799,8 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
|
||||
}
|
||||
else if(replayType == eReplay_OnlyDraw)
|
||||
{
|
||||
VkCommandBuffer cmd = m_PartialReplayData.singleDrawCmdBuffer = GetNextCmd();
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT };
|
||||
VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer;
|
||||
|
||||
VkResult vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERT(vkr == VK_SUCCESS);
|
||||
|
||||
bool rpWasActive = m_PartialReplayData.renderPassActive;
|
||||
|
||||
// if a render pass was active, begin it and set up the partial replay state
|
||||
@@ -1800,15 +1818,20 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
|
||||
// but we want to keep the partial replay data state intact, so restore
|
||||
// whether or not a render pass was active.
|
||||
m_PartialReplayData.renderPassActive = rpWasActive;
|
||||
|
||||
}
|
||||
else
|
||||
RDCFATAL("Unexpected replay type");
|
||||
|
||||
if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE)
|
||||
{
|
||||
VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer;
|
||||
|
||||
ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd));
|
||||
|
||||
SubmitCmds();
|
||||
|
||||
m_PartialReplayData.singleDrawCmdBuffer = VK_NULL_HANDLE;
|
||||
m_PartialReplayData.outsideCmdBuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
else
|
||||
RDCFATAL("Unexpected replay type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,12 @@ struct DrawcallTreeNode
|
||||
#undef SERIALISED_PARAMETER
|
||||
#define SERIALISED_PARAMETER Serialiser *localSerialiser,
|
||||
|
||||
struct DrawcallCallback
|
||||
{
|
||||
virtual void PreDraw(uint32_t eid) = 0;
|
||||
virtual void PostDraw(uint32_t eid) = 0;
|
||||
};
|
||||
|
||||
class WrappedVulkan : public IFrameCapturer
|
||||
{
|
||||
private:
|
||||
@@ -147,6 +153,8 @@ private:
|
||||
VulkanDebugManager *m_DebugManager;
|
||||
|
||||
Threading::CriticalSection m_CapTransitionLock;
|
||||
|
||||
DrawcallCallback *m_DrawcallCallback;
|
||||
|
||||
uint32_t m_FrameCounter;
|
||||
|
||||
@@ -284,10 +292,11 @@ private:
|
||||
VkCommandBuffer resultPartialCmdBuffer;
|
||||
VkDevice partialDevice; // device for above cmd buffer
|
||||
|
||||
// if we're replaying just a single draw we don't go through the
|
||||
// if we're replaying just a single draw or a particular command
|
||||
// buffer subsection of command events, we don't go through the
|
||||
// whole original command buffers to set up the partial replay,
|
||||
// so we just set this command buffer
|
||||
VkCommandBuffer singleDrawCmdBuffer;
|
||||
VkCommandBuffer outsideCmdBuffer;
|
||||
|
||||
// this records where in the frame a command buffer was submitted,
|
||||
// so that we know if our replay range ends in one of these ranges
|
||||
@@ -332,18 +341,18 @@ private:
|
||||
|
||||
bool IsPartialCmd(ResourceId cmdid)
|
||||
{
|
||||
return m_PartialReplayData.singleDrawCmdBuffer != VK_NULL_HANDLE ||
|
||||
return m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE ||
|
||||
cmdid == m_PartialReplayData.partialParent;
|
||||
}
|
||||
bool InPartialRange()
|
||||
{
|
||||
return m_PartialReplayData.singleDrawCmdBuffer != VK_NULL_HANDLE ||
|
||||
return m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE ||
|
||||
m_BakedCmdBufferInfo[m_PartialReplayData.partialParent].curEventID <= m_LastEventID - m_PartialReplayData.baseEvent;
|
||||
}
|
||||
VkCommandBuffer PartialCmdBuf()
|
||||
{
|
||||
if(m_PartialReplayData.singleDrawCmdBuffer != VK_NULL_HANDLE)
|
||||
return m_PartialReplayData.singleDrawCmdBuffer;
|
||||
if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE)
|
||||
return m_PartialReplayData.outsideCmdBuffer;
|
||||
return m_PartialReplayData.resultPartialCmdBuffer;
|
||||
}
|
||||
|
||||
@@ -494,6 +503,8 @@ public:
|
||||
FetchAPIEvent GetEvent(uint32_t eventID);
|
||||
const FetchDrawcall *GetDrawcall(uint32_t frameID, uint32_t eventID);
|
||||
|
||||
void SetDrawcallCB(DrawcallCallback *cb) { m_DrawcallCallback = cb; }
|
||||
|
||||
// Device initialization
|
||||
|
||||
IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateInstance,
|
||||
|
||||
@@ -583,7 +583,11 @@ vector<uint32_t> VulkanReplay::GetPassEvents(uint32_t frameID, uint32_t eventID)
|
||||
if(start == draw)
|
||||
break;
|
||||
|
||||
if(start->flags & eDraw_Drawcall)
|
||||
// include pass boundaries, these will be filtered out later
|
||||
// so we don't actually do anything (init postvs/draw overlay)
|
||||
// but it's useful to have the first part of the pass as part
|
||||
// of the list
|
||||
if(start->flags & (eDraw_Drawcall|eDraw_PassBoundary))
|
||||
passEvents.push_back(start->eventID);
|
||||
|
||||
start = m_pDriver->GetDrawcall(frameID, (uint32_t)start->next);
|
||||
@@ -3772,9 +3776,46 @@ void VulkanReplay::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
||||
GetDebugManager()->InitPostVSBuffers(frameID, eventID);
|
||||
}
|
||||
|
||||
struct InitPostVSCallback : public DrawcallCallback
|
||||
{
|
||||
InitPostVSCallback(WrappedVulkan *vk, VulkanReplay *rp, uint32_t frameID, const vector<uint32_t> &events)
|
||||
: m_pDriver(vk)
|
||||
, m_pReplay(rp)
|
||||
, m_FrameID(frameID)
|
||||
, m_Events(events)
|
||||
{ m_pDriver->SetDrawcallCB(this); }
|
||||
~InitPostVSCallback()
|
||||
{ m_pDriver->SetDrawcallCB(NULL); }
|
||||
|
||||
void PreDraw(uint32_t eid)
|
||||
{
|
||||
if(std::find(m_Events.begin(), m_Events.end(), eid) != m_Events.end())
|
||||
m_pReplay->InitPostVSBuffers(m_FrameID, eid);
|
||||
}
|
||||
|
||||
void PostDraw(uint32_t eid)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t m_FrameID;
|
||||
WrappedVulkan *m_pDriver;
|
||||
VulkanReplay *m_pReplay;
|
||||
const vector<uint32_t> &m_Events;
|
||||
};
|
||||
|
||||
void VulkanReplay::InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &events)
|
||||
{
|
||||
// Stub, will implement this in a minute
|
||||
// first we must replay up to the first event without replaying it. This ensures any
|
||||
// non-command buffer calls like memory unmaps etc all happen correctly before this
|
||||
// command buffer
|
||||
m_pDriver->ReplayLog(frameID, 0, events.front(), eReplay_WithoutDraw);
|
||||
|
||||
InitPostVSCallback cb(m_pDriver, this, frameID, events);
|
||||
|
||||
// now we replay the events, which are guaranteed (because we generated them in
|
||||
// GetPassEvents above) to come from the same command buffer, so the event IDs are
|
||||
// still locally continuous, even if we jump into replaying.
|
||||
m_pDriver->ReplayLog(frameID, events.front(), events.back(), eReplay_Full);
|
||||
}
|
||||
|
||||
vector<EventUsage> VulkanReplay::GetUsage(ResourceId id)
|
||||
|
||||
@@ -45,8 +45,12 @@ bool WrappedVulkan::Serialise_vkCmdDraw(
|
||||
{
|
||||
if(IsPartialCmd(cmdid) && InPartialRange())
|
||||
{
|
||||
if(m_DrawcallCallback) m_DrawcallCallback->PreDraw(m_RootEventID);
|
||||
|
||||
commandBuffer = PartialCmdBuf();
|
||||
ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vtxCount, instCount, firstVtx, firstInst);
|
||||
|
||||
if(m_DrawcallCallback) m_DrawcallCallback->PostDraw(m_RootEventID);
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
@@ -975,8 +979,12 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexed(
|
||||
{
|
||||
if(IsPartialCmd(cmdid) && InPartialRange())
|
||||
{
|
||||
if(m_DrawcallCallback) m_DrawcallCallback->PreDraw(m_RootEventID);
|
||||
|
||||
commandBuffer = PartialCmdBuf();
|
||||
ObjDisp(commandBuffer)->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst);
|
||||
|
||||
if(m_DrawcallCallback) m_DrawcallCallback->PostDraw(m_RootEventID);
|
||||
}
|
||||
}
|
||||
else if(m_State == READING)
|
||||
|
||||
Reference in New Issue
Block a user