From 82177dbd6a4da311c2447a51414f31145d3e2fc0 Mon Sep 17 00:00:00 2001 From: Tobin Ehlis Date: Tue, 25 Oct 2016 09:36:53 -0600 Subject: layers:Refactor CreateDescriptorSetLayout Update CreateDescriptorSetLayout() to use Pre/Post pattern and split out validation of createInfo for the layout to occur before the creation of the layout. --- layers/core_validation.cpp | 29 ++++++++++++++++++++++------- layers/core_validation.h | 1 + layers/descriptor_sets.cpp | 26 +++++++++++++++++++------- layers/descriptor_sets.h | 5 +++-- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 71d140ba..c2b78c08 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -6715,17 +6715,32 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, const VkSamplerCre return result; } +static bool PreCallValidateCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info) { + if (dev_data->instance_data->disabled.create_descriptor_set_layout) + return false; + return cvdescriptorset::DescriptorSetLayout::ValidateCreateInfo(dev_data->report_data, create_info); +} + +static void PostCallRecordCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info, + VkDescriptorSetLayout set_layout) { + // TODOSC : Capture layout bindings set + dev_data->descriptorSetLayoutMap[set_layout] = new cvdescriptorset::DescriptorSetLayout(create_info, set_layout); +} + VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) { layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); - // TODO: Need to validate create state prior to calling down the chain - VkResult result = dev_data->dispatch_table.CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout); - if (VK_SUCCESS == result) { - // TODOSC : Capture layout bindings set - std::lock_guard lock(global_lock); - dev_data->descriptorSetLayoutMap[*pSetLayout] = - new cvdescriptorset::DescriptorSetLayout(dev_data->report_data, pCreateInfo, *pSetLayout); + VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; + std::unique_lock lock(global_lock); + bool skip = PreCallValidateCreateDescriptorSetLayout(dev_data, pCreateInfo); + if (!skip) { + lock.unlock(); + result = dev_data->dispatch_table.CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout); + if (VK_SUCCESS == result) { + lock.lock(); + PostCallRecordCreateDescriptorSetLayout(dev_data, pCreateInfo, *pSetLayout); + } } return result; } diff --git a/layers/core_validation.h b/layers/core_validation.h index 288bfac7..44121ec7 100644 --- a/layers/core_validation.h +++ b/layers/core_validation.h @@ -68,6 +68,7 @@ */ struct CHECK_DISABLED { bool command_buffer_state; + bool create_descriptor_set_layout; bool destroy_buffer_view; // Skip validation at DestroyBufferView time bool destroy_image_view; // Skip validation at DestroyImageView time bool destroy_pipeline; // Skip validation at DestroyPipeline time diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp index 0c6747d6..52c0b339 100644 --- a/layers/descriptor_sets.cpp +++ b/layers/descriptor_sets.cpp @@ -24,18 +24,13 @@ #include // Construct DescriptorSetLayout instance from given create info -cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(debug_report_data *report_data, - const VkDescriptorSetLayoutCreateInfo *p_create_info, +cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *p_create_info, const VkDescriptorSetLayout layout) : layout_(layout), binding_count_(p_create_info->bindingCount), descriptor_count_(0), dynamic_descriptor_count_(0) { uint32_t global_index = 0; for (uint32_t i = 0; i < binding_count_; ++i) { descriptor_count_ += p_create_info->pBindings[i].descriptorCount; - if (!binding_to_index_map_.emplace(p_create_info->pBindings[i].binding, i).second) { - log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, - reinterpret_cast(layout_), __LINE__, VALIDATION_ERROR_02345, "DS", - "duplicated binding number in VkDescriptorSetLayoutBinding. %s", validation_error_map[VALIDATION_ERROR_02345]); - } + binding_to_index_map_.emplace(p_create_info->pBindings[i].binding, i); binding_to_global_start_index_map_[p_create_info->pBindings[i].binding] = global_index; global_index += p_create_info->pBindings[i].descriptorCount ? p_create_info->pBindings[i].descriptorCount - 1 : 0; binding_to_global_end_index_map_[p_create_info->pBindings[i].binding] = global_index; @@ -53,6 +48,23 @@ cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(debug_report_data *rep } } } + +// Validate descriptor set layout create info +bool cvdescriptorset::DescriptorSetLayout::ValidateCreateInfo(debug_report_data *report_data, + const VkDescriptorSetLayoutCreateInfo *create_info) { + bool skip = false; + std::unordered_set bindings; + for (uint32_t i = 0; i < create_info->bindingCount; ++i) { + if (bindings.count(create_info->pBindings[i].binding)) { + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, + VALIDATION_ERROR_02345, "DS", "duplicated binding number in VkDescriptorSetLayoutBinding. %s", + validation_error_map[VALIDATION_ERROR_02345]); + } + bindings.insert(create_info->pBindings[i].binding); + } + return skip; +} + // put all bindings into the given set void cvdescriptorset::DescriptorSetLayout::FillBindingSet(std::unordered_set *binding_set) const { for (auto binding_index_pair : binding_to_index_map_) diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h index 8316bbb0..2cf45e74 100644 --- a/layers/descriptor_sets.h +++ b/layers/descriptor_sets.h @@ -89,8 +89,9 @@ namespace cvdescriptorset { class DescriptorSetLayout { public: // Constructors and destructor - DescriptorSetLayout(debug_report_data *report_data, const VkDescriptorSetLayoutCreateInfo *p_create_info, - const VkDescriptorSetLayout layout); + DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *p_create_info, const VkDescriptorSetLayout layout); + // Validate create info - should be called prior to creation + static bool ValidateCreateInfo(debug_report_data *, const VkDescriptorSetLayoutCreateInfo *); // Straightforward Get functions VkDescriptorSetLayout GetDescriptorSetLayout() const { return layout_; }; uint32_t GetTotalDescriptorCount() const { return descriptor_count_; }; -- cgit v1.2.3