layers: Pass unique error codes through descriptor validation
authorTobin Ehlis <tobine@google.com>
Thu, 6 Oct 2016 23:43:11 +0000 (17:43 -0600)
committerTobin Ehlis <tobine@google.com>
Mon, 10 Oct 2016 23:40:34 +0000 (17:40 -0600)
Descriptor validation builds up error strings at multiple levels such as
UpdateError->WriteUpdate->BufferUpdate->BufferOffset. The final error is
then reported via a log_msg() call at the top level.

In order for this design to allow for the new unique error codes, we need
to pass error codes down the chain in the same way we pass error strings
down the chain.

This change adds error msg passing for descriptor updates. Many error
codes are added in as well as comments for codes that are missing or need
to be updated.

The database file is also updated to account for all of the checks that
were updated and/or reviewed.

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

index e2be8fe..59db198 100644 (file)
@@ -6778,6 +6778,7 @@ CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateI
 
 VKAPI_ATTR VkResult VKAPI_CALL
 ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags) {
+    // TODO : Add checks for VALIDATION_ERROR_00928
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     VkResult result = dev_data->dispatch_table.ResetDescriptorPool(device, descriptorPool, flags);
     if (VK_SUCCESS == result) {
index 653078a..4af5674 100644 (file)
@@ -536,25 +536,30 @@ void cvdescriptorset::DescriptorSet::PerformWriteUpdate(const VkWriteDescriptorS
 }
 // Validate Copy update
 bool cvdescriptorset::DescriptorSet::ValidateCopyUpdate(const debug_report_data *report_data, const VkCopyDescriptorSet *update,
-                                                        const DescriptorSet *src_set, std::string *error) {
+                                                        const DescriptorSet *src_set, UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                                        std::string *error_msg) {
     // Verify idle ds
     if (in_use.load()) {
+        // TODO : Re-using Allocate Idle error code, need copy update idle error code
+        *error_code = VALIDATION_ERROR_00919;
         std::stringstream error_str;
         error_str << "Cannot call vkUpdateDescriptorSets() to perform copy update on descriptor set " << set_
                   << " that is in use by a command buffer.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     if (!p_layout_->HasBinding(update->dstBinding)) {
+        *error_code = VALIDATION_ERROR_00966;
         std::stringstream error_str;
         error_str << "DescriptorSet " << set_ << " does not have copy update dest binding of " << update->dstBinding << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     if (!src_set->HasBinding(update->srcBinding)) {
+        *error_code = VALIDATION_ERROR_00964;
         std::stringstream error_str;
         error_str << "DescriptorSet " << set_ << " does not have copy update src binding of " << update->srcBinding << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // src & dst set bindings are valid
@@ -562,26 +567,31 @@ bool cvdescriptorset::DescriptorSet::ValidateCopyUpdate(const debug_report_data
     auto src_start_idx = src_set->GetGlobalStartIndexFromBinding(update->srcBinding) + update->srcArrayElement;
     if ((src_start_idx + update->descriptorCount) > src_set->GetTotalDescriptorCount()) {
         // SRC update out of bounds
+        *error_code = VALIDATION_ERROR_00965;
         std::stringstream error_str;
         error_str << "Attempting copy update from descriptorSet " << update->srcSet << " binding#" << update->srcBinding
                   << " with offset index of " << src_set->GetGlobalStartIndexFromBinding(update->srcBinding)
                   << " plus update array offset of " << update->srcArrayElement << " and update of " << update->descriptorCount
                   << " descriptors oversteps total number of descriptors in set: " << src_set->GetTotalDescriptorCount() << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     auto dst_start_idx = p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) + update->dstArrayElement;
     if ((dst_start_idx + update->descriptorCount) > p_layout_->GetTotalDescriptorCount()) {
         // DST update out of bounds
+        *error_code = VALIDATION_ERROR_00967;
         std::stringstream error_str;
         error_str << "Attempting copy update to descriptorSet " << set_ << " binding#" << update->dstBinding
                   << " with offset index of " << p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding)
                   << " plus update array offset of " << update->dstArrayElement << " and update of " << update->descriptorCount
                   << " descriptors oversteps total number of descriptors in set: " << p_layout_->GetTotalDescriptorCount() << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // Check that types match
+    // TODO : Base default error case going from here is VALIDATION_ERROR_00968 which covers all consistency issues, need more
+    // fine-grained error codes
+    *error_code = VALIDATION_ERROR_00968;
     auto src_type = src_set->GetTypeFromBinding(update->srcBinding);
     auto dst_type = p_layout_->GetTypeFromBinding(update->dstBinding);
     if (src_type != dst_type) {
@@ -589,14 +599,14 @@ bool cvdescriptorset::DescriptorSet::ValidateCopyUpdate(const debug_report_data
         error_str << "Attempting copy update to descriptorSet " << set_ << " binding #" << update->dstBinding << " with type "
                   << string_VkDescriptorType(dst_type) << " from descriptorSet " << src_set->GetSet() << " binding #"
                   << update->srcBinding << " with type " << string_VkDescriptorType(src_type) << ". Types do not match.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // Verify consistency of src & dst bindings if update crosses binding boundaries
     if ((!src_set->GetLayout()->VerifyUpdateConsistency(update->srcBinding, update->srcArrayElement, update->descriptorCount,
-                                                        "copy update from", src_set->GetSet(), error)) ||
+                                                        "copy update from", src_set->GetSet(), error_msg)) ||
         (!p_layout_->VerifyUpdateConsistency(update->dstBinding, update->dstArrayElement, update->descriptorCount, "copy update to",
-                                             set_, error))) {
+                                             set_, error_msg))) {
         return false;
     }
     // First make sure source descriptors are updated
@@ -605,12 +615,12 @@ bool cvdescriptorset::DescriptorSet::ValidateCopyUpdate(const debug_report_data
             std::stringstream error_str;
             error_str << "Attempting copy update from descriptorSet " << src_set << " binding #" << update->srcBinding << " but descriptor at array offset "
                       << update->srcArrayElement + i << " has not been updated.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
     }
     // Update parameters all look good and descriptor updated so verify update contents
-    if (!VerifyCopyUpdateContents(update, src_set, src_type, src_start_idx, error))
+    if (!VerifyCopyUpdateContents(update, src_set, src_type, src_start_idx, error_code, error_msg))
         return false;
 
     // All checks passed so update is good
@@ -669,13 +679,15 @@ bool cvdescriptorset::ValidateSampler(const VkSampler sampler, const core_valida
 }
 
 bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout image_layout, VkDescriptorType type,
-                                          const core_validation::layer_data *dev_data,
-                                          std::string *error) {
+                                          const core_validation::layer_data *dev_data, UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                          std::string *error_msg) {
+    // TODO : Defaulting to 00943 for all cases here. Need to create new error codes for various cases.
+    *error_code = VALIDATION_ERROR_00943;
     auto iv_state = getImageViewState(dev_data, image_view);
     if (!iv_state) {
         std::stringstream error_str;
         error_str << "Invalid VkImageView: " << image_view;
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // Note that when an imageview is created, we validated that memory is bound so no need to re-check here
@@ -691,7 +703,8 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
         usage = image_node->createInfo.usage;
         // Validate that memory is bound to image
         if (ValidateMemoryIsBoundToImage(dev_data, image_node, "vkUpdateDescriptorSets()")) {
-            *error = "No memory bound to image.";
+            // TODO : Need new code(s) for language in 11.6 Memory Association
+            *error_msg = "No memory bound to image.";
             return false;
         }
     } else {
@@ -708,9 +721,11 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
     if (format == VK_FORMAT_MAX_ENUM) {
         std::stringstream error_str;
         error_str << "Invalid image (" << image << ") in imageView (" << image_view << ").";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
+    // TODO : The various image aspect and format checks here are based on general spec language in 11.5 Image Views section under
+    // vkCreateImageView(). What's the best way to create unique id for these cases?
     bool ds = vk_format_is_depth_or_stencil(format);
     switch (image_layout) {
     case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
@@ -719,7 +734,7 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
             std::stringstream error_str;
             error_str << "ImageView (" << image_view << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but does "
                                                         "not have VK_IMAGE_ASPECT_COLOR_BIT set.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         // format must NOT be DS
@@ -728,7 +743,7 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
             error_str << "ImageView (" << image_view
                       << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but the image format is "
                       << string_VkFormat(format) << " which is not a color format.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         break;
@@ -740,7 +755,7 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
                 // both  must NOT be set
                 std::stringstream error_str;
                 error_str << "ImageView (" << image_view << ") has both STENCIL and DEPTH aspects set";
-                *error = error_str.str();
+                *error_msg = error_str.str();
                 return false;
             }
         } else if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
@@ -748,7 +763,7 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
             std::stringstream error_str;
             error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
                       << " but does not have STENCIL or DEPTH aspects set";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         // format must be DS
@@ -756,7 +771,7 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
             std::stringstream error_str;
             error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
                       << " but the image format is " << string_VkFormat(format) << " which is not a depth/stencil format.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         break;
@@ -773,7 +788,7 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
                                  "image in a descriptor set, please only set either VK_IMAGE_ASPECT_DEPTH_BIT or "
                                  "VK_IMAGE_ASPECT_STENCIL_BIT depending on whether it will be used for depth reads or stencil "
                                  "reads respectively.";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             }
@@ -781,6 +796,10 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
         break;
     }
     // Now validate that usage flags are correctly set for given type of update
+    // TODO : The various image usage bit requirements are in general spec language for VkImageUsageFlags bit block in 11.3 Images
+    // under vkCreateImage()
+    // TODO : Need to also validate case VALIDATION_ERROR_00952 where STORAGE_IMAGE & INPUT_ATTACH types must have been created with
+    // identify swizzle
     std::string error_usage_bit;
     switch (type) {
     case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
@@ -810,7 +829,7 @@ bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout
         error_str << "ImageView (" << image_view << ") with usage mask 0x" << usage
                   << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
                   << error_usage_bit << " set.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     return true;
@@ -1000,13 +1019,14 @@ bool cvdescriptorset::ValidateUpdateDescriptorSets(const debug_report_data *repo
                         "Cannot call vkUpdateDescriptorSets() on descriptor set 0x%" PRIxLEAST64 " that has not been allocated.",
                         reinterpret_cast<uint64_t &>(dest_set));
         } else {
+            UNIQUE_VALIDATION_ERROR_CODE error_code;
             std::string error_str;
-            if (!set_node->ValidateWriteUpdate(report_data, &p_wds[i], &error_str)) {
+            if (!set_node->ValidateWriteUpdate(report_data, &p_wds[i], &error_code, &error_str)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                                     reinterpret_cast<uint64_t &>(dest_set), __LINE__, DRAWSTATE_INVALID_WRITE_UPDATE, "DS",
+                                     reinterpret_cast<uint64_t &>(dest_set), __LINE__, error_code, "DS",
                                      "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x%" PRIx64
-                                     " with error: %s",
-                                     reinterpret_cast<uint64_t &>(dest_set), error_str.c_str());
+                                     " with error: %s. %s",
+                                     reinterpret_cast<uint64_t &>(dest_set), error_str.c_str(), validation_error_map[error_code]);
             }
         }
     }
@@ -1018,25 +1038,26 @@ bool cvdescriptorset::ValidateUpdateDescriptorSets(const debug_report_data *repo
         auto dst_node = core_validation::getSetNode(dev_data, dst_set);
         if (!src_node) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                                 reinterpret_cast<uint64_t &>(src_set), __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
+                                 reinterpret_cast<uint64_t &>(src_set), __LINE__, VALIDATION_ERROR_00971, "DS",
                                  "Cannot call vkUpdateDescriptorSets() to copy from descriptor set 0x%" PRIxLEAST64
-                                 " that has not been allocated.",
-                                 reinterpret_cast<uint64_t &>(src_set));
+                                 " that has not been allocated. %s",
+                                 reinterpret_cast<uint64_t &>(src_set), validation_error_map[VALIDATION_ERROR_00971]);
         } else if (!dst_node) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                                 reinterpret_cast<uint64_t &>(dst_set), __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
