mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
VK IndirectDraw fixes primarily for overlay handling
- Unify Draw Indirect replay callback handling into a helper functions (for Draw* and DrawMesh*) - Replay callback handling uses its own Indirect Buffer for partial replay - Fix event skipping when at an event inside the outer Indirect action - The curEID might not be the same as baseEventID. - This could skip later events which should be replayed, if for example doing multiple partial replays. - Fix DrawMesh Indirect HandlePreCallback() not specifying ActionFlags::MeshDispatch in all cases
This commit is contained in:
@@ -3799,6 +3799,10 @@ RDResult WrappedVulkan::ReadLogInitialisation(RDCFile *rdc, bool storeStructured
|
||||
GPUBuffer::eGPUBufferGPULocal | GPUBuffer::eGPUBufferIndirectBuffer);
|
||||
m_IndirectBuffer.Name("m_IndirectBuffer");
|
||||
|
||||
m_IndirectBufferCB.Create(this, GetDev(), m_IndirectBufferSize * 2, 1,
|
||||
GPUBuffer::eGPUBufferGPULocal | GPUBuffer::eGPUBufferIndirectBuffer);
|
||||
m_IndirectBufferCB.Name("m_IndirectBufferActionCB");
|
||||
|
||||
m_IndirectCommandBuffer = GetNextCmd();
|
||||
|
||||
// steal the command buffer out of the pending commands - we'll manage its lifetime ourselves
|
||||
|
||||
@@ -693,6 +693,7 @@ private:
|
||||
|
||||
GPUBuffer m_IndirectBuffer;
|
||||
size_t m_IndirectBufferSize = 0;
|
||||
GPUBuffer m_IndirectBufferCB;
|
||||
VkCommandBuffer m_IndirectCommandBuffer = VK_NULL_HANDLE;
|
||||
bool m_IndirectDraw = false;
|
||||
|
||||
@@ -1186,6 +1187,9 @@ private:
|
||||
VkDeviceSize counterOffset = 0);
|
||||
void ExecuteIndirectReadback(VkCommandBuffer commandBuffer,
|
||||
const VkIndirectRecordData &indirectcopy);
|
||||
void ReplayIndirectCB(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
|
||||
uint32_t countToReplay, uint32_t stride, uint32_t curEID,
|
||||
uint32_t baseEventID, VkIndirectPatchType type);
|
||||
|
||||
WriteSerialiser &GetThreadSerialiser();
|
||||
template <typename SerialiserType>
|
||||
|
||||
@@ -1057,6 +1057,7 @@ void WrappedVulkan::Shutdown()
|
||||
m_Replay->DestroyResources();
|
||||
|
||||
m_IndirectBuffer.Destroy();
|
||||
m_IndirectBufferCB.Destroy();
|
||||
|
||||
// destroy debug manager and any objects it created
|
||||
SAFE_DELETE(m_DebugManager);
|
||||
|
||||
@@ -162,6 +162,149 @@ void WrappedVulkan::ExecuteIndirectReadback(VkCommandBuffer commandBuffer,
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedVulkan::ReplayIndirectCB(VkCommandBuffer commandBuffer, VkBuffer buffer,
|
||||
VkDeviceSize offset, uint32_t countToReplay, uint32_t stride,
|
||||
uint32_t curEID, uint32_t baseEventID, VkIndirectPatchType type)
|
||||
{
|
||||
const uint32_t drawidx = (curEID > baseEventID) ? (curEID - baseEventID - 1) : 0;
|
||||
const uint32_t firstDraw = m_FirstEventID <= 1 ? 0 : drawidx;
|
||||
|
||||
// copy off the buffer segment to our indirect draw buffer
|
||||
|
||||
VkMarkerRegion::Begin(StringFormat::Fmt("Drawcall callback replay (drawCount=%u)", countToReplay),
|
||||
commandBuffer);
|
||||
|
||||
VkBufferMemoryBarrier bufBarrier = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
NULL,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
m_IndirectBufferCB.UnwrappedBuffer(),
|
||||
0,
|
||||
m_IndirectBufferSize};
|
||||
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
// initialise to 0 so all other draws don't draw anything
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdFillBuffer(Unwrap(commandBuffer), m_IndirectBufferCB.UnwrappedBuffer(), 0,
|
||||
m_IndirectBufferSize, 0);
|
||||
|
||||
const VkDeviceSize drawStart = firstDraw * stride;
|
||||
VkDeviceSize indirectCmdSize = 0;
|
||||
bool draw = false;
|
||||
bool drawIndexed = false;
|
||||
bool drawMesh = false;
|
||||
switch(type)
|
||||
{
|
||||
case VkIndirectPatchType::DrawIndirect:
|
||||
case VkIndirectPatchType::DrawIndirectCount:
|
||||
indirectCmdSize = sizeof(VkDrawIndirectCommand);
|
||||
draw = true;
|
||||
break;
|
||||
case VkIndirectPatchType::DrawIndexedIndirect:
|
||||
case VkIndirectPatchType::DrawIndexedIndirectCount:
|
||||
indirectCmdSize = sizeof(VkDrawIndexedIndirectCommand);
|
||||
drawIndexed = true;
|
||||
break;
|
||||
case VkIndirectPatchType::MeshIndirect:
|
||||
case VkIndirectPatchType::MeshIndirectCount:
|
||||
indirectCmdSize = sizeof(VkDrawMeshTasksIndirectCommandEXT);
|
||||
drawMesh = true;
|
||||
break;
|
||||
default: RDCERR("Unhandled VkIndirectPatchType %u", (uint32_t)(type)); break;
|
||||
};
|
||||
ActionFlags actionFlags = drawMesh ? ActionFlags::MeshDispatch : ActionFlags::Drawcall;
|
||||
|
||||
const VkDeviceSize drawEnd =
|
||||
((countToReplay > 0) ? (countToReplay - 1) * stride : 0) + indirectCmdSize;
|
||||
|
||||
const VkDeviceSize regionSize = (drawEnd > drawStart) ? drawEnd - drawStart : 0;
|
||||
VkBufferCopy region = {offset + drawStart, drawStart, regionSize};
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(buffer), m_IndirectBufferCB.UnwrappedBuffer(),
|
||||
1, ®ion);
|
||||
|
||||
// finally wait for copy to complete before drawing from it
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.offset = 0;
|
||||
bufBarrier.size = indirectCmdSize;
|
||||
|
||||
for(uint32_t i = firstDraw; i < countToReplay; i++)
|
||||
{
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, actionFlags, i + 1);
|
||||
|
||||
// action up to and including i. The previous draws will be nop'd out
|
||||
const uint32_t countToDraw = i + 1;
|
||||
if(draw)
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndirect(Unwrap(commandBuffer), m_IndirectBufferCB.UnwrappedBuffer(), 0,
|
||||
countToDraw, stride);
|
||||
}
|
||||
else if(drawIndexed)
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndexedIndirect(Unwrap(commandBuffer), m_IndirectBufferCB.UnwrappedBuffer(), 0,
|
||||
countToDraw, stride);
|
||||
}
|
||||
else if(drawMesh)
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), m_IndirectBufferCB.UnwrappedBuffer(),
|
||||
0, countToDraw, stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Missing Draw Type");
|
||||
}
|
||||
|
||||
if(eventId && m_ActionCallback->PostDraw(eventId, ActionFlags::Drawcall, commandBuffer))
|
||||
{
|
||||
if(draw)
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndirect(Unwrap(commandBuffer), m_IndirectBufferCB.UnwrappedBuffer(), 0,
|
||||
countToDraw, stride);
|
||||
}
|
||||
else if(drawIndexed)
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndexedIndirect(Unwrap(commandBuffer), m_IndirectBufferCB.UnwrappedBuffer(), 0,
|
||||
countToDraw, stride);
|
||||
}
|
||||
else if(drawMesh)
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(
|
||||
Unwrap(commandBuffer), m_IndirectBufferCB.UnwrappedBuffer(), 0, countToDraw, stride);
|
||||
}
|
||||
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::Drawcall, commandBuffer);
|
||||
}
|
||||
|
||||
// now that we're done, nop out this draw so that the next time around we only draw
|
||||
// the next draw.
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdFillBuffer(Unwrap(commandBuffer), bufBarrier.buffer, bufBarrier.offset,
|
||||
bufBarrier.size, 0);
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.offset += stride;
|
||||
}
|
||||
|
||||
VkMarkerRegion::End(commandBuffer);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCmdDraw(SerialiserType &ser, VkCommandBuffer commandBuffer,
|
||||
uint32_t vertexCount, uint32_t instanceCount,
|
||||
@@ -393,6 +536,8 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t countEventsReplayed = count;
|
||||
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
|
||||
@@ -416,74 +561,19 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t baseEventID = it->eventId;
|
||||
const uint32_t baseEventID = it->eventId;
|
||||
|
||||
uint32_t executesReplayed = RDCMIN(m_LastEventID - baseEventID, count);
|
||||
// executesReplayed is relative to baseEventID
|
||||
// compute the number of events to skip relative to the curEID
|
||||
countEventsReplayed = (baseEventID + executesReplayed) - curEID;
|
||||
|
||||
// when we have a callback, submit every action individually to the callback
|
||||
if(m_ActionCallback)
|
||||
{
|
||||
VkMarkerRegion::Begin(
|
||||
StringFormat::Fmt("Drawcall callback replay (drawCount=%u)", count), commandBuffer);
|
||||
|
||||
// first copy off the buffer segment to our indirect action buffer
|
||||
VkBufferMemoryBarrier bufBarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
NULL,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(buffer),
|
||||
offset,
|
||||
(count > 0 ? stride * (count - 1) : 0) + sizeof(VkDrawIndirectCommand),
|
||||
};
|
||||
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
VkBufferCopy region = {offset, 0, bufBarrier.size};
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(buffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 1, ®ion);
|
||||
|
||||
// wait for the copy to finish
|
||||
bufBarrier.buffer = m_IndirectBuffer.UnwrappedBuffer();
|
||||
bufBarrier.offset = 0;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.size = sizeof(VkDrawIndirectCommand);
|
||||
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, ActionFlags::Drawcall, i + 1);
|
||||
|
||||
// action up to and including i. The previous draws will be nop'd out
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndirect(Unwrap(commandBuffer), m_IndirectBuffer.UnwrappedBuffer(), 0,
|
||||
i + 1, stride);
|
||||
|
||||
if(eventId &&
|
||||
m_ActionCallback->PostDraw(eventId, ActionFlags::Drawcall, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndirect(Unwrap(commandBuffer), m_IndirectBuffer.UnwrappedBuffer(),
|
||||
0, i + 1, stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::Drawcall, commandBuffer);
|
||||
}
|
||||
|
||||
// now that we're done, nop out this draw so that the next time around we only draw
|
||||
// the next draw.
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdFillBuffer(Unwrap(commandBuffer), bufBarrier.buffer, bufBarrier.offset,
|
||||
bufBarrier.size, 0);
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.offset += stride;
|
||||
}
|
||||
|
||||
VkMarkerRegion::End(commandBuffer);
|
||||
uint32_t countToReplay = RDCMIN(count, executesReplayed);
|
||||
ReplayIndirectCB(commandBuffer, buffer, offset, countToReplay, stride, curEID,
|
||||
baseEventID, VkIndirectPatchType::DrawIndirect);
|
||||
}
|
||||
// To add the multidraw, we made an event N that is the 'parent' marker, then
|
||||
// N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected
|
||||
@@ -584,10 +674,11 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu
|
||||
}
|
||||
|
||||
// multidraws skip the event ID past the whole thing
|
||||
++countEventsReplayed;
|
||||
if(m_FirstEventID > 1)
|
||||
m_RootEventID += count + 1;
|
||||
m_RootEventID += countEventsReplayed;
|
||||
else
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += count + 1;
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += countEventsReplayed;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -601,8 +692,8 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(SerialiserType &ser, VkCommandBu
|
||||
// add on the size we'll need for an indirect buffer in the worst case.
|
||||
// Note that we'll only ever be partially replaying one draw at a time, so we only need the
|
||||
// worst case.
|
||||
m_IndirectBufferSize =
|
||||
RDCMAX(m_IndirectBufferSize, sizeof(VkDrawIndirectCommand) + count * stride);
|
||||
m_IndirectBufferSize = RDCMAX(m_IndirectBufferSize, sizeof(VkDrawIndirectCommand) +
|
||||
(count > 0 ? count - 1 : 0) * stride);
|
||||
|
||||
rdcstr name = "vkCmdDrawIndirect";
|
||||
|
||||
@@ -804,6 +895,8 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser,
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t countEventsReplayed = count;
|
||||
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
|
||||
@@ -827,30 +920,19 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser,
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t baseEventID = it->eventId;
|
||||
const uint32_t baseEventID = it->eventId;
|
||||
|
||||
uint32_t executesReplayed = RDCMIN(m_LastEventID - baseEventID, count);
|
||||
// executesReplayed is relative to baseEventID
|
||||
// compute the number of events to skip relative to the curEID
|
||||
countEventsReplayed = (baseEventID + executesReplayed) - curEID;
|
||||
|
||||
// when we have a callback, submit every action individually to the callback
|
||||
if(m_ActionCallback)
|
||||
{
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, ActionFlags::Drawcall, i + 1);
|
||||
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset, 1,
|
||||
stride);
|
||||
|
||||
if(eventId &&
|
||||
m_ActionCallback->PostDraw(eventId, ActionFlags::Drawcall, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset, 1,
|
||||
stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::Drawcall, commandBuffer);
|
||||
}
|
||||
|
||||
offset += stride;
|
||||
}
|
||||
uint32_t countToReplay = RDCMIN(count, executesReplayed);
|
||||
ReplayIndirectCB(commandBuffer, buffer, offset, countToReplay, stride, curEID,
|
||||
baseEventID, VkIndirectPatchType::DrawIndexedIndirect);
|
||||
}
|
||||
// To add the multidraw, we made an event N that is the 'parent' marker, then
|
||||
// N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected
|
||||
@@ -963,10 +1045,11 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser,
|
||||
}
|
||||
|
||||
// multidraws skip the event ID past the whole thing
|
||||
++countEventsReplayed;
|
||||
if(m_FirstEventID > 1)
|
||||
m_RootEventID += count + 1;
|
||||
m_RootEventID += countEventsReplayed;
|
||||
else
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += count + 1;
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += countEventsReplayed;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -980,8 +1063,8 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(SerialiserType &ser,
|
||||
// add on the size we'll need for an indirect buffer in the worst case.
|
||||
// Note that we'll only ever be partially replaying one draw at a time, so we only need the
|
||||
// worst case.
|
||||
m_IndirectBufferSize =
|
||||
RDCMAX(m_IndirectBufferSize, sizeof(VkDrawIndexedIndirectCommand) + count * stride);
|
||||
m_IndirectBufferSize = RDCMAX(m_IndirectBufferSize, sizeof(VkDrawIndexedIndirectCommand) +
|
||||
(count > 0 ? count - 1 : 0) * stride);
|
||||
|
||||
rdcstr name = "vkCmdDrawIndexedIndirect";
|
||||
|
||||
@@ -2765,6 +2848,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirectCount(SerialiserType &ser,
|
||||
// Fortunately when we're not in the re-recording command buffer the EID tracking isn't
|
||||
// needed.
|
||||
uint32_t count = maxDrawCount;
|
||||
uint32_t countEventsReplayed = count;
|
||||
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
@@ -2789,7 +2873,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirectCount(SerialiserType &ser,
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t baseEventID = it->eventId;
|
||||
const uint32_t baseEventID = it->eventId;
|
||||
|
||||
// get the number of draws by looking at how many children the parent action has.
|
||||
const rdcarray<ActionDescription> &children = GetAction(it->eventId)->children;
|
||||
@@ -2799,71 +2883,17 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirectCount(SerialiserType &ser,
|
||||
if(!children.empty() && children.back().flags & ActionFlags::PopMarker)
|
||||
count--;
|
||||
|
||||
uint32_t executesReplayed = RDCMIN(m_LastEventID - baseEventID, count);
|
||||
// executesReplayed is relative to baseEventID
|
||||
// compute the number of events to skip relative to the curEID
|
||||
countEventsReplayed = (baseEventID + executesReplayed) - curEID;
|
||||
|
||||
// when we have a callback, submit every action individually to the callback
|
||||
if(m_ActionCallback)
|
||||
{
|
||||
VkMarkerRegion::Begin(
|
||||
StringFormat::Fmt("Drawcall callback replay (drawCount=%u)", count), commandBuffer);
|
||||
|
||||
// first copy off the buffer segment to our indirect draw buffer
|
||||
VkBufferMemoryBarrier bufBarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
NULL,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(buffer),
|
||||
offset,
|
||||
(count > 0 ? stride * (count - 1) : 0) + sizeof(VkDrawIndirectCommand),
|
||||
};
|
||||
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
VkBufferCopy region = {offset, 0, bufBarrier.size};
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(buffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 1, ®ion);
|
||||
|
||||
// wait for the copy to finish
|
||||
bufBarrier.buffer = m_IndirectBuffer.UnwrappedBuffer();
|
||||
bufBarrier.offset = 0;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.size = sizeof(VkDrawIndirectCommand);
|
||||
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, ActionFlags::Drawcall, i + 1);
|
||||
|
||||
// action up to and including i. The previous draws will be nop'd out
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndirect(Unwrap(commandBuffer), m_IndirectBuffer.UnwrappedBuffer(), 0,
|
||||
i + 1, stride);
|
||||
|
||||
if(eventId && m_ActionCallback->PostDraw(eventId, ActionFlags::Drawcall, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndirect(Unwrap(commandBuffer), m_IndirectBuffer.UnwrappedBuffer(), 0,
|
||||
i + 1, stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::Drawcall, commandBuffer);
|
||||
}
|
||||
|
||||
// now that we're done, nop out this draw so that the next time around we only draw
|
||||
// the next draw.
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdFillBuffer(Unwrap(commandBuffer), bufBarrier.buffer, bufBarrier.offset,
|
||||
bufBarrier.size, 0);
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.offset += stride;
|
||||
}
|
||||
|
||||
VkMarkerRegion::End(commandBuffer);
|
||||
uint32_t countToReplay = RDCMIN(count, executesReplayed);
|
||||
ReplayIndirectCB(commandBuffer, buffer, offset, countToReplay, stride, curEID,
|
||||
baseEventID, VkIndirectPatchType::DrawIndirectCount);
|
||||
}
|
||||
// To add the multidraw, we made an event N that is the 'parent' marker, then
|
||||
// N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected
|
||||
@@ -2961,10 +2991,11 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirectCount(SerialiserType &ser,
|
||||
}
|
||||
|
||||
// multidraws skip the event ID past the whole thing
|
||||
++countEventsReplayed;
|
||||
if(m_FirstEventID > 1)
|
||||
m_RootEventID += count + 1;
|
||||
m_RootEventID += countEventsReplayed;
|
||||
else
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += count + 1;
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += countEventsReplayed;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3121,6 +3152,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirectCount(
|
||||
// Fortunately when we're not in the re-recording command buffer the EID tracking isn't
|
||||
// needed.
|
||||
uint32_t count = maxDrawCount;
|
||||
uint32_t countEventsReplayed = count;
|
||||
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
@@ -3145,7 +3177,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirectCount(
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t baseEventID = it->eventId;
|
||||
const uint32_t baseEventID = it->eventId;
|
||||
|
||||
// get the number of draws by looking at how many children the parent action has.
|
||||
const rdcarray<ActionDescription> &children = GetAction(it->eventId)->children;
|
||||
@@ -3155,71 +3187,17 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirectCount(
|
||||
if(!children.empty() && children.back().flags & ActionFlags::PopMarker)
|
||||
count--;
|
||||
|
||||
uint32_t executesReplayed = RDCMIN(m_LastEventID - baseEventID, count);
|
||||
// executesReplayed is relative to baseEventID
|
||||
// compute the number of events to skip relative to the curEID
|
||||
countEventsReplayed = (baseEventID + executesReplayed) - curEID;
|
||||
|
||||
// when we have a callback, submit every action individually to the callback
|
||||
if(m_ActionCallback)
|
||||
{
|
||||
VkMarkerRegion::Begin(
|
||||
StringFormat::Fmt("Drawcall callback replay (drawCount=%u)", count), commandBuffer);
|
||||
|
||||
// first copy off the buffer segment to our indirect draw buffer
|
||||
VkBufferMemoryBarrier bufBarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
NULL,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(buffer),
|
||||
offset,
|
||||
(count > 0 ? stride * (count - 1) : 0) + sizeof(VkDrawIndirectCommand),
|
||||
};
|
||||
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
VkBufferCopy region = {offset, 0, bufBarrier.size};
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(buffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 1, ®ion);
|
||||
|
||||
// wait for the copy to finish
|
||||
bufBarrier.buffer = m_IndirectBuffer.UnwrappedBuffer();
|
||||
bufBarrier.offset = 0;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.size = sizeof(VkDrawIndexedIndirectCommand);
|
||||
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, ActionFlags::Drawcall, i + 1);
|
||||
|
||||
// action up to and including i. The previous draws will be nop'd out
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndexedIndirect(Unwrap(commandBuffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 0, i + 1, stride);
|
||||
|
||||
if(eventId && m_ActionCallback->PostDraw(eventId, ActionFlags::Drawcall, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawIndexedIndirect(Unwrap(commandBuffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 0, i + 1, stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::Drawcall, commandBuffer);
|
||||
}
|
||||
|
||||
// now that we're done, nop out this draw so that the next time around we only draw
|
||||
// the next draw.
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdFillBuffer(Unwrap(commandBuffer), bufBarrier.buffer, bufBarrier.offset,
|
||||
bufBarrier.size, 0);
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.offset += stride;
|
||||
}
|
||||
|
||||
VkMarkerRegion::End(commandBuffer);
|
||||
uint32_t countToReplay = RDCMIN(count, executesReplayed);
|
||||
ReplayIndirectCB(commandBuffer, buffer, offset, countToReplay, stride, curEID,
|
||||
baseEventID, VkIndirectPatchType::DrawIndexedIndirectCount);
|
||||
}
|
||||
// To add the multidraw, we made an event N that is the 'parent' marker, then
|
||||
// N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected
|
||||
@@ -3318,10 +3296,11 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirectCount(
|
||||
}
|
||||
|
||||
// multidraws skip the event ID past the whole thing
|
||||
++countEventsReplayed;
|
||||
if(m_FirstEventID > 1)
|
||||
m_RootEventID += count + 1;
|
||||
m_RootEventID += countEventsReplayed;
|
||||
else
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += count + 1;
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += countEventsReplayed;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4477,7 +4456,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectEXT(SerialiserType &ser,
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
|
||||
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer);
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, ActionFlags::MeshDispatch);
|
||||
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), Unwrap(buffer), offset,
|
||||
@@ -4496,6 +4475,8 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectEXT(SerialiserType &ser,
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t countEventsReplayed = drawCount;
|
||||
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
|
||||
@@ -4521,75 +4502,17 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectEXT(SerialiserType &ser,
|
||||
{
|
||||
uint32_t baseEventID = it->eventId;
|
||||
|
||||
uint32_t executesReplayed = RDCMIN(m_LastEventID - baseEventID, drawCount);
|
||||
// executesReplayed is relative to baseEventID
|
||||
// compute the number of events to skip relative to the curEID
|
||||
countEventsReplayed = (baseEventID + executesReplayed) - curEID;
|
||||
|
||||
// when we have a callback, submit every action individually to the callback
|
||||
if(m_ActionCallback)
|
||||
{
|
||||
VkMarkerRegion::Begin(
|
||||
StringFormat::Fmt("Mesh Drawcall callback replay (drawCount=%u)", drawCount),
|
||||
commandBuffer);
|
||||
|
||||
// first copy off the buffer segment to our indirect action buffer
|
||||
VkBufferMemoryBarrier bufBarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
NULL,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(buffer),
|
||||
offset,
|
||||
(drawCount > 0 ? stride * (drawCount - 1) : 0) +
|
||||
sizeof(VkDrawMeshTasksIndirectCommandEXT),
|
||||
};
|
||||
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
VkBufferCopy region = {offset, 0, bufBarrier.size};
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(buffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 1, ®ion);
|
||||
|
||||
// wait for the copy to finish
|
||||
bufBarrier.buffer = m_IndirectBuffer.UnwrappedBuffer();
|
||||
bufBarrier.offset = 0;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.size = sizeof(VkDrawMeshTasksIndirectCommandEXT);
|
||||
|
||||
for(uint32_t i = 0; i < drawCount; i++)
|
||||
{
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, ActionFlags::MeshDispatch, i + 1);
|
||||
|
||||
// action up to and including i. The previous draws will be nop'd out
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(
|
||||
Unwrap(commandBuffer), m_IndirectBuffer.UnwrappedBuffer(), 0, i + 1, stride);
|
||||
|
||||
if(eventId &&
|
||||
m_ActionCallback->PostDraw(eventId, ActionFlags::MeshDispatch, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 0, i + 1,
|
||||
stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::MeshDispatch, commandBuffer);
|
||||
}
|
||||
|
||||
// now that we're done, nop out this draw so that the next time around we only draw
|
||||
// the next draw.
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdFillBuffer(Unwrap(commandBuffer), bufBarrier.buffer, bufBarrier.offset,
|
||||
bufBarrier.size, 0);
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.offset += stride;
|
||||
}
|
||||
|
||||
VkMarkerRegion::End(commandBuffer);
|
||||
uint32_t countToReplay = RDCMIN(drawCount, executesReplayed);
|
||||
ReplayIndirectCB(commandBuffer, buffer, offset, countToReplay, stride, curEID,
|
||||
baseEventID, VkIndirectPatchType::MeshIndirect);
|
||||
}
|
||||
// To add the multidraw, we made an event N that is the 'parent' marker, then
|
||||
// N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected
|
||||
@@ -4683,29 +4606,19 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectEXT(SerialiserType &ser,
|
||||
stride = sizeof(VkDrawMeshTasksIndirectCommandEXT);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t eventId =
|
||||
HandlePreCallback(commandBuffer, ActionFlags::MeshDispatch, drawidx + 1);
|
||||
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), unwrappedBuffer, offset,
|
||||
drawCount, stride);
|
||||
|
||||
if(eventId &&
|
||||
m_ActionCallback->PostDraw(eventId, ActionFlags::MeshDispatch, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), unwrappedBuffer, offset,
|
||||
drawCount, stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::MeshDispatch, commandBuffer);
|
||||
}
|
||||
}
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), unwrappedBuffer, offset,
|
||||
drawCount, stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// multidraws skip the event ID past the whole thing
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += drawCount + 1;
|
||||
++countEventsReplayed;
|
||||
if(m_FirstEventID > 1)
|
||||
m_RootEventID += countEventsReplayed;
|
||||
else
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += countEventsReplayed;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -4720,8 +4633,9 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectEXT(SerialiserType &ser,
|
||||
// add on the size we'll need for an indirect buffer in the worst case.
|
||||
// Note that we'll only ever be partially replaying one draw at a time, so we only need the
|
||||
// worst case.
|
||||
m_IndirectBufferSize = RDCMAX(m_IndirectBufferSize,
|
||||
sizeof(VkDrawMeshTasksIndirectCommandEXT) + drawCount * stride);
|
||||
m_IndirectBufferSize =
|
||||
RDCMAX(m_IndirectBufferSize, sizeof(VkDrawMeshTasksIndirectCommandEXT) +
|
||||
(drawCount > 0 ? drawCount - 1 : 0) * stride);
|
||||
|
||||
rdcstr name = "vkCmdDrawMeshTasksIndirectEXT";
|
||||
|
||||
@@ -4897,6 +4811,7 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectCountEXT(
|
||||
// Fortunately when we're not in the re-recording command buffer the EID tracking isn't
|
||||
// needed.
|
||||
uint32_t count = maxDrawCount;
|
||||
uint32_t countEventsReplayed = count;
|
||||
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
@@ -4931,73 +4846,17 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectCountEXT(
|
||||
if(!children.empty() && children.back().flags & ActionFlags::PopMarker)
|
||||
count--;
|
||||
|
||||
uint32_t executesReplayed = RDCMIN(m_LastEventID - baseEventID, count);
|
||||
// executesReplayed is relative to baseEventID
|
||||
// compute the number of events to skip relative to the curEID
|
||||
countEventsReplayed = (baseEventID + executesReplayed) - curEID;
|
||||
|
||||
// when we have a callback, submit every action individually to the callback
|
||||
if(m_ActionCallback)
|
||||
{
|
||||
VkMarkerRegion::Begin(
|
||||
StringFormat::Fmt("Mesh Dispatch callback replay (drawCount=%u)", count),
|
||||
commandBuffer);
|
||||
|
||||
// first copy off the buffer segment to our indirect draw buffer
|
||||
VkBufferMemoryBarrier bufBarrier = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
NULL,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
VK_QUEUE_FAMILY_IGNORED,
|
||||
Unwrap(buffer),
|
||||
offset,
|
||||
(count > 0 ? stride * (count - 1) : 0) + sizeof(VkDrawMeshTasksIndirectCommandEXT),
|
||||
};
|
||||
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
VkBufferCopy region = {offset, 0, bufBarrier.size};
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(buffer),
|
||||
m_IndirectBuffer.UnwrappedBuffer(), 1, ®ion);
|
||||
|
||||
// wait for the copy to finish
|
||||
bufBarrier.buffer = m_IndirectBuffer.UnwrappedBuffer();
|
||||
bufBarrier.offset = 0;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.size = sizeof(VkDrawMeshTasksIndirectCommandEXT);
|
||||
|
||||
for(uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
uint32_t eventId = HandlePreCallback(commandBuffer, ActionFlags::MeshDispatch, i + 1);
|
||||
|
||||
// action up to and including i. The previous draws will be nop'd out
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(
|
||||
Unwrap(commandBuffer), m_IndirectBuffer.UnwrappedBuffer(), 0, i + 1, stride);
|
||||
|
||||
if(eventId &&
|
||||
m_ActionCallback->PostDraw(eventId, ActionFlags::MeshDispatch, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(
|
||||
Unwrap(commandBuffer), m_IndirectBuffer.UnwrappedBuffer(), 0, i + 1, stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::MeshDispatch, commandBuffer);
|
||||
}
|
||||
|
||||
// now that we're done, nop out this draw so that the next time around we only draw
|
||||
// the next draw.
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdFillBuffer(Unwrap(commandBuffer), bufBarrier.buffer, bufBarrier.offset,
|
||||
bufBarrier.size, 0);
|
||||
bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
bufBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
DoPipelineBarrier(commandBuffer, 1, &bufBarrier);
|
||||
|
||||
bufBarrier.offset += stride;
|
||||
}
|
||||
|
||||
VkMarkerRegion::End(commandBuffer);
|
||||
uint32_t countToReplay = RDCMIN(count, executesReplayed);
|
||||
ReplayIndirectCB(commandBuffer, buffer, offset, countToReplay, stride, curEID,
|
||||
baseEventID, VkIndirectPatchType::MeshIndirectCount);
|
||||
}
|
||||
// To add the multidraw, we made an event N that is the 'parent' marker, then
|
||||
// N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected
|
||||
@@ -5090,29 +4949,19 @@ bool WrappedVulkan::Serialise_vkCmdDrawMeshTasksIndirectCountEXT(
|
||||
stride = sizeof(VkDrawMeshTasksIndirectCommandEXT);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t eventId =
|
||||
HandlePreCallback(commandBuffer, ActionFlags::MeshDispatch, drawidx + 1);
|
||||
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), unwrappedBuffer, offset,
|
||||
count, stride);
|
||||
|
||||
if(eventId &&
|
||||
m_ActionCallback->PostDraw(eventId, ActionFlags::MeshDispatch, commandBuffer))
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), unwrappedBuffer, offset,
|
||||
count, stride);
|
||||
m_ActionCallback->PostRedraw(eventId, ActionFlags::MeshDispatch, commandBuffer);
|
||||
}
|
||||
}
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdDrawMeshTasksIndirectEXT(Unwrap(commandBuffer), unwrappedBuffer, offset, count,
|
||||
stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// multidraws skip the event ID past the whole thing
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += count + 1;
|
||||
++countEventsReplayed;
|
||||
if(m_FirstEventID > 1)
|
||||
m_RootEventID += countEventsReplayed;
|
||||
else
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID += countEventsReplayed;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user