From: Tobin Ehlis Date: Fri, 3 Feb 2017 00:26:40 +0000 (-0700) Subject: layers:Add buffer descriptor device limit checks X-Git-Tag: upstream/1.1.92~1643 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=13e86f8706e6ceb9a09ee8f016f13c0dfaf463a3;p=platform%2Fupstream%2FVulkan-Tools.git layers:Add buffer descriptor device limit checks This adds missing checks for max range for storage and uniform buffer updates. Also update database file. --- diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 75a65c0..ff84729 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -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) { diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h index 98d6991..c89b023 100644 --- a/layers/core_validation_types.h +++ b/layers/core_validation_types.h @@ -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 *); diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp index f071fcd..2219dfb 100644 --- a/layers/descriptor_sets.cpp +++ b/layers/descriptor_sets.cpp @@ -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; } diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h index c51b373..f5ec998 100644 --- a/layers/descriptor_sets.h +++ b/layers/descriptor_sets.h @@ -398,6 +398,7 @@ class DescriptorSet : public BASE_NODE { std::vector> 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_ diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt index 4005d32..135190a 100644 --- a/layers/vk_validation_error_database.txt +++ b/layers/vk_validation_error_database.txt @@ -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)~^~