+                                 reinterpret_cast<uint64_t &>(dst_set), __LINE__, VALIDATION_ERROR_00972, "DS",
                                  "Cannot call vkUpdateDescriptorSets() to copy to descriptor set 0x%" PRIxLEAST64
-                                 " that has not been allocated.",
-                                 reinterpret_cast<uint64_t &>(dst_set));
+                                 " that has not been allocated. %s",
+                                 reinterpret_cast<uint64_t &>(dst_set), validation_error_map[VALIDATION_ERROR_00972]);
         } else {
+            UNIQUE_VALIDATION_ERROR_CODE error_code;
             std::string error_str;
-            if (!dst_node->ValidateCopyUpdate(report_data, &p_cds[i], src_node, &error_str)) {
-                skip_call |=
-                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                            reinterpret_cast<uint64_t &>(dst_set), __LINE__, DRAWSTATE_INVALID_COPY_UPDATE, "DS",
-                            "vkUpdateDescriptorsSets() failed copy update from Descriptor Set 0x%" PRIx64
-                            " to Descriptor Set 0x%" PRIx64 " with error: %s",
-                            reinterpret_cast<uint64_t &>(src_set), reinterpret_cast<uint64_t &>(dst_set), error_str.c_str());
+            if (!dst_node->ValidateCopyUpdate(report_data, &p_cds[i], src_node, &error_code, &error_str)) {
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
+                                     reinterpret_cast<uint64_t &>(dst_set), __LINE__, error_code, "DS",
+                                     "vkUpdateDescriptorsSets() failed copy update from Descriptor Set 0x%" PRIx64
+                                     " to Descriptor Set 0x%" PRIx64 " with error: %s. %s",
+                                     reinterpret_cast<uint64_t &>(src_set), reinterpret_cast<uint64_t &>(dst_set),
+                                     error_str.c_str(), validation_error_map[error_code]);
             }
         }
     }
