Implement clear before draw/before pass overlays for vulkan

This commit is contained in:
baldurk
2016-02-07 18:50:41 +01:00
parent 2ea17e0394
commit 2e84a50ee2
2 changed files with 113 additions and 18 deletions
+18 -18
View File
@@ -1854,6 +1854,8 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
}
VkResult vkr = VK_SUCCESS;
bool rpWasActive = false;
// 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
@@ -1867,6 +1869,15 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
rpWasActive = m_PartialReplayData.renderPassActive;
// if a render pass was active, begin it and set up the partial replay state
if(m_PartialReplayData.renderPassActive)
m_RenderState.BeginRenderPassAndApplyState(cmd);
// if we had a compute pipeline, need to bind that
else if(m_RenderState.compute.pipeline != ResourceId())
m_RenderState.BindPipeline(cmd);
}
if(replayType == eReplay_Full)
@@ -1879,18 +1890,14 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t
}
else if(replayType == eReplay_OnlyDraw)
{
VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer;
bool rpWasActive = m_PartialReplayData.renderPassActive;
// if a render pass was active, begin it and set up the partial replay state
if(m_PartialReplayData.renderPassActive)
m_RenderState.BeginRenderPassAndApplyState(cmd);
// if we had a compute pipeline, need to bind that
else if(m_RenderState.compute.pipeline != ResourceId())
m_RenderState.BindPipeline(cmd);
ContextReplayLog(EXECUTING, endEventID, endEventID, partial);
}
else
RDCFATAL("Unexpected replay type");
if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE)
{
VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer;
// check if the render pass is active - it could have become active
// even if it wasn't before (if the above event was a CmdBeginRenderPass)
@@ -1901,13 +1908,6 @@ 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));
+95
View File
@@ -3119,6 +3119,101 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve
m_pDriver->vkDestroyFramebuffer(m_Device, depthFB, NULL);
}
}
else if(overlay == eTexOverlay_ClearBeforeDraw || overlay == eTexOverlay_ClearBeforePass)
{
// clear the overlay image itself
float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, (VkClearColorValue *)black, 1, &subresourceRange);
vector<uint32_t> events = passEvents;
if(overlay == eTexOverlay_ClearBeforeDraw)
events.clear();
events.push_back(eventID);
{
vkr = vt->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
size_t startEvent = 0;
// if we're ClearBeforePass the first event will be a vkBeginRenderPass.
// if there are any other events, we need to play up to right before them
// so that we have all the render state set up to do
// BeginRenderPassAndApplyState and a clear. If it's just the begin, we
// just play including it, do the clear, then we won't replay anything
// in the loop below
if(overlay == eTexOverlay_ClearBeforePass)
{
const FetchDrawcall *draw = m_pDriver->GetDrawcall(frameID, events[0]);
if(draw && draw->flags & eDraw_BeginPass)
{
if(events.size() == 1)
{
m_pDriver->ReplayLog(frameID, 0, events[0], eReplay_Full);
}
else
{
startEvent = 1;
m_pDriver->ReplayLog(frameID, 0, events[1], eReplay_WithoutDraw);
}
}
}
else
{
m_pDriver->ReplayLog(frameID, 0, events[0], eReplay_WithoutDraw);
}
cmd = m_pDriver->GetNextCmd();
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
m_pDriver->m_RenderState.BeginRenderPassAndApplyState(cmd);
VkClearAttachment blackclear = {
VK_IMAGE_ASPECT_COLOR_BIT, 0,
{ 0.0f, 0.0f, 0.0f, 0.0f }
};
vector<VkClearAttachment> atts;
VulkanCreationInfo::Framebuffer &fb = m_pDriver->m_CreationInfo.m_Framebuffer[m_pDriver->m_RenderState.framebuffer];
VulkanCreationInfo::RenderPass &rp = m_pDriver->m_CreationInfo.m_RenderPass[m_pDriver->m_RenderState.renderPass];
for(size_t i=0; i < rp.subpasses[m_pDriver->m_RenderState.subpass].colorAttachments.size(); i++)
{
blackclear.colorAttachment = rp.subpasses[m_pDriver->m_RenderState.subpass].colorAttachments[i];
atts.push_back(blackclear);
}
VkClearRect rect = {
{
{ 0, 0 },
{ fb.width, fb.height },
},
0, 1,
};
vt->CmdClearAttachments(Unwrap(cmd), (uint32_t)atts.size(), &atts[0], 1, &rect);
vkr = vt->EndCommandBuffer(Unwrap(cmd));
RDCASSERT(vkr == VK_SUCCESS);
for(size_t i = startEvent; i < events.size(); i++)
{
m_pDriver->ReplayLog(frameID, events[i], events[i], eReplay_OnlyDraw);
if(overlay == eTexOverlay_ClearBeforePass && i+1 < events.size())
m_pDriver->ReplayLog(frameID, events[i]+1, events[i+1], eReplay_WithoutDraw);
}
cmd = m_pDriver->GetNextCmd();
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
RDCASSERT(vkr == VK_SUCCESS);
}
}
else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw)
{
VulkanRenderState prevstate = m_pDriver->m_RenderState;