mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Add support for VK_KHR_create_renderpass2
This commit is contained in:
@@ -465,6 +465,10 @@ enum class VulkanChunk : uint32_t
|
||||
vkGetDeviceQueue2,
|
||||
vkCmdDrawIndirectCountKHR,
|
||||
vkCmdDrawIndexedIndirectCountKHR,
|
||||
vkCreateRenderPass2KHR,
|
||||
vkCmdBeginRenderPass2KHR,
|
||||
vkCmdNextSubpass2KHR,
|
||||
vkCmdEndRenderPass2KHR,
|
||||
Max,
|
||||
};
|
||||
|
||||
@@ -654,6 +658,13 @@ DECLARE_REFLECTION_STRUCT(VkProtectedSubmitInfo);
|
||||
DECLARE_REFLECTION_STRUCT(VkImageFormatListCreateInfoKHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkImageViewASTCDecodeModeEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkShaderModuleValidationCacheCreateInfoEXT);
|
||||
DECLARE_REFLECTION_STRUCT(VkAttachmentDescription2KHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkSubpassDescription2KHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkSubpassDependency2KHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkAttachmentReference2KHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkRenderPassCreateInfo2KHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkSubpassBeginInfoKHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkSubpassEndInfoKHR);
|
||||
DECLARE_REFLECTION_STRUCT(VkDispatchIndirectCommand);
|
||||
DECLARE_REFLECTION_STRUCT(VkDrawIndirectCommand);
|
||||
DECLARE_REFLECTION_STRUCT(VkDrawIndexedIndirectCommand);
|
||||
@@ -733,6 +744,9 @@ DECLARE_DESERIALISE_TYPE(VkDeviceGroupRenderPassBeginInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkMemoryAllocateFlagsInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkProtectedSubmitInfo);
|
||||
DECLARE_DESERIALISE_TYPE(VkImageFormatListCreateInfoKHR);
|
||||
DECLARE_DESERIALISE_TYPE(VkRenderPassCreateInfo2KHR);
|
||||
DECLARE_DESERIALISE_TYPE(VkSubpassBeginInfoKHR);
|
||||
DECLARE_DESERIALISE_TYPE(VkSubpassEndInfoKHR);
|
||||
|
||||
#if defined(VK_KHR_external_memory_win32) || defined(VK_NV_external_memory_win32)
|
||||
DECLARE_REFLECTION_STRUCT(VkImportMemoryWin32HandleInfoNV);
|
||||
|
||||
@@ -699,6 +699,9 @@ static const VkExtensionProperties supportedExtensions[] = {
|
||||
{
|
||||
VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_KHR_BIND_MEMORY_2_SPEC_VERSION,
|
||||
},
|
||||
{
|
||||
VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION,
|
||||
},
|
||||
{
|
||||
VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION,
|
||||
},
|
||||
@@ -2670,6 +2673,15 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
|
||||
VK_NULL_HANDLE, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case VulkanChunk::vkCreateRenderPass2KHR:
|
||||
return Serialise_vkCreateRenderPass2KHR(ser, VK_NULL_HANDLE, NULL, NULL, NULL);
|
||||
case VulkanChunk::vkCmdBeginRenderPass2KHR:
|
||||
return Serialise_vkCmdBeginRenderPass2KHR(ser, VK_NULL_HANDLE, NULL, NULL);
|
||||
case VulkanChunk::vkCmdNextSubpass2KHR:
|
||||
return Serialise_vkCmdNextSubpass2KHR(ser, VK_NULL_HANDLE, NULL, NULL);
|
||||
case VulkanChunk::vkCmdEndRenderPass2KHR:
|
||||
return Serialise_vkCmdEndRenderPass2KHR(ser, VK_NULL_HANDLE, NULL);
|
||||
|
||||
default:
|
||||
{
|
||||
SystemChunk system = (SystemChunk)chunk;
|
||||
|
||||
@@ -742,8 +742,6 @@ private:
|
||||
|
||||
std::vector<VkImageMemoryBarrier> GetImplicitRenderPassBarriers(uint32_t subpass = 0);
|
||||
string MakeRenderPassOpString(bool store);
|
||||
void MakeSubpassLoadRP(VkRenderPassCreateInfo &info, const VkRenderPassCreateInfo *origInfo,
|
||||
uint32_t s);
|
||||
|
||||
bool IsDrawInRenderPass();
|
||||
|
||||
@@ -1915,4 +1913,18 @@ public:
|
||||
|
||||
// VK_KHR_shared_presentable_image
|
||||
VkResult vkGetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapchain);
|
||||
|
||||
// VK_KHR_create_renderpass2
|
||||
IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateRenderPass2KHR, VkDevice device,
|
||||
const VkRenderPassCreateInfo2KHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass);
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBeginRenderPass2KHR, VkCommandBuffer commandBuffer,
|
||||
const VkRenderPassBeginInfo *pRenderPassBegin,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo);
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdNextSubpass2KHR, VkCommandBuffer commandBuffer,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo);
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndRenderPass2KHR, VkCommandBuffer commandBuffer,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo);
|
||||
\
|
||||
};
|
||||
|
||||
@@ -351,7 +351,8 @@
|
||||
CheckExt(MVK_moltenvk, VKXX); \
|
||||
CheckExt(KHR_draw_indirect_count, VKXX); \
|
||||
CheckExt(EXT_validation_cache, VKXX); \
|
||||
CheckExt(KHR_shared_presentable_image, VKXX);
|
||||
CheckExt(KHR_shared_presentable_image, VKXX); \
|
||||
CheckExt(KHR_create_renderpass2, VKXX);
|
||||
|
||||
#define HookInitVulkanInstanceExts() \
|
||||
HookInitExtension(KHR_surface, DestroySurfaceKHR); \
|
||||
@@ -468,6 +469,10 @@
|
||||
HookInitExtension(EXT_validation_cache, MergeValidationCachesEXT); \
|
||||
HookInitExtension(EXT_validation_cache, GetValidationCacheDataEXT); \
|
||||
HookInitExtension(KHR_shared_presentable_image, GetSwapchainStatusKHR); \
|
||||
HookInitExtension(KHR_create_renderpass2, CreateRenderPass2KHR); \
|
||||
HookInitExtension(KHR_create_renderpass2, CmdBeginRenderPass2KHR); \
|
||||
HookInitExtension(KHR_create_renderpass2, CmdNextSubpass2KHR); \
|
||||
HookInitExtension(KHR_create_renderpass2, CmdEndRenderPass2KHR); \
|
||||
HookInitDevice_PlatformSpecific()
|
||||
|
||||
#define DefineHooks() \
|
||||
@@ -994,6 +999,17 @@
|
||||
HookDefine4(VkResult, vkGetValidationCacheDataEXT, VkDevice, device, VkValidationCacheEXT, \
|
||||
validationCache, size_t *, pDataSize, void *, pData); \
|
||||
HookDefine2(VkResult, vkGetSwapchainStatusKHR, VkDevice, device, VkSwapchainKHR, swapchain); \
|
||||
HookDefine4(VkResult, vkCreateRenderPass2KHR, VkDevice, device, \
|
||||
const VkRenderPassCreateInfo2KHR *, pCreateInfo, const VkAllocationCallbacks *, \
|
||||
pAllocator, VkRenderPass *, pRenderPass); \
|
||||
HookDefine3(void, vkCmdBeginRenderPass2KHR, VkCommandBuffer, commandBuffer, \
|
||||
const VkRenderPassBeginInfo *, pRenderPassBegin, const VkSubpassBeginInfoKHR *, \
|
||||
pSubpassBeginInfo); \
|
||||
HookDefine3(void, vkCmdNextSubpass2KHR, VkCommandBuffer, commandBuffer, \
|
||||
const VkSubpassBeginInfoKHR *, pSubpassBeginInfo, const VkSubpassEndInfoKHR *, \
|
||||
pSubpassEndInfo); \
|
||||
HookDefine2(void, vkCmdEndRenderPass2KHR, VkCommandBuffer, commandBuffer, \
|
||||
const VkSubpassEndInfoKHR *, pSubpassEndInfo); \
|
||||
HookDefine_PlatformSpecific()
|
||||
|
||||
struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
|
||||
|
||||
@@ -503,9 +503,20 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan,
|
||||
VulkanCreationInfo &info,
|
||||
const VkRenderPassCreateInfo *pCreateInfo)
|
||||
{
|
||||
attachments.reserve(pCreateInfo->attachmentCount);
|
||||
attachments.resize(pCreateInfo->attachmentCount);
|
||||
for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++)
|
||||
attachments.push_back(pCreateInfo->pAttachments[i]);
|
||||
{
|
||||
Attachment &dst = attachments[i];
|
||||
dst.flags = pCreateInfo->pAttachments[i].flags;
|
||||
dst.format = pCreateInfo->pAttachments[i].format;
|
||||
dst.samples = pCreateInfo->pAttachments[i].samples;
|
||||
dst.loadOp = pCreateInfo->pAttachments[i].loadOp;
|
||||
dst.storeOp = pCreateInfo->pAttachments[i].storeOp;
|
||||
dst.stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp;
|
||||
dst.stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp;
|
||||
dst.initialLayout = pCreateInfo->pAttachments[i].initialLayout;
|
||||
dst.finalLayout = pCreateInfo->pAttachments[i].finalLayout;
|
||||
}
|
||||
|
||||
// VK_KHR_multiview
|
||||
const VkRenderPassMultiviewCreateInfo *multiview =
|
||||
@@ -559,6 +570,68 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan,
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan,
|
||||
VulkanCreationInfo &info,
|
||||
const VkRenderPassCreateInfo2KHR *pCreateInfo)
|
||||
{
|
||||
attachments.resize(pCreateInfo->attachmentCount);
|
||||
for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++)
|
||||
{
|
||||
Attachment &dst = attachments[i];
|
||||
dst.flags = pCreateInfo->pAttachments[i].flags;
|
||||
dst.format = pCreateInfo->pAttachments[i].format;
|
||||
dst.samples = pCreateInfo->pAttachments[i].samples;
|
||||
dst.loadOp = pCreateInfo->pAttachments[i].loadOp;
|
||||
dst.storeOp = pCreateInfo->pAttachments[i].storeOp;
|
||||
dst.stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp;
|
||||
dst.stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp;
|
||||
dst.initialLayout = pCreateInfo->pAttachments[i].initialLayout;
|
||||
dst.finalLayout = pCreateInfo->pAttachments[i].finalLayout;
|
||||
}
|
||||
|
||||
subpasses.resize(pCreateInfo->subpassCount);
|
||||
for(uint32_t subp = 0; subp < pCreateInfo->subpassCount; subp++)
|
||||
{
|
||||
const VkSubpassDescription2KHR &src = pCreateInfo->pSubpasses[subp];
|
||||
Subpass &dst = subpasses[subp];
|
||||
|
||||
dst.inputAttachments.resize(src.inputAttachmentCount);
|
||||
dst.inputLayouts.resize(src.inputAttachmentCount);
|
||||
for(uint32_t i = 0; i < src.inputAttachmentCount; i++)
|
||||
{
|
||||
dst.inputAttachments[i] = src.pInputAttachments[i].attachment;
|
||||
dst.inputLayouts[i] = src.pInputAttachments[i].layout;
|
||||
}
|
||||
|
||||
dst.colorAttachments.resize(src.colorAttachmentCount);
|
||||
dst.resolveAttachments.resize(src.colorAttachmentCount);
|
||||
dst.colorLayouts.resize(src.colorAttachmentCount);
|
||||
for(uint32_t i = 0; i < src.colorAttachmentCount; i++)
|
||||
{
|
||||
dst.resolveAttachments[i] =
|
||||
src.pResolveAttachments ? src.pResolveAttachments[i].attachment : ~0U;
|
||||
dst.colorAttachments[i] = src.pColorAttachments[i].attachment;
|
||||
dst.colorLayouts[i] = src.pColorAttachments[i].layout;
|
||||
}
|
||||
|
||||
dst.depthstencilAttachment =
|
||||
(src.pDepthStencilAttachment != NULL &&
|
||||
src.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED
|
||||
? (int32_t)src.pDepthStencilAttachment->attachment
|
||||
: -1);
|
||||
dst.depthstencilLayout = (src.pDepthStencilAttachment != NULL &&
|
||||
src.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED
|
||||
? src.pDepthStencilAttachment->layout
|
||||
: VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
|
||||
for(uint32_t i = 0; i < 32; i++)
|
||||
{
|
||||
if(src.viewMask & (1 << i))
|
||||
dst.multiviews.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanCreationInfo::Framebuffer::Init(VulkanResourceManager *resourceMan,
|
||||
VulkanCreationInfo &info,
|
||||
const VkFramebufferCreateInfo *pCreateInfo)
|
||||
|
||||
@@ -252,8 +252,23 @@ struct VulkanCreationInfo
|
||||
{
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkRenderPassCreateInfo *pCreateInfo);
|
||||
void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info,
|
||||
const VkRenderPassCreateInfo2KHR *pCreateInfo);
|
||||
|
||||
vector<VkAttachmentDescription> attachments;
|
||||
struct Attachment
|
||||
{
|
||||
VkAttachmentDescriptionFlags flags;
|
||||
VkFormat format;
|
||||
VkSampleCountFlagBits samples;
|
||||
VkAttachmentLoadOp loadOp;
|
||||
VkAttachmentStoreOp storeOp;
|
||||
VkAttachmentLoadOp stencilLoadOp;
|
||||
VkAttachmentStoreOp stencilStoreOp;
|
||||
VkImageLayout initialLayout;
|
||||
VkImageLayout finalLayout;
|
||||
};
|
||||
|
||||
vector<Attachment> attachments;
|
||||
|
||||
struct Subpass
|
||||
{
|
||||
|
||||
@@ -2560,6 +2560,159 @@ void DoSerialise(SerialiserType &ser, VkShaderModuleValidationCacheCreateInfoEXT
|
||||
// SERIALISE_MEMBER(validationCache);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkAttachmentDescription2KHR &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER_TYPED(VkAttachmentDescriptionFlagBits, flags);
|
||||
SERIALISE_MEMBER(format);
|
||||
SERIALISE_MEMBER(samples);
|
||||
SERIALISE_MEMBER(loadOp);
|
||||
SERIALISE_MEMBER(storeOp);
|
||||
SERIALISE_MEMBER(stencilLoadOp);
|
||||
SERIALISE_MEMBER(stencilStoreOp);
|
||||
SERIALISE_MEMBER(initialLayout);
|
||||
SERIALISE_MEMBER(finalLayout);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkAttachmentReference2KHR &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER(attachment);
|
||||
SERIALISE_MEMBER(layout);
|
||||
SERIALISE_MEMBER(aspectMask);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkSubpassDescription2KHR &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER_TYPED(VkSubpassDescriptionFlagBits, flags);
|
||||
SERIALISE_MEMBER(pipelineBindPoint);
|
||||
SERIALISE_MEMBER(viewMask);
|
||||
|
||||
SERIALISE_MEMBER(inputAttachmentCount);
|
||||
SERIALISE_MEMBER_ARRAY(pInputAttachments, inputAttachmentCount);
|
||||
|
||||
SERIALISE_MEMBER(colorAttachmentCount);
|
||||
SERIALISE_MEMBER_ARRAY(pColorAttachments, colorAttachmentCount);
|
||||
SERIALISE_MEMBER_ARRAY(pResolveAttachments, colorAttachmentCount);
|
||||
|
||||
SERIALISE_MEMBER_OPT(pDepthStencilAttachment);
|
||||
|
||||
SERIALISE_MEMBER(preserveAttachmentCount);
|
||||
SERIALISE_MEMBER_ARRAY(pPreserveAttachments, preserveAttachmentCount);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkSubpassDependency2KHR &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER(srcSubpass);
|
||||
SERIALISE_MEMBER(dstSubpass);
|
||||
SERIALISE_MEMBER_TYPED(VkPipelineStageFlagBits, srcStageMask);
|
||||
SERIALISE_MEMBER_TYPED(VkPipelineStageFlagBits, dstStageMask);
|
||||
SERIALISE_MEMBER_TYPED(VkAccessFlagBits, srcAccessMask);
|
||||
SERIALISE_MEMBER_TYPED(VkAccessFlagBits, dstAccessMask);
|
||||
SERIALISE_MEMBER_TYPED(VkDependencyFlagBits, dependencyFlags);
|
||||
SERIALISE_MEMBER(viewOffset);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkRenderPassCreateInfo2KHR &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER_TYPED(VkFlagWithNoBits, flags);
|
||||
SERIALISE_MEMBER(attachmentCount);
|
||||
SERIALISE_MEMBER_ARRAY(pAttachments, attachmentCount);
|
||||
SERIALISE_MEMBER(subpassCount);
|
||||
SERIALISE_MEMBER_ARRAY(pSubpasses, subpassCount);
|
||||
SERIALISE_MEMBER(dependencyCount);
|
||||
SERIALISE_MEMBER_ARRAY(pDependencies, dependencyCount);
|
||||
SERIALISE_MEMBER(correlatedViewMaskCount);
|
||||
SERIALISE_MEMBER_ARRAY(pCorrelatedViewMasks, correlatedViewMaskCount);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkRenderPassCreateInfo2KHR &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
for(uint32_t i = 0; i < el.attachmentCount; i++)
|
||||
{
|
||||
DeserialiseNext(el.pAttachments[i].pNext);
|
||||
}
|
||||
delete[] el.pAttachments;
|
||||
for(uint32_t i = 0; i < el.subpassCount; i++)
|
||||
{
|
||||
DeserialiseNext(el.pSubpasses[i].pNext);
|
||||
|
||||
if(el.pSubpasses[i].pDepthStencilAttachment)
|
||||
DeserialiseNext(el.pSubpasses[i].pDepthStencilAttachment->pNext);
|
||||
|
||||
for(uint32_t j = 0; j < el.pSubpasses[i].colorAttachmentCount; j++)
|
||||
{
|
||||
DeserialiseNext(el.pSubpasses[i].pColorAttachments[j].pNext);
|
||||
if(el.pSubpasses[i].pResolveAttachments)
|
||||
DeserialiseNext(el.pSubpasses[i].pResolveAttachments[j].pNext);
|
||||
}
|
||||
|
||||
for(uint32_t j = 0; j < el.pSubpasses[i].inputAttachmentCount; j++)
|
||||
DeserialiseNext(el.pSubpasses[i].pInputAttachments[j].pNext);
|
||||
|
||||
delete el.pSubpasses[i].pDepthStencilAttachment;
|
||||
delete[] el.pSubpasses[i].pInputAttachments;
|
||||
delete[] el.pSubpasses[i].pColorAttachments;
|
||||
delete[] el.pSubpasses[i].pResolveAttachments;
|
||||
delete[] el.pSubpasses[i].pPreserveAttachments;
|
||||
}
|
||||
delete[] el.pSubpasses;
|
||||
for(uint32_t i = 0; i < el.dependencyCount; i++)
|
||||
{
|
||||
DeserialiseNext(el.pDependencies[i].pNext);
|
||||
}
|
||||
delete[] el.pDependencies;
|
||||
delete[] el.pCorrelatedViewMasks;
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkSubpassBeginInfoKHR &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
|
||||
SERIALISE_MEMBER(contents);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkSubpassBeginInfoKHR &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkSubpassEndInfoKHR &el)
|
||||
{
|
||||
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR);
|
||||
SerialiseNext(ser, el.sType, el.pNext);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Deserialise(const VkSubpassEndInfoKHR &el)
|
||||
{
|
||||
DeserialiseNext(el.pNext);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, VkDispatchIndirectCommand &el)
|
||||
{
|
||||
@@ -3177,6 +3330,9 @@ INSTANTIATE_SERIALISE_TYPE(VkProtectedSubmitInfo);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkImageFormatListCreateInfoKHR);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkImageViewASTCDecodeModeEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkShaderModuleValidationCacheCreateInfoEXT);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkRenderPassCreateInfo2KHR);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkSubpassBeginInfoKHR);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkSubpassEndInfoKHR);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkDispatchIndirectCommand);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkDrawIndirectCommand);
|
||||
INSTANTIATE_SERIALISE_TYPE(VkDrawIndexedIndirectCommand);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
template <>
|
||||
std::string DoStringise(const VulkanChunk &el)
|
||||
{
|
||||
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1118, "Chunks changed without updating names");
|
||||
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1122, "Chunks changed without updating names");
|
||||
|
||||
BEGIN_ENUM_STRINGISE(VulkanChunk)
|
||||
{
|
||||
@@ -150,6 +150,10 @@ std::string DoStringise(const VulkanChunk &el)
|
||||
STRINGISE_ENUM_CLASS(vkGetDeviceQueue2);
|
||||
STRINGISE_ENUM_CLASS(vkCmdDrawIndirectCountKHR);
|
||||
STRINGISE_ENUM_CLASS(vkCmdDrawIndexedIndirectCountKHR);
|
||||
STRINGISE_ENUM_CLASS(vkCreateRenderPass2KHR);
|
||||
STRINGISE_ENUM_CLASS(vkCmdBeginRenderPass2KHR);
|
||||
STRINGISE_ENUM_CLASS(vkCmdNextSubpass2KHR);
|
||||
STRINGISE_ENUM_CLASS(vkCmdEndRenderPass2KHR);
|
||||
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
|
||||
}
|
||||
END_ENUM_STRINGISE()
|
||||
|
||||
@@ -219,7 +219,7 @@ string WrappedVulkan::MakeRenderPassOpString(bool store)
|
||||
const VulkanCreationInfo::Framebuffer &fbinfo =
|
||||
m_CreationInfo.m_Framebuffer[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer];
|
||||
|
||||
const vector<VkAttachmentDescription> &atts = info.attachments;
|
||||
const vector<VulkanCreationInfo::RenderPass::Attachment> &atts = info.attachments;
|
||||
|
||||
if(atts.empty())
|
||||
{
|
||||
@@ -1352,6 +1352,389 @@ void WrappedVulkan::vkCmdEndRenderPass(VkCommandBuffer commandBuffer)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCmdBeginRenderPass2KHR(SerialiserType &ser,
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkRenderPassBeginInfo *pRenderPassBegin,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo)
|
||||
{
|
||||
SERIALISE_ELEMENT(commandBuffer);
|
||||
SERIALISE_ELEMENT_LOCAL(RenderPassBegin, *pRenderPassBegin);
|
||||
SERIALISE_ELEMENT_LOCAL(SubpassBegin, *pSubpassBeginInfo);
|
||||
|
||||
Serialise_DebugMessages(ser);
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
VkRenderPassBeginInfo unwrappedInfo = RenderPassBegin;
|
||||
unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass);
|
||||
unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer);
|
||||
|
||||
VkSubpassBeginInfoKHR unwrappedBeginInfo = SubpassBegin;
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedInfo.pNext) +
|
||||
GetNextPatchSize(unwrappedBeginInfo.pNext));
|
||||
|
||||
UnwrapNextChain(m_State, "VkRenderPassBeginInfo", tempMem, (VkBaseInStructure *)&unwrappedInfo);
|
||||
UnwrapNextChain(m_State, "VkSubpassBeginInfoKHR", tempMem,
|
||||
(VkBaseInStructure *)&unwrappedBeginInfo);
|
||||
|
||||
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
|
||||
|
||||
if(IsActiveReplaying(m_State))
|
||||
{
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
|
||||
|
||||
// always track this, for WrappedVulkan::IsDrawInRenderPass()
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass = 0;
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass =
|
||||
GetResID(RenderPassBegin.renderPass);
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer =
|
||||
GetResID(RenderPassBegin.framebuffer);
|
||||
|
||||
// only if we're partially recording do we update this state
|
||||
if(ShouldUpdateRenderState(m_LastCmdBufferID, true))
|
||||
{
|
||||
m_Partial[Primary].renderPassActive = true;
|
||||
|
||||
m_RenderState.subpass = 0;
|
||||
|
||||
m_RenderState.renderPass = GetResID(RenderPassBegin.renderPass);
|
||||
m_RenderState.framebuffer = GetResID(RenderPassBegin.framebuffer);
|
||||
m_RenderState.renderArea = RenderPassBegin.renderArea;
|
||||
}
|
||||
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdBeginRenderPass2KHR(Unwrap(commandBuffer), &unwrappedInfo, &unwrappedBeginInfo);
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdBeginRenderPass2KHR(Unwrap(commandBuffer), &unwrappedInfo, &unwrappedBeginInfo);
|
||||
|
||||
// track while reading, for fetching the right set of outputs in AddDrawcall
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass = 0;
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = GetResID(RenderPassBegin.renderPass);
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer =
|
||||
GetResID(RenderPassBegin.framebuffer);
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
|
||||
AddEvent();
|
||||
DrawcallDescription draw;
|
||||
draw.name =
|
||||
StringFormat::Fmt("vkCmdBeginRenderPass2KHR(%s)", MakeRenderPassOpString(false).c_str());
|
||||
draw.flags |= DrawFlags::PassBoundary | DrawFlags::BeginPass;
|
||||
|
||||
AddDrawcall(draw, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedVulkan::vkCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkRenderPassBeginInfo *pRenderPassBegin,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo)
|
||||
{
|
||||
SCOPED_DBG_SINK();
|
||||
|
||||
VkRenderPassBeginInfo unwrappedInfo = *pRenderPassBegin;
|
||||
unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass);
|
||||
unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer);
|
||||
|
||||
VkSubpassBeginInfoKHR unwrappedBeginInfo = *pSubpassBeginInfo;
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedInfo.pNext) +
|
||||
GetNextPatchSize(unwrappedBeginInfo.pNext));
|
||||
|
||||
UnwrapNextChain(m_State, "VkRenderPassBeginInfo", tempMem, (VkBaseInStructure *)&unwrappedInfo);
|
||||
UnwrapNextChain(m_State, "VkSubpassBeginInfoKHR", tempMem,
|
||||
(VkBaseInStructure *)&unwrappedBeginInfo);
|
||||
|
||||
SERIALISE_TIME_CALL(
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdBeginRenderPass2KHR(Unwrap(commandBuffer), &unwrappedInfo, &unwrappedBeginInfo));
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
VkResourceRecord *record = GetRecord(commandBuffer);
|
||||
|
||||
CACHE_THREAD_SERIALISER();
|
||||
ser.SetDrawChunk();
|
||||
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginRenderPass2KHR);
|
||||
Serialise_vkCmdBeginRenderPass2KHR(ser, commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
record->MarkResourceFrameReferenced(GetResID(pRenderPassBegin->renderPass), eFrameRef_Read);
|
||||
|
||||
VkResourceRecord *fb = GetRecord(pRenderPassBegin->framebuffer);
|
||||
|
||||
record->MarkResourceFrameReferenced(fb->GetResourceID(), eFrameRef_Read);
|
||||
for(size_t i = 0; fb->imageAttachments[i].barrier.sType; i++)
|
||||
{
|
||||
VkResourceRecord *att = fb->imageAttachments[i].record;
|
||||
if(att == NULL)
|
||||
break;
|
||||
|
||||
record->MarkResourceFrameReferenced(att->baseResource, eFrameRef_Write);
|
||||
if(att->baseResourceMem != ResourceId())
|
||||
record->MarkResourceFrameReferenced(att->baseResourceMem, eFrameRef_Read);
|
||||
if(att->sparseInfo)
|
||||
record->cmdInfo->sparse.insert(att->sparseInfo);
|
||||
record->cmdInfo->dirtied.insert(att->baseResource);
|
||||
}
|
||||
|
||||
record->cmdInfo->framebuffer = fb;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCmdNextSubpass2KHR(SerialiserType &ser, VkCommandBuffer commandBuffer,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo)
|
||||
{
|
||||
SERIALISE_ELEMENT(commandBuffer);
|
||||
SERIALISE_ELEMENT_LOCAL(SubpassBegin, *pSubpassBeginInfo);
|
||||
SERIALISE_ELEMENT_LOCAL(SubpassEnd, *pSubpassEndInfo);
|
||||
|
||||
Serialise_DebugMessages(ser);
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
VkSubpassBeginInfoKHR unwrappedBeginInfo = SubpassBegin;
|
||||
VkSubpassEndInfoKHR unwrappedEndInfo = SubpassEnd;
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedBeginInfo.pNext) +
|
||||
GetNextPatchSize(unwrappedEndInfo.pNext));
|
||||
|
||||
UnwrapNextChain(m_State, "VkSubpassBeginInfoKHR", tempMem,
|
||||
(VkBaseInStructure *)&unwrappedBeginInfo);
|
||||
UnwrapNextChain(m_State, "VkSubpassEndInfoKHR", tempMem, (VkBaseInStructure *)&unwrappedEndInfo);
|
||||
|
||||
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
|
||||
|
||||
if(IsActiveReplaying(m_State))
|
||||
{
|
||||
// don't do anything if we're executing a single draw, NextSubpass is meaningless (and invalid
|
||||
// on a partial render pass)
|
||||
if(InRerecordRange(m_LastCmdBufferID) && m_FirstEventID != m_LastEventID)
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
|
||||
|
||||
// always track this, for WrappedVulkan::IsDrawInRenderPass()
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass++;
|
||||
|
||||
if(ShouldUpdateRenderState(m_LastCmdBufferID, true))
|
||||
m_RenderState.subpass++;
|
||||
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdNextSubpass2KHR(Unwrap(commandBuffer), &unwrappedBeginInfo, &unwrappedEndInfo);
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdNextSubpass2KHR(Unwrap(commandBuffer), &unwrappedBeginInfo, &unwrappedEndInfo);
|
||||
|
||||
// track while reading, for fetching the right set of outputs in AddDrawcall
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass++;
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers();
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), &imgBarriers[0]);
|
||||
|
||||
AddEvent();
|
||||
DrawcallDescription draw;
|
||||
draw.name = StringFormat::Fmt("vkCmdNextSubpass2KHR() => %u",
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass);
|
||||
draw.flags |= DrawFlags::PassBoundary | DrawFlags::BeginPass | DrawFlags::EndPass;
|
||||
|
||||
AddDrawcall(draw, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedVulkan::vkCmdNextSubpass2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo)
|
||||
{
|
||||
SCOPED_DBG_SINK();
|
||||
|
||||
VkSubpassBeginInfoKHR unwrappedBeginInfo = *pSubpassBeginInfo;
|
||||
VkSubpassEndInfoKHR unwrappedEndInfo = *pSubpassEndInfo;
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedBeginInfo.pNext) +
|
||||
GetNextPatchSize(unwrappedEndInfo.pNext));
|
||||
|
||||
UnwrapNextChain(m_State, "VkSubpassBeginInfoKHR", tempMem,
|
||||
(VkBaseInStructure *)&unwrappedBeginInfo);
|
||||
UnwrapNextChain(m_State, "VkSubpassEndInfoKHR", tempMem, (VkBaseInStructure *)&unwrappedEndInfo);
|
||||
|
||||
SERIALISE_TIME_CALL(
|
||||
ObjDisp(commandBuffer)
|
||||
->CmdNextSubpass2KHR(Unwrap(commandBuffer), &unwrappedBeginInfo, &unwrappedEndInfo));
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
VkResourceRecord *record = GetRecord(commandBuffer);
|
||||
|
||||
CACHE_THREAD_SERIALISER();
|
||||
ser.SetDrawChunk();
|
||||
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdNextSubpass2KHR);
|
||||
Serialise_vkCmdNextSubpass2KHR(ser, commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCmdEndRenderPass2KHR(SerialiserType &ser,
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo)
|
||||
{
|
||||
SERIALISE_ELEMENT(commandBuffer);
|
||||
SERIALISE_ELEMENT_LOCAL(SubpassEnd, *pSubpassEndInfo);
|
||||
|
||||
Serialise_DebugMessages(ser);
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
VkSubpassEndInfoKHR unwrappedEndInfo = SubpassEnd;
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedEndInfo.pNext));
|
||||
|
||||
UnwrapNextChain(m_State, "VkSubpassEndInfoKHR", tempMem, (VkBaseInStructure *)&unwrappedEndInfo);
|
||||
|
||||
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
|
||||
|
||||
if(IsActiveReplaying(m_State))
|
||||
{
|
||||
if(InRerecordRange(m_LastCmdBufferID))
|
||||
{
|
||||
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
|
||||
|
||||
// always track this, for WrappedVulkan::IsDrawInRenderPass()
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = ResourceId();
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = ResourceId();
|
||||
|
||||
if(ShouldUpdateRenderState(m_LastCmdBufferID, true))
|
||||
{
|
||||
m_Partial[Primary].renderPassActive = false;
|
||||
}
|
||||
|
||||
ObjDisp(commandBuffer)->CmdEndRenderPass2KHR(Unwrap(commandBuffer), &unwrappedEndInfo);
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers(~0U);
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), imgBarriers.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjDisp(commandBuffer)->CmdEndRenderPass2KHR(Unwrap(commandBuffer), &unwrappedEndInfo);
|
||||
|
||||
std::vector<VkImageMemoryBarrier> imgBarriers = GetImplicitRenderPassBarriers(~0U);
|
||||
|
||||
ResourceId cmd = GetResID(commandBuffer);
|
||||
GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts,
|
||||
(uint32_t)imgBarriers.size(), &imgBarriers[0]);
|
||||
|
||||
AddEvent();
|
||||
DrawcallDescription draw;
|
||||
draw.name =
|
||||
StringFormat::Fmt("vkCmdEndRenderPass2KHR(%s)", MakeRenderPassOpString(true).c_str());
|
||||
draw.flags |= DrawFlags::PassBoundary | DrawFlags::EndPass;
|
||||
|
||||
AddDrawcall(draw, true);
|
||||
|
||||
// track while reading, reset this to empty so AddDrawcall sets no outputs,
|
||||
// but only AFTER the above AddDrawcall (we want it grouped together)
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = ResourceId();
|
||||
m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = ResourceId();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedVulkan::vkCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo)
|
||||
{
|
||||
SCOPED_DBG_SINK();
|
||||
|
||||
VkSubpassEndInfoKHR unwrappedEndInfo = *pSubpassEndInfo;
|
||||
|
||||
byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedEndInfo.pNext));
|
||||
|
||||
UnwrapNextChain(m_State, "VkSubpassEndInfoKHR", tempMem, (VkBaseInStructure *)&unwrappedEndInfo);
|
||||
|
||||
SERIALISE_TIME_CALL(
|
||||
ObjDisp(commandBuffer)->CmdEndRenderPass2KHR(Unwrap(commandBuffer), &unwrappedEndInfo));
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
VkResourceRecord *record = GetRecord(commandBuffer);
|
||||
|
||||
CACHE_THREAD_SERIALISER();
|
||||
ser.SetDrawChunk();
|
||||
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndRenderPass2KHR);
|
||||
Serialise_vkCmdEndRenderPass2KHR(ser, commandBuffer, pSubpassEndInfo);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
|
||||
VkResourceRecord *fb = record->cmdInfo->framebuffer;
|
||||
|
||||
std::vector<VkImageMemoryBarrier> barriers;
|
||||
|
||||
for(size_t i = 0; fb->imageAttachments[i].barrier.sType; i++)
|
||||
{
|
||||
if(fb->imageAttachments[i].barrier.oldLayout == fb->imageAttachments[i].barrier.newLayout)
|
||||
continue;
|
||||
|
||||
barriers.push_back(fb->imageAttachments[i].barrier);
|
||||
}
|
||||
|
||||
// apply the implicit layout transitions here
|
||||
{
|
||||
SCOPED_LOCK(m_ImageLayoutsLock);
|
||||
GetResourceManager()->RecordBarriers(GetRecord(commandBuffer)->cmdInfo->imgbarriers,
|
||||
m_ImageLayouts, (uint32_t)barriers.size(), &barriers[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCmdBindPipeline(SerialiserType &ser, VkCommandBuffer commandBuffer,
|
||||
VkPipelineBindPoint pipelineBindPoint,
|
||||
@@ -3915,6 +4298,15 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdNextSubpass, VkCommandBuffer commandB
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndRenderPass, VkCommandBuffer commandBuffer);
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBeginRenderPass2KHR, VkCommandBuffer commandBuffer,
|
||||
const VkRenderPassBeginInfo *pRenderPassBegin,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo);
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdNextSubpass2KHR, VkCommandBuffer commandBuffer,
|
||||
const VkSubpassBeginInfoKHR *pSubpassBeginInfo,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo);
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndRenderPass2KHR, VkCommandBuffer commandBuffer,
|
||||
const VkSubpassEndInfoKHR *pSubpassEndInfo);
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBindPipeline, VkCommandBuffer commandBuffer,
|
||||
VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline);
|
||||
|
||||
@@ -4004,4 +4396,4 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdInsertDebugUtilsLabelEXT, VkCommandBu
|
||||
const VkDebugUtilsLabelEXT *pLabelInfo);
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetDeviceMask, VkCommandBuffer commandBuffer,
|
||||
uint32_t deviceMask);
|
||||
uint32_t deviceMask);
|
||||
@@ -24,23 +24,8 @@
|
||||
|
||||
#include "../vk_core.h"
|
||||
|
||||
template <>
|
||||
VkFramebufferCreateInfo WrappedVulkan::UnwrapInfo(const VkFramebufferCreateInfo *info)
|
||||
{
|
||||
VkFramebufferCreateInfo ret = *info;
|
||||
|
||||
VkImageView *unwrapped = GetTempArray<VkImageView>(info->attachmentCount);
|
||||
for(uint32_t i = 0; i < info->attachmentCount; i++)
|
||||
unwrapped[i] = Unwrap(info->pAttachments[i]);
|
||||
|
||||
ret.renderPass = Unwrap(ret.renderPass);
|
||||
ret.pAttachments = unwrapped;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WrappedVulkan::MakeSubpassLoadRP(VkRenderPassCreateInfo &info,
|
||||
const VkRenderPassCreateInfo *origInfo, uint32_t s)
|
||||
template <typename RPCreateInfo>
|
||||
static void MakeSubpassLoadRP(RPCreateInfo &info, const RPCreateInfo *origInfo, uint32_t s)
|
||||
{
|
||||
info.subpassCount = 1;
|
||||
info.pSubpasses = origInfo->pSubpasses + s;
|
||||
@@ -48,8 +33,14 @@ void WrappedVulkan::MakeSubpassLoadRP(VkRenderPassCreateInfo &info,
|
||||
// remove any dependencies
|
||||
info.dependencyCount = 0;
|
||||
|
||||
const VkSubpassDescription *sub = info.pSubpasses;
|
||||
VkAttachmentDescription *att = (VkAttachmentDescription *)info.pAttachments;
|
||||
// we use decltype here because this is templated to work for regular and create_renderpass2
|
||||
// structs
|
||||
using SubpassInfo = typename std::remove_reference<decltype(info.pSubpasses[0])>::type;
|
||||
using AttachmentInfo =
|
||||
std::remove_cv<typename std::remove_reference<decltype(info.pAttachments[0])>::type>::type;
|
||||
|
||||
SubpassInfo *sub = info.pSubpasses;
|
||||
AttachmentInfo *att = (AttachmentInfo *)info.pAttachments;
|
||||
|
||||
// apply this subpass's attachment layouts to the initial and final layouts
|
||||
// so that this RP doesn't perform any layout transitions
|
||||
@@ -79,6 +70,21 @@ void WrappedVulkan::MakeSubpassLoadRP(VkRenderPassCreateInfo &info,
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
VkFramebufferCreateInfo WrappedVulkan::UnwrapInfo(const VkFramebufferCreateInfo *info)
|
||||
{
|
||||
VkFramebufferCreateInfo ret = *info;
|
||||
|
||||
VkImageView *unwrapped = GetTempArray<VkImageView>(info->attachmentCount);
|
||||
for(uint32_t i = 0; i < info->attachmentCount; i++)
|
||||
unwrapped[i] = Unwrap(info->pAttachments[i]);
|
||||
|
||||
ret.renderPass = Unwrap(ret.renderPass);
|
||||
ret.pAttachments = unwrapped;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// note, for threading reasons we ensure to release the wrappers before
|
||||
// releasing the underlying object. Otherwise after releasing the vulkan object
|
||||
// that same handle could be returned by create on another thread, and we
|
||||
@@ -907,6 +913,221 @@ VkResult WrappedVulkan::vkCreateRenderPass(VkDevice device, const VkRenderPassCr
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCreateRenderPass2KHR(SerialiserType &ser, VkDevice device,
|
||||
const VkRenderPassCreateInfo2KHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkRenderPass *pRenderPass)
|
||||
{
|
||||
SERIALISE_ELEMENT(device);
|
||||
SERIALISE_ELEMENT_LOCAL(CreateInfo, *pCreateInfo);
|
||||
SERIALISE_ELEMENT_OPT(pAllocator);
|
||||
SERIALISE_ELEMENT_LOCAL(RenderPass, GetResID(*pRenderPass)).TypedAs("VkRenderPass");
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
VkRenderPass rp = VK_NULL_HANDLE;
|
||||
|
||||
VulkanCreationInfo::RenderPass rpinfo;
|
||||
rpinfo.Init(GetResourceManager(), m_CreationInfo, &CreateInfo);
|
||||
|
||||
// we want to store off the data so we can display it after the pass.
|
||||
// override any user-specified DONT_CARE.
|
||||
// Likewise we don't want to throw away data before we're ready, so change
|
||||
// any load ops to LOAD instead of DONT_CARE (which is valid!). We of course
|
||||
// leave any LOAD_OP_CLEAR alone.
|
||||
VkAttachmentDescription2KHR *att = (VkAttachmentDescription2KHR *)CreateInfo.pAttachments;
|
||||
for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++)
|
||||
{
|
||||
att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
if(att[i].loadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
|
||||
att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
if(att[i].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
|
||||
att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
|
||||
// renderpass can't start or end in presentable layout on replay
|
||||
ReplacePresentableImageLayout(att[i].initialLayout);
|
||||
ReplacePresentableImageLayout(att[i].finalLayout);
|
||||
}
|
||||
|
||||
VkResult ret = ObjDisp(device)->CreateRenderPass2KHR(Unwrap(device), &CreateInfo, NULL, &rp);
|
||||
|
||||
if(ret != VK_SUCCESS)
|
||||
{
|
||||
RDCERR("Failed on resource serialise-creation, VkResult: %s", ToStr(ret).c_str());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId live;
|
||||
|
||||
if(GetResourceManager()->HasWrapper(ToTypedHandle(rp)))
|
||||
{
|
||||
live = GetResourceManager()->GetNonDispWrapper(rp)->id;
|
||||
|
||||
// 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)->DestroyRenderPass(Unwrap(device), rp, NULL);
|
||||
|
||||
// whenever the new ID is requested, return the old ID, via replacements.
|
||||
GetResourceManager()->ReplaceResource(RenderPass, GetResourceManager()->GetOriginalID(live));
|
||||
}
|
||||
else
|
||||
{
|
||||
live = GetResourceManager()->WrapResource(Unwrap(device), rp);
|
||||
GetResourceManager()->AddLiveResource(RenderPass, rp);
|
||||
|
||||
// make a version of the render pass that loads from its attachments,
|
||||
// so it can be used for replaying a single draw after a render pass
|
||||
// without doing a clear or a DONT_CARE load.
|
||||
for(uint32_t i = 0; i < CreateInfo.attachmentCount; i++)
|
||||
{
|
||||
att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
}
|
||||
|
||||
VkRenderPassCreateInfo2KHR loadInfo = CreateInfo;
|
||||
|
||||
rpinfo.loadRPs.resize(CreateInfo.subpassCount);
|
||||
|
||||
// create a render pass for each subpass that maintains attachment layouts
|
||||
for(uint32_t s = 0; s < CreateInfo.subpassCount; s++)
|
||||
{
|
||||
MakeSubpassLoadRP(loadInfo, &CreateInfo, s);
|
||||
|
||||
ret = ObjDisp(device)->CreateRenderPass2KHR(Unwrap(device), &loadInfo, NULL,
|
||||
&rpinfo.loadRPs[s]);
|
||||
RDCASSERTEQUAL(ret, VK_SUCCESS);
|
||||
|
||||
// handle the loadRP being a duplicate
|
||||
if(GetResourceManager()->HasWrapper(ToTypedHandle(rpinfo.loadRPs[s])))
|
||||
{
|
||||
// just fetch the existing wrapped object
|
||||
rpinfo.loadRPs[s] =
|
||||
(VkRenderPass)(uint64_t)GetResourceManager()->GetNonDispWrapper(rpinfo.loadRPs[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)->DestroyRenderPass(Unwrap(device), rpinfo.loadRPs[s], NULL);
|
||||
|
||||
// don't need to ReplaceResource as no IDs are involved
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceId loadRPid =
|
||||
GetResourceManager()->WrapResource(Unwrap(device), rpinfo.loadRPs[s]);
|
||||
|
||||
// register as a live-only resource, so it is cleaned up properly
|
||||
GetResourceManager()->AddLiveResource(loadRPid, rpinfo.loadRPs[s]);
|
||||
}
|
||||
}
|
||||
|
||||
m_CreationInfo.m_RenderPass[live] = rpinfo;
|
||||
}
|
||||
}
|
||||
|
||||
AddResource(RenderPass, ResourceType::RenderPass, "Render Pass");
|
||||
DerivedResource(device, RenderPass);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
VkResult WrappedVulkan::vkCreateRenderPass2KHR(VkDevice device,
|
||||
const VkRenderPassCreateInfo2KHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkRenderPass *pRenderPass)
|
||||
{
|
||||
VkResult ret;
|
||||
SERIALISE_TIME_CALL(ret = ObjDisp(device)->CreateRenderPass2KHR(Unwrap(device), pCreateInfo,
|
||||
pAllocator, pRenderPass));
|
||||
|
||||
if(ret == VK_SUCCESS)
|
||||
{
|
||||
ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pRenderPass);
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
Chunk *chunk = NULL;
|
||||
|
||||
{
|
||||
CACHE_THREAD_SERIALISER();
|
||||
|
||||
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCreateRenderPass2KHR);
|
||||
Serialise_vkCreateRenderPass2KHR(ser, device, pCreateInfo, NULL, pRenderPass);
|
||||
|
||||
chunk = scope.Get();
|
||||
}
|
||||
|
||||
VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pRenderPass);
|
||||
record->AddChunk(chunk);
|
||||
|
||||
// +1 for the terminal value
|
||||
uint32_t arrayCount = pCreateInfo->attachmentCount + 1;
|
||||
|
||||
record->imageAttachments = new AttachmentInfo[arrayCount];
|
||||
|
||||
RDCEraseMem(record->imageAttachments, sizeof(AttachmentInfo) * arrayCount);
|
||||
|
||||
for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++)
|
||||
{
|
||||
record->imageAttachments[i].record = NULL;
|
||||
record->imageAttachments[i].barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
record->imageAttachments[i].barrier.oldLayout = pCreateInfo->pAttachments[i].initialLayout;
|
||||
record->imageAttachments[i].barrier.newLayout = pCreateInfo->pAttachments[i].finalLayout;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetResourceManager()->AddLiveResource(id, *pRenderPass);
|
||||
|
||||
VulkanCreationInfo::RenderPass rpinfo;
|
||||
rpinfo.Init(GetResourceManager(), m_CreationInfo, pCreateInfo);
|
||||
|
||||
VkRenderPassCreateInfo2KHR info = *pCreateInfo;
|
||||
|
||||
VkAttachmentDescription2KHR atts[16];
|
||||
RDCASSERT(ARRAY_COUNT(atts) >= (size_t)info.attachmentCount);
|
||||
|
||||
// make a version of the render pass that loads from its attachments,
|
||||
// so it can be used for replaying a single draw after a render pass
|
||||
// without doing a clear or a DONT_CARE load.
|
||||
for(uint32_t i = 0; i < info.attachmentCount; i++)
|
||||
{
|
||||
atts[i] = info.pAttachments[i];
|
||||
atts[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
atts[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
}
|
||||
|
||||
info.pAttachments = atts;
|
||||
|
||||
rpinfo.loadRPs.resize(pCreateInfo->subpassCount);
|
||||
|
||||
// create a render pass for each subpass that maintains attachment layouts
|
||||
for(uint32_t s = 0; s < pCreateInfo->subpassCount; s++)
|
||||
{
|
||||
MakeSubpassLoadRP(info, pCreateInfo, s);
|
||||
|
||||
ret = ObjDisp(device)->CreateRenderPass2KHR(Unwrap(device), &info, NULL, &rpinfo.loadRPs[s]);
|
||||
RDCASSERTEQUAL(ret, VK_SUCCESS);
|
||||
|
||||
ResourceId loadRPid = GetResourceManager()->WrapResource(Unwrap(device), rpinfo.loadRPs[s]);
|
||||
|
||||
// register as a live-only resource, so it is cleaned up properly
|
||||
GetResourceManager()->AddLiveResource(loadRPid, rpinfo.loadRPs[s]);
|
||||
}
|
||||
|
||||
m_CreationInfo.m_RenderPass[id] = rpinfo;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedVulkan::Serialise_vkCreateQueryPool(SerialiserType &ser, VkDevice device,
|
||||
const VkQueryPoolCreateInfo *pCreateInfo,
|
||||
@@ -1706,6 +1927,10 @@ INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateRenderPass, VkDevice device,
|
||||
const VkRenderPassCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass);
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateRenderPass2KHR, VkDevice device,
|
||||
const VkRenderPassCreateInfo2KHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass);
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateQueryPool, VkDevice device,
|
||||
const VkQueryPoolCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool);
|
||||
|
||||
Reference in New Issue
Block a user