@@ -1074,9 +1095,11 @@ void cvdescriptorset::PerformUpdateDescriptorSets(const core_validation::layer_d
 // Validate the state for a given write update but don't actually perform the update
 //  If an error would occur for this update, return false and fill in details in error_msg string
 bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data *report_data, const VkWriteDescriptorSet *update,
-                                                         std::string *error_msg) {
+                                                         UNIQUE_VALIDATION_ERROR_CODE *error_code, std::string *error_msg) {
     // Verify idle ds
     if (in_use.load()) {
+        // TODO : Re-using Allocate Idle error code, need write update idle error code
+        *error_code = VALIDATION_ERROR_00919;
         std::stringstream error_str;
         error_str << "Cannot call vkUpdateDescriptorSets() to perform write update on descriptor set " << set_
                   << " that is in use by a command buffer.";
@@ -1085,6 +1108,7 @@ bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data
     }
     // Verify dst binding exists
     if (!p_layout_->HasBinding(update->dstBinding)) {
+        *error_code = VALIDATION_ERROR_00936;
         std::stringstream error_str;
         error_str << "DescriptorSet " << set_ << " does not have binding " << update->dstBinding << ".";
         *error_msg = error_str.str();
@@ -1094,6 +1118,7 @@ bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data
     auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) + update->dstArrayElement;
     auto type = p_layout_->GetTypeFromBinding(update->dstBinding);
     if (type != update->descriptorType) {
+        *error_code = VALIDATION_ERROR_00937;
         std::stringstream error_str;
         error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with type "
                   << string_VkDescriptorType(type) << " but update type is " << string_VkDescriptorType(update->descriptorType);
@@ -1101,6 +1126,7 @@ bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data
         return false;
     }
     if ((start_idx + update->descriptorCount) > p_layout_->GetTotalDescriptorCount()) {
+        *error_code = VALIDATION_ERROR_00938;
         std::stringstream error_str;
         error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with "
                   << p_layout_->GetTotalDescriptorCount() << " total descriptors but update of " << update->descriptorCount
@@ -1112,10 +1138,12 @@ bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data
     }
     // Verify consecutive bindings match (if needed)
     if (!p_layout_->VerifyUpdateConsistency(update->dstBinding, update->dstArrayElement, update->descriptorCount, "write update to",
-                                            set_, error_msg))
+                                            set_, error_msg)) {
+        *error_code = VALIDATION_ERROR_00938;
         return false;
+    }
     // Update is within bounds and consistent so last step is to validate update contents
-    if (!VerifyWriteUpdateContents(update, start_idx, error_msg)) {
+    if (!VerifyWriteUpdateContents(update, start_idx, error_code, error_msg)) {
         std::stringstream error_str;
         error_str << "Write update to descriptor in set " << set_ << " binding #" << update->dstBinding
                   << " failed with error message: " << error_msg->c_str();
@@ -1126,32 +1154,36 @@ bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data
     return true;
 }
 // For the given buffer, verify that its creation parameters are appropriate for the given type
-//  If there's an error, update the error string with details and return false, else return true
+//  If there's an error, update the error_msg string with details and return false, else return true
 bool cvdescriptorset::DescriptorSet::ValidateBufferUsage(BUFFER_NODE const *buffer_node, VkDescriptorType type,
-                                                         std::string *error) const {
+                                                         UNIQUE_VALIDATION_ERROR_CODE *error_code, std::string *error_msg) const {
     // Verify that usage bits set correctly for given type
     auto usage = buffer_node->createInfo.usage;
     std::string error_usage_bit;
     switch (type) {
     case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
         if (!(usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00950;
             error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT";
         }
         break;
     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
         if (!(usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00951;
             error_usage_bit = "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT";
         }
         break;
     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
         if (!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00946;
             error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT";
         }
         break;
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
         if (!(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00947;
             error_usage_bit = "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT";
         }
         break;
@@ -1163,7 +1195,7 @@ bool cvdescriptorset::DescriptorSet::ValidateBufferUsage(BUFFER_NODE const *buff
         error_str << "Buffer (" << buffer_node->buffer << ") with usage mask 0x" << usage
                   << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
                   << error_usage_bit << " set.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     return true;
@@ -1173,48 +1205,56 @@ bool cvdescriptorset::DescriptorSet::ValidateBufferUsage(BUFFER_NODE const *buff
 //  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)]
-// If there's an error, update the error string with details and return false, else return true
+// 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,
-                                                          std::string *error) const {
+                                                          UNIQUE_VALIDATION_ERROR_CODE *error_code, std::string *error_msg) const {
+    // TODO : Defaulting to 00962 for all cases here. Need to create new error codes for a few cases below.
+    *error_code = VALIDATION_ERROR_00962;
     // First make sure that buffer is valid
     auto buffer_node = getBufferNode(device_data_, buffer_info->buffer);
     if (!buffer_node) {
         std::stringstream error_str;
         error_str << "Invalid VkBuffer: " << buffer_info->buffer;
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     if (ValidateMemoryIsBoundToBuffer(device_data_, buffer_node, "vkUpdateDescriptorSets()")) {
-        *error = "No memory bound to buffer.";
+        // TODO : This is a repeat code, need new code(s) for language in 11.6 Memory Association
+        *error_msg = "No memory bound to buffer.";
         return false;
     }
     // Verify usage bits
-    if (!ValidateBufferUsage(buffer_node, type, error)) {
-        // error will have been updated by ValidateBufferUsage()
+    if (!ValidateBufferUsage(buffer_node, type, error_code, error_msg)) {
+        // 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;
         std::stringstream error_str;
         error_str << "VkDescriptorBufferInfo offset of " << buffer_info->offset << " is greater than buffer " << buffer_node->buffer
                   << " size of " << buffer_node->createInfo.size;
-        *error = error_str.str();
+        *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) {
+            *error_code = VALIDATION_ERROR_00960;
             std::stringstream error_str;
             error_str << "VkDescriptorBufferInfo range is not VK_WHOLE_SIZE and is zero, which is not allowed.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         // Range must be VK_WHOLE_SIZE or <= (buffer size - offset)
         if (buffer_info->range > (buffer_node->createInfo.size - buffer_info->offset)) {
+            *error_code = VALIDATION_ERROR_00961;
             std::stringstream error_str;
             error_str << "VkDescriptorBufferInfo range is " << buffer_info->range << " which is greater than buffer size ("
                       << buffer_node->createInfo.size << ") minus requested offset of " << buffer_info->offset;
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
     }
@@ -1223,17 +1263,18 @@ bool cvdescriptorset::DescriptorSet::ValidateBufferUpdate(VkDescriptorBufferInfo
 
 // Verify that the contents of the update are ok, but don't perform actual update
 bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDescriptorSet *update, const uint32_t index,
-                                                               std::string *error) const {
+                                                               UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                                               std::string *error_msg) const {
     switch (update->descriptorType) {
     case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             // Validate image
             auto image_view = update->pImageInfo[di].imageView;
             auto image_layout = update->pImageInfo[di].imageLayout;
-            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to combined image sampler descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to combined image sampler descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1243,10 +1284,11 @@ bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDesc
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             if (!descriptors_[index + di].get()->IsImmutableSampler()) {
                 if (!ValidateSampler(update->pImageInfo[di].sampler, device_data_)) {
+                    *error_code = VALIDATION_ERROR_00942;
                     std::stringstream error_str;
                     error_str << "Attempted write update to sampler descriptor with invalid sampler: "
                               << update->pImageInfo[di].sampler << ".";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             } else {
@@ -1261,10 +1303,10 @@ bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDesc
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto image_view = update->pImageInfo[di].imageView;
             auto image_layout = update->pImageInfo[di].imageLayout;
-            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to image descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to image descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1276,16 +1318,17 @@ bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDesc
             auto buffer_view = update->pTexelBufferView[di];
             auto bv_state = getBufferViewState(device_data_, buffer_view);
             if (!bv_state) {
+                *error_code = VALIDATION_ERROR_00940;
                 std::stringstream error_str;
                 error_str << "Attempted write update to texel buffer descriptor with invalid buffer view: " << buffer_view;
-                *error = error_str.str();
+                *error_msg = error_str.str();
                 return false;
             }
             auto buffer = bv_state->create_info.buffer;
-            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), update->descriptorType, error)) {
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), update->descriptorType, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to texel buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to texel buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1296,10 +1339,10 @@ bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDesc
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
-            if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, error)) {
+            if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1314,16 +1357,21 @@ bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDesc
 }
 // Verify that the contents of the update are ok, but don't perform actual update
 bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescriptorSet *update, const DescriptorSet *src_set,
-                                                              VkDescriptorType type, uint32_t index, std::string *error) const {
+                                                              VkDescriptorType type, uint32_t index,
+                                                              UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                                              std::string *error_msg) const {
+    // Note : Repurposing some Write update error codes here as specific details aren't called out for copy updates like they are
+    // for write updates
     switch (src_set->descriptors_[index]->descriptor_class) {
     case PlainSampler: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             if (!src_set->descriptors_[index + di]->IsImmutableSampler()) {
                 auto update_sampler = static_cast<SamplerDescriptor *>(src_set->descriptors_[index + di].get())->GetSampler();
                 if (!ValidateSampler(update_sampler, device_data_)) {
+                    *error_code = VALIDATION_ERROR_00942;
                     std::stringstream error_str;
                     error_str << "Attempted copy update to sampler descriptor with invalid sampler: " << update_sampler << ".";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             } else {
@@ -1339,9 +1387,10 @@ bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescri
             if (!img_samp_desc->IsImmutableSampler()) {
                 auto update_sampler = img_samp_desc->GetSampler();
                 if (!ValidateSampler(update_sampler, device_data_)) {
+                    *error_code = VALIDATION_ERROR_00942;
                     std::stringstream error_str;
                     error_str << "Attempted copy update to sampler descriptor with invalid sampler: " << update_sampler << ".";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             } else {
@@ -1350,10 +1399,10 @@ bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescri
             // Validate image
             auto image_view = img_samp_desc->GetImageView();
             auto image_layout = img_samp_desc->GetImageLayout();
-            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to combined image sampler descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to combined image sampler descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1364,10 +1413,10 @@ bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescri
             auto img_desc = static_cast<const ImageDescriptor *>(src_set->descriptors_[index + di].get());
             auto image_view = img_desc->GetImageView();
             auto image_layout = img_desc->GetImageLayout();
-            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to image descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to image descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1378,16 +1427,17 @@ bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescri
             auto buffer_view = static_cast<TexelDescriptor *>(src_set->descriptors_[index + di].get())->GetBufferView();
             auto bv_state = getBufferViewState(device_data_, buffer_view);
             if (!bv_state) {
+                *error_code = VALIDATION_ERROR_00940;
                 std::stringstream error_str;
                 error_str << "Attempted copy update to texel buffer descriptor with invalid buffer view: " << buffer_view;
-                *error = error_str.str();
+                *error_msg = error_str.str();
                 return false;
             }
             auto buffer = bv_state->create_info.buffer;
-            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error)) {
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1396,10 +1446,10 @@ bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescri
     case GeneralBuffer: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto buffer = static_cast<BufferDescriptor *>(src_set->descriptors_[index + di].get())->GetBuffer();
-            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error)) {
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1440,23 +1490,21 @@ bool cvdescriptorset::ValidateAllocateDescriptorSets(const debug_report_data *re
     auto pool_node = getPoolNode(dev_data, p_alloc_info->descriptorPool);
     // Track number of descriptorSets allowable in this pool
     if (pool_node->availableSets < p_alloc_info->descriptorSetCount) {
-        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                             reinterpret_cast<uint64_t &>(pool_node->pool), __LINE__, VALIDATION_ERROR_00911, "DS",
-                             "Unable to allocate %u descriptorSets from pool 0x%" PRIxLEAST64
-                             ". This pool only has %d descriptorSets remaining. %s",
-                             p_alloc_info->descriptorSetCount, reinterpret_cast<uint64_t &>(pool_node->pool),
-                             pool_node->availableSets, validation_error_map[VALIDATION_ERROR_00911]);
+        skip_call |= log_msg(
+            report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
+            reinterpret_cast<uint64_t &>(pool_node->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
+            "Unable to allocate %u descriptorSets from pool 0x%" PRIxLEAST64 ". This pool only has %d descriptorSets remaining.",
+            p_alloc_info->descriptorSetCount, reinterpret_cast<uint64_t &>(pool_node->pool), pool_node->availableSets);
     }
     // Determine whether descriptor counts are satisfiable
     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
         if (ds_data->required_descriptors_by_type[i] > pool_node->availableDescriptorTypeCount[i]) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                                 reinterpret_cast<const uint64_t &>(pool_node->pool), __LINE__, VALIDATION_ERROR_00912, "DS",
-                                 "Unable to allocate %u descriptors of type %s from pool 0x%" PRIxLEAST64
-                                 ". This pool only has %d descriptors of this type remaining. %s",
+                                 reinterpret_cast<const uint64_t &>(pool_node->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY,
+                                 "DS", "Unable to allocate %u descriptors of type %s from pool 0x%" PRIxLEAST64
+                                       ". This pool only has %d descriptors of this type remaining.",
                                  ds_data->required_descriptors_by_type[i], string_VkDescriptorType(VkDescriptorType(i)),
-                                 reinterpret_cast<uint64_t &>(pool_node->pool), pool_node->availableDescriptorTypeCount[i],
-                                 validation_error_map[VALIDATION_ERROR_00912]);
+                                 reinterpret_cast<uint64_t &>(pool_node->pool), pool_node->availableDescriptorTypeCount[i]);
         }
     }
 
index 4345154..2ea8388 100644 (file)
@@ -168,7 +168,8 @@ class Descriptor {
 // Shared helper functions - These are useful because the shared sampler image descriptor type
 //  performs common functions with both sampler and image descriptors so they can share their common functions
 bool ValidateSampler(const VkSampler, const core_validation::layer_data *);
-bool ValidateImageUpdate(VkImageView, VkImageLayout, VkDescriptorType, const core_validation::layer_data *, std::string *);
+bool ValidateImageUpdate(VkImageView, VkImageLayout, VkDescriptorType, const core_validation::layer_data *,
+                         UNIQUE_VALIDATION_ERROR_CODE *, std::string *);
 
 class SamplerDescriptor : public Descriptor {
   public:
@@ -330,11 +331,13 @@ class DescriptorSet : public BASE_NODE {
 
     // Descriptor Update functions. These functions validate state and perform update separately
     // Validate contents of a WriteUpdate
-    bool ValidateWriteUpdate(const debug_report_data *, const VkWriteDescriptorSet *, std::string *);
+    bool ValidateWriteUpdate(const debug_report_data *, const VkWriteDescriptorSet *, UNIQUE_VALIDATION_ERROR_CODE *,
+                             std::string *);
     // Perform a WriteUpdate whose contents were just validated using ValidateWriteUpdate
     void PerformWriteUpdate(const VkWriteDescriptorSet *);
     // Validate contents of a CopyUpdate
-    bool ValidateCopyUpdate(const debug_report_data *, const VkCopyDescriptorSet *, const DescriptorSet *, std::string *);
+    bool ValidateCopyUpdate(const debug_report_data *, const VkCopyDescriptorSet *, const DescriptorSet *,
+                            UNIQUE_VALIDATION_ERROR_CODE *, std::string *);
     // Perform a CopyUpdate whose contents were just validated using ValidateCopyUpdate
     void PerformCopyUpdate(const VkCopyDescriptorSet *, const DescriptorSet *);
 
@@ -360,11 +363,13 @@ class DescriptorSet : public BASE_NODE {
     bool IsUpdated() const { return some_update_; };
 
   private:
-    bool VerifyWriteUpdateContents(const VkWriteDescriptorSet *, const uint32_t, std::string *) const;
+    bool VerifyWriteUpdateContents(const VkWriteDescriptorSet *, const uint32_t, UNIQUE_VALIDATION_ERROR_CODE *,
+                                   std::string *) const;
     bool VerifyCopyUpdateContents(const VkCopyDescriptorSet *, const DescriptorSet *, VkDescriptorType, uint32_t,
-                                  std::string *) const;
-    bool ValidateBufferUsage(BUFFER_NODE const *, VkDescriptorType, std::string *) const;
-    bool ValidateBufferUpdate(VkDescriptorBufferInfo const *, VkDescriptorType, std::string *) const;
+                                  UNIQUE_VALIDATION_ERROR_CODE *, std::string *) const;
+    bool ValidateBufferUsage(BUFFER_NODE const *, VkDescriptorType, UNIQUE_VALIDATION_ERROR_CODE *, std::string *) const;
+    bool ValidateBufferUpdate(VkDescriptorBufferInfo const *, VkDescriptorType, UNIQUE_VALIDATION_ERROR_CODE *,
+                              std::string *) const;
     // Private helper to set all bound cmd buffers to INVALID state
     void InvalidateBoundCmdBuffers();
     bool some_update_; // has any part of the set ever been updated?
index 8d371d7..3817bfd 100644 (file)
@@ -942,39 +942,39 @@ VALIDATION_ERROR_00932~^~U~^~Unknown~^~For more information refer to Vulkan Spec
 VALIDATION_ERROR_00933~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#vkUpdateDescriptorSets)
 VALIDATION_ERROR_00934~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorWriteCount is not 0, pDescriptorWrites must be a pointer to an array of descriptorWriteCount valid VkWriteDescriptorSet structures' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#vkUpdateDescriptorSets)
 VALIDATION_ERROR_00935~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorCopyCount is not 0, pDescriptorCopies must be a pointer to an array of descriptorCopyCount valid VkCopyDescriptorSet structures' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#vkUpdateDescriptorSets)
-VALIDATION_ERROR_00936~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding point within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00937~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorType must match the type of dstBinding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00938~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00936~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding point within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00937~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorType must match the type of dstBinding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00938~^~Y~^~WriteDescriptorSetIntegrityCheck~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00939~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pImageInfo must be a pointer to an array of descriptorCount valid VkDescriptorImageInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00940~^~U~^~Unknown~^~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 or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00940~^~Y~InvalidBufferViewObject~Unknown~^~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 or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00941~^~U~^~Unknown~^~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_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00942~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and dstSet was not allocated with a layout that included immutable samplers for dstBinding with descriptorType, the sampler member of any given element of pImageInfo must be a valid VkSampler object' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00943~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00944~^~U~^~Unknown~^~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 offset member of any given element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00945~^~U~^~Unknown~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00946~^~U~^~Unknown~^~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 buffer member of any given element of pBufferInfo must have been created with VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00947~^~U~^~Unknown~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00948~^~U~^~Unknown~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00949~^~U~^~Unknown~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00950~^~U~^~Unknown~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00951~^~U~^~Unknown~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00952~^~U~^~Unknown~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00942~^~Y~^~SampleDescriptorUpdateError~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and dstSet was not allocated with a layout that included immutable samplers for dstBinding with descriptorType, the sampler member of any given element of pImageInfo must be a valid VkSampler object' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00943~^~Y~^~ImageViewDescriptorUpdateError~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00944~^~N~^~None~^~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 offset member of any given element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00945~^~N~^~None~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00946~^~Y~^~DSUsageBitsErrors~^~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 buffer member of any given element of pBufferInfo must have been created with VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00947~^~Y~^~DSUsageBitsErrors~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00948~^~N~^~None~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00949~^~N~^~None~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00950~^~Y~^~DSUsageBitsErrors~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00951~^~Y~^~DSUsageBitsErrors~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
+VALIDATION_ERROR_00952~^~N~^~None~^~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/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00953~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00954~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00955~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00956~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorType must be a valid VkDescriptorType value' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00957~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
 VALIDATION_ERROR_00958~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of dstSet, and the elements of pTexelBufferView that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#descriptorsets-updates-consecutive)
-VALIDATION_ERROR_00959~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
-VALIDATION_ERROR_00960~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
-VALIDATION_ERROR_00961~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be less than or equal to the size of buffer minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
-VALIDATION_ERROR_00962~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
+VALIDATION_ERROR_00959~^~Y~^~DSBufferInfoErrors~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
+VALIDATION_ERROR_00960~^~Y~^~DSBufferInfoErrors~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
+VALIDATION_ERROR_00961~^~Y~^~DSBufferInfoErrors~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be less than or equal to the size of buffer minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
+VALIDATION_ERROR_00962~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorBufferInfo)
 VALIDATION_ERROR_00963~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of imageView, and sampler that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkDescriptorImageInfo)
-VALIDATION_ERROR_00964~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'srcBinding must be a valid binding within srcSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
-VALIDATION_ERROR_00965~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of srcArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by srcBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
-VALIDATION_ERROR_00966~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
-VALIDATION_ERROR_00967~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
-VALIDATION_ERROR_00968~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If srcSet is equal to dstSet, then the source and destination ranges of descriptors must not overlap, where the ranges may include array elements from consecutive bindings as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
+VALIDATION_ERROR_00964~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'srcBinding must be a valid binding within srcSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
+VALIDATION_ERROR_00965~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of srcArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by srcBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
+VALIDATION_ERROR_00966~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
+VALIDATION_ERROR_00967~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
+VALIDATION_ERROR_00968~^~Y~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If srcSet is equal to dstSet, then the source and destination ranges of descriptors must not overlap, where the ranges may include array elements from consecutive bindings as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
 VALIDATION_ERROR_00969~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'sType must be VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
 VALIDATION_ERROR_00970~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)
 VALIDATION_ERROR_00971~^~U~^~Unknown~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'srcSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html#VkCopyDescriptorSet)