From f4e141e843c14ba67642d0e11030ec042f50826a Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 15 Apr 2020 10:33:57 +0100 Subject: [PATCH] Handle invalid pointers in create info when viewport state is dynamic --- renderdoc/driver/vulkan/vk_serialise.cpp | 30 +++++++++++++++++++++++- util/test/demos/vk/vk_parameter_zoo.cpp | 13 ++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index 992c588a9..19e93834b 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -2758,7 +2758,35 @@ void DoSerialise(SerialiserType &ser, VkGraphicsPipelineCreateInfo &el) if(hasValidRasterization) { - SERIALISE_MEMBER_OPT(pViewportState); + // we have a similar problem with needing pDynamicState to determine if the pViewports/pScissors + // members are valid or not. + if(ser.IsReading() || el.pViewportState == NULL) + { + // all the hard work is done while writing. On reading, just serialise (optionally) directly. + SERIALISE_MEMBER_OPT(pViewportState); + } + else + { + bool dynamicViewport = false, dynamicScissor = false; + + for(uint32_t i = 0; el.pDynamicState && i < el.pDynamicState->dynamicStateCount; i++) + { + if(el.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_VIEWPORT) + dynamicViewport = true; + else if(el.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_SCISSOR) + dynamicScissor = true; + } + + VkPipelineViewportStateCreateInfo viewportState = *el.pViewportState; + VkPipelineViewportStateCreateInfo *pViewportState = &viewportState; + + if(dynamicScissor) + viewportState.pScissors = NULL; + if(dynamicViewport) + viewportState.pViewports = NULL; + + SERIALISE_ELEMENT_OPT(pViewportState); + } } else { diff --git a/util/test/demos/vk/vk_parameter_zoo.cpp b/util/test/demos/vk/vk_parameter_zoo.cpp index c9e072467..df82aba11 100644 --- a/util/test/demos/vk/vk_parameter_zoo.cpp +++ b/util/test/demos/vk/vk_parameter_zoo.cpp @@ -427,6 +427,19 @@ void main() CHECK_VKR(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, baked, NULL, &dummy)); vkDestroyPipeline(device, dummy, NULL); + VkPipelineViewportStateCreateInfo *viewState = + (VkPipelineViewportStateCreateInfo *)&pipeCreateInfo.viewportState; + + baked->pViewportState = viewState; + + // viewport and scissor are already dynamic, so just set viewports and scissors to invalid + // pointers + viewState->pViewports = (VkViewport *)0x1234; + viewState->pScissors = (VkRect2D *)0x1234; + + CHECK_VKR(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, baked, NULL, &dummy)); + vkDestroyPipeline(device, dummy, NULL); + // if we disable rasterization, tons of things can be NULL/garbage pipeCreateInfo.rasterizationState.rasterizerDiscardEnable = VK_TRUE;