The RenderDoc application crashes while loading a capture containing a VkRenderPass with multiple passes which was created with a VkRenderPassInputAttachmentAspectCreateInfo structure in its VkRenderPassCreateInfo chain.
The stack trace: (click to expand)
```
nvoglv64.dll!00007ffa52ca8e45()
nvoglv64.dll!00007ffa52ca7ffd()
renderdoc.dll!WrappedVulkan::Serialise_vkCreateRenderPass(ReadSerialiser & ser, VkDevice_T *) Line 1119
at c:\build\renderdoc\renderdoc\driver\vulkan\wrappers\vk_misc_funcs.cpp(1119)
renderdoc.dll!WrappedVulkan::ProcessChunk(ReadSerialiser & ser, VulkanChunk chunk) Line 3261
at c:\build\renderdoc\renderdoc\driver\vulkan\vk_core.cpp(3261)
renderdoc.dll!WrappedVulkan::ReadLogInitialisation(RDCFile * rdc, bool storeStructuredBuffers) Line 2639
at c:\build\renderdoc\renderdoc\driver\vulkan\vk_core.cpp(2639)
renderdoc.dll!VulkanReplay::ReadLogInitialisation(RDCFile * rdc, bool storeStructuredBuffers) Line 225
at c:\build\renderdoc\renderdoc\driver\vulkan\vk_replay.cpp(225)
renderdoc.dll!ReplayController::PostCreateInit(IReplayDriver * device, RDCFile * rdc) Line 2148
at c:\build\renderdoc\renderdoc\replay\replay_controller.cpp(2148)
renderdoc.dll!ReplayController::CreateDevice(RDCFile * rdc, const ReplayOptions & opts) Line 2115
at c:\build\renderdoc\renderdoc\replay\replay_controller.cpp(2115)
renderdoc.dll!CaptureFile::OpenCapture(const ReplayOptions & opts, std::function progress) Line 371
at c:\build\renderdoc\renderdoc\replay\capture_file.cpp(371)
qrenderdoc.exe!ReplayManager::run(int proxyRenderer, const QString & capturefile, const ReplayOptions & opts, std::function progress) Line 452
at c:\build\renderdoc\qrenderdoc\code\replaymanager.cpp(452)
[Inline Frame] qrenderdoc.exe!ReplayManager::OpenCapture::__l2::::operator()() Line 58
at c:\build\renderdoc\qrenderdoc\code\replaymanager.cpp(58)
[Inline Frame] qrenderdoc.exe!std::_Invoker_functor::_Call(ReplayManager::OpenCapture::__l2:: &) Line 1375
at c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1375)
[Inline Frame] qrenderdoc.exe!std::invoke(ReplayManager::OpenCapture::__l2:: &) Line 1443
at c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1443)
[Inline Frame] qrenderdoc.exe!std::_Invoke_ret(std::_Forced) Line 1461
at c:\program files (x86)\microsoft visual studio 14.0\vc\include\type_traits(1461)
qrenderdoc.exe!std::_Func_impl<,std::allocator,void>::_Do_call() Line 214
at c:\program files (x86)\microsoft visual studio 14.0\vc\include\functional(214)
[Inline Frame] qrenderdoc.exe!std::_Func_class::operator()() Line 279
at c:\program files (x86)\microsoft visual studio 14.0\vc\include\functional(279)
qrenderdoc.exe!LambdaThread::process() Line 511
at c:\build\renderdoc\qrenderdoc\code\qrdutils.h(511)
Qt5Core.dll!00007ffaba2a1d49()
Qt5Core.dll!00007ffaba0d4c0f()
Qt5Core.dll!00007ffaba0d5e6f()
kernel32.dll!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()
```
As far as I can tell from WrappedVulkan::Serialise_vkCreateRenderPass() the code simply does not handle VkRenderPassInputAttachmentAspectCreateInfo and ends up passing invalid parameters when creating separate passes for each individual subpass of the original.
The structure chain of loadInfo contains all the same VkInputAttachmentAspectReference entries which were passed to the original vkCreateRenderPass call. In my particular case s (the subpass index) is 1, loadInfo.pSubpasses[0].inputAttachmentCount is 0, but the VkRenderPassInputAttachmentAspectCreateInfo's two pAspectReferences both reference the input attachments of subpass 0.
Ideally, RenderDoc should filter out the VkInputAttachmentAspectReference entries for each subpass and then zero out their subpass fields.
It might also be OK to drop the structure from the chain entirely as its purpose is merely optimization.
Steps to reproduce
I can't share a capture of the application, but this is roughly how the render pass is created:
const auto attachments = std::vector<vk::AttachmentDescription>{
vk::AttachmentDescription{{} /*flags*/, vk::Format::eD32SfloatS8Uint, /*...*/},
/* other attachments */
};
const auto input_attachment_ref = vk::AttachmentReference{0, vk::ImageLayout::eShaderReadOnlyOptimal};
const auto subpasses = std::vector<vk::SubpassDescription>{
vk::SubpassDescription{vk::SubpassDescriptionFlags{},
vk::PipelineBindPoint::eGraphics,
{1, &input_attachment_ref} /*input*/,
/*other attachments*/},
vk::SubpassDescription{vk::SubpassDescriptionFlags{},
vk::PipelineBindPoint::eGraphics,
{} /*input*/,
/*other attachments*/},
};
const auto dependencies = std::vector<vk::SubpassDependency>{};
const auto input_aspect_refs = std::vector<vk::InputAttachmentAspectReference>{
vk::InputAttachmentAspectReference{0 /*subpass*/, 0 /*inputAttachmentIndex*/, vk::ImageAspectFlagBits::eDepth}
};
const auto input_aspect_create_info = vk::RenderPassInputAttachmentAspectCreateInfo{input_aspect_refs};
const auto create_info = vk::RenderPassCreateInfo{vk::RenderPassCreateFlags{},
attachments,
subpasses,
dependencies,
&input_aspect_create_info /*pNext*/};
Description
The RenderDoc application crashes while loading a capture containing a
VkRenderPass
with multiple passes which was created with aVkRenderPassInputAttachmentAspectCreateInfo
structure in itsVkRenderPassCreateInfo
chain.The stack trace: (click to expand)
``` nvoglv64.dll!00007ffa52ca8e45() nvoglv64.dll!00007ffa52ca7ffd() renderdoc.dll!WrappedVulkan::Serialise_vkCreateRenderPassAs far as I can tell from
WrappedVulkan::Serialise_vkCreateRenderPass()
the code simply does not handleVkRenderPassInputAttachmentAspectCreateInfo
and ends up passing invalid parameters when creating separate passes for each individual subpass of the original. The structure chain ofloadInfo
contains all the sameVkInputAttachmentAspectReference
entries which were passed to the originalvkCreateRenderPass
call. In my particular cases
(the subpass index) is1
,loadInfo.pSubpasses[0].inputAttachmentCount
is0
, but theVkRenderPassInputAttachmentAspectCreateInfo
's twopAspectReferences
both reference the input attachments of subpass0
.Ideally, RenderDoc should filter out the
VkInputAttachmentAspectReference
entries for each subpass and then zero out theirsubpass
fields. It might also be OK to drop the structure from the chain entirely as its purpose is merely optimization.Steps to reproduce
I can't share a capture of the application, but this is roughly how the render pass is created:
Environment