diff options
Diffstat (limited to 'layers/descriptor_sets.cpp')
| -rw-r--r-- | layers/descriptor_sets.cpp | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp index cf2229aa..142f1eff 100644 --- a/layers/descriptor_sets.cpp +++ b/layers/descriptor_sets.cpp @@ -18,6 +18,9 @@ * Author: Tobin Ehlis <tobine@google.com> */ +// Allow use of STL min and max functions in Windows +#define NOMINMAX + #include "descriptor_sets.h" #include "vk_enum_string_helper.h" #include "vk_safe_struct.h" @@ -74,6 +77,18 @@ bool cvdescriptorset::DescriptorSetLayout::ValidateCreateInfo(debug_report_data return skip; } +// Return the number of descriptors for the given binding and all successive bindings +uint32_t cvdescriptorset::DescriptorSetLayout::GetConsecutiveDescriptorCountFromBinding(uint32_t binding) const { + // If binding is invalid we'll return 0 + uint32_t binding_count = 0; + auto bi_itr = binding_to_index_map_.find(binding); + while (bi_itr != binding_to_index_map_.end()) { + binding_count += bindings_[bi_itr->second].descriptorCount; + bi_itr++; + } + return binding_count; +} + // put all bindings into the given set void cvdescriptorset::DescriptorSetLayout::FillBindingSet(std::unordered_set<uint32_t> *binding_set) const { for (auto binding_index_pair : binding_to_index_map_) @@ -546,10 +561,21 @@ void cvdescriptorset::DescriptorSet::InvalidateBoundCmdBuffers() { } // Perform write update in given update struct void cvdescriptorset::DescriptorSet::PerformWriteUpdate(const VkWriteDescriptorSet *update) { - auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) + update->dstArrayElement; - // perform update - for (uint32_t di = 0; di < update->descriptorCount; ++di) { - descriptors_[start_idx + di]->WriteUpdate(update, di); + // Perform update on a per-binding basis as consecutive updates roll over to next binding + auto descriptors_remaining = update->descriptorCount; + auto binding_being_updated = update->dstBinding; + auto offset = update->dstArrayElement; + while (descriptors_remaining) { + uint32_t update_count = std::min(descriptors_remaining, GetDescriptorCountFromBinding(binding_being_updated)); + auto global_idx = p_layout_->GetGlobalStartIndexFromBinding(binding_being_updated) + offset; + // Loop over the updates for a single binding at a time + for (uint32_t di = 0; di < update_count; ++di) { + descriptors_[global_idx + di]->WriteUpdate(update, di); + } + // Roll over to next binding in case of consecutive update + descriptors_remaining -= update_count; + offset = 0; + binding_being_updated++; } if (update->descriptorCount) some_update_ = true; @@ -1169,14 +1195,15 @@ bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data *error_msg = error_str.str(); return false; } - if ((start_idx + update->descriptorCount) > p_layout_->GetTotalDescriptorCount()) { + if (update->descriptorCount > + (p_layout_->GetConsecutiveDescriptorCountFromBinding(update->dstBinding) - update->dstArrayElement)) { *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 - << " descriptors starting at binding offset of " << p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) - << " combined with update array element offset of " << update->dstArrayElement - << " oversteps the size of this descriptor set"; + << p_layout_->GetConsecutiveDescriptorCountFromBinding(update->dstBinding) + << " descriptors in that binding and all successive bindings of the set, but update of " + << update->descriptorCount << " descriptors combined with update array element offset of " + << update->dstArrayElement << " oversteps the available number of consecutive descriptors"; *error_msg = error_str.str(); return false; } |
