Create an equivalent 'loadFB' framebuffer for every 'loadRP' renderpass

* In order to be able to split apart and partially replay every render
  pass, we change them to always STORE instead of DONT_CARE, and then
  create a patched version that only has a single subpass (for each
  subpass in the original) and has LOAD/STORE semantics.
* However because of the requirements for framebuffer <-> renderpass
  we have to now multiply up the framebuffer to make a patched fb to
  correspond to each patched renderpass.
This commit is contained in:
baldurk
2017-08-17 13:06:22 +01:00
parent f442543ab5
commit e77f3ad8d1
3 changed files with 68 additions and 3 deletions
+3
View File
@@ -254,6 +254,9 @@ struct VulkanCreationInfo
vector<Attachment> attachments;
uint32_t width, height, layers;
// See above in loadRPs - we need to duplicate and make framebuffer equivalents for each
vector<VkFramebuffer> loadFBs;
};
map<ResourceId, Framebuffer> m_Framebuffer;
+1 -1
View File
@@ -99,7 +99,7 @@ void VulkanRenderState::BeginRenderPassAndApplyState(VkCommandBuffer cmd, Pipeli
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
NULL,
Unwrap(m_CreationInfo->m_RenderPass[renderPass].loadRPs[subpass]),
Unwrap(GetResourceManager()->GetCurrentHandle<VkFramebuffer>(framebuffer)),
Unwrap(m_CreationInfo->m_Framebuffer[framebuffer].loadFBs[subpass]),
renderArea,
(uint32_t)m_CreationInfo->m_RenderPass[renderPass].attachments.size(),
empty,
@@ -497,7 +497,46 @@ bool WrappedVulkan::Serialise_vkCreateFramebuffer(Serialiser *localSerialiser, V
live = GetResourceManager()->WrapResource(Unwrap(device), fb);
GetResourceManager()->AddLiveResource(id, fb);
m_CreationInfo.m_Framebuffer[live].Init(GetResourceManager(), m_CreationInfo, &info);
VulkanCreationInfo::Framebuffer fbinfo;
fbinfo.Init(GetResourceManager(), m_CreationInfo, &info);
const VulkanCreationInfo::RenderPass &rpinfo =
m_CreationInfo.m_RenderPass[GetResourceManager()->GetNonDispWrapper(info.renderPass)->id];
fbinfo.loadFBs.resize(rpinfo.loadRPs.size());
// create a render pass for each subpass that maintains attachment layouts
for(size_t s = 0; s < fbinfo.loadFBs.size(); s++)
{
info.renderPass = Unwrap(rpinfo.loadRPs[s]);
ret = ObjDisp(device)->CreateFramebuffer(Unwrap(device), &info, NULL, &fbinfo.loadFBs[s]);
RDCASSERTEQUAL(ret, VK_SUCCESS);
// handle the loadRP being a duplicate
if(GetResourceManager()->HasWrapper(ToTypedHandle(fbinfo.loadFBs[s])))
{
// just fetch the existing wrapped object
fbinfo.loadFBs[s] =
(VkFramebuffer)(uint64_t)GetResourceManager()->GetNonDispWrapper(fbinfo.loadFBs[s]);
// destroy this instance of the duplicate, as we must have matching create/destroy
// calls and there won't be a wrapped resource hanging around to destroy this one.
ObjDisp(device)->DestroyFramebuffer(Unwrap(device), fbinfo.loadFBs[s], NULL);
// don't need to ReplaceResource as no IDs are involved
}
else
{
ResourceId loadFBid =
GetResourceManager()->WrapResource(Unwrap(device), fbinfo.loadFBs[s]);
// register as a live-only resource, so it is cleaned up properly
GetResourceManager()->AddLiveResource(loadFBid, fbinfo.loadFBs[s]);
}
}
m_CreationInfo.m_Framebuffer[live] = fbinfo;
}
}
}
@@ -567,7 +606,30 @@ VkResult WrappedVulkan::vkCreateFramebuffer(VkDevice device,
{
GetResourceManager()->AddLiveResource(id, *pFramebuffer);
m_CreationInfo.m_Framebuffer[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo);
VulkanCreationInfo::Framebuffer fbinfo;
fbinfo.Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo);
const VulkanCreationInfo::RenderPass &rpinfo =
m_CreationInfo.m_RenderPass[GetResID(pCreateInfo->renderPass)];
fbinfo.loadFBs.resize(rpinfo.loadRPs.size());
// create a render pass for each subpass that maintains attachment layouts
for(size_t s = 0; s < fbinfo.loadFBs.size(); s++)
{
unwrappedInfo.renderPass = Unwrap(rpinfo.loadRPs[s]);
ret = ObjDisp(device)->CreateFramebuffer(Unwrap(device), &unwrappedInfo, NULL,
&fbinfo.loadFBs[s]);
RDCASSERTEQUAL(ret, VK_SUCCESS);
ResourceId loadFBid = GetResourceManager()->WrapResource(Unwrap(device), fbinfo.loadFBs[s]);
// register as a live-only resource, so it is cleaned up properly
GetResourceManager()->AddLiveResource(loadFBid, fbinfo.loadFBs[s]);
}
m_CreationInfo.m_Framebuffer[id] = fbinfo;
}
}