From ba327b3690953add911703ee0d94cb7888f52c02 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B3zef=20Kucia?= Date: Wed, 25 Oct 2017 22:15:22 +0200 Subject: [PATCH] layers: Validate push descriptor set layout count --- layers/core_validation.cpp | 30 +++++++++++++++++++++--------- layers/core_validation_types.h | 4 ++-- layers/descriptor_sets.h | 3 ++- layers/vk_validation_error_database.txt | 2 +- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 0cd14d7..3702870 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -4827,19 +4827,34 @@ VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, const VkPip } } + std::vector> set_layouts(pCreateInfo->setLayoutCount, nullptr); + unique_lock_t lock(global_lock); + unsigned int push_descriptor_set_count = 0; + for (i = 0; i < pCreateInfo->setLayoutCount; ++i) { + set_layouts[i] = GetDescriptorSetLayout(dev_data, pCreateInfo->pSetLayouts[i]); + if (set_layouts[i]->IsPushDescriptor()) ++push_descriptor_set_count; + } + lock.unlock(); + if (push_descriptor_set_count > 1) { + skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, VALIDATION_ERROR_0fe0024a, "DS", + "vkCreatePipelineLayout() Multiple push descriptor sets found. %s", + validation_error_map[VALIDATION_ERROR_0fe0024a]); + } + if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; + VkResult result = dev_data->dispatch_table.CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); if (VK_SUCCESS == result) { - lock_guard_t lock(global_lock); + lock.lock(); PIPELINE_LAYOUT_NODE &plNode = dev_data->pipelineLayoutMap[*pPipelineLayout]; plNode.layout = *pPipelineLayout; plNode.set_layouts.resize(pCreateInfo->setLayoutCount); - for (i = 0; i < pCreateInfo->setLayoutCount; ++i) { - plNode.set_layouts[i] = GetDescriptorSetLayout(dev_data, pCreateInfo->pSetLayouts[i]); - } + plNode.set_layouts.swap(set_layouts); plNode.push_constant_ranges.resize(pCreateInfo->pushConstantRangeCount); for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { plNode.push_constant_ranges[i] = pCreateInfo->pPushConstantRanges[i]; } + lock.unlock(); } return result; } @@ -5501,7 +5516,7 @@ static void PreCallRecordCmdBindDescriptorSets(layer_data *device_data, GLOBAL_C if ((last_bound->boundDescriptorSets[set_idx + firstSet] != nullptr) && last_bound->boundDescriptorSets[set_idx + firstSet]->IsPushDescriptor()) { - last_bound->push_descriptors[set_idx + firstSet] = nullptr; + last_bound->push_descriptor_set = nullptr; last_bound->boundDescriptorSets[set_idx + firstSet] = nullptr; } @@ -5671,9 +5686,6 @@ static void PreCallRecordCmdPushDescriptorSetKHR(layer_data *device_data, VkComm uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites) { auto cb_state = GetCBNode(device_data, commandBuffer); - if (set >= cb_state->lastBound[pipelineBindPoint].push_descriptors.size()) { - cb_state->lastBound[pipelineBindPoint].push_descriptors.resize(set + 1); - } if (set >= cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.size()) { cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.resize(set + 1); cb_state->lastBound[pipelineBindPoint].dynamicOffsets.resize(set + 1); @@ -5682,7 +5694,7 @@ static void PreCallRecordCmdPushDescriptorSetKHR(layer_data *device_data, VkComm std::unique_ptr new_desc{ new cvdescriptorset::DescriptorSet(0, 0, layout_state->set_layouts[set], device_data)}; cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[set] = new_desc.get(); - cb_state->lastBound[pipelineBindPoint].push_descriptors[set] = std::move(new_desc); + cb_state->lastBound[pipelineBindPoint].push_descriptor_set = std::move(new_desc); } VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index cfc0a91..dc9d754 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -628,7 +628,7 @@ struct LAST_BOUND_STATE { // Track each set that has been bound // Ordered bound set tracking where index is set# that given set is bound to std::vector boundDescriptorSets; - std::vector> push_descriptors; + std::unique_ptr push_descriptor_set; // one dynamic offset per dynamic descriptor bound to this CB std::vector> dynamicOffsets; @@ -636,7 +636,7 @@ struct LAST_BOUND_STATE { pipeline_state = nullptr; pipeline_layout.reset(); boundDescriptorSets.clear(); - push_descriptors.clear(); + push_descriptor_set = nullptr; dynamicOffsets.clear(); } }; diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h index 0a40b8e..3065669 100644 --- a/layers/descriptor_sets.h +++ b/layers/descriptor_sets.h @@ -144,6 +144,7 @@ class DescriptorSetLayout { // For a particular binding starting at offset and having update_count descriptors // updated, verify that for any binding boundaries crossed, the update is consistent bool VerifyUpdateConsistency(uint32_t, uint32_t, uint32_t, const char *, const VkDescriptorSet, std::string *) const; + bool IsPushDescriptor() const { return GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR; }; private: VkDescriptorSetLayout layout_; @@ -384,7 +385,7 @@ class DescriptorSet : public BASE_NODE { }; // Return true if any part of set has ever been updated bool IsUpdated() const { return some_update_; }; - bool IsPushDescriptor() const { return p_layout_->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR; }; + bool IsPushDescriptor() const { return p_layout_->IsPushDescriptor(); }; private: bool VerifyWriteUpdateContents(const VkWriteDescriptorSet *, const uint32_t, UNIQUE_VALIDATION_ERROR_CODE *, diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt index 38c8e4c..cd61c25 100644 --- a/layers/vk_validation_error_database.txt +++ b/layers/vk_validation_error_database.txt @@ -1120,7 +1120,7 @@ VALIDATION_ERROR_0fe00242~^~N~^~None~^~vkCreatePipelineLayout~^~VUID-VkPipelineL VALIDATION_ERROR_0fe00244~^~N~^~None~^~vkCreatePipelineLayout~^~VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290~^~core~^~The spec valid usage text states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSampledImages' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00290)~^~ VALIDATION_ERROR_0fe00246~^~N~^~None~^~vkCreatePipelineLayout~^~VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00291~^~core~^~The spec valid usage text states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorStorageImages' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00291)~^~ VALIDATION_ERROR_0fe00248~^~Y~^~InvalidPushConstants~^~vkCreatePipelineLayout~^~VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292~^~core~^~The spec valid usage text states 'Any two elements of pPushConstantRanges must not include the same stage in stageFlags' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pPushConstantRanges-00292)~^~ -VALIDATION_ERROR_0fe0024a~^~N~^~Unknown~^~vkCreatePipelineLayout~^~VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293~^~(VK_KHR_push_descriptor)~^~The spec valid usage text states 'pSetLayouts must not contain more than one descriptor set layout that was created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293)~^~ +VALIDATION_ERROR_0fe0024a~^~Y~^~MultiplePushDescriptorSets~^~vkCreatePipelineLayout~^~VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293~^~(VK_KHR_push_descriptor)~^~The spec valid usage text states 'pSetLayouts must not contain more than one descriptor set layout that was created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-00293)~^~ VALIDATION_ERROR_0fe00d18~^~N~^~None~^~VkPipelineLayoutCreateInfo~^~VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01676~^~core~^~The spec valid usage text states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorInputAttachments' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01676)~^~ VALIDATION_ERROR_0fe00d1a~^~N~^~None~^~VkPipelineLayoutCreateInfo~^~VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677~^~core~^~The spec valid usage text states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetSamplers' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01677)~^~ VALIDATION_ERROR_0fe00d1c~^~N~^~None~^~VkPipelineLayoutCreateInfo~^~VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01678~^~core~^~The spec valid usage text states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER accessible across all shader stagess and and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetUniformBuffers' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkPipelineLayoutCreateInfo-pSetLayouts-01678)~^~ -- 2.7.4