Make sure pipelines are used with the right subpass in a partial replay

* When we do a partial replay we truncate the render pass to only have
  one subpass, but pipelines are created for a particular subpass. So
  at creation time we create a new pipeline that points to subpass 0 so
  we can use it later together with the truncated render passes.
This commit is contained in:
baldurk
2017-07-06 16:03:30 +01:00
parent 19ecf36b13
commit 01eb50089c
7 changed files with 36 additions and 11 deletions
+1 -1
View File
@@ -2437,7 +2437,7 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay
else if(m_RenderState.compute.pipeline != ResourceId())
{
// if we had a compute pipeline, need to bind that
m_RenderState.BindPipeline(cmd, VulkanRenderState::BindCompute);
m_RenderState.BindPipeline(cmd, VulkanRenderState::BindCompute, false);
}
}
+2 -2
View File
@@ -4982,7 +4982,7 @@ struct VulkanQuadOverdrawCallback : public VulkanDrawcallCallback
pipestate.graphics.descSets[pipe.first].descSet = GetResID(m_pDebug->m_QuadDescSet);
if(cmd)
pipestate.BindPipeline(cmd, VulkanRenderState::BindGraphics);
pipestate.BindPipeline(cmd, VulkanRenderState::BindGraphics, false);
}
bool PostDraw(uint32_t eid, VkCommandBuffer cmd)
@@ -4994,7 +4994,7 @@ struct VulkanQuadOverdrawCallback : public VulkanDrawcallCallback
m_pDriver->GetRenderState() = m_PrevState;
RDCASSERT(cmd);
m_pDriver->GetRenderState().BindPipeline(cmd, VulkanRenderState::BindGraphics);
m_pDriver->GetRenderState().BindPipeline(cmd, VulkanRenderState::BindGraphics, false);
return true;
}
+4
View File
@@ -89,6 +89,10 @@ struct VulkanCreationInfo
ResourceId renderpass;
uint32_t subpass;
// a variant of the pipeline that uses subpass 0, used for when we are replaying in isolation.
// See loadRPs in the RenderPass info
VkPipeline subpass0pipe;
// VkGraphicsPipelineCreateInfo
VkPipelineCreateFlags flags;
+8 -5
View File
@@ -106,7 +106,7 @@ void VulkanRenderState::BeginRenderPassAndApplyState(VkCommandBuffer cmd, Pipeli
};
ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
BindPipeline(cmd, binding);
BindPipeline(cmd, binding, true);
if(ibuffer.buf != ResourceId())
ObjDisp(cmd)->CmdBindIndexBuffer(
@@ -120,13 +120,16 @@ void VulkanRenderState::BeginRenderPassAndApplyState(VkCommandBuffer cmd, Pipeli
&vbuffers[i].offs);
}
void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding binding)
void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding binding, bool subpass0)
{
if(graphics.pipeline != ResourceId() && binding == BindGraphics)
{
ObjDisp(cmd)->CmdBindPipeline(
Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS,
Unwrap(GetResourceManager()->GetCurrentHandle<VkPipeline>(graphics.pipeline)));
VkPipeline pipe = GetResourceManager()->GetCurrentHandle<VkPipeline>(graphics.pipeline);
if(subpass0 && m_CreationInfo->m_Pipeline[graphics.pipeline].subpass0pipe != VK_NULL_HANDLE)
pipe = m_CreationInfo->m_Pipeline[graphics.pipeline].subpass0pipe;
ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe));
ResourceId pipeLayoutId = m_CreationInfo->m_Pipeline[graphics.pipeline].layout;
VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle<VkPipelineLayout>(pipeLayoutId);
+1 -1
View File
@@ -44,7 +44,7 @@ struct VulkanRenderState
VulkanRenderState &operator=(const VulkanRenderState &o);
void BeginRenderPassAndApplyState(VkCommandBuffer cmd, PipelineBinding binding);
void EndRenderPass(VkCommandBuffer cmd);
void BindPipeline(VkCommandBuffer cmd, PipelineBinding binding);
void BindPipeline(VkCommandBuffer cmd, PipelineBinding binding, bool subpass0);
// dynamic state
vector<VkViewport> views;
@@ -656,7 +656,8 @@ bool WrappedVulkan::Serialise_vkCreateRenderPass(Serialiser *localSerialiser, Vk
{
MakeSubpassLoadRP(loadInfo, &info, s);
ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rpinfo.loadRPs[s]);
ret =
ObjDisp(device)->CreateRenderPass(Unwrap(device), &loadInfo, NULL, &rpinfo.loadRPs[s]);
RDCASSERTEQUAL(ret, VK_SUCCESS);
// handle the loadRP being a duplicate
@@ -342,7 +342,24 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
live = GetResourceManager()->WrapResource(Unwrap(device), pipe);
GetResourceManager()->AddLiveResource(id, pipe);
m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &info);
VulkanCreationInfo::Pipeline &pipeInfo = m_CreationInfo.m_Pipeline[live];
pipeInfo.Init(GetResourceManager(), m_CreationInfo, &info);
ResourceId renderPassID = GetResourceManager()->GetNonDispWrapper(info.renderPass)->id;
info.renderPass = Unwrap(m_CreationInfo.m_RenderPass[renderPassID].loadRPs[info.subpass]);
info.subpass = 0;
ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache), 1,
&info, NULL, &pipeInfo.subpass0pipe);
RDCASSERTEQUAL(ret, VK_SUCCESS);
ResourceId subpass0id =
GetResourceManager()->WrapResource(Unwrap(device), pipeInfo.subpass0pipe);
// register as a live-only resource, so it is cleaned up properly
GetResourceManager()->AddLiveResource(subpass0id, pipeInfo.subpass0pipe);
}
}
}