From 7f36ca0776f1d8d801fc85bb87a23ff440db5dd3 Mon Sep 17 00:00:00 2001 From: Petr Kraus Date: Thu, 14 Dec 2017 20:57:36 +0100 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) --- 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 8515a645..0fa94a7f 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