mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Account for implicit renderpass barriers when partially replaying
This commit is contained in:
@@ -2881,6 +2881,13 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
VkResult vkr = VK_SUCCESS;
|
||||
|
||||
bool rpWasActive = false;
|
||||
// these are the image barriers to take the images from their current state to whatever is
|
||||
// needed for the loadRP. This is because when creating the loadRP we set initial = final =
|
||||
// attachment layout, to ensure it's in a known layout (and not transitioned from UNDEFINED or
|
||||
// something). We do a 'safe' transition from current layout to what's expected in the
|
||||
// attachment, which should always be a nop or overriding an UNDEFINED transition. Then we put
|
||||
// it back again afterwards.
|
||||
std::vector<VkImageMemoryBarrier> loadRPImgBarriers;
|
||||
|
||||
// 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
|
||||
@@ -2904,29 +2911,29 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
if(m_Partial[Primary].renderPassActive)
|
||||
{
|
||||
// first apply implicit transitions to the right subpass
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
loadRPImgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
// don't transition from undefined, or contents will be discarded, instead transition from
|
||||
// the current state.
|
||||
for(size_t i = 0; i < imgBarriers.size(); i++)
|
||||
for(size_t i = 0; i < loadRPImgBarriers.size(); i++)
|
||||
{
|
||||
if(imgBarriers[i].oldLayout == VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
if(loadRPImgBarriers[i].oldLayout == VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
{
|
||||
// TODO find overlapping range and transition that instead
|
||||
imgBarriers[i].oldLayout =
|
||||
m_ImageLayouts[GetResourceManager()->GetNonDispWrapper(imgBarriers[i].image)->id]
|
||||
loadRPImgBarriers[i].oldLayout =
|
||||
m_ImageLayouts[GetResourceManager()->GetNonDispWrapper(loadRPImgBarriers[i].image)->id]
|
||||
.subresourceStates[0]
|
||||
.newLayout;
|
||||
}
|
||||
}
|
||||
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[GetResID(cmd)].imgbarriers,
|
||||
m_ImageLayouts, (uint32_t)imgBarriers.size(),
|
||||
&imgBarriers[0]);
|
||||
m_ImageLayouts, (uint32_t)loadRPImgBarriers.size(),
|
||||
&loadRPImgBarriers[0]);
|
||||
|
||||
ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 0, NULL, 0, NULL,
|
||||
(uint32_t)imgBarriers.size(), &imgBarriers[0]);
|
||||
(uint32_t)loadRPImgBarriers.size(), &loadRPImgBarriers[0]);
|
||||
|
||||
const DrawcallDescription *draw = GetDrawcall(endEventID);
|
||||
|
||||
@@ -2983,6 +2990,20 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
|
||||
if(m_Partial[Primary].renderPassActive)
|
||||
m_RenderState.EndRenderPass(cmd);
|
||||
|
||||
// reverse the loadRPImgBarriers
|
||||
for(size_t i = 0; i < loadRPImgBarriers.size(); i++)
|
||||
{
|
||||
std::swap(loadRPImgBarriers[i].oldLayout, loadRPImgBarriers[i].newLayout);
|
||||
}
|
||||
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[GetResID(cmd)].imgbarriers,
|
||||
m_ImageLayouts, (uint32_t)loadRPImgBarriers.size(),
|
||||
&loadRPImgBarriers[0]);
|
||||
|
||||
ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 0, NULL, 0, NULL,
|
||||
(uint32_t)loadRPImgBarriers.size(), &loadRPImgBarriers[0]);
|
||||
|
||||
// we might have replayed a CmdBeginRenderPass or CmdEndRenderPass,
|
||||
// but we want to keep the partial replay data state intact, so restore
|
||||
// whether or not a render pass was active.
|
||||
|
||||
@@ -922,9 +922,28 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(SerialiserType &ser, VkCommandB
|
||||
uint32_t numSubpasses =
|
||||
(uint32_t)m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses.size();
|
||||
|
||||
for(uint32_t sub = m_RenderState.subpass; sub < numSubpasses - 1; sub++)
|
||||
// for each subpass we skip, and for the finalLayout transition at the end of the
|
||||
// renderpass, update our tracking. These are executed implicitly but because we're
|
||||
// sneaking past them here our tracking will get out of date.
|
||||
uint32_t &sub = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass;
|
||||
|
||||
for(sub = m_RenderState.subpass; sub < numSubpasses - 1; sub++)
|
||||
{
|
||||
ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
GetResourceManager()->RecordBarriers(
|
||||
m_BakedCmdBufferInfo[GetResID(commandBuffer)].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), &imgBarriers[0]);
|
||||
}
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers(~0U);
|
||||
|
||||
GetResourceManager()->RecordBarriers(
|
||||
m_BakedCmdBufferInfo[GetResID(commandBuffer)].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), &imgBarriers[0]);
|
||||
|
||||
ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user