aboutsummaryrefslogtreecommitdiff
path: root/layers/descriptor_sets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layers/descriptor_sets.cpp')
-rw-r--r--layers/descriptor_sets.cpp341
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