layers:Add buffer descriptor device limit checks
authorTobin Ehlis <tobine@google.com>
Fri, 3 Feb 2017 00:26:40 +0000 (17:26 -0700)
committerTobin Ehlis <tobine@google.com>
Mon, 6 Feb 2017 21:34:18 +0000 (14:34 -0700)
This adds missing checks for max range for storage and uniform buffer
updates. Also update database file.

layers/core_validation.cpp
layers/core_validation_types.h
layers/descriptor_sets.cpp
layers/descriptor_sets.h
layers/vk_validation_error_database.txt

index 75a65c0..ff84729 100644 (file)
@@ -2122,6 +2122,10 @@ static PIPELINE_LAYOUT_NODE const *getPipelineLayout(layer_data const *my_data,
     return &it->second;
 }
 
+VkPhysicalDeviceLimits GetPhysicalDeviceLimits(layer_data const *dev_data) {
+    return dev_data->phys_dev_properties.properties.limits;
+}
+
 // Return true if for a given PSO, the given state enum is dynamic, else return false
 static bool isDynamic(const PIPELINE_STATE *pPipeline, const VkDynamicState state) {
     if (pPipeline && pPipeline->graphicsPipelineCI.pDynamicState) {
index 98d6991..c89b023 100644 (file)
@@ -760,6 +760,9 @@ bool insideRenderPass(const layer_data *my_data, GLOBAL_CB_NODE *pCB, const char
 void SetImageMemoryValid(layer_data *dev_data, IMAGE_STATE *image_state, bool valid);
 void UpdateCmdBufferLastCmd(layer_data *my_data, GLOBAL_CB_NODE *cb_state, const CMD_TYPE cmd);
 bool outsideRenderPass(const layer_data *my_data, GLOBAL_CB_NODE *pCB, const char *apiName, UNIQUE_VALIDATION_ERROR_CODE msgCode);
+void SetLayout(GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const IMAGE_CMD_BUF_LAYOUT_NODE &node);
+void SetLayout(GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const VkImageLayout &layout);
+VkPhysicalDeviceLimits GetPhysicalDeviceLimits(layer_data const *);
 
 // Prototypes for layer_data accessor functions.  These should be in their own header file at some point
 PFN_vkGetPhysicalDeviceFormatProperties GetFormatPropertiesPointer(layer_data *);
index f071fcd..2219dfb 100644 (file)
@@ -304,7 +304,12 @@ cvdescriptorset::AllocateDescriptorSetsData::AllocateDescriptorSetsData(uint32_t
 
 cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, const VkDescriptorPool pool,
                                               const DescriptorSetLayout *layout, const core_validation::layer_data *dev_data)
-    : some_update_(false), set_(set), pool_state_(nullptr), p_layout_(layout), device_data_(dev_data) {
+    : some_update_(false),
+      set_(set),
+      pool_state_(nullptr),
+      p_layout_(layout),
+      device_data_(dev_data),
+      limits_(GetPhysicalDeviceLimits(dev_data)) {
     pool_state_ = getDescriptorPoolState(dev_data, pool);
     // Foreach binding, create default descriptors of given type
     for (uint32_t i = 0; i < p_layout_->GetBindingCount(); ++i) {
@@ -1256,6 +1261,7 @@ bool cvdescriptorset::DescriptorSet::ValidateBufferUsage(BUFFER_STATE const *buf
 //  2. buffer was created with correct usage flags
 //  3. offset is less than buffer size
 //  4. range is either VK_WHOLE_SIZE or falls in (0, (buffer size - offset)]
+//  5. range and offset are within the device's limits
 // If there's an error, update the error_msg string with details and return false, else return true
 bool cvdescriptorset::DescriptorSet::ValidateBufferUpdate(VkDescriptorBufferInfo const *buffer_info, VkDescriptorType type,
                                                           UNIQUE_VALIDATION_ERROR_CODE *error_code, std::string *error_msg) const {
@@ -1273,7 +1279,6 @@ bool cvdescriptorset::DescriptorSet::ValidateBufferUpdate(VkDescriptorBufferInfo
         // error_msg will have been updated by ValidateBufferUsage()
         return false;
     }
-    // TODO : Need to also validate device limit offset requirements captured in VALIDATION_ERROR_00944,945
     // offset must be less than buffer size
     if (buffer_info->offset > buffer_node->createInfo.size) {
         *error_code = VALIDATION_ERROR_00959;
@@ -1283,7 +1288,6 @@ bool cvdescriptorset::DescriptorSet::ValidateBufferUpdate(VkDescriptorBufferInfo
         *error_msg = error_str.str();
         return false;
     }
-    // TODO : Need to also validate device limit range requirements captured in VALIDATION_ERROR_00948,949
     if (buffer_info->range != VK_WHOLE_SIZE) {
         // Range must be VK_WHOLE_SIZE or > 0
         if (!buffer_info->range) {
@@ -1303,6 +1307,30 @@ bool cvdescriptorset::DescriptorSet::ValidateBufferUpdate(VkDescriptorBufferInfo
             return false;
         }
     }
+    // Check buffer update sizes against device limits
+    if (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type || VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC == type) {
+        auto max_ub_range = limits_.maxUniformBufferRange;
+        // TODO : If range is WHOLE_SIZE, need to make sure underlying buffer size doesn't exceed device max
+        if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_ub_range) {
+            *error_code = VALIDATION_ERROR_00948;
+            std::stringstream error_str;
+            error_str << "VkDescriptorBufferInfo range is " << buffer_info->range
+                      << " which is greater than this device's maxUniformBufferRange (" << max_ub_range << ")";
+            *error_msg = error_str.str();
+            return false;
+        }
+    } else if (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == type || VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC == type) {
+        auto max_sb_range = limits_.maxStorageBufferRange;
+        // TODO : If range is WHOLE_SIZE, need to make sure underlying buffer size doesn't exceed device max
+        if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_sb_range) {
+            *error_code = VALIDATION_ERROR_00949;
+            std::stringstream error_str;
+            error_str << "VkDescriptorBufferInfo range is " << buffer_info->range
+                      << " which is greater than this device's maxStorageBufferRange (" << max_sb_range << ")";
+            *error_msg = error_str.str();
+            return false;
+        }
+    }
     return true;
 }
 
index c51b373..f5ec998 100644 (file)
@@ -398,6 +398,7 @@ class DescriptorSet : public BASE_NODE {
     std::vector<std::unique_ptr<Descriptor>> descriptors_;
     // Ptr to device data used for various data look-ups
     const core_validation::layer_data *device_data_;
+    const VkPhysicalDeviceLimits limits_;
 };
 }
 #endif  // CORE_VALIDATION_DESCRIPTOR_SETS_H_
index 4005d32..135190a 100644 (file)
@@ -936,8 +936,8 @@ VALIDATION_ERROR_00944~^~Y~^~None~^~vkUpdateDescriptorSets~^~For more informatio
 VALIDATION_ERROR_00945~^~Y~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the offset member of any given element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
 VALIDATION_ERROR_00946~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the buffer member of any given element of pBufferInfo that is non-sparse must be bound completely and contiguously to a single VkDeviceMemory object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
 VALIDATION_ERROR_00947~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the buffer member of any given element of pBufferInfo must have been created with VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
-VALIDATION_ERROR_00948~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxUniformBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
-VALIDATION_ERROR_00949~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxStorageBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
+VALIDATION_ERROR_00948~^~Y~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxUniformBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
+VALIDATION_ERROR_00949~^~Y~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxStorageBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
 VALIDATION_ERROR_00950~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, the VkBuffer that any given element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
 VALIDATION_ERROR_00951~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, the VkBuffer that any given element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~
 VALIDATION_ERROR_00952~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView member of any given element of pImageInfo must have been created with the identity swizzle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWriteDescriptorSet)~^~