From 9efb8af92de180ea85ee8062ddcd4aee00dbd2c0 Mon Sep 17 00:00:00 2001 From: Petr Kraus Date: Sun, 10 Sep 2017 02:26:33 +0200 Subject: layers: Fix Graphics Pipeline pointers not ignored Some VkGraphicsPipelineCreateInfo pointers must be ignored under some conditions, but were not in the layers. Add relevant tests. Fix tests found broken (using depth or color without attachment in subpass) Change-Id: I3e2a3f61a52c72ce3a11483ff8b031189f4c61c9 --- layers/unique_objects.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'layers/unique_objects.cpp') diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp index d324ce49..8af77724 100644 --- a/layers/unique_objects.cpp +++ b/layers/unique_objects.cpp @@ -328,7 +328,22 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipeli local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount]; std::lock_guard lock(global_lock); for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) { - local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]); + bool uses_color_attachment = false; + bool uses_depthstencil_attachment = false; + { + const auto subpasses_uses_it = + device_data->renderpasses_states.find(Unwrap(device_data, pCreateInfos[idx0].renderPass)); + if (subpasses_uses_it != device_data->renderpasses_states.end()) { + const auto &subpasses_uses = subpasses_uses_it->second; + if (subpasses_uses.subpasses_using_color_attachment.count(pCreateInfos[idx0].subpass)) + uses_color_attachment = true; + if (subpasses_uses.subpasses_using_depthstencil_attachment.count(pCreateInfos[idx0].subpass)) + uses_depthstencil_attachment = true; + } + } + + local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0], uses_color_attachment, uses_depthstencil_attachment); + if (pCreateInfos[idx0].basePipelineHandle) { local_pCreateInfos[idx0].basePipelineHandle = Unwrap(device_data, pCreateInfos[idx0].basePipelineHandle); } @@ -366,6 +381,55 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipeli return result; } +static void PostCallCreateRenderPass(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, VkRenderPass renderPass) { + auto &renderpass_state = dev_data->renderpasses_states[renderPass]; + + for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) { + bool uses_color = false; + for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i) + if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true; + + bool uses_depthstencil = false; + if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment) + if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) + uses_depthstencil = true; + + if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass); + if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass); + } +} + +VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { + layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); + VkResult result = dev_data->dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass); + if (VK_SUCCESS == result) { + std::lock_guard lock(global_lock); + + PostCallCreateRenderPass(dev_data, pCreateInfo, *pRenderPass); + + *pRenderPass = WrapNew(dev_data, *pRenderPass); + } + return result; +} + +static void PostCallDestroyRenderPass(layer_data *dev_data, VkRenderPass renderPass) { + dev_data->renderpasses_states.erase(renderPass); +} + +VKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) { + layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); + std::unique_lock lock(global_lock); + uint64_t renderPass_id = reinterpret_cast(renderPass); + renderPass = (VkRenderPass)dev_data->unique_id_mapping[renderPass_id]; + dev_data->unique_id_mapping.erase(renderPass_id); + lock.unlock(); + dev_data->dispatch_table.DestroyRenderPass(device, renderPass, pAllocator); + + lock.lock(); + PostCallDestroyRenderPass(dev_data, renderPass); +} + VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) { layer_data *my_map_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); -- cgit v1.2.3