diff options
Diffstat (limited to 'layers/descriptor_sets.cpp')
-rw-r--r-- | layers/descriptor_sets.cpp | 341 |
1 files changed, 173 insertions, 168 deletions
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp index 301cf014d..8dcdf8b44 100644 --- a/layers/descriptor_sets.cpp +++ b/layers/descriptor_sets.cpp @@ -318,7 +318,7 @@ bool cvdescriptorset::ValidateDescriptorSetLayoutCreateInfo( const uint32_t max_push_descriptors, const bool descriptor_indexing_ext, const VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features, const VkPhysicalDeviceInlineUniformBlockFeaturesEXT *inline_uniform_block_features, - const VkPhysicalDeviceInlineUniformBlockPropertiesEXT *inline_uniform_block_props) { + const VkPhysicalDeviceInlineUniformBlockPropertiesEXT *inline_uniform_block_props, const DeviceExtensions *device_extensions) { bool skip = false; std::unordered_set<uint32_t> bindings; uint64_t total_descriptors = 0; @@ -370,16 +370,24 @@ bool cvdescriptorset::ValidateDescriptorSetLayoutCreateInfo( } if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) { - if ((binding_info.descriptorCount % 4) != 0) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkDescriptorSetLayoutBinding-descriptorType-02209", - "descriptorCount =(%" PRIu32 ") must be a multiple of 4", binding_info.descriptorCount); - } - if (binding_info.descriptorCount > inline_uniform_block_props->maxInlineUniformBlockSize) { - skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, - "VUID-VkDescriptorSetLayoutBinding-descriptorType-02210", - "descriptorCount =(%" PRIu32 ") must be less than or equal to maxInlineUniformBlockSize", - binding_info.descriptorCount); + if (!device_extensions->vk_ext_inline_uniform_block) { + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 0, + "UNASSIGNED-Extension not enabled", + "Creating VkDescriptorSetLayout with descriptor type VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT " + "but extension %s is missing", + VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME); + } else { + if ((binding_info.descriptorCount % 4) != 0) { + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkDescriptorSetLayoutBinding-descriptorType-02209", + "descriptorCount =(%" PRIu32 ") must be a multiple of 4", binding_info.descriptorCount); + } + if (binding_info.descriptorCount > inline_uniform_block_props->maxInlineUniformBlockSize) { + skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + "VUID-VkDescriptorSetLayoutBinding-descriptorType-02210", + "descriptorCount =(%" PRIu32 ") must be less than or equal to maxInlineUniformBlockSize", + binding_info.descriptorCount); + } } } @@ -544,7 +552,8 @@ cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, const V pool_state_(nullptr), p_layout_(layout), state_data_(state_data), - variable_count_(variable_count) { + variable_count_(variable_count), + change_count_(0) { pool_state_ = state_data->GetDescriptorPoolState(pool); // Foreach binding, create default descriptors of given type descriptors_.reserve(p_layout_->GetTotalDescriptorCount()); @@ -630,7 +639,7 @@ static char const *StringDescriptorReqComponentType(descriptor_req req) { return "(none)"; } -static unsigned DescriptorRequirementsBitsFromFormat(VkFormat fmt) { +unsigned DescriptorRequirementsBitsFromFormat(VkFormat fmt) { if (FormatIsSInt(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_SINT; if (FormatIsUInt(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_UINT; if (FormatIsDepthAndStencil(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT | DESCRIPTOR_REQ_COMPONENT_TYPE_UINT; @@ -644,8 +653,8 @@ static unsigned DescriptorRequirementsBitsFromFormat(VkFormat fmt) { // that any update buffers are valid, and that any dynamic offsets are within the bounds of their buffers. // Return true if state is acceptable, or false and write an error message into error string bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const std::map<uint32_t, descriptor_req> &bindings, - const std::vector<uint32_t> &dynamic_offsets, CMD_BUFFER_STATE *cb_node, const char *caller, - std::string *error) { + const std::vector<uint32_t> &dynamic_offsets, const CMD_BUFFER_STATE *cb_node, + const char *caller, std::string *error) const { using DescriptorClass = cvdescriptorset::DescriptorClass; using BufferDescriptor = cvdescriptorset::BufferDescriptor; using ImageDescriptor = cvdescriptorset::ImageDescriptor; @@ -662,6 +671,14 @@ bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const st *error = error_str.str(); return false; } + + if (binding_it.GetDescriptorBindingFlags() & + (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT)) { + // Can't validate the descriptor because it may not have been updated, + // or the view could have been destroyed + continue; + } + // Copy the range, the end range is subject to update based on variable length descriptor arrays. cvdescriptorset::IndexRange index_range = binding_it.GetGlobalIndexRange(); auto array_idx = 0; // Track array idx if we're dealing with array descriptors @@ -675,11 +692,8 @@ bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const st uint32_t index = i - index_range.start; const auto *descriptor = descriptor_set->GetDescriptorFromGlobalIndex(i); - if ((binding_it.GetDescriptorBindingFlags() & - (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT)) || - descriptor->GetClass() == DescriptorClass::InlineUniform) { - // Can't validate the descriptor because it may not have been updated, - // or the view could have been destroyed + if (descriptor->GetClass() == DescriptorClass::InlineUniform) { + // Can't validate the descriptor because it may not have been updated. continue; } else if (!descriptor->updated) { std::stringstream error_str; @@ -760,55 +774,59 @@ bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const st *error = error_str.str(); return false; } - auto image_view_ci = image_view_state->create_info; + const auto &image_view_ci = image_view_state->create_info; - if ((reqs & DESCRIPTOR_REQ_ALL_VIEW_TYPE_BITS) && (~reqs & (1 << image_view_ci.viewType))) { - // bad view type - std::stringstream error_str; - error_str << "Descriptor in binding #" << binding << " index " << index - << " requires an image view of type " << StringDescriptorReqViewType(reqs) << " but got " - << string_VkImageViewType(image_view_ci.viewType) << "."; - *error = error_str.str(); - return false; - } + if (reqs & DESCRIPTOR_REQ_ALL_VIEW_TYPE_BITS) { + if (~reqs & (1 << image_view_ci.viewType)) { + // bad view type + std::stringstream error_str; + error_str << "Descriptor in binding #" << binding << " index " << index + << " requires an image view of type " << StringDescriptorReqViewType(reqs) << " but got " + << string_VkImageViewType(image_view_ci.viewType) << "."; + *error = error_str.str(); + return false; + } - auto format_bits = DescriptorRequirementsBitsFromFormat(image_view_ci.format); - if (!(reqs & format_bits)) { - // bad component type - std::stringstream error_str; - error_str << "Descriptor in binding #" << binding << " index " << index << " requires " - << StringDescriptorReqComponentType(reqs) << " component type, but bound descriptor format is " - << string_VkFormat(image_view_ci.format) << "."; - *error = error_str.str(); - return false; + if (!(reqs & image_view_state->descriptor_format_bits)) { + // bad component type + std::stringstream error_str; + error_str << "Descriptor in binding #" << binding << " index " << index << " requires " + << StringDescriptorReqComponentType(reqs) + << " component type, but bound descriptor format is " << string_VkFormat(image_view_ci.format) + << "."; + *error = error_str.str(); + return false; + } } - auto image_node = GetImageState(image_view_ci.image); - assert(image_node); - // Verify Image Layout - // No "invalid layout" VUID required for this call, since the optimal_layout parameter is UNDEFINED. - bool hit_error = false; - VerifyImageLayout(cb_node, image_node, image_view_state->normalized_subresource_range, - image_view_ci.subresourceRange.aspectMask, image_layout, VK_IMAGE_LAYOUT_UNDEFINED, caller, - kVUIDUndefined, "VUID-VkDescriptorImageInfo-imageLayout-00344", &hit_error); - if (hit_error) { - *error = - "Image layout specified at vkUpdateDescriptorSet* or vkCmdPushDescriptorSet* time " - "doesn't match actual image layout at time descriptor is used. See previous error callback for " - "specific details."; - return false; + if (!disabled.image_layout_validation) { + auto image_node = GetImageState(image_view_ci.image); + assert(image_node); + // Verify Image Layout + // No "invalid layout" VUID required for this call, since the optimal_layout parameter is UNDEFINED. + bool hit_error = false; + VerifyImageLayout(cb_node, image_node, image_view_state->normalized_subresource_range, + image_view_ci.subresourceRange.aspectMask, image_layout, VK_IMAGE_LAYOUT_UNDEFINED, + caller, kVUIDUndefined, "VUID-VkDescriptorImageInfo-imageLayout-00344", &hit_error); + if (hit_error) { + *error = + "Image layout specified at vkUpdateDescriptorSet* or vkCmdPushDescriptorSet* time " + "doesn't match actual image layout at time descriptor is used. See previous error callback for " + "specific details."; + return false; + } } // Verify Sample counts - if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) && image_node->createInfo.samples != VK_SAMPLE_COUNT_1_BIT) { + if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) && image_view_state->samples != VK_SAMPLE_COUNT_1_BIT) { std::stringstream error_str; error_str << "Descriptor in binding #" << binding << " index " << index << " requires bound image to have VK_SAMPLE_COUNT_1_BIT but got " - << string_VkSampleCountFlagBits(image_node->createInfo.samples) << "."; + << string_VkSampleCountFlagBits(image_view_state->samples) << "."; *error = error_str.str(); return false; } - if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) && image_node->createInfo.samples == VK_SAMPLE_COUNT_1_BIT) { + if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) && image_view_state->samples == VK_SAMPLE_COUNT_1_BIT) { std::stringstream error_str; error_str << "Descriptor in binding #" << binding << " index " << index << " requires bound image to have multiple samples, but got VK_SAMPLE_COUNT_1_BIT."; @@ -863,7 +881,7 @@ bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const st *error = error_str.str(); return false; } else { - SAMPLER_STATE *sampler_state = GetSamplerState(sampler); + const SAMPLER_STATE *sampler_state = GetSamplerState(sampler); if (sampler_state->samplerConversion && !descriptor->IsImmutableSampler()) { std::stringstream error_str; error_str << "sampler (" << sampler << ") in the descriptor set (" << descriptor_set->GetSet() @@ -879,49 +897,6 @@ bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const st return true; } -// For given bindings, place any update buffers or images into the passed-in unordered_sets -uint32_t cvdescriptorset::DescriptorSet::GetStorageUpdates(const std::map<uint32_t, descriptor_req> &bindings, - std::unordered_set<VkBuffer> *buffer_set, - std::unordered_set<VkImageView> *image_set) const { - auto num_updates = 0; - for (auto binding_pair : bindings) { - auto binding = binding_pair.first; - // If a binding doesn't exist, skip it - if (!p_layout_->HasBinding(binding)) { - continue; - } - uint32_t start_idx = p_layout_->GetGlobalIndexRangeFromBinding(binding).start; - if (descriptors_[start_idx]->IsStorage()) { - if (Image == descriptors_[start_idx]->descriptor_class) { - for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) { - if (descriptors_[start_idx + i]->updated) { - image_set->insert(static_cast<ImageDescriptor *>(descriptors_[start_idx + i].get())->GetImageView()); - num_updates++; - } - } - } else if (TexelBuffer == descriptors_[start_idx]->descriptor_class) { - for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) { - if (descriptors_[start_idx + i]->updated) { - auto bufferview = static_cast<TexelDescriptor *>(descriptors_[start_idx + i].get())->GetBufferView(); - auto bv_state = state_data_->GetBufferViewState(bufferview); - if (bv_state) { - buffer_set->insert(bv_state->create_info.buffer); - num_updates++; - } - } - } - } else if (GeneralBuffer == descriptors_[start_idx]->descriptor_class) { - for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) { - if (descriptors_[start_idx + i]->updated) { - buffer_set->insert(static_cast<BufferDescriptor *>(descriptors_[start_idx + i].get())->GetBuffer()); - num_updates++; - } - } - } - } - } - return num_updates; -} // Set is being deleted or updates so invalidate all bound cmd buffers void cvdescriptorset::DescriptorSet::InvalidateBoundCmdBuffers() { state_data_->InvalidateCommandBuffers(cb_bindings, VulkanTypedHandle(set_, kVulkanObjectTypeDescriptorSet)); @@ -954,7 +929,10 @@ void cvdescriptorset::DescriptorSet::PerformWriteUpdate(const VkWriteDescriptorS offset = 0; binding_being_updated++; } - if (update->descriptorCount) some_update_ = true; + if (update->descriptorCount) { + some_update_ = true; + change_count_++; + } if (!(p_layout_->GetDescriptorBindingFlagsFromBinding(update->dstBinding) & (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT))) { @@ -1172,6 +1150,7 @@ void cvdescriptorset::DescriptorSet::PerformCopyUpdate(const VkCopyDescriptorSet if (src->updated) { dst->CopyUpdate(src); some_update_ = true; + change_count_++; } else { dst->updated = false; } @@ -1190,14 +1169,27 @@ void cvdescriptorset::DescriptorSet::PerformCopyUpdate(const VkCopyDescriptorSet // TODO: Modify the UpdateDrawState virtural functions to *only* set initial layout and not change layouts // Prereq: This should be called for a set that has been confirmed to be active for the given cb_node, meaning it's going // to be used in a draw by the given cb_node -void cvdescriptorset::DescriptorSet::UpdateDrawState(CoreChecks *device_data, CMD_BUFFER_STATE *cb_node, +void cvdescriptorset::DescriptorSet::UpdateDrawState(ValidationStateTracker *device_data, CMD_BUFFER_STATE *cb_node, const std::map<uint32_t, descriptor_req> &binding_req_map) { - // bind cb to this descriptor set - cb_bindings.insert(cb_node); - // Add bindings for descriptor set, the set's pool, and individual objects in the set - cb_node->object_bindings.emplace(set_, kVulkanObjectTypeDescriptorSet); - pool_state_->cb_bindings.insert(cb_node); - cb_node->object_bindings.emplace(pool_state_->pool, kVulkanObjectTypeDescriptorPool); + if (!device_data->disabled.command_buffer_state) { + // bind cb to this descriptor set + // Add bindings for descriptor set, the set's pool, and individual objects in the set + auto inserted = cb_node->object_bindings.emplace(set_, kVulkanObjectTypeDescriptorSet); + if (inserted.second) { + cb_bindings.insert(cb_node); + auto inserted2 = cb_node->object_bindings.emplace(pool_state_->pool, kVulkanObjectTypeDescriptorPool); + if (inserted2.second) { + pool_state_->cb_bindings.insert(cb_node); + } + } + } + + // Descriptor UpdateDrawState functions do two things - associate resources to the command buffer, + // and call image layout validation callbacks. If both are disabled, skip the entire loop. + if (device_data->disabled.command_buffer_state && device_data->disabled.image_layout_validation) { + return; + } + // For the active slots, use set# to look up descriptorSet from boundDescriptorSets, and bind all of that descriptor set's // resources for (auto binding_req_pair : binding_req_map) { @@ -1214,47 +1206,34 @@ void cvdescriptorset::DescriptorSet::UpdateDrawState(CoreChecks *device_data, CM } } -void cvdescriptorset::DescriptorSet::FilterAndTrackOneBindingReq(const BindingReqMap::value_type &binding_req_pair, - const BindingReqMap &in_req, BindingReqMap *out_req, - TrackedBindings *bindings) { - assert(out_req); - assert(bindings); - const auto binding = binding_req_pair.first; - // Use insert and look at the boolean ("was inserted") in the returned pair to see if this is a new set member. - // Saves one hash lookup vs. find ... compare w/ end ... insert. - const auto it_bool_pair = bindings->insert(binding); - if (it_bool_pair.second) { - out_req->emplace(binding_req_pair); +void cvdescriptorset::DescriptorSet::FilterOneBindingReq(const BindingReqMap::value_type &binding_req_pair, BindingReqMap *out_req, + const TrackedBindings &bindings, uint32_t limit) { + if (bindings.size() < limit) { + const auto it = bindings.find(binding_req_pair.first); + if (it == bindings.cend()) out_req->emplace(binding_req_pair); } } -void cvdescriptorset::DescriptorSet::FilterAndTrackOneBindingReq(const BindingReqMap::value_type &binding_req_pair, - const BindingReqMap &in_req, BindingReqMap *out_req, - TrackedBindings *bindings, uint32_t limit) { - if (bindings->size() < limit) FilterAndTrackOneBindingReq(binding_req_pair, in_req, out_req, bindings); -} - -void cvdescriptorset::DescriptorSet::FilterAndTrackBindingReqs(CMD_BUFFER_STATE *cb_state, const BindingReqMap &in_req, - BindingReqMap *out_req) { - TrackedBindings &bound = cached_validation_[cb_state].command_binding_and_usage; - if (bound.size() == GetBindingCount()) { - return; // All bindings are bound, out req is empty - } - for (const auto &binding_req_pair : in_req) { - const auto binding = binding_req_pair.first; - // If a binding doesn't exist, or has already been bound, skip it - if (p_layout_->HasBinding(binding)) { - FilterAndTrackOneBindingReq(binding_req_pair, in_req, out_req, &bound); +void cvdescriptorset::DescriptorSet::FilterBindingReqs(const CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline, + const BindingReqMap &in_req, BindingReqMap *out_req) const { + // For const cleanliness we have to find in the maps... + const auto validated_it = cached_validation_.find(&cb_state); + if (validated_it == cached_validation_.cend()) { + // We have nothing validated, copy in to out + for (const auto &binding_req_pair : in_req) { + out_req->emplace(binding_req_pair); } + return; } -} + const auto &validated = validated_it->second; -void cvdescriptorset::DescriptorSet::FilterAndTrackBindingReqs(CMD_BUFFER_STATE *cb_state, PIPELINE_STATE *pipeline, - const BindingReqMap &in_req, BindingReqMap *out_req) { - auto &validated = cached_validation_[cb_state]; - auto &image_sample_val = validated.image_samplers[pipeline]; - auto *const dynamic_buffers = &validated.dynamic_buffers; - auto *const non_dynamic_buffers = &validated.non_dynamic_buffers; + const auto image_sample_version_it = validated.image_samplers.find(&pipeline); + const VersionedBindings *image_sample_version = nullptr; + if (image_sample_version_it != validated.image_samplers.cend()) { + image_sample_version = &(image_sample_version_it->second); + } + const auto &dynamic_buffers = validated.dynamic_buffers; + const auto &non_dynamic_buffers = validated.non_dynamic_buffers; const auto &stats = p_layout_->GetBindingTypeStats(); for (const auto &binding_req_pair : in_req) { auto binding = binding_req_pair.first; @@ -1266,22 +1245,55 @@ void cvdescriptorset::DescriptorSet::FilterAndTrackBindingReqs(CMD_BUFFER_STATE // If image_layout have changed , the image descriptors need to be validated against them. if ((layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || (layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { - FilterAndTrackOneBindingReq(binding_req_pair, in_req, out_req, dynamic_buffers, stats.dynamic_buffer_count); + FilterOneBindingReq(binding_req_pair, out_req, dynamic_buffers, stats.dynamic_buffer_count); } else if ((layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) || (layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)) { - FilterAndTrackOneBindingReq(binding_req_pair, in_req, out_req, non_dynamic_buffers, stats.non_dynamic_buffer_count); + FilterOneBindingReq(binding_req_pair, out_req, non_dynamic_buffers, stats.non_dynamic_buffer_count); } else { // This is rather crude, as the changed layouts may not impact the bound descriptors, // but the simple "versioning" is a simple "dirt" test. - auto &version = image_sample_val[binding]; // Take advantage of default construtor zero initialzing new entries - if (version != cb_state->image_layout_change_count) { - version = cb_state->image_layout_change_count; + bool stale = true; + if (image_sample_version) { + const auto version_it = image_sample_version->find(binding); + if (version_it != image_sample_version->cend() && (version_it->second == cb_state.image_layout_change_count)) { + stale = false; + } + } + if (stale) { out_req->emplace(binding_req_pair); } } } } +void cvdescriptorset::DescriptorSet::UpdateValidationCache(const CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline, + const BindingReqMap &updated_bindings) { + // For const cleanliness we have to find in the maps... + auto &validated = cached_validation_[&cb_state]; + + auto &image_sample_version = validated.image_samplers[&pipeline]; + auto &dynamic_buffers = validated.dynamic_buffers; + auto &non_dynamic_buffers = validated.non_dynamic_buffers; + for (const auto &binding_req_pair : updated_bindings) { + auto binding = binding_req_pair.first; + VkDescriptorSetLayoutBinding const *layout_binding = p_layout_->GetDescriptorSetLayoutBindingPtrFromBinding(binding); + if (!layout_binding) { + continue; + } + // Caching criteria differs per type. + if ((layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || + (layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { + dynamic_buffers.emplace(binding); + } else if ((layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) || + (layout_binding->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)) { + non_dynamic_buffers.emplace(binding); + } else { + // Save the layout change version... + image_sample_version[binding] = cb_state.image_layout_change_count; + } + } +} + cvdescriptorset::SamplerDescriptor::SamplerDescriptor(const VkSampler *immut) : sampler_(VK_NULL_HANDLE), immutable_(false) { updated = false; descriptor_class = PlainSampler; @@ -1529,7 +1541,7 @@ void cvdescriptorset::SamplerDescriptor::CopyUpdate(const Descriptor *src) { updated = true; } -void cvdescriptorset::SamplerDescriptor::UpdateDrawState(CoreChecks *dev_data, CMD_BUFFER_STATE *cb_node) { +void cvdescriptorset::SamplerDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) { if (!immutable_) { auto sampler_state = dev_data->GetSamplerState(sampler_); if (sampler_state) dev_data->AddCommandBufferBindingSampler(cb_node, sampler_state); @@ -1568,7 +1580,7 @@ void cvdescriptorset::ImageSamplerDescriptor::CopyUpdate(const Descriptor *src) image_layout_ = image_layout; } -void cvdescriptorset::ImageSamplerDescriptor::UpdateDrawState(CoreChecks *dev_data, CMD_BUFFER_STATE *cb_node) { +void cvdescriptorset::ImageSamplerDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) { // First add binding for any non-immutable sampler if (!immutable_) { auto sampler_state = dev_data->GetSamplerState(sampler_); @@ -1578,7 +1590,7 @@ void cvdescriptorset::ImageSamplerDescriptor::UpdateDrawState(CoreChecks *dev_da auto iv_state = dev_data->GetImageViewState(image_view_); if (iv_state) { dev_data->AddCommandBufferBindingImageView(cb_node, iv_state); - dev_data->SetImageViewInitialLayout(cb_node, *iv_state, image_layout_); + dev_data->CallSetImageViewInitialLayoutCallback(cb_node, *iv_state, image_layout_); } } @@ -1604,12 +1616,12 @@ void cvdescriptorset::ImageDescriptor::CopyUpdate(const Descriptor *src) { image_layout_ = image_layout; } -void cvdescriptorset::ImageDescriptor::UpdateDrawState(CoreChecks *dev_data, CMD_BUFFER_STATE *cb_node) { +void cvdescriptorset::ImageDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) { // Add binding for image auto iv_state = dev_data->GetImageViewState(image_view_); if (iv_state) { dev_data->AddCommandBufferBindingImageView(cb_node, iv_state); - dev_data->SetImageViewInitialLayout(cb_node, *iv_state, image_layout_); + dev_data->CallSetImageViewInitialLayoutCallback(cb_node, *iv_state, image_layout_); } } @@ -1642,7 +1654,7 @@ void cvdescriptorset::BufferDescriptor::CopyUpdate(const Descriptor *src) { range_ = buff_desc->range_; } -void cvdescriptorset::BufferDescriptor::UpdateDrawState(CoreChecks *dev_data, CMD_BUFFER_STATE *cb_node) { +void cvdescriptorset::BufferDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) { auto buffer_node = dev_data->GetBufferState(buffer_); if (buffer_node) dev_data->AddCommandBufferBindingBuffer(cb_node, buffer_node); } @@ -1663,7 +1675,7 @@ void cvdescriptorset::TexelDescriptor::CopyUpdate(const Descriptor *src) { buffer_view_ = static_cast<const TexelDescriptor *>(src)->buffer_view_; } -void cvdescriptorset::TexelDescriptor::UpdateDrawState(CoreChecks *dev_data, CMD_BUFFER_STATE *cb_node) { +void cvdescriptorset::TexelDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) { auto bv_state = dev_data->GetBufferViewState(buffer_view_); if (bv_state) { dev_data->AddCommandBufferBindingBufferView(cb_node, bv_state); @@ -2259,21 +2271,14 @@ void ValidationStateTracker::PerformAllocateDescriptorSets(const VkDescriptorSet } } -cvdescriptorset::PrefilterBindRequestMap::PrefilterBindRequestMap(cvdescriptorset::DescriptorSet &ds, const BindingReqMap &in_map, - CMD_BUFFER_STATE *cb_state) - : filtered_map_(), orig_map_(in_map) { - if (ds.GetTotalDescriptorCount() > kManyDescriptors_) { - filtered_map_.reset(new std::map<uint32_t, descriptor_req>()); - ds.FilterAndTrackBindingReqs(cb_state, orig_map_, filtered_map_.get()); - } -} -cvdescriptorset::PrefilterBindRequestMap::PrefilterBindRequestMap(cvdescriptorset::DescriptorSet &ds, const BindingReqMap &in_map, - CMD_BUFFER_STATE *cb_state, PIPELINE_STATE *pipeline) - : filtered_map_(), orig_map_(in_map) { - if (ds.GetTotalDescriptorCount() > kManyDescriptors_) { +const BindingReqMap &cvdescriptorset::PrefilterBindRequestMap::FilteredMap(const CMD_BUFFER_STATE &cb_state, + const PIPELINE_STATE &pipeline) { + if (IsManyDescriptors()) { filtered_map_.reset(new std::map<uint32_t, descriptor_req>()); - ds.FilterAndTrackBindingReqs(cb_state, pipeline, orig_map_, filtered_map_.get()); + descriptor_set_.FilterBindingReqs(cb_state, pipeline, orig_map_, filtered_map_.get()); + return *filtered_map_; } + return orig_map_; } // Starting at offset descriptor of given binding, parse over update_count |