layers: Validate push descriptor set layout count
authorJózef Kucia <joseph.kucia@gmail.com>
Wed, 25 Oct 2017 20:15:22 +0000 (22:15 +0200)
committerTobin Ehlis <tobine@google.com>
Thu, 26 Oct 2017 14:45:55 +0000 (08:45 -0600)
layers/core_validation.cpp
layers/core_validation_types.h
layers/descriptor_sets.h
layers/vk_validation_error_database.txt

index 0cd14d7..3702870 100644 (file)
@@ -4827,19 +4827,34 @@ VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, const VkPip
         }
     }
 
+    std::vector<std::shared_ptr<cvdescriptorset::DescriptorSetLayout const>> 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<cvdescriptorset::DescriptorSet> 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,
index cfc0a91..dc9d754 100644 (file)
@@ -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<cvdescriptorset::DescriptorSet *> boundDescriptorSets;
-    std::vector<std::unique_ptr<cvdescriptorset::DescriptorSet>> push_descriptors;
+    std::unique_ptr<cvdescriptorset::DescriptorSet> push_descriptor_set;
     // one dynamic offset per dynamic descriptor bound to this CB
     std::vector<std::vector<uint32_t>> 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();
     }
 };
index 0a40b8e..3065669 100644 (file)
@@ -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 *,
index 38c8e4c..cd61c25 100644 (file)
@@ -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)~^~