blob: edd0ac2ca442c3730b44457b0593f9e2640c2d8e [file] [log] [blame]
sfricke-samsung691299b2021-01-01 20:48:48 -08001/* Copyright (c) 2015-2021 The Khronos Group Inc.
2 * Copyright (c) 2015-2021 Valve Corporation
3 * Copyright (c) 2015-2021 LunarG, Inc.
4 * Copyright (C) 2015-2021 Google Inc.
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06005 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Tobin Ehlis <tobine@google.com>
John Zulaufc483f442017-12-15 14:02:06 -070019 * John Zulauf <jzulauf@lunarg.com>
Jeremy Kniagere6827432020-04-01 09:05:56 -060020 * Jeremy Kniager <jeremyk@lunarg.com>
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060021 */
22
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -070023#include "chassis.h"
Mark Lobodzinski76d76662019-02-14 14:38:21 -070024#include "core_validation_error_enums.h"
25#include "core_validation.h"
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060026#include "descriptor_sets.h"
John Zulaufd47d0612018-02-16 13:00:34 -070027#include "hash_vk_types.h"
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060028#include "vk_enum_string_helper.h"
29#include "vk_safe_struct.h"
Jeff Bolzfdf96072018-04-10 14:32:18 -050030#include "vk_typemap_helper.h"
Tobin Ehlisc8266452017-04-07 12:20:30 -060031#include "buffer_validation.h"
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060032#include <sstream>
Mark Lobodzinski2eee5d82016-12-02 15:33:18 -070033#include <algorithm>
John Zulauff4c07882019-01-24 14:03:36 -070034#include <array>
John Zulauf1f8174b2018-02-16 12:58:37 -070035#include <memory>
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060036
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060037static DESCRIPTOR_POOL_STATE::TypeCountMap GetMaxTypeCounts(const VkDescriptorPoolCreateInfo *create_info) {
38 DESCRIPTOR_POOL_STATE::TypeCountMap counts;
39 // Collect maximums per descriptor type.
40 for (uint32_t i = 0; i < create_info->poolSizeCount; ++i) {
41 const auto &pool_size = create_info->pPoolSizes[i];
42 uint32_t type = static_cast<uint32_t>(pool_size.type);
43 // Same descriptor types can appear several times
44 counts[type] += pool_size.descriptorCount;
45 }
46 return counts;
47}
48
49DESCRIPTOR_POOL_STATE::DESCRIPTOR_POOL_STATE(ValidationStateTracker *dev, const VkDescriptorPool pool,
50 const VkDescriptorPoolCreateInfo *pCreateInfo)
51 : BASE_NODE(pool, kVulkanObjectTypeDescriptorPool),
52 dev_data(dev),
53 maxSets(pCreateInfo->maxSets),
54 availableSets(pCreateInfo->maxSets),
55 createInfo(pCreateInfo),
56 maxDescriptorTypeCount(GetMaxTypeCounts(pCreateInfo)),
57 availableDescriptorTypeCount(maxDescriptorTypeCount) {}
58
59void DESCRIPTOR_POOL_STATE::Allocate(const VkDescriptorSetAllocateInfo *alloc_info, const VkDescriptorSet *descriptor_sets,
60 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) {
61 // Account for sets and individual descriptors allocated from pool
62 availableSets -= alloc_info->descriptorSetCount;
63 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
64 availableDescriptorTypeCount[it->first] -= ds_data->required_descriptors_by_type.at(it->first);
65 }
66
67 const auto *variable_count_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(alloc_info->pNext);
68 bool variable_count_valid = variable_count_info && variable_count_info->descriptorSetCount == alloc_info->descriptorSetCount;
69
70 // Create tracking object for each descriptor set; insert into global map and the pool's set.
71 for (uint32_t i = 0; i < alloc_info->descriptorSetCount; i++) {
72 uint32_t variable_count = variable_count_valid ? variable_count_info->pDescriptorCounts[i] : 0;
73
74 auto new_ds = std::make_shared<cvdescriptorset::DescriptorSet>(descriptor_sets[i], this, ds_data->layout_nodes[i],
75 variable_count, dev_data);
76 sets.emplace(descriptor_sets[i], new_ds.get());
77 dev_data->setMap.emplace(descriptor_sets[i], std::move(new_ds));
78 }
79}
80
81void DESCRIPTOR_POOL_STATE::Free(uint32_t count, const VkDescriptorSet *descriptor_sets) {
82 // Update available descriptor sets in pool
83 availableSets += count;
84
85 // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap
86 for (uint32_t i = 0; i < count; ++i) {
87 if (descriptor_sets[i] != VK_NULL_HANDLE) {
88 auto iter = sets.find(descriptor_sets[i]);
89 assert(iter != sets.end());
90 auto *set_state = iter->second;
91 uint32_t type_index = 0, descriptor_count = 0;
92 for (uint32_t j = 0; j < set_state->GetBindingCount(); ++j) {
93 type_index = static_cast<uint32_t>(set_state->GetTypeFromIndex(j));
94 descriptor_count = set_state->GetDescriptorCountFromIndex(j);
95 availableDescriptorTypeCount[type_index] += descriptor_count;
96 }
97 set_state->Destroy();
98 dev_data->setMap.erase(iter->first);
99 sets.erase(iter);
100 }
101 }
102}
103
104void DESCRIPTOR_POOL_STATE::Reset() {
105 // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
106 for (auto entry : sets) {
107 entry.second->Destroy();
108 dev_data->setMap.erase(entry.first);
109 }
110 sets.clear();
111 // Reset available count for each type and available sets for this pool
112 availableDescriptorTypeCount = maxDescriptorTypeCount;
113 availableSets = maxSets;
114}
115
116void DESCRIPTOR_POOL_STATE::Destroy() {
117 Reset();
118 BASE_NODE::Destroy();
119}
120
Jeff Bolzfdf96072018-04-10 14:32:18 -0500121// ExtendedBinding collects a VkDescriptorSetLayoutBinding and any extended
122// state that comes from a different array/structure so they can stay together
123// while being sorted by binding number.
124struct ExtendedBinding {
Mike Schuchardt2df08912020-12-15 16:28:09 -0800125 ExtendedBinding(const VkDescriptorSetLayoutBinding *l, VkDescriptorBindingFlags f) : layout_binding(l), binding_flags(f) {}
Jeff Bolzfdf96072018-04-10 14:32:18 -0500126
127 const VkDescriptorSetLayoutBinding *layout_binding;
Mike Schuchardt2df08912020-12-15 16:28:09 -0800128 VkDescriptorBindingFlags binding_flags;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500129};
130
John Zulauf508d13a2018-01-05 15:10:34 -0700131struct BindingNumCmp {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500132 bool operator()(const ExtendedBinding &a, const ExtendedBinding &b) const {
133 return a.layout_binding->binding < b.layout_binding->binding;
John Zulauf508d13a2018-01-05 15:10:34 -0700134 }
135};
136
John Zulauf613fd982019-06-04 15:14:41 -0600137using DescriptorSet = cvdescriptorset::DescriptorSet;
John Zulauf4a015c92019-06-04 09:50:05 -0600138using DescriptorSetLayout = cvdescriptorset::DescriptorSetLayout;
John Zulaufd47d0612018-02-16 13:00:34 -0700139using DescriptorSetLayoutDef = cvdescriptorset::DescriptorSetLayoutDef;
140using DescriptorSetLayoutId = cvdescriptorset::DescriptorSetLayoutId;
141
John Zulauf34ebf272018-02-16 13:08:47 -0700142// Canonical dictionary of DescriptorSetLayoutDef (without any handle/device specific information)
143cvdescriptorset::DescriptorSetLayoutDict descriptor_set_layout_dict;
John Zulaufd47d0612018-02-16 13:00:34 -0700144
Shannon McPhersonc06c33d2018-06-28 17:21:12 -0600145DescriptorSetLayoutId GetCanonicalId(const VkDescriptorSetLayoutCreateInfo *p_create_info) {
John Zulauf34ebf272018-02-16 13:08:47 -0700146 return descriptor_set_layout_dict.look_up(DescriptorSetLayoutDef(p_create_info));
John Zulaufd47d0612018-02-16 13:00:34 -0700147}
John Zulauf34ebf272018-02-16 13:08:47 -0700148
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600149// Construct DescriptorSetLayout instance from given create info
John Zulauf48a6a702017-12-22 17:14:54 -0700150// Proactively reserve and resize as possible, as the reallocation was visible in profiling
John Zulauf1f8174b2018-02-16 12:58:37 -0700151cvdescriptorset::DescriptorSetLayoutDef::DescriptorSetLayoutDef(const VkDescriptorSetLayoutCreateInfo *p_create_info)
152 : flags_(p_create_info->flags), binding_count_(0), descriptor_count_(0), dynamic_descriptor_count_(0) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700153 const auto *flags_create_info = LvlFindInChain<VkDescriptorSetLayoutBindingFlagsCreateInfo>(p_create_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500154
sfricke-samsung0d00aed2021-03-08 23:31:17 -0800155 binding_type_stats_ = {0, 0};
Jeff Bolzfdf96072018-04-10 14:32:18 -0500156 std::set<ExtendedBinding, BindingNumCmp> sorted_bindings;
John Zulauf508d13a2018-01-05 15:10:34 -0700157 const uint32_t input_bindings_count = p_create_info->bindingCount;
158 // Sort the input bindings in binding number order, eliminating duplicates
159 for (uint32_t i = 0; i < input_bindings_count; i++) {
Mike Schuchardt2df08912020-12-15 16:28:09 -0800160 VkDescriptorBindingFlags flags = 0;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500161 if (flags_create_info && flags_create_info->bindingCount == p_create_info->bindingCount) {
162 flags = flags_create_info->pBindingFlags[i];
163 }
Jeremy Gebbenfc6f8152021-03-18 16:58:55 -0600164 sorted_bindings.emplace(p_create_info->pBindings + i, flags);
John Zulaufb6d71202017-12-22 16:47:09 -0700165 }
166
ziga-lunargd67b5f52021-10-16 23:52:59 +0200167 const auto *mutable_descriptor_type_create_info = LvlFindInChain<VkMutableDescriptorTypeCreateInfoVALVE>(p_create_info->pNext);
168 if (mutable_descriptor_type_create_info) {
169 mutable_types_.resize(mutable_descriptor_type_create_info->mutableDescriptorTypeListCount);
170 for (uint32_t i = 0; i < mutable_descriptor_type_create_info->mutableDescriptorTypeListCount; ++i) {
171 const auto &list = mutable_descriptor_type_create_info->pMutableDescriptorTypeLists[i];
172 mutable_types_[i].reserve(list.descriptorTypeCount);
173 for (uint32_t j = 0; j < list.descriptorTypeCount; ++j) {
174 mutable_types_[i].push_back(list.pDescriptorTypes[j]);
175 }
176 }
177 }
178
John Zulaufb6d71202017-12-22 16:47:09 -0700179 // Store the create info in the sorted order from above
John Zulauf508d13a2018-01-05 15:10:34 -0700180 uint32_t index = 0;
181 binding_count_ = static_cast<uint32_t>(sorted_bindings.size());
182 bindings_.reserve(binding_count_);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500183 binding_flags_.reserve(binding_count_);
John Zulauf508d13a2018-01-05 15:10:34 -0700184 binding_to_index_map_.reserve(binding_count_);
John Zulauf79f06582021-02-27 18:38:39 -0700185 for (const auto &input_binding : sorted_bindings) {
John Zulauf508d13a2018-01-05 15:10:34 -0700186 // Add to binding and map, s.t. it is robust to invalid duplication of binding_num
Jeff Bolzfdf96072018-04-10 14:32:18 -0500187 const auto binding_num = input_binding.layout_binding->binding;
John Zulauf508d13a2018-01-05 15:10:34 -0700188 binding_to_index_map_[binding_num] = index++;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500189 bindings_.emplace_back(input_binding.layout_binding);
John Zulauf508d13a2018-01-05 15:10:34 -0700190 auto &binding_info = bindings_.back();
Jeff Bolzfdf96072018-04-10 14:32:18 -0500191 binding_flags_.emplace_back(input_binding.binding_flags);
John Zulauf508d13a2018-01-05 15:10:34 -0700192
John Zulaufb6d71202017-12-22 16:47:09 -0700193 descriptor_count_ += binding_info.descriptorCount;
194 if (binding_info.descriptorCount > 0) {
195 non_empty_bindings_.insert(binding_num);
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700196 }
John Zulaufb6d71202017-12-22 16:47:09 -0700197
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800198 if (IsDynamicDescriptor(binding_info.descriptorType)) {
sfricke-samsung0d00aed2021-03-08 23:31:17 -0800199 dynamic_descriptor_count_ += binding_info.descriptorCount;
200 }
201
202 // Get stats depending on descriptor type for caching later
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800203 if (IsBufferDescriptor(binding_info.descriptorType)) {
204 if (IsDynamicDescriptor(binding_info.descriptorType)) {
205 binding_type_stats_.dynamic_buffer_count++;
206 } else {
207 binding_type_stats_.non_dynamic_buffer_count++;
208 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600209 }
210 }
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700211 assert(bindings_.size() == binding_count_);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500212 assert(binding_flags_.size() == binding_count_);
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700213 uint32_t global_index = 0;
John Zulauf7705bfc2019-06-10 09:52:04 -0600214 global_index_range_.reserve(binding_count_);
215 // Vector order is finalized so build vectors of descriptors and dynamic offsets by binding index
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700216 for (uint32_t i = 0; i < binding_count_; ++i) {
John Zulaufc483f442017-12-15 14:02:06 -0700217 auto final_index = global_index + bindings_[i].descriptorCount;
John Zulauf7705bfc2019-06-10 09:52:04 -0600218 global_index_range_.emplace_back(global_index, final_index);
John Zulaufc483f442017-12-15 14:02:06 -0700219 global_index = final_index;
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700220 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600221}
Tobin Ehlis154c2692016-10-25 09:36:53 -0600222
John Zulaufd47d0612018-02-16 13:00:34 -0700223size_t cvdescriptorset::DescriptorSetLayoutDef::hash() const {
224 hash_util::HashCombiner hc;
225 hc << flags_;
226 hc.Combine(bindings_);
John Zulauf223b69d2018-11-09 16:00:59 -0700227 hc.Combine(binding_flags_);
John Zulaufd47d0612018-02-16 13:00:34 -0700228 return hc.Value();
229}
230//
231
John Zulauf1f8174b2018-02-16 12:58:37 -0700232// Return valid index or "end" i.e. binding_count_;
233// The asserts in "Get" are reduced to the set where no valid answer(like null or 0) could be given
234// Common code for all binding lookups.
235uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetIndexFromBinding(uint32_t binding) const {
236 const auto &bi_itr = binding_to_index_map_.find(binding);
237 if (bi_itr != binding_to_index_map_.cend()) return bi_itr->second;
238 return GetBindingCount();
239}
240VkDescriptorSetLayoutBinding const *cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorSetLayoutBindingPtrFromIndex(
241 const uint32_t index) const {
242 if (index >= bindings_.size()) return nullptr;
243 return bindings_[index].ptr();
244}
245// Return descriptorCount for given index, 0 if index is unavailable
246uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorCountFromIndex(const uint32_t index) const {
247 if (index >= bindings_.size()) return 0;
248 return bindings_[index].descriptorCount;
249}
250// For the given index, return descriptorType
251VkDescriptorType cvdescriptorset::DescriptorSetLayoutDef::GetTypeFromIndex(const uint32_t index) const {
252 assert(index < bindings_.size());
253 if (index < bindings_.size()) return bindings_[index].descriptorType;
254 return VK_DESCRIPTOR_TYPE_MAX_ENUM;
255}
256// For the given index, return stageFlags
257VkShaderStageFlags cvdescriptorset::DescriptorSetLayoutDef::GetStageFlagsFromIndex(const uint32_t index) const {
258 assert(index < bindings_.size());
259 if (index < bindings_.size()) return bindings_[index].stageFlags;
260 return VkShaderStageFlags(0);
261}
Jeff Bolzfdf96072018-04-10 14:32:18 -0500262// Return binding flags for given index, 0 if index is unavailable
Mike Schuchardt2df08912020-12-15 16:28:09 -0800263VkDescriptorBindingFlags cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorBindingFlagsFromIndex(const uint32_t index) const {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500264 if (index >= binding_flags_.size()) return 0;
265 return binding_flags_[index];
266}
John Zulauf1f8174b2018-02-16 12:58:37 -0700267
John Zulauf7705bfc2019-06-10 09:52:04 -0600268const cvdescriptorset::IndexRange &cvdescriptorset::DescriptorSetLayoutDef::GetGlobalIndexRangeFromIndex(uint32_t index) const {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700269 const static IndexRange k_invalid_range = {0xFFFFFFFF, 0xFFFFFFFF};
270 if (index >= binding_flags_.size()) return k_invalid_range;
John Zulauf7705bfc2019-06-10 09:52:04 -0600271 return global_index_range_[index];
John Zulauf1f8174b2018-02-16 12:58:37 -0700272}
273
John Zulauf7705bfc2019-06-10 09:52:04 -0600274// For the given binding, return the global index range (half open)
275// As start and end are often needed in pairs, get both with a single lookup.
John Zulauf1f8174b2018-02-16 12:58:37 -0700276const cvdescriptorset::IndexRange &cvdescriptorset::DescriptorSetLayoutDef::GetGlobalIndexRangeFromBinding(
277 const uint32_t binding) const {
John Zulauf7705bfc2019-06-10 09:52:04 -0600278 uint32_t index = GetIndexFromBinding(binding);
279 return GetGlobalIndexRangeFromIndex(index);
John Zulauf1f8174b2018-02-16 12:58:37 -0700280}
281
282// For given binding, return ptr to ImmutableSampler array
283VkSampler const *cvdescriptorset::DescriptorSetLayoutDef::GetImmutableSamplerPtrFromBinding(const uint32_t binding) const {
284 const auto &bi_itr = binding_to_index_map_.find(binding);
285 if (bi_itr != binding_to_index_map_.end()) {
286 return bindings_[bi_itr->second].pImmutableSamplers;
287 }
288 return nullptr;
289}
290// Move to next valid binding having a non-zero binding count
291uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetNextValidBinding(const uint32_t binding) const {
292 auto it = non_empty_bindings_.upper_bound(binding);
293 assert(it != non_empty_bindings_.cend());
294 if (it != non_empty_bindings_.cend()) return *it;
295 return GetMaxBinding() + 1;
296}
297// For given index, return ptr to ImmutableSampler array
298VkSampler const *cvdescriptorset::DescriptorSetLayoutDef::GetImmutableSamplerPtrFromIndex(const uint32_t index) const {
299 if (index < bindings_.size()) {
300 return bindings_[index].pImmutableSamplers;
301 }
302 return nullptr;
303}
John Zulauf9ce3b252019-06-06 15:20:22 -0600304
ziga-lunargd67b5f52021-10-16 23:52:59 +0200305bool cvdescriptorset::DescriptorSetLayoutDef::IsTypeMutable(const VkDescriptorType type, uint32_t binding) const {
306 if (binding < mutable_types_.size()) {
307 if (mutable_types_[binding].size() > 0) {
308 for (const auto mutable_type : mutable_types_[binding]) {
309 if (type == mutable_type) {
310 return true;
311 }
312 }
313 return false;
314 }
315 }
316 // If mutableDescriptorTypeListCount is zero or if VkMutableDescriptorTypeCreateInfoVALVE structure is not included in the pNext
317 // chain, the VkMutableDescriptorTypeListVALVE for each element is considered to be zero or NULL for each member.
318 return false;
319}
320
ziga-lunarge5d28542021-10-24 21:14:25 +0200321const std::vector<VkDescriptorType> &cvdescriptorset::DescriptorSetLayoutDef::GetMutableTypes(uint32_t binding) const {
322 if (binding >= mutable_types_.size()) {
323 static const std::vector<VkDescriptorType> empty = {};
324 return empty;
325 }
326 return mutable_types_[binding];
327}
328
John Zulauf9ce3b252019-06-06 15:20:22 -0600329// If our layout is compatible with rh_ds_layout, return true.
330bool cvdescriptorset::DescriptorSetLayout::IsCompatible(DescriptorSetLayout const *rh_ds_layout) const {
331 bool compatible = (this == rh_ds_layout) || (GetLayoutDef() == rh_ds_layout->GetLayoutDef());
332 return compatible;
333}
John Zulauf1f8174b2018-02-16 12:58:37 -0700334
John Zulauff43695f2019-09-13 17:56:26 -0600335// TODO: Find a way to add smarts to the autogenerated version of this
336static std::string smart_string_VkShaderStageFlags(VkShaderStageFlags stage_flags) {
337 if (stage_flags == VK_SHADER_STAGE_ALL) {
338 return string_VkShaderStageFlagBits(VK_SHADER_STAGE_ALL);
339 }
340
341 return string_VkShaderStageFlags(stage_flags);
342}
343
344// If our layout is compatible with bound_dsl, return true,
345// else return false and fill in error_msg will description of what causes incompatibility
346bool cvdescriptorset::VerifySetLayoutCompatibility(const debug_report_data *report_data, DescriptorSetLayout const *layout_dsl,
347 DescriptorSetLayout const *bound_dsl, std::string *error_msg) {
348 // Short circuit the detailed check.
349 if (layout_dsl->IsCompatible(bound_dsl)) return true;
350
351 // Do a detailed compatibility check of this lhs def (referenced by layout_dsl), vs. the rhs (layout and def)
John Zulauf9ce3b252019-06-06 15:20:22 -0600352 // Should only be run if trivial accept has failed, and in that context should return false.
John Zulauff43695f2019-09-13 17:56:26 -0600353 VkDescriptorSetLayout layout_dsl_handle = layout_dsl->GetDescriptorSetLayout();
354 VkDescriptorSetLayout bound_dsl_handle = bound_dsl->GetDescriptorSetLayout();
355 DescriptorSetLayoutDef const *layout_ds_layout_def = layout_dsl->GetLayoutDef();
356 DescriptorSetLayoutDef const *bound_ds_layout_def = bound_dsl->GetLayoutDef();
John Zulauf9ce3b252019-06-06 15:20:22 -0600357
358 // Check descriptor counts
John Zulauff43695f2019-09-13 17:56:26 -0600359 const auto bound_total_count = bound_ds_layout_def->GetTotalDescriptorCount();
360 if (layout_ds_layout_def->GetTotalDescriptorCount() != bound_ds_layout_def->GetTotalDescriptorCount()) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700361 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600362 error_str << report_data->FormatHandle(layout_dsl_handle) << " from pipeline layout has "
363 << layout_ds_layout_def->GetTotalDescriptorCount() << " total descriptors, but "
364 << report_data->FormatHandle(bound_dsl_handle) << ", which is bound, has " << bound_total_count
365 << " total descriptors.";
John Zulauf1f8174b2018-02-16 12:58:37 -0700366 *error_msg = error_str.str();
367 return false; // trivial fail case
368 }
John Zulaufd47d0612018-02-16 13:00:34 -0700369
John Zulauf1f8174b2018-02-16 12:58:37 -0700370 // Descriptor counts match so need to go through bindings one-by-one
371 // and verify that type and stageFlags match
John Zulauff43695f2019-09-13 17:56:26 -0600372 for (const auto &layout_binding : layout_ds_layout_def->GetBindings()) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700373 // TODO : Do we also need to check immutable samplers?
John Zulauff43695f2019-09-13 17:56:26 -0600374 const auto bound_binding = bound_ds_layout_def->GetBindingInfoFromBinding(layout_binding.binding);
375 if (layout_binding.descriptorCount != bound_binding->descriptorCount) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700376 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600377 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
378 << " from pipeline layout has a descriptorCount of " << layout_binding.descriptorCount << " but binding "
379 << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
380 << ", which is bound, has a descriptorCount of " << bound_binding->descriptorCount;
John Zulauf1f8174b2018-02-16 12:58:37 -0700381 *error_msg = error_str.str();
382 return false;
John Zulauff43695f2019-09-13 17:56:26 -0600383 } else if (layout_binding.descriptorType != bound_binding->descriptorType) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700384 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600385 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
386 << " from pipeline layout is type '" << string_VkDescriptorType(layout_binding.descriptorType)
387 << "' but binding " << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
388 << ", which is bound, is type '" << string_VkDescriptorType(bound_binding->descriptorType) << "'";
John Zulauf1f8174b2018-02-16 12:58:37 -0700389 *error_msg = error_str.str();
390 return false;
John Zulauff43695f2019-09-13 17:56:26 -0600391 } else if (layout_binding.stageFlags != bound_binding->stageFlags) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700392 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600393 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
394 << " from pipeline layout has stageFlags " << smart_string_VkShaderStageFlags(layout_binding.stageFlags)
395 << " but binding " << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
396 << ", which is bound, has stageFlags " << smart_string_VkShaderStageFlags(bound_binding->stageFlags);
John Zulauf1f8174b2018-02-16 12:58:37 -0700397 *error_msg = error_str.str();
398 return false;
399 }
400 }
Tony-LunarG692b8b42019-09-30 16:07:26 -0600401
402 const auto &ds_layout_flags = layout_ds_layout_def->GetBindingFlags();
403 const auto &bound_layout_flags = bound_ds_layout_def->GetBindingFlags();
404 if (bound_layout_flags != ds_layout_flags) {
405 std::stringstream error_str;
406 assert(ds_layout_flags.size() == bound_layout_flags.size());
407 size_t i;
408 for (i = 0; i < ds_layout_flags.size(); i++) {
409 if (ds_layout_flags[i] != bound_layout_flags[i]) break;
410 }
411 error_str << report_data->FormatHandle(layout_dsl_handle)
412 << " from pipeline layout does not have the same binding flags at binding " << i << " ( "
413 << string_VkDescriptorBindingFlagsEXT(ds_layout_flags[i]) << " ) as "
414 << report_data->FormatHandle(bound_dsl_handle) << " ( "
415 << string_VkDescriptorBindingFlagsEXT(bound_layout_flags[i]) << " ), which is bound";
416 *error_msg = error_str.str();
417 return false;
418 }
419
John Zulauf9ce3b252019-06-06 15:20:22 -0600420 // No detailed check should succeed if the trivial check failed -- or the dictionary has failed somehow.
421 bool compatible = true;
422 assert(!compatible);
423 return compatible;
John Zulauf1f8174b2018-02-16 12:58:37 -0700424}
425
426bool cvdescriptorset::DescriptorSetLayoutDef::IsNextBindingConsistent(const uint32_t binding) const {
427 if (!binding_to_index_map_.count(binding + 1)) return false;
428 auto const &bi_itr = binding_to_index_map_.find(binding);
429 if (bi_itr != binding_to_index_map_.end()) {
430 const auto &next_bi_itr = binding_to_index_map_.find(binding + 1);
431 if (next_bi_itr != binding_to_index_map_.end()) {
432 auto type = bindings_[bi_itr->second].descriptorType;
433 auto stage_flags = bindings_[bi_itr->second].stageFlags;
434 auto immut_samp = bindings_[bi_itr->second].pImmutableSamplers ? true : false;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500435 auto flags = binding_flags_[bi_itr->second];
John Zulauf1f8174b2018-02-16 12:58:37 -0700436 if ((type != bindings_[next_bi_itr->second].descriptorType) ||
437 (stage_flags != bindings_[next_bi_itr->second].stageFlags) ||
Jeff Bolzfdf96072018-04-10 14:32:18 -0500438 (immut_samp != (bindings_[next_bi_itr->second].pImmutableSamplers ? true : false)) ||
439 (flags != binding_flags_[next_bi_itr->second])) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700440 return false;
441 }
442 return true;
443 }
444 }
445 return false;
446}
John Zulauf1f8174b2018-02-16 12:58:37 -0700447
448// The DescriptorSetLayout stores the per handle data for a descriptor set layout, and references the common defintion for the
449// handle invariant portion
450cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *p_create_info,
451 const VkDescriptorSetLayout layout)
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600452 : BASE_NODE(layout, kVulkanObjectTypeDescriptorSetLayout), layout_id_(GetCanonicalId(p_create_info)) {}
John Zulauf1f8174b2018-02-16 12:58:37 -0700453
Tobin Ehlis154c2692016-10-25 09:36:53 -0600454// Validate descriptor set layout create info
John Zulaufd9435c32019-06-05 15:55:36 -0600455bool cvdescriptorset::ValidateDescriptorSetLayoutCreateInfo(
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700456 const ValidationObject *val_obj, const VkDescriptorSetLayoutCreateInfo *create_info, const bool push_descriptor_ext,
Jeff Bolzfdf96072018-04-10 14:32:18 -0500457 const uint32_t max_push_descriptors, const bool descriptor_indexing_ext,
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700458 const VkPhysicalDeviceVulkan12Features *core12_features,
Jeff Bolze54ae892018-09-08 12:16:29 -0500459 const VkPhysicalDeviceInlineUniformBlockFeaturesEXT *inline_uniform_block_features,
ziga-lunarg637356a2021-07-19 12:36:34 +0200460 const VkPhysicalDeviceInlineUniformBlockPropertiesEXT *inline_uniform_block_props,
461 const VkPhysicalDeviceAccelerationStructureFeaturesKHR *acceleration_structure_features,
462 const DeviceExtensions *device_extensions) {
Tobin Ehlis154c2692016-10-25 09:36:53 -0600463 bool skip = false;
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700464 layer_data::unordered_set<uint32_t> bindings;
John Zulauf0fdeab32018-01-23 11:27:35 -0700465 uint64_t total_descriptors = 0;
466
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700467 const auto *flags_create_info = LvlFindInChain<VkDescriptorSetLayoutBindingFlagsCreateInfo>(create_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500468
469 const bool push_descriptor_set = !!(create_info->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
John Zulauf0fdeab32018-01-23 11:27:35 -0700470 if (push_descriptor_set && !push_descriptor_ext) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800471 skip |= val_obj->LogError(
472 val_obj->device, kVUID_Core_DrawState_ExtensionNotEnabled,
473 "vkCreateDescriptorSetLayout(): Attempted to use %s in %s but its required extension %s has not been enabled.\n",
474 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR", "VkDescriptorSetLayoutCreateInfo::flags",
475 VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
John Zulauf0fdeab32018-01-23 11:27:35 -0700476 }
477
Mike Schuchardt2df08912020-12-15 16:28:09 -0800478 const bool update_after_bind_set = !!(create_info->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500479 if (update_after_bind_set && !descriptor_indexing_ext) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800480 skip |= val_obj->LogError(
481 val_obj->device, kVUID_Core_DrawState_ExtensionNotEnabled,
482 "vkCreateDescriptorSetLayout(): Attemped to use %s in %s but its required extension %s has not been enabled.\n",
483 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT", "VkDescriptorSetLayoutCreateInfo::flags",
484 VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500485 }
486
John Zulauf0fdeab32018-01-23 11:27:35 -0700487 auto valid_type = [push_descriptor_set](const VkDescriptorType type) {
488 return !push_descriptor_set ||
Dave Houlton142c4cb2018-10-17 15:04:41 -0600489 ((type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) && (type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) &&
Jeff Bolze54ae892018-09-08 12:16:29 -0500490 (type != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT));
John Zulauf0fdeab32018-01-23 11:27:35 -0700491 };
492
Jeff Bolzfdf96072018-04-10 14:32:18 -0500493 uint32_t max_binding = 0;
494
ziga-lunarg185ef282021-07-19 13:13:28 +0200495 uint32_t update_after_bind = create_info->bindingCount;
496 uint32_t uniform_buffer_dynamic = create_info->bindingCount;
497 uint32_t storage_buffer_dynamic = create_info->bindingCount;
498
Tobin Ehlis154c2692016-10-25 09:36:53 -0600499 for (uint32_t i = 0; i < create_info->bindingCount; ++i) {
John Zulauf0fdeab32018-01-23 11:27:35 -0700500 const auto &binding_info = create_info->pBindings[i];
Jeff Bolzfdf96072018-04-10 14:32:18 -0500501 max_binding = std::max(max_binding, binding_info.binding);
502
John Zulauf0fdeab32018-01-23 11:27:35 -0700503 if (!bindings.insert(binding_info.binding).second) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700504 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-binding-00279",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800505 "vkCreateDescriptorSetLayout(): pBindings[%u] has duplicated binding number (%u).", i,
506 binding_info.binding);
Tobin Ehlis154c2692016-10-25 09:36:53 -0600507 }
John Zulauf0fdeab32018-01-23 11:27:35 -0700508 if (!valid_type(binding_info.descriptorType)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700509 skip |= val_obj->LogError(val_obj->device,
510 (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
511 ? "VUID-VkDescriptorSetLayoutCreateInfo-flags-02208"
512 : "VUID-VkDescriptorSetLayoutCreateInfo-flags-00280",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800513 "vkCreateDescriptorSetLayout(): pBindings[%u] has invalid type %s , for push descriptors.", i,
514 string_VkDescriptorType(binding_info.descriptorType));
John Zulauf0fdeab32018-01-23 11:27:35 -0700515 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500516
517 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
sfricke-samsungc1e27c32021-01-16 09:32:49 -0800518 if (!inline_uniform_block_features->inlineUniformBlock) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800519 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-04604",
520 "vkCreateDescriptorSetLayout(): pBindings[%u] is creating VkDescriptorSetLayout with "
521 "descriptor type VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT "
Jeremy Gebbenda6b48f2021-05-13 10:46:18 -0600522 "but the inlineUniformBlock feature is not enabled",
523 i);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600524 } else {
525 if ((binding_info.descriptorCount % 4) != 0) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800526 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02209",
527 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorCount =(%" PRIu32
528 ") but must be a multiple of 4",
529 i, binding_info.descriptorCount);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600530 }
531 if (binding_info.descriptorCount > inline_uniform_block_props->maxInlineUniformBlockSize) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700532 skip |=
533 val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02210",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800534 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorCount =(%" PRIu32
535 ") but must be less than or equal to maxInlineUniformBlockSize (%u)",
536 i, binding_info.descriptorCount, inline_uniform_block_props->maxInlineUniformBlockSize);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600537 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500538 }
ziga-lunarg185ef282021-07-19 13:13:28 +0200539 } else if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
540 uniform_buffer_dynamic = i;
541 } else if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
542 storage_buffer_dynamic = i;
Jeff Bolze54ae892018-09-08 12:16:29 -0500543 }
544
Tony-LunarG7337b312020-04-15 16:40:25 -0600545 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
546 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
sfricke-samsung45996a42021-09-16 13:45:27 -0700547 binding_info.pImmutableSamplers && IsExtEnabled(device_extensions->vk_ext_custom_border_color)) {
Tony-LunarG7337b312020-04-15 16:40:25 -0600548 const CoreChecks *core_checks = reinterpret_cast<const CoreChecks *>(val_obj);
549 for (uint32_t j = 0; j < binding_info.descriptorCount; j++) {
550 const SAMPLER_STATE *sampler_state = core_checks->GetSamplerState(binding_info.pImmutableSamplers[j]);
551 if (sampler_state && (sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
552 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800553 skip |= val_obj->LogError(
554 val_obj->device, "VUID-VkDescriptorSetLayoutBinding-pImmutableSamplers-04009",
Jeremy Gebbenda6b48f2021-05-13 10:46:18 -0600555 "vkCreateDescriptorSetLayout(): pBindings[%u].pImmutableSamplers[%u] has VkSampler %s"
sfricke-samsungbda4a852021-03-06 20:58:01 -0800556 " presented as immutable has a custom border color",
Jeremy Gebbenda6b48f2021-05-13 10:46:18 -0600557 i, j, val_obj->report_data->FormatHandle(binding_info.pImmutableSamplers[j]).c_str());
Tony-LunarG7337b312020-04-15 16:40:25 -0600558 }
559 }
560 }
561
ziga-lunarg6d770792021-07-19 11:27:18 +0200562 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE && binding_info.pImmutableSamplers != nullptr) {
563 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-04605",
564 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorType "
565 "VK_DESCRIPTOR_TYPE_MUTABLE_VALVE but pImmutableSamplers is not NULL.",
566 i);
567 }
568
John Zulauf0fdeab32018-01-23 11:27:35 -0700569 total_descriptors += binding_info.descriptorCount;
Tobin Ehlis154c2692016-10-25 09:36:53 -0600570 }
John Zulauf0fdeab32018-01-23 11:27:35 -0700571
Jeff Bolzfdf96072018-04-10 14:32:18 -0500572 if (flags_create_info) {
573 if (flags_create_info->bindingCount != 0 && flags_create_info->bindingCount != create_info->bindingCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700574 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-bindingCount-03002",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800575 "vkCreateDescriptorSetLayout(): VkDescriptorSetLayoutCreateInfo::bindingCount (%d) != "
Mike Schuchardt2df08912020-12-15 16:28:09 -0800576 "VkDescriptorSetLayoutBindingFlagsCreateInfo::bindingCount (%d)",
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700577 create_info->bindingCount, flags_create_info->bindingCount);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500578 }
579
580 if (flags_create_info->bindingCount == create_info->bindingCount) {
581 for (uint32_t i = 0; i < create_info->bindingCount; ++i) {
582 const auto &binding_info = create_info->pBindings[i];
583
Mike Schuchardt2df08912020-12-15 16:28:09 -0800584 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT) {
ziga-lunarg185ef282021-07-19 13:13:28 +0200585 update_after_bind = i;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500586 if (!update_after_bind_set) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700587 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-flags-03000",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800588 "vkCreateDescriptorSetLayout(): pBindings[%u] does not have "
589 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT.",
590 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500591 }
592
593 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700594 !core12_features->descriptorBindingUniformBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800595 skip |= val_obj->LogError(
596 val_obj->device,
597 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
598 "descriptorBindingUniformBufferUpdateAfterBind-03005",
599 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
600 "for %s since descriptorBindingUniformBufferUpdateAfterBind is not enabled.",
601 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500602 }
603 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
604 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
605 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700606 !core12_features->descriptorBindingSampledImageUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800607 skip |= val_obj->LogError(
608 val_obj->device,
609 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
610 "descriptorBindingSampledImageUpdateAfterBind-03006",
611 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
612 "for %s since descriptorBindingSampledImageUpdateAfterBind is not enabled.",
613 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500614 }
615 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700616 !core12_features->descriptorBindingStorageImageUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800617 skip |= val_obj->LogError(
618 val_obj->device,
619 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
620 "descriptorBindingStorageImageUpdateAfterBind-03007",
621 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
622 "for %s since descriptorBindingStorageImageUpdateAfterBind is not enabled.",
623 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500624 }
625 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700626 !core12_features->descriptorBindingStorageBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800627 skip |= val_obj->LogError(
628 val_obj->device,
629 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
630 "descriptorBindingStorageBufferUpdateAfterBind-03008",
631 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
632 "for %s since descriptorBindingStorageBufferUpdateAfterBind is not enabled.",
633 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500634 }
635 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700636 !core12_features->descriptorBindingUniformTexelBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800637 skip |= val_obj->LogError(
638 val_obj->device,
639 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
640 "descriptorBindingUniformTexelBufferUpdateAfterBind-03009",
641 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
642 "for %s since descriptorBindingUniformTexelBufferUpdateAfterBind is not enabled.",
643 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500644 }
645 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700646 !core12_features->descriptorBindingStorageTexelBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800647 skip |= val_obj->LogError(
648 val_obj->device,
649 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
650 "descriptorBindingStorageTexelBufferUpdateAfterBind-03010",
651 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
652 "for %s since descriptorBindingStorageTexelBufferUpdateAfterBind is not enabled.",
653 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500654 }
655 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
656 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
657 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700658 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-None-03011",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800659 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
660 "VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT for %s.",
661 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500662 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500663
664 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
665 !inline_uniform_block_features->descriptorBindingInlineUniformBlockUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800666 skip |= val_obj->LogError(
667 val_obj->device,
668 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
669 "descriptorBindingInlineUniformBlockUpdateAfterBind-02211",
670 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
671 "for %s since descriptorBindingInlineUniformBlockUpdateAfterBind is not enabled.",
672 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolze54ae892018-09-08 12:16:29 -0500673 }
ziga-lunarg637356a2021-07-19 12:36:34 +0200674 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR ||
675 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV) &&
676 !acceleration_structure_features->descriptorBindingAccelerationStructureUpdateAfterBind) {
677 skip |= val_obj->LogError(val_obj->device,
678 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
679 "descriptorBindingAccelerationStructureUpdateAfterBind-03570",
680 "vkCreateDescriptorSetLayout(): pBindings[%" PRIu32
681 "] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
682 "for %s if "
683 "VkPhysicalDeviceAccelerationStructureFeaturesKHR::"
684 "descriptorBindingAccelerationStructureUpdateAfterBind is not enabled.",
685 i, string_VkDescriptorType(binding_info.descriptorType));
686 }
Jeff Bolzfdf96072018-04-10 14:32:18 -0500687 }
688
Mike Schuchardt2df08912020-12-15 16:28:09 -0800689 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700690 if (!core12_features->descriptorBindingUpdateUnusedWhilePending) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700691 skip |= val_obj->LogError(
692 val_obj->device,
Mike Schuchardt65847d92019-12-20 13:50:47 -0800693 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingUpdateUnusedWhilePending-03012",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800694 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
695 "VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT for %s since "
696 "descriptorBindingUpdateUnusedWhilePending is not enabled.",
697 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500698 }
699 }
700
Mike Schuchardt2df08912020-12-15 16:28:09 -0800701 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700702 if (!core12_features->descriptorBindingPartiallyBound) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700703 skip |= val_obj->LogError(
704 val_obj->device,
705 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingPartiallyBound-03013",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800706 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT for "
707 "%s since descriptorBindingPartiallyBound is not enabled.",
708 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500709 }
710 }
711
Mike Schuchardt2df08912020-12-15 16:28:09 -0800712 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT) {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500713 if (binding_info.binding != max_binding) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800714 skip |= val_obj->LogError(
715 val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004",
716 "vkCreateDescriptorSetLayout(): pBindings[%u] has VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT "
717 "but %u is the largest value of all the bindings.",
718 i, binding_info.binding);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500719 }
720
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700721 if (!core12_features->descriptorBindingVariableDescriptorCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700722 skip |= val_obj->LogError(
723 val_obj->device,
Mike Schuchardt65847d92019-12-20 13:50:47 -0800724 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingVariableDescriptorCount-03014",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800725 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
726 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for %s since "
727 "descriptorBindingVariableDescriptorCount is not enabled.",
728 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500729 }
sfricke-samsung4ba7d6e2021-03-06 20:56:35 -0800730 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
731 (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700732 skip |= val_obj->LogError(val_obj->device,
733 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03015",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800734 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
735 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for %s.",
736 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500737 }
738 }
739
740 if (push_descriptor_set &&
741 (flags_create_info->pBindingFlags[i] &
Mike Schuchardt2df08912020-12-15 16:28:09 -0800742 (VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT |
743 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT))) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800744 skip |= val_obj->LogError(
745 val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-flags-03003",
746 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, "
747 "VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, or "
748 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for with "
749 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR.",
750 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500751 }
752 }
753 }
754 }
755
ziga-lunarg185ef282021-07-19 13:13:28 +0200756 if (update_after_bind < create_info->bindingCount) {
757 if (uniform_buffer_dynamic < create_info->bindingCount) {
758 skip |=
759 val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-descriptorType-03001",
760 "vkCreateDescriptorSetLayout(): binding (%" PRIi32
761 ") has VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
762 "flag, but binding (%" PRIi32 ") has descriptor type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC.",
763 update_after_bind, uniform_buffer_dynamic);
764 }
765 if (storage_buffer_dynamic < create_info->bindingCount) {
766 skip |=
767 val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-descriptorType-03001",
768 "vkCreateDescriptorSetLayout(): binding (%" PRIi32
769 ") has VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
770 "flag, but binding (%" PRIi32 ") has descriptor type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC.",
771 update_after_bind, storage_buffer_dynamic);
772 }
773 }
774
John Zulauf0fdeab32018-01-23 11:27:35 -0700775 if ((push_descriptor_set) && (total_descriptors > max_push_descriptors)) {
776 const char *undefined = push_descriptor_ext ? "" : " -- undefined";
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700777 skip |= val_obj->LogError(
778 val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-flags-00281",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800779 "vkCreateDescriptorSetLayout(): for push descriptor, total descriptor count in layout (%" PRIu64
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700780 ") must not be greater than VkPhysicalDevicePushDescriptorPropertiesKHR::maxPushDescriptors (%" PRIu32 "%s).",
781 total_descriptors, max_push_descriptors, undefined);
John Zulauf0fdeab32018-01-23 11:27:35 -0700782 }
783
Tobin Ehlis154c2692016-10-25 09:36:53 -0600784 return skip;
785}
786
Mark Lobodzinskie12b6e32020-06-29 11:44:15 -0600787void cvdescriptorset::AllocateDescriptorSetsData::Init(uint32_t count) {
788 layout_nodes.resize(count);
Mark Lobodzinskie12b6e32020-06-29 11:44:15 -0600789}
Tobin Ehlis68d0adf2016-06-01 11:33:50 -0600790
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500791cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, DESCRIPTOR_POOL_STATE *pool_state,
Jeff Bolzfdf96072018-04-10 14:32:18 -0500792 const std::shared_ptr<DescriptorSetLayout const> &layout, uint32_t variable_count,
John Zulaufd2c3dae2019-12-12 11:02:17 -0700793 const cvdescriptorset::DescriptorSet::StateTracker *state_data)
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600794 : BASE_NODE(set, kVulkanObjectTypeDescriptorSet),
795 some_update_(false),
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500796 pool_state_(pool_state),
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700797 layout_(layout),
John Zulaufd2c3dae2019-12-12 11:02:17 -0700798 state_data_(state_data),
Jeff Bolzdd4cfa12019-08-11 20:57:51 -0500799 variable_count_(variable_count),
800 change_count_(0) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600801 if (pool_state_) {
802 pool_state_->AddParent(this);
803 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600804 // Foreach binding, create default descriptors of given type
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700805 descriptors_.reserve(layout_->GetTotalDescriptorCount());
806 descriptor_store_.resize(layout_->GetTotalDescriptorCount());
John Zulaufe4850d42019-12-30 16:10:55 -0700807 auto free_descriptor = descriptor_store_.data();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700808 for (uint32_t i = 0; i < layout_->GetBindingCount(); ++i) {
809 auto type = layout_->GetTypeFromIndex(i);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600810 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700811 case VK_DESCRIPTOR_TYPE_SAMPLER: {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700812 auto immut_sampler = layout_->GetImmutableSamplerPtrFromIndex(i);
813 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
Tobin Ehlis082c7512017-05-08 11:24:57 -0600814 if (immut_sampler) {
John Zulaufe4850d42019-12-30 16:10:55 -0700815 descriptors_.emplace_back(new ((free_descriptor++)->Sampler())
816 SamplerDescriptor(state_data, immut_sampler + di));
Tobin Ehlis082c7512017-05-08 11:24:57 -0600817 some_update_ = true; // Immutable samplers are updated at creation
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700818 } else {
John Zulaufe4850d42019-12-30 16:10:55 -0700819 descriptors_.emplace_back(new ((free_descriptor++)->Sampler()) SamplerDescriptor(state_data, nullptr));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700820 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600821 descriptors_.back()->AddParent(this);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700822 }
823 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600824 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700825 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700826 auto immut = layout_->GetImmutableSamplerPtrFromIndex(i);
827 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
Tobin Ehlis082c7512017-05-08 11:24:57 -0600828 if (immut) {
John Zulaufe4850d42019-12-30 16:10:55 -0700829 descriptors_.emplace_back(new ((free_descriptor++)->ImageSampler())
830 ImageSamplerDescriptor(state_data, immut + di));
Tobin Ehlis082c7512017-05-08 11:24:57 -0600831 some_update_ = true; // Immutable samplers are updated at creation
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700832 } else {
John Zulaufe4850d42019-12-30 16:10:55 -0700833 descriptors_.emplace_back(new ((free_descriptor++)->ImageSampler())
834 ImageSamplerDescriptor(state_data, nullptr));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700835 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600836 descriptors_.back()->AddParent(this);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700837 }
838 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600839 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700840 // ImageDescriptors
841 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
842 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
843 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700844 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700845 descriptors_.emplace_back(new ((free_descriptor++)->Image()) ImageDescriptor(type));
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600846 descriptors_.back()->AddParent(this);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700847 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700848 break;
849 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
850 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700851 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700852 descriptors_.emplace_back(new ((free_descriptor++)->Texel()) TexelDescriptor(type));
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600853 descriptors_.back()->AddParent(this);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700854 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700855 break;
sfricke-samsung4ca35652021-03-05 02:22:10 -0800856 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
857 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
858 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700859 descriptors_.emplace_back(new ((free_descriptor++)->Buffer()) BufferDescriptor(type));
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600860 descriptors_.back()->AddParent(this);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700861 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700862 break;
Jeff Bolze54ae892018-09-08 12:16:29 -0500863 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700864 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700865 descriptors_.emplace_back(new ((free_descriptor++)->InlineUniform()) InlineUniformDescriptor(type));
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600866 descriptors_.back()->AddParent(this);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700867 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500868 break;
Eric Werness30127fd2018-10-31 21:01:03 -0700869 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
sourav parmarcd5fb182020-07-17 12:58:44 -0700870 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700871 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700872 descriptors_.emplace_back(new ((free_descriptor++)->AccelerationStructure())
873 AccelerationStructureDescriptor(type));
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600874 descriptors_.back()->AddParent(this);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700875 }
Jeff Bolzfbe51582018-09-13 10:01:35 -0500876 break;
Tony-LunarGf563b362021-03-18 16:13:18 -0600877 case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
878 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
ziga-lunarge5d28542021-10-24 21:14:25 +0200879 descriptors_.emplace_back(new ((free_descriptor++)->Mutable()) MutableDescriptor());
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600880 descriptors_.back()->AddParent(this);
Tony-LunarGf563b362021-03-18 16:13:18 -0600881 }
882 break;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700883 default:
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800884 if (IsDynamicDescriptor(type) && IsBufferDescriptor(type)) {
885 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
886 dynamic_offset_idx_to_descriptor_list_.push_back(descriptors_.size());
887 descriptors_.emplace_back(new ((free_descriptor++)->Buffer()) BufferDescriptor(type));
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600888 descriptors_.back()->AddParent(this);
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800889 }
890 } else {
891 assert(0); // Bad descriptor type specified
892 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700893 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600894 }
895 }
896}
Tobin Ehlis56a30942016-05-19 08:00:00 -0600897
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600898void cvdescriptorset::DescriptorSet::Destroy() {
899 if (pool_state_) {
900 pool_state_->RemoveParent(this);
901 }
902 for (auto &desc: descriptors_) {
903 desc->RemoveParent(this);
904 }
905 BASE_NODE::Destroy();
906}
Chris Forbes57989132016-07-26 17:06:10 +1200907
Jeremy Gebben90ce4162021-08-25 14:23:07 -0600908static std::string StringDescriptorReqViewType(DescriptorReqFlags req) {
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700909 std::string result("");
Mark Lobodzinski29f451a2020-02-10 16:15:30 -0700910 for (unsigned i = 0; i <= VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; i++) {
Chris Forbes57989132016-07-26 17:06:10 +1200911 if (req & (1 << i)) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700912 if (result.size()) result += ", ";
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700913 result += string_VkImageViewType(VkImageViewType(i));
Chris Forbes57989132016-07-26 17:06:10 +1200914 }
915 }
916
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700917 if (!result.size()) result = "(none)";
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700918
919 return result;
Chris Forbes57989132016-07-26 17:06:10 +1200920}
921
Jeremy Gebben90ce4162021-08-25 14:23:07 -0600922static char const *StringDescriptorReqComponentType(DescriptorReqFlags req) {
Chris Forbesda01e8d2018-08-27 15:36:57 -0700923 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_SINT) return "SINT";
924 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_UINT) return "UINT";
925 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT) return "FLOAT";
926 return "(none)";
927}
928
Jeff Bolz6cede832019-08-09 23:30:39 -0500929unsigned DescriptorRequirementsBitsFromFormat(VkFormat fmt) {
Chris Forbesda01e8d2018-08-27 15:36:57 -0700930 if (FormatIsSInt(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_SINT;
931 if (FormatIsUInt(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_UINT;
sfricke-samsunged028b02021-09-06 23:14:51 -0700932 // Formats such as VK_FORMAT_D16_UNORM_S8_UINT are both
Chris Forbesda01e8d2018-08-27 15:36:57 -0700933 if (FormatIsDepthAndStencil(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT | DESCRIPTOR_REQ_COMPONENT_TYPE_UINT;
934 if (fmt == VK_FORMAT_UNDEFINED) return 0;
935 // everything else -- UNORM/SNORM/FLOAT/USCALED/SSCALED is all float in the shader.
936 return DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT;
937}
938
Tobin Ehlis3066db62016-08-22 08:12:23 -0600939// Validate that the state of this set is appropriate for the given bindings and dynamic_offsets at Draw time
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600940// This includes validating that all descriptors in the given bindings are updated,
941// that any update buffers are valid, and that any dynamic offsets are within the bounds of their buffers.
942// Return true if state is acceptable, or false and write an error message into error string
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600943bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const BindingReqMap &bindings,
944 const std::vector<uint32_t> &dynamic_offsets, const CMD_BUFFER_STATE *cb_node,
Niels Möller1f945f62021-07-12 15:06:02 +0200945 const std::vector<IMAGE_VIEW_STATE *> *attachments, const std::vector<SUBPASS_INFO> *subpasses,
locke-lunargfc78e932020-11-19 17:06:24 -0700946 const char *caller, const DrawDispatchVuid &vuids) const {
Jeremy Gebben37ed31e2021-04-23 12:12:10 -0600947 layer_data::optional<layer_data::unordered_map<VkImageView, VkImageLayout>> checked_layouts;
Karl Schultz2171f932021-03-19 10:47:01 -0600948 if (descriptor_set->GetTotalDescriptorCount() > cvdescriptorset::PrefilterBindRequestMap::kManyDescriptors_) {
949 checked_layouts.emplace();
950 }
Tony-LunarGace473a2020-05-06 12:48:04 -0600951 bool result = false;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600952 VkFramebuffer framebuffer = cb_node->activeFramebuffer ? cb_node->activeFramebuffer->framebuffer() : VK_NULL_HANDLE;
John Zulauf79f06582021-02-27 18:38:39 -0700953 for (const auto &binding_pair : bindings) {
954 const auto binding = binding_pair.first;
John Zulauf382e1912019-06-10 15:27:44 -0600955 DescriptorSetLayout::ConstBindingIterator binding_it(descriptor_set->GetLayout().get(), binding);
956 if (binding_it.AtEnd()) { // End at construction is the condition for an invalid binding.
Tony-LunarGace473a2020-05-06 12:48:04 -0600957 auto set = descriptor_set->GetSet();
locke-lunarg1328e8e2020-08-20 12:40:08 -0600958 result |= LogError(set, vuids.descriptor_valid,
Tony-LunarGace473a2020-05-06 12:48:04 -0600959 "%s encountered the following validation error at %s time: Attempting to "
960 "validate DrawState for binding #%u which is an invalid binding for this descriptor set.",
961 report_data->FormatHandle(set).c_str(), caller, binding);
962 return result;
Tobin Ehlis58c59582016-06-21 12:34:33 -0600963 }
Jeff Bolz6cede832019-08-09 23:30:39 -0500964
965 if (binding_it.GetDescriptorBindingFlags() &
Mike Schuchardt2df08912020-12-15 16:28:09 -0800966 (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT)) {
Jeff Bolz6cede832019-08-09 23:30:39 -0500967 // Can't validate the descriptor because it may not have been updated,
968 // or the view could have been destroyed
969 continue;
970 }
John Zulauf81dd1f12021-01-26 16:49:16 -0700971 // // This is a record time only path
972 const bool record_time_validate = true;
locke-lunargfc78e932020-11-19 17:06:24 -0700973 result |= ValidateDescriptorSetBindingData(cb_node, descriptor_set, dynamic_offsets, binding_pair, framebuffer, attachments,
Karl Schultz2171f932021-03-19 10:47:01 -0600974 subpasses, record_time_validate, caller, vuids, checked_layouts);
unknown3087a642019-09-26 17:21:05 -0600975 }
Tony-LunarGace473a2020-05-06 12:48:04 -0600976 return result;
unknown3087a642019-09-26 17:21:05 -0600977}
Jeff Bolz6cede832019-08-09 23:30:39 -0500978
locke-lunargb8be8222020-10-20 00:34:37 -0600979bool CoreChecks::ValidateDescriptorSetBindingData(const CMD_BUFFER_STATE *cb_node, const DescriptorSet *descriptor_set,
980 const std::vector<uint32_t> &dynamic_offsets,
John Zulauf79f06582021-02-27 18:38:39 -0700981 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
Mark Lobodzinski85ebd402020-12-03 12:56:07 -0700982 VkFramebuffer framebuffer, const std::vector<IMAGE_VIEW_STATE *> *attachments,
Niels Möller1f945f62021-07-12 15:06:02 +0200983 const std::vector<SUBPASS_INFO> *subpasses, bool record_time_validate,
Karl Schultz2171f932021-03-19 10:47:01 -0600984 const char *caller, const DrawDispatchVuid &vuids,
Jeremy Gebben37ed31e2021-04-23 12:12:10 -0600985 layer_data::optional<layer_data::unordered_map<VkImageView, VkImageLayout>> &checked_layouts) const {
unknown3087a642019-09-26 17:21:05 -0600986 using DescriptorClass = cvdescriptorset::DescriptorClass;
987 using BufferDescriptor = cvdescriptorset::BufferDescriptor;
988 using ImageDescriptor = cvdescriptorset::ImageDescriptor;
989 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
990 using SamplerDescriptor = cvdescriptorset::SamplerDescriptor;
991 using TexelDescriptor = cvdescriptorset::TexelDescriptor;
Jeff Bolz95176d02020-04-01 00:36:16 -0500992 using AccelerationStructureDescriptor = cvdescriptorset::AccelerationStructureDescriptor;
locke-lunarg36045992020-08-20 16:54:37 -0600993 const auto binding = binding_info.first;
Jeremy Gebbene151b6b2021-04-09 18:03:06 -0600994 bool skip = false;
unknown3087a642019-09-26 17:21:05 -0600995 DescriptorSetLayout::ConstBindingIterator binding_it(descriptor_set->GetLayout().get(), binding);
996 {
John Zulauf382e1912019-06-10 15:27:44 -0600997 // Copy the range, the end range is subject to update based on variable length descriptor arrays.
998 cvdescriptorset::IndexRange index_range = binding_it.GetGlobalIndexRange();
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700999 auto array_idx = 0; // Track array idx if we're dealing with array descriptors
Jeff Bolzfdf96072018-04-10 14:32:18 -05001000
John Zulauf382e1912019-06-10 15:27:44 -06001001 if (binding_it.IsVariableDescriptorCount()) {
Jeff Bolzfdf96072018-04-10 14:32:18 -05001002 // Only validate the first N descriptors if it uses variable_count
John Zulauf382e1912019-06-10 15:27:44 -06001003 index_range.end = index_range.start + descriptor_set->GetVariableDescriptorCount();
Jeff Bolzfdf96072018-04-10 14:32:18 -05001004 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001005 for (uint32_t i = index_range.start; !skip && i < index_range.end; ++i, ++array_idx) {
Lockeb994adf2019-03-29 23:52:31 -06001006 uint32_t index = i - index_range.start;
John Zulauf382e1912019-06-10 15:27:44 -06001007 const auto *descriptor = descriptor_set->GetDescriptorFromGlobalIndex(i);
Jeremy Gebben550ebbd2021-03-11 05:04:52 -07001008 const auto descriptor_class = descriptor->GetClass();
Lockeb994adf2019-03-29 23:52:31 -06001009
Jeremy Gebben550ebbd2021-03-11 05:04:52 -07001010 if (descriptor_class == DescriptorClass::InlineUniform) {
Jeff Bolz6cede832019-08-09 23:30:39 -05001011 // Can't validate the descriptor because it may not have been updated.
Jeff Bolzfdf96072018-04-10 14:32:18 -05001012 continue;
John Zulauf382e1912019-06-10 15:27:44 -06001013 } else if (!descriptor->updated) {
Tony-LunarGace473a2020-05-06 12:48:04 -06001014 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001015 return LogError(
1016 set, vuids.descriptor_valid,
1017 "Descriptor set %s encountered the following validation error at %s time: Descriptor in binding #%" PRIu32
1018 " index %" PRIu32
1019 " is being used in draw but has never been updated via vkUpdateDescriptorSets() or a similar call.",
1020 report_data->FormatHandle(set).c_str(), caller, binding, index);
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001021 }
1022 switch (descriptor_class) {
1023 case DescriptorClass::GeneralBuffer: {
1024 const auto *buffer_desc = static_cast<const BufferDescriptor *>(descriptor);
1025 skip =
1026 ValidateGeneralBufferDescriptor(caller, vuids, cb_node, descriptor_set, *buffer_desc, binding_info, index);
1027 } break;
1028 case DescriptorClass::ImageSampler: {
1029 const auto *image_sampler_desc = static_cast<const ImageSamplerDescriptor *>(descriptor);
1030 skip = ValidateImageDescriptor(caller, vuids, cb_node, descriptor_set, *image_sampler_desc, binding_info, index,
1031 record_time_validate, attachments, subpasses, framebuffer, binding_it.GetType(),
1032 checked_layouts);
1033 if (!skip) {
1034 skip = ValidateSamplerDescriptor(caller, vuids, cb_node, descriptor_set, binding_info, index,
1035 image_sampler_desc->GetSampler(), image_sampler_desc->IsImmutableSampler(),
1036 image_sampler_desc->GetSamplerState());
Karl Schultz76d16a42020-11-11 05:05:33 -07001037 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001038 } break;
1039 case DescriptorClass::Image: {
1040 const auto *image_desc = static_cast<const ImageDescriptor *>(descriptor);
1041 skip = ValidateImageDescriptor(caller, vuids, cb_node, descriptor_set, *image_desc, binding_info, index,
1042 record_time_validate, attachments, subpasses, framebuffer, binding_it.GetType(),
1043 checked_layouts);
1044 } break;
1045 case DescriptorClass::PlainSampler: {
1046 const auto *sampler_desc = static_cast<const SamplerDescriptor *>(descriptor);
1047 skip = ValidateSamplerDescriptor(caller, vuids, cb_node, descriptor_set, binding_info, index,
1048 sampler_desc->GetSampler(), sampler_desc->IsImmutableSampler(),
1049 sampler_desc->GetSamplerState());
1050 } break;
1051 case DescriptorClass::TexelBuffer: {
1052 const auto *texel_desc = static_cast<const TexelDescriptor *>(descriptor);
1053 skip = ValidateTexelDescriptor(caller, vuids, cb_node, descriptor_set, *texel_desc, binding_info, index);
1054 } break;
1055 case DescriptorClass::AccelerationStructure: {
1056 const auto *accel_desc = static_cast<const AccelerationStructureDescriptor *>(descriptor);
1057 skip = ValidateAccelerationDescriptor(caller, vuids, cb_node, descriptor_set, *accel_desc, binding_info, index);
1058 } break;
1059 default:
1060 break;
1061 }
1062 }
1063 }
1064 return skip;
1065}
locke-lunarg36045992020-08-20 16:54:37 -06001066
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001067bool CoreChecks::ValidateGeneralBufferDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1068 const cvdescriptorset::DescriptorSet *descriptor_set,
1069 const cvdescriptorset::BufferDescriptor &descriptor,
1070 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
1071 uint32_t index) const {
1072 // Verify that buffers are valid
1073 auto buffer = descriptor.GetBuffer();
1074 auto buffer_node = descriptor.GetBufferState();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001075 if ((!buffer_node && !enabled_features.robustness2_features.nullDescriptor) || (buffer_node && buffer_node->Destroyed())) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001076 auto set = descriptor_set->GetSet();
1077 return LogError(set, vuids.descriptor_valid,
1078 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1079 "binding #%" PRIu32 " index %" PRIu32 " is using buffer %s that is invalid or has been destroyed.",
1080 report_data->FormatHandle(set).c_str(), caller, binding_info.first, index,
1081 report_data->FormatHandle(buffer).c_str());
1082 }
1083 if (buffer) {
1084 if (buffer_node && !buffer_node->sparse) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001085 for (const auto &item: buffer_node->GetBoundMemory()) {
1086 auto &binding = item.second;
1087 if (binding.mem_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001088 auto set = descriptor_set->GetSet();
1089 return LogError(set, vuids.descriptor_valid,
1090 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1091 "binding #%" PRIu32 " index %" PRIu32 " is uses buffer %s that references invalid memory %s.",
1092 report_data->FormatHandle(set).c_str(), caller, binding_info.first, index,
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001093 report_data->FormatHandle(buffer).c_str(),
1094 report_data->FormatHandle(binding.mem_state->mem()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001095 }
1096 }
1097 }
1098 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1099 if (ValidateProtectedBuffer(cb_node, buffer_node, caller, vuids.unprotected_command_buffer,
1100 "Buffer is in a descriptorSet")) {
1101 return true;
1102 }
1103 if (binding_info.second.is_writable &&
1104 ValidateUnprotectedBuffer(cb_node, buffer_node, caller, vuids.protected_command_buffer,
1105 "Buffer is in a descriptorSet")) {
1106 return true;
1107 }
1108 }
1109 }
1110 return false;
1111}
Chris Forbes1f7f3ca2017-05-08 13:54:50 -07001112
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001113bool CoreChecks::ValidateImageDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1114 const cvdescriptorset::DescriptorSet *descriptor_set,
1115 const cvdescriptorset::ImageDescriptor &image_descriptor,
1116 const std::pair<const uint32_t, DescriptorRequirement> &binding_info, uint32_t index,
1117 bool record_time_validate, const std::vector<IMAGE_VIEW_STATE *> *attachments,
Niels Möller1f945f62021-07-12 15:06:02 +02001118 const std::vector<SUBPASS_INFO> *subpasses, VkFramebuffer framebuffer,
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001119 VkDescriptorType descriptor_type,
Jeremy Gebben37ed31e2021-04-23 12:12:10 -06001120 layer_data::optional<layer_data::unordered_map<VkImageView, VkImageLayout>> &checked_layouts) const {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001121 std::vector<const SAMPLER_STATE *> sampler_states;
1122 VkImageView image_view = image_descriptor.GetImageView();
1123 const IMAGE_VIEW_STATE *image_view_state = image_descriptor.GetImageViewState();
1124 VkImageLayout image_layout = image_descriptor.GetImageLayout();
1125 const auto binding = binding_info.first;
1126 const auto reqs = binding_info.second.reqs;
Karl Schultz76d16a42020-11-11 05:05:33 -07001127
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001128 if (image_descriptor.GetClass() == cvdescriptorset::DescriptorClass::ImageSampler) {
1129 sampler_states.emplace_back(
1130 static_cast<const cvdescriptorset::ImageSamplerDescriptor &>(image_descriptor).GetSamplerState());
1131 } else {
1132 if (binding_info.second.samplers_used_by_image.size() > index) {
1133 for (auto &sampler : binding_info.second.samplers_used_by_image[index]) {
1134 // NOTE: This check _shouldn't_ be necessary due to the checks made in IsSpecificDescriptorType in
1135 // shader_validation.cpp. However, without this check some traces still crash.
1136 if (sampler.second && (sampler.second->GetClass() == cvdescriptorset::DescriptorClass::PlainSampler)) {
1137 const auto *sampler_state =
1138 static_cast<const cvdescriptorset::SamplerDescriptor *>(sampler.second)->GetSamplerState();
1139 if (sampler_state) sampler_states.emplace_back(sampler_state);
1140 }
1141 }
1142 }
1143 }
locke-lunarg4e1e4632020-10-26 01:52:19 -06001144
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001145 if ((!image_view_state && !enabled_features.robustness2_features.nullDescriptor) ||
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001146 (image_view_state && image_view_state->Destroyed())) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001147 // Image view must have been destroyed since initial update. Could potentially flag the descriptor
1148 // as "invalid" (updated = false) at DestroyImageView() time and detect this error at bind time
Jeff Bolz165818a2020-05-08 11:19:03 -05001149
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001150 auto set = descriptor_set->GetSet();
1151 return LogError(set, vuids.descriptor_valid,
1152 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1153 "binding #%" PRIu32 " index %" PRIu32 " is using imageView %s that is invalid or has been destroyed.",
1154 report_data->FormatHandle(set).c_str(), caller, binding, index,
1155 report_data->FormatHandle(image_view).c_str());
1156 }
1157 if (image_view) {
1158 const auto &image_view_ci = image_view_state->create_info;
1159 const auto *image_state = image_view_state->image_state.get();
Jeff Bolz165818a2020-05-08 11:19:03 -05001160
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001161 if (reqs & DESCRIPTOR_REQ_ALL_VIEW_TYPE_BITS) {
1162 if (~reqs & (1 << image_view_ci.viewType)) {
1163 auto set = descriptor_set->GetSet();
1164 return LogError(set, vuids.descriptor_valid,
1165 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1166 "in binding #%" PRIu32 " index %" PRIu32 " requires an image view of type %s but got %s.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08001167 report_data->FormatHandle(set).c_str(), caller, binding, index,
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001168 StringDescriptorReqViewType(reqs).c_str(), string_VkImageViewType(image_view_ci.viewType));
1169 }
locke-lunarg25b6c352020-08-06 17:44:18 -06001170
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001171 if (!(reqs & image_view_state->descriptor_format_bits)) {
1172 // bad component type
1173 auto set = descriptor_set->GetSet();
1174 return LogError(set, vuids.descriptor_valid,
1175 "Descriptor set %s encountered the following validation error at %s time: "
1176 "Descriptor in binding "
1177 "#%" PRIu32 " index %" PRIu32 " requires %s component type, but bound descriptor format is %s.",
1178 report_data->FormatHandle(set).c_str(), caller, binding, index,
1179 StringDescriptorReqComponentType(reqs), string_VkFormat(image_view_ci.format));
1180 }
1181 }
locke-lunarg540b2252020-08-03 13:23:36 -06001182
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001183 // NOTE: Submit time validation of UPDATE_AFTER_BIND image layout is not possible with the
1184 // image layout tracking as currently implemented, so only record_time_validation is done
1185 if (!disabled[image_layout_validation] && record_time_validate) {
1186 // Verify Image Layout
1187 // No "invalid layout" VUID required for this call, since the optimal_layout parameter is UNDEFINED.
1188 // The caller provides a checked_layouts map when there are a large number of layouts to check,
1189 // making it worthwhile to keep track of verified layouts and not recheck them.
1190 bool already_validated = false;
1191 if (checked_layouts) {
1192 auto search = checked_layouts->find(image_view);
1193 if (search != checked_layouts->end() && search->second == image_layout) {
1194 already_validated = true;
1195 }
1196 }
1197 if (!already_validated) {
1198 bool hit_error = false;
1199 VerifyImageLayout(cb_node, image_state, image_view_state->normalized_subresource_range,
1200 image_view_ci.subresourceRange.aspectMask, image_layout, VK_IMAGE_LAYOUT_UNDEFINED, caller,
1201 kVUIDUndefined, "VUID-VkDescriptorImageInfo-imageLayout-00344", &hit_error);
1202 if (hit_error) {
1203 auto set = descriptor_set->GetSet();
1204 return LogError(set, vuids.descriptor_valid,
1205 "Descriptor set %s encountered the following validation error at %s time: Image layout "
1206 "specified "
1207 "at vkUpdateDescriptorSet* or vkCmdPushDescriptorSet* time "
1208 "doesn't match actual image layout at time descriptor is used. See previous error callback for "
1209 "specific details.",
1210 report_data->FormatHandle(set).c_str(), caller);
1211 }
1212 if (checked_layouts) {
1213 checked_layouts->emplace(image_view, image_layout);
1214 }
1215 }
1216 }
locke-lunarg540b2252020-08-03 13:23:36 -06001217
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001218 // Verify Sample counts
1219 if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) && image_view_state->samples != VK_SAMPLE_COUNT_1_BIT) {
1220 auto set = descriptor_set->GetSet();
1221 return LogError(set, vuids.descriptor_valid,
1222 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1223 "binding #%" PRIu32 " index %" PRIu32 " requires bound image to have VK_SAMPLE_COUNT_1_BIT but got %s.",
1224 report_data->FormatHandle(set).c_str(), caller, binding, index,
1225 string_VkSampleCountFlagBits(image_view_state->samples));
1226 }
1227 if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) && image_view_state->samples == VK_SAMPLE_COUNT_1_BIT) {
1228 auto set = descriptor_set->GetSet();
1229 return LogError(set, vuids.descriptor_valid,
1230 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1231 "in binding #%" PRIu32 " index %" PRIu32
1232 " requires bound image to have multiple samples, but got VK_SAMPLE_COUNT_1_BIT.",
1233 report_data->FormatHandle(set).c_str(), caller, binding, index);
1234 }
locke-lunarg36045992020-08-20 16:54:37 -06001235
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001236 // Verify VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
1237 if ((reqs & DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION) && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) &&
1238 !(image_view_state->format_features & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) {
1239 auto set = descriptor_set->GetSet();
1240 LogObjectList objlist(set);
1241 objlist.add(image_view);
1242 return LogError(objlist, vuids.imageview_atomic,
1243 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1244 "in binding #%" PRIu32 " index %" PRIu32
1245 ", %s, format %s, doesn't "
1246 "contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT.",
1247 report_data->FormatHandle(set).c_str(), caller, binding, index,
1248 report_data->FormatHandle(image_view).c_str(), string_VkFormat(image_view_ci.format));
1249 }
locke-lunarg654a9052020-10-13 16:28:42 -06001250
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001251 // Verify if attachments are used in DescriptorSet
Niels Möller1f945f62021-07-12 15:06:02 +02001252 if (attachments && attachments->size() > 0 && subpasses && (descriptor_type != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06001253 bool ds_aspect = (image_view_state->normalized_subresource_range.aspectMask &
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001254 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1255 ? true
1256 : false;
1257 uint32_t att_index = 0;
1258 for (const auto &view_state : *attachments) {
Niels Möller1f945f62021-07-12 15:06:02 +02001259 const SUBPASS_INFO& subpass = (*subpasses)[att_index];
1260 if (!subpass.used || !view_state || view_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001261 continue;
1262 }
Ricardo Garciafe2b7682021-07-30 10:44:57 +02001263 if (ds_aspect && (subpass.usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ||
1264 subpass.usage == VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001265 if ((image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1266 image_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
1267 image_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL) &&
Niels Möller1f945f62021-07-12 15:06:02 +02001268 (subpass.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1269 subpass.layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
1270 subpass.layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL)) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001271 continue;
Chris Forbes1f7f3ca2017-05-08 13:54:50 -07001272 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001273 if ((image_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL &&
Niels Möller1f945f62021-07-12 15:06:02 +02001274 subpass.layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) ||
1275 (subpass.layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL &&
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001276 image_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)) {
1277 continue;
1278 }
1279 }
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001280 if (view_state->image_view() == image_view) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001281 auto set = descriptor_set->GetSet();
1282 LogObjectList objlist(set);
1283 objlist.add(image_view);
1284 objlist.add(framebuffer);
1285 return LogError(objlist, vuids.image_subresources,
1286 "Descriptor set %s encountered the following validation error at %s time: %s is used in "
1287 "Descriptor in binding #%" PRIu32 " index %" PRIu32 " and %s attachment # %" PRIu32 ".",
1288 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
1289 binding, index, report_data->FormatHandle(framebuffer).c_str(), att_index);
1290 } else {
1291 if (image_view_state->OverlapSubresource(*view_state)) {
Karl Schultz76d16a42020-11-11 05:05:33 -07001292 auto set = descriptor_set->GetSet();
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001293 LogObjectList objlist(set);
1294 objlist.add(image_view);
1295 objlist.add(framebuffer);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001296 objlist.add(view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001297 return LogError(
1298 objlist, vuids.image_subresources,
1299 "Descriptor set %s encountered the following validation error at %s time: "
1300 "Image subresources of %s in "
1301 "Descriptor in binding #%" PRIu32 " index %" PRIu32 " and %s in %s attachment # %" PRIu32 " overlap.",
1302 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(), binding,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001303 index, report_data->FormatHandle(view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001304 report_data->FormatHandle(framebuffer).c_str(), att_index);
Karl Schultz76d16a42020-11-11 05:05:33 -07001305 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001306 }
1307 ++att_index;
1308 }
1309 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1310 if (ValidateProtectedImage(cb_node, image_view_state->image_state.get(), caller, vuids.unprotected_command_buffer,
1311 "Image is in a descriptorSet")) {
1312 return true;
1313 }
1314 if (binding_info.second.is_writable &&
1315 ValidateUnprotectedImage(cb_node, image_view_state->image_state.get(), caller, vuids.protected_command_buffer,
1316 "Image is in a descriptorSet")) {
1317 return true;
1318 }
1319 }
1320 }
Chris Forbese92dd1d2019-01-21 15:58:57 -08001321
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001322 for (const auto *sampler_state : sampler_states) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001323 if (!sampler_state || sampler_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001324 continue;
1325 }
locke-lunarg25b6c352020-08-06 17:44:18 -06001326
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001327 // TODO: Validate 04015 for DescriptorClass::PlainSampler
1328 if ((sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
1329 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) &&
1330 (sampler_state->customCreateInfo.format == VK_FORMAT_UNDEFINED)) {
1331 if (image_view_state->create_info.format == VK_FORMAT_B4G4R4A4_UNORM_PACK16 ||
1332 image_view_state->create_info.format == VK_FORMAT_B5G6R5_UNORM_PACK16 ||
1333 image_view_state->create_info.format == VK_FORMAT_B5G5R5A1_UNORM_PACK16) {
1334 auto set = descriptor_set->GetSet();
1335 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001336 objlist.add(sampler_state->sampler());
1337 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001338 return LogError(objlist, "VUID-VkSamplerCustomBorderColorCreateInfoEXT-format-04015",
1339 "Descriptor set %s encountered the following validation error at %s time: Sampler %s in "
1340 "binding #%" PRIu32 " index %" PRIu32
1341 " has a custom border color with format = VK_FORMAT_UNDEFINED and is used to "
1342 "sample an image view %s with format %s",
1343 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001344 report_data->FormatHandle(sampler_state->sampler()).c_str(), binding, index,
1345 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001346 string_VkFormat(image_view_state->create_info.format));
1347 }
1348 }
1349 VkFilter sampler_mag_filter = sampler_state->createInfo.magFilter;
1350 VkFilter sampler_min_filter = sampler_state->createInfo.minFilter;
1351 VkBool32 sampler_compare_enable = sampler_state->createInfo.compareEnable;
1352 if ((sampler_mag_filter == VK_FILTER_LINEAR || sampler_min_filter == VK_FILTER_LINEAR) &&
1353 (sampler_compare_enable == VK_FALSE) &&
1354 !(image_view_state->format_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) {
1355 auto set = descriptor_set->GetSet();
1356 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001357 objlist.add(sampler_state->sampler());
1358 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001359 return LogError(objlist, vuids.linear_sampler,
1360 "Descriptor set %s encountered the following validation error at %s time: Sampler "
1361 "(%s) is set to use VK_FILTER_LINEAR with "
1362 "compareEnable is set to VK_TRUE, but image view's (%s) format (%s) does not "
1363 "contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT in its format features.",
1364 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001365 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1366 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001367 string_VkFormat(image_view_state->create_info.format));
1368 }
1369 if (sampler_mag_filter == VK_FILTER_CUBIC_EXT || sampler_min_filter == VK_FILTER_CUBIC_EXT) {
1370 if (!(image_view_state->format_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) {
1371 auto set = descriptor_set->GetSet();
1372 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001373 objlist.add(sampler_state->sampler());
1374 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001375 return LogError(objlist, vuids.cubic_sampler,
1376 "Descriptor set %s encountered the following validation error at %s time: "
1377 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT, then "
1378 "image view's (%s) format (%s) MUST contain "
1379 "VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT in its format features.",
1380 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001381 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1382 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001383 string_VkFormat(image_view_state->create_info.format));
1384 }
1385
1386 if (IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
1387 const auto reduction_mode_info =
1388 LvlFindInChain<VkSamplerReductionModeCreateInfo>(sampler_state->createInfo.pNext);
1389 if (reduction_mode_info &&
1390 (reduction_mode_info->reductionMode == VK_SAMPLER_REDUCTION_MODE_MIN ||
1391 reduction_mode_info->reductionMode == VK_SAMPLER_REDUCTION_MODE_MAX) &&
1392 !image_view_state->filter_cubic_props.filterCubicMinmax) {
1393 auto set = descriptor_set->GetSet();
1394 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001395 objlist.add(sampler_state->sampler());
1396 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001397 return LogError(objlist, vuids.filter_cubic_min_max,
1398 "Descriptor set %s encountered the following validation error at %s time: "
1399 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT & %s, "
1400 "but image view (%s) doesn't support filterCubicMinmax.",
1401 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001402 report_data->FormatHandle(sampler_state->sampler()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001403 string_VkSamplerReductionMode(reduction_mode_info->reductionMode),
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001404 report_data->FormatHandle(image_view_state->image_view()).c_str());
Chris Forbese92dd1d2019-01-21 15:58:57 -08001405 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001406
1407 if (!image_view_state->filter_cubic_props.filterCubic) {
1408 auto set = descriptor_set->GetSet();
1409 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001410 objlist.add(sampler_state->sampler());
1411 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001412 return LogError(objlist, vuids.filter_cubic,
1413 "Descriptor set %s encountered the following validation error at %s time: "
1414 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT, "
1415 "but image view (%s) doesn't support filterCubic.",
1416 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001417 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1418 report_data->FormatHandle(image_view_state->image_view()).c_str());
Jeff Bolz95176d02020-04-01 00:36:16 -05001419 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001420 }
locke-lunarg4e1e4632020-10-26 01:52:19 -06001421
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001422 if (IsExtEnabled(device_extensions.vk_img_filter_cubic)) {
Clemens Kern5a42ea62021-09-29 16:30:23 +02001423 if (image_view_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_3D ||
1424 image_view_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1425 image_view_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
Tony-LunarGace473a2020-05-06 12:48:04 -06001426 auto set = descriptor_set->GetSet();
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001427 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001428 objlist.add(sampler_state->sampler());
1429 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001430 return LogError(objlist, vuids.img_filter_cubic,
1431 "Descriptor set %s encountered the following validation error at %s time: Sampler "
1432 "(%s)is set to use VK_FILTER_CUBIC_EXT while the VK_IMG_filter_cubic extension "
1433 "is enabled, but image view (%s) has an invalid imageViewType (%s).",
1434 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001435 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1436 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001437 string_VkImageViewType(image_view_state->create_info.viewType));
Tobin Ehlisb1a2e4b2018-03-16 07:54:24 -06001438 }
1439 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001440 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001441
1442 if ((image_state->createInfo.flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) &&
1443 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE ||
1444 sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE ||
1445 sampler_state->createInfo.addressModeW != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)) {
1446 std::string address_mode_letter =
1447 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1448 ? "U"
1449 : (sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) ? "V" : "W";
1450 VkSamplerAddressMode address_mode =
1451 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1452 ? sampler_state->createInfo.addressModeU
1453 : (sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1454 ? sampler_state->createInfo.addressModeV
1455 : sampler_state->createInfo.addressModeW;
1456 auto set = descriptor_set->GetSet();
1457 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001458 objlist.add(sampler_state->sampler());
1459 objlist.add(image_state->image());
1460 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001461 return LogError(objlist, vuids.corner_sampled_address_mode,
1462 "Descriptor set %s encountered the following validation error at %s time: Image "
1463 "(%s) in image view (%s) is created with flag "
1464 "VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and can only be sampled using "
1465 "VK_SAMPLER_ADDRESS_MODE_CLAMP_EDGE, but sampler (%s) has "
1466 "createInfo.addressMode%s set to %s.",
1467 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001468 report_data->FormatHandle(image_state->image()).c_str(),
1469 report_data->FormatHandle(image_view_state->image_view()).c_str(),
1470 report_data->FormatHandle(sampler_state->sampler()).c_str(), address_mode_letter.c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001471 string_VkSamplerAddressMode(address_mode));
1472 }
1473
1474 // UnnormalizedCoordinates sampler validations
1475 if (sampler_state->createInfo.unnormalizedCoordinates) {
1476 // If ImageView is used by a unnormalizedCoordinates sampler, it needs to check ImageView type
1477 if (image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_3D || image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1478 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY ||
1479 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY ||
1480 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
1481 auto set = descriptor_set->GetSet();
1482 LogObjectList objlist(set);
1483 objlist.add(image_view);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001484 objlist.add(sampler_state->sampler());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001485 return LogError(objlist, vuids.sampler_imageview_type,
1486 "Descriptor set %s encountered the following validation error at %s time: %s, type: %s in "
1487 "Descriptor in binding #%" PRIu32 " index %" PRIu32 "is used by %s.",
1488 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
1489 string_VkImageViewType(image_view_ci.viewType), binding, index,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001490 report_data->FormatHandle(sampler_state->sampler()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001491 }
1492
1493 // sampler must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample*
1494 // instructions with ImplicitLod, Dref or Proj in their name
1495 if (reqs & DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ) {
1496 auto set = descriptor_set->GetSet();
1497 LogObjectList objlist(set);
1498 objlist.add(image_view);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001499 objlist.add(sampler_state->sampler());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001500 return LogError(objlist, vuids.sampler_implicitLod_dref_proj,
1501 "Descriptor set %s encountered the following validation error at %s time: %s in "
1502 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1503 " is used by %s that uses invalid operator.",
1504 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001505 binding, index, report_data->FormatHandle(sampler_state->sampler()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001506 }
1507
1508 // sampler must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample*
1509 // instructions that includes a LOD bias or any offset values
1510 if (reqs & DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET) {
1511 auto set = descriptor_set->GetSet();
1512 LogObjectList objlist(set);
1513 objlist.add(image_view);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001514 objlist.add(sampler_state->sampler());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001515 return LogError(objlist, vuids.sampler_bias_offset,
1516 "Descriptor set %s encountered the following validation error at %s time: %s in "
1517 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1518 " is used by %s that uses invalid bias or offset operator.",
1519 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001520 binding, index, report_data->FormatHandle(sampler_state->sampler()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001521 }
1522 }
1523 }
1524 }
1525 return false;
1526}
1527
1528bool CoreChecks::ValidateTexelDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1529 const cvdescriptorset::DescriptorSet *descriptor_set,
1530 const cvdescriptorset::TexelDescriptor &texel_descriptor,
1531 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
1532 uint32_t index) const {
1533 auto buffer_view = texel_descriptor.GetBufferView();
1534 auto buffer_view_state = texel_descriptor.GetBufferViewState();
1535 const auto binding = binding_info.first;
1536 const auto reqs = binding_info.second.reqs;
1537 if ((!buffer_view_state && !enabled_features.robustness2_features.nullDescriptor) ||
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001538 (buffer_view_state && buffer_view_state->Destroyed())) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001539 auto set = descriptor_set->GetSet();
1540 return LogError(set, vuids.descriptor_valid,
1541 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1542 "binding #%" PRIu32 " index %" PRIu32 " is using bufferView %s that is invalid or has been destroyed.",
1543 report_data->FormatHandle(set).c_str(), caller, binding, index,
1544 report_data->FormatHandle(buffer_view).c_str());
1545 }
1546 if (buffer_view) {
1547 auto buffer = buffer_view_state->create_info.buffer;
1548 auto buffer_state = buffer_view_state->buffer_state.get();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001549 if (buffer_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001550 auto set = descriptor_set->GetSet();
1551 return LogError(set, vuids.descriptor_valid,
1552 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1553 "binding #%" PRIu32 " index %" PRIu32 " is using buffer %s that has been destroyed.",
1554 report_data->FormatHandle(set).c_str(), caller, binding, index,
1555 report_data->FormatHandle(buffer).c_str());
1556 }
1557 auto format_bits = DescriptorRequirementsBitsFromFormat(buffer_view_state->create_info.format);
1558
1559 if (!(reqs & format_bits)) {
1560 // bad component type
1561 auto set = descriptor_set->GetSet();
1562 return LogError(set, vuids.descriptor_valid,
1563 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1564 "binding #%" PRIu32 " index %" PRIu32 " requires %s component type, but bound descriptor format is %s.",
1565 report_data->FormatHandle(set).c_str(), caller, binding, index, StringDescriptorReqComponentType(reqs),
1566 string_VkFormat(buffer_view_state->create_info.format));
1567 }
1568
1569 // Verify VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
1570 if ((reqs & DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION) &&
1571 (descriptor_set->GetTypeFromBinding(binding) == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) &&
1572 !(buffer_view_state->format_features & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)) {
1573 auto set = descriptor_set->GetSet();
1574 LogObjectList objlist(set);
1575 objlist.add(buffer_view);
1576 return LogError(objlist, "UNASSIGNED-None-MismatchAtomicBufferFeature",
1577 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1578 "in binding #%" PRIu32 " index %" PRIu32
1579 ", %s, format %s, doesn't "
1580 "contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT.",
1581 report_data->FormatHandle(set).c_str(), caller, binding, index,
1582 report_data->FormatHandle(buffer_view).c_str(), string_VkFormat(buffer_view_state->create_info.format));
1583 }
1584 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1585 if (ValidateProtectedBuffer(cb_node, buffer_view_state->buffer_state.get(), caller, vuids.unprotected_command_buffer,
1586 "Buffer is in a descriptorSet")) {
1587 return true;
1588 }
1589 if (binding_info.second.is_writable &&
1590 ValidateUnprotectedBuffer(cb_node, buffer_view_state->buffer_state.get(), caller, vuids.protected_command_buffer,
1591 "Buffer is in a descriptorSet")) {
1592 return true;
1593 }
1594 }
1595 }
1596 return false;
1597}
1598
1599bool CoreChecks::ValidateAccelerationDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1600 const cvdescriptorset::DescriptorSet *descriptor_set,
1601 const cvdescriptorset::AccelerationStructureDescriptor &descriptor,
1602 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
1603 uint32_t index) const {
1604 // Verify that acceleration structures are valid
1605 const auto binding = binding_info.first;
1606 if (descriptor.is_khr()) {
1607 auto acc = descriptor.GetAccelerationStructure();
1608 auto acc_node = descriptor.GetAccelerationStructureStateKHR();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001609 if (!acc_node || acc_node->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001610 if (acc != VK_NULL_HANDLE || !enabled_features.robustness2_features.nullDescriptor) {
1611 auto set = descriptor_set->GetSet();
1612 return LogError(set, vuids.descriptor_valid,
1613 "Descriptor set %s encountered the following validation error at %s time: "
1614 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1615 " is using acceleration structure %s that is invalid or has been destroyed.",
1616 report_data->FormatHandle(set).c_str(), caller, binding, index,
1617 report_data->FormatHandle(acc).c_str());
1618 }
1619 } else {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001620 for (const auto &item: acc_node->GetBoundMemory()) {
1621 auto &mem_binding = item.second;
1622 if (mem_binding.mem_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001623 auto set = descriptor_set->GetSet();
1624 return LogError(set, vuids.descriptor_valid,
1625 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1626 "binding #%" PRIu32 " index %" PRIu32
1627 " is using acceleration structure %s that references invalid memory %s.",
1628 report_data->FormatHandle(set).c_str(), caller, binding, index,
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001629 report_data->FormatHandle(acc).c_str(),
1630 report_data->FormatHandle(mem_binding.mem_state->mem()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001631 }
1632 }
1633 }
1634 } else {
1635 auto acc = descriptor.GetAccelerationStructureNV();
1636 auto acc_node = descriptor.GetAccelerationStructureStateNV();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001637 if (!acc_node || acc_node->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001638 if (acc != VK_NULL_HANDLE || !enabled_features.robustness2_features.nullDescriptor) {
1639 auto set = descriptor_set->GetSet();
1640 return LogError(set, vuids.descriptor_valid,
1641 "Descriptor set %s encountered the following validation error at %s time: "
1642 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1643 " is using acceleration structure %s that is invalid or has been destroyed.",
1644 report_data->FormatHandle(set).c_str(), caller, binding, index,
1645 report_data->FormatHandle(acc).c_str());
1646 }
1647 } else {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001648 for (const auto &item : acc_node->GetBoundMemory()) {
1649 auto &mem_binding = item.second;
1650 if (mem_binding.mem_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001651 auto set = descriptor_set->GetSet();
1652 return LogError(set, vuids.descriptor_valid,
1653 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1654 "binding #%" PRIu32 " index %" PRIu32
1655 " is using acceleration structure %s that references invalid memory %s.",
1656 report_data->FormatHandle(set).c_str(), caller, binding, index,
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001657 report_data->FormatHandle(acc).c_str(),
1658 report_data->FormatHandle(mem_binding.mem_state->mem()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001659 }
1660 }
1661 }
1662 }
1663 return false;
1664}
1665
1666// If the validation is related to both of image and sampler,
1667// please leave it in (descriptor_class == DescriptorClass::ImageSampler || descriptor_class ==
1668// DescriptorClass::Image) Here is to validate for only sampler.
1669bool CoreChecks::ValidateSamplerDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1670 const cvdescriptorset::DescriptorSet *descriptor_set,
1671 const std::pair<const uint32_t, DescriptorRequirement> &binding_info, uint32_t index,
1672 VkSampler sampler, bool is_immutable, const SAMPLER_STATE *sampler_state) const {
1673 // Verify Sampler still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001674 if (!sampler_state || sampler_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001675 auto set = descriptor_set->GetSet();
1676 return LogError(set, vuids.descriptor_valid,
1677 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1678 "binding #%" PRIu32 " index %" PRIu32 " is using sampler %s that is invalid or has been destroyed.",
1679 report_data->FormatHandle(set).c_str(), caller, binding_info.first, index,
1680 report_data->FormatHandle(sampler).c_str());
1681 } else {
1682 if (sampler_state->samplerConversion && !is_immutable) {
1683 auto set = descriptor_set->GetSet();
1684 return LogError(set, vuids.descriptor_valid,
1685 "Descriptor set %s encountered the following validation error at %s time: sampler (%s) "
1686 "in the descriptor set (%s) contains a YCBCR conversion (%s), then the sampler MUST "
1687 "also exist as an immutable sampler.",
1688 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(sampler).c_str(),
1689 report_data->FormatHandle(descriptor_set->GetSet()).c_str(),
1690 report_data->FormatHandle(sampler_state->samplerConversion).c_str());
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001691 }
1692 }
Tony-LunarGace473a2020-05-06 12:48:04 -06001693 return false;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001694}
Chris Forbes57989132016-07-26 17:06:10 +12001695
John Zulauf1d27e0a2018-11-05 10:12:48 -07001696// Loop through the write updates to do for a push descriptor set, ignoring dstSet
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001697void cvdescriptorset::DescriptorSet::PerformPushDescriptorsUpdate(ValidationStateTracker *dev_data, uint32_t write_count,
1698 const VkWriteDescriptorSet *p_wds) {
John Zulauf1d27e0a2018-11-05 10:12:48 -07001699 assert(IsPushDescriptor());
1700 for (uint32_t i = 0; i < write_count; i++) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001701 PerformWriteUpdate(dev_data, &p_wds[i]);
John Zulauf1d27e0a2018-11-05 10:12:48 -07001702 }
Jason Macnak83cfd582019-07-31 10:14:24 -07001703
1704 push_descriptor_set_writes.clear();
1705 push_descriptor_set_writes.reserve(static_cast<std::size_t>(write_count));
1706 for (uint32_t i = 0; i < write_count; i++) {
1707 push_descriptor_set_writes.push_back(safe_VkWriteDescriptorSet(&p_wds[i]));
1708 }
John Zulauf1d27e0a2018-11-05 10:12:48 -07001709}
1710
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001711// Perform write update in given update struct
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001712void cvdescriptorset::DescriptorSet::PerformWriteUpdate(ValidationStateTracker *dev_data, const VkWriteDescriptorSet *update) {
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001713 // Perform update on a per-binding basis as consecutive updates roll over to next binding
1714 auto descriptors_remaining = update->descriptorCount;
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001715 auto offset = update->dstArrayElement;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001716 auto orig_binding = DescriptorSetLayout::ConstBindingIterator(layout_.get(), update->dstBinding);
locke-lunarge46b7782019-09-10 01:44:20 -06001717 auto current_binding = orig_binding;
1718
Tobin Ehlise16805c2017-08-09 09:10:37 -06001719 uint32_t update_index = 0;
locke-lunarge46b7782019-09-10 01:44:20 -06001720 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
1721 while (descriptors_remaining && orig_binding.IsConsistent(current_binding)) {
1722 const auto &index_range = current_binding.GetGlobalIndexRange();
1723 auto global_idx = index_range.start + offset;
1724 // global_idx is which descriptor is needed to update. If global_idx > index_range.end, it means the descriptor isn't in
1725 // this binding, maybe in next binding.
1726 if (global_idx >= index_range.end) {
1727 offset -= current_binding.GetDescriptorCount();
1728 ++current_binding;
1729 continue;
1730 }
1731
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001732 // Loop over the updates for a single binding at a time
locke-lunarge46b7782019-09-10 01:44:20 -06001733 uint32_t update_count = std::min(descriptors_remaining, current_binding.GetDescriptorCount() - offset);
Tobin Ehlise16805c2017-08-09 09:10:37 -06001734 for (uint32_t di = 0; di < update_count; ++di, ++update_index) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001735 descriptors_[global_idx + di]->WriteUpdate(this, state_data_, update, update_index);
ziga-lunarge5d28542021-10-24 21:14:25 +02001736 descriptors_[global_idx + di]->SetDescriptorType(update->descriptorType);
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001737 }
1738 // Roll over to next binding in case of consecutive update
1739 descriptors_remaining -= update_count;
locke-lunarge46b7782019-09-10 01:44:20 -06001740 if (descriptors_remaining) {
1741 // Starting offset is beyond the current binding. Check consistency, update counters and advance to the next binding,
1742 // looking for the start point. All bindings (even those skipped) must be consistent with the update and with the
1743 // original binding.
1744 offset = 0;
1745 ++current_binding;
1746 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001747 }
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05001748 if (update->descriptorCount) {
1749 some_update_ = true;
1750 change_count_++;
1751 }
Tobin Ehlis56a30942016-05-19 08:00:00 -06001752
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001753 if (!IsPushDescriptor() && !(layout_->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08001754 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001755 Invalidate(false);
Jeff Bolzfdf96072018-04-10 14:32:18 -05001756 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001757}
Tobin Ehlis300888c2016-05-18 13:43:26 -06001758// Validate Copy update
John Zulaufc93c4252019-06-25 09:19:49 -06001759bool CoreChecks::ValidateCopyUpdate(const VkCopyDescriptorSet *update, const DescriptorSet *dst_set, const DescriptorSet *src_set,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001760 const char *func_name, std::string *error_code, std::string *error_msg) const {
Jeff Bolz6aad1742019-10-16 11:10:09 -05001761 auto dst_layout = dst_set->GetLayout().get();
1762 auto src_layout = src_set->GetLayout().get();
John Zulaufd9435c32019-06-05 15:55:36 -06001763
John Zulauf5dfd45c2018-01-17 11:06:34 -07001764 // Verify dst layout still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001765 if (dst_layout->Destroyed()) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001766 *error_code = "VUID-VkCopyDescriptorSet-dstSet-parameter";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06001767 std::ostringstream str;
1768 str << "Cannot call " << func_name << " to perform copy update on dstSet " << report_data->FormatHandle(dst_set->GetSet())
1769 << " created with destroyed " << report_data->FormatHandle(dst_layout->GetDescriptorSetLayout()) << ".";
1770 *error_msg = str.str();
John Zulauf5dfd45c2018-01-17 11:06:34 -07001771 return false;
1772 }
1773
1774 // Verify src layout still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001775 if (src_layout->Destroyed()) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001776 *error_code = "VUID-VkCopyDescriptorSet-srcSet-parameter";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06001777 std::ostringstream str;
1778 str << "Cannot call " << func_name << " to perform copy update on dstSet " << report_data->FormatHandle(dst_set->GetSet())
1779 << " from srcSet " << report_data->FormatHandle(src_set->GetSet()) << " created with destroyed "
1780 << report_data->FormatHandle(src_layout->GetDescriptorSetLayout()) << ".";
1781 *error_msg = str.str();
John Zulauf5dfd45c2018-01-17 11:06:34 -07001782 return false;
1783 }
1784
John Zulaufd9435c32019-06-05 15:55:36 -06001785 if (!dst_layout->HasBinding(update->dstBinding)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001786 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-00347";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001787 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001788 error_str << "DescriptorSet " << report_data->FormatHandle(dst_set->GetSet())
1789 << " does not have copy update dest binding of " << update->dstBinding;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001790 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001791 return false;
1792 }
1793 if (!src_set->HasBinding(update->srcBinding)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001794 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-00345";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001795 std::stringstream error_str;
sourav parmarf4a78252020-04-10 13:04:21 -07001796 error_str << "DescriptorSet " << report_data->FormatHandle(src_set->GetSet())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001797 << " does not have copy update src binding of " << update->srcBinding;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001798 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001799 return false;
1800 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001801 // Verify idle ds
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001802 if (dst_set->InUse() &&
John Zulaufd9435c32019-06-05 15:55:36 -06001803 !(dst_layout->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08001804 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeff Bolzfdf96072018-04-10 14:32:18 -05001805 // TODO : Re-using Free Idle error code, need copy update idle error code
Dave Houlton00c154e2018-05-24 13:20:50 -06001806 *error_code = "VUID-vkFreeDescriptorSets-pDescriptorSets-00309";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001807 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001808 error_str << "Cannot call " << func_name << " to perform copy update on descriptor set "
1809 << report_data->FormatHandle(dst_set->GetSet()) << " that is in use by a command buffer";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001810 *error_msg = error_str.str();
1811 return false;
1812 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001813 // src & dst set bindings are valid
1814 // Check bounds of src & dst
John Zulaufc483f442017-12-15 14:02:06 -07001815 auto src_start_idx = src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start + update->srcArrayElement;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001816 if ((src_start_idx + update->descriptorCount) > src_set->GetTotalDescriptorCount()) {
1817 // SRC update out of bounds
Dave Houlton00c154e2018-05-24 13:20:50 -06001818 *error_code = "VUID-VkCopyDescriptorSet-srcArrayElement-00346";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001819 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001820 error_str << "Attempting copy update from descriptorSet " << report_data->FormatHandle(update->srcSet) << " binding#"
1821 << update->srcBinding << " with offset index of "
1822 << src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start << " plus update array offset of "
1823 << update->srcArrayElement << " and update of " << update->descriptorCount
Tobin Ehlis1d81edd2016-11-21 09:50:49 -07001824 << " descriptors oversteps total number of descriptors in set: " << src_set->GetTotalDescriptorCount();
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001825 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001826 return false;
1827 }
John Zulaufd9435c32019-06-05 15:55:36 -06001828 auto dst_start_idx = dst_layout->GetGlobalIndexRangeFromBinding(update->dstBinding).start + update->dstArrayElement;
1829 if ((dst_start_idx + update->descriptorCount) > dst_layout->GetTotalDescriptorCount()) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001830 // DST update out of bounds
Dave Houlton00c154e2018-05-24 13:20:50 -06001831 *error_code = "VUID-VkCopyDescriptorSet-dstArrayElement-00348";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001832 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001833 error_str << "Attempting copy update to descriptorSet " << report_data->FormatHandle(dst_set->GetSet()) << " binding#"
1834 << update->dstBinding << " with offset index of "
1835 << dst_layout->GetGlobalIndexRangeFromBinding(update->dstBinding).start << " plus update array offset of "
1836 << update->dstArrayElement << " and update of " << update->descriptorCount
John Zulaufd9435c32019-06-05 15:55:36 -06001837 << " descriptors oversteps total number of descriptors in set: " << dst_layout->GetTotalDescriptorCount();
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001838 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001839 return false;
1840 }
1841 // Check that types match
Shannon McPhersonafe55122020-05-25 16:20:19 -06001842 // TODO : Base default error case going from here is "VUID-VkAcquireNextImageInfoKHR-semaphore-parameter" 2ba which covers all
Dave Houltond8ed0212018-05-16 17:18:24 -06001843 // consistency issues, need more fine-grained error codes
Dave Houlton00c154e2018-05-24 13:20:50 -06001844 *error_code = "VUID-VkCopyDescriptorSet-srcSet-00349";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001845 auto src_type = src_set->GetTypeFromBinding(update->srcBinding);
John Zulaufd9435c32019-06-05 15:55:36 -06001846 auto dst_type = dst_layout->GetTypeFromBinding(update->dstBinding);
Ricardo Garcia14f4f762021-04-13 11:36:12 +02001847 if (src_type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE && dst_type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE && src_type != dst_type) {
sourav parmarf4a78252020-04-10 13:04:21 -07001848 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02632";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001849 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001850 error_str << "Attempting copy update to descriptorSet " << report_data->FormatHandle(dst_set->GetSet()) << " binding #"
1851 << update->dstBinding << " with type " << string_VkDescriptorType(dst_type) << " from descriptorSet "
1852 << report_data->FormatHandle(src_set->GetSet()) << " binding #" << update->srcBinding << " with type "
1853 << string_VkDescriptorType(src_type) << ". Types do not match";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001854 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001855 return false;
1856 }
1857 // Verify consistency of src & dst bindings if update crosses binding boundaries
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001858 if ((!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(src_layout, update->srcBinding),
John Zulauf4a015c92019-06-04 09:50:05 -06001859 update->srcArrayElement, update->descriptorCount, "copy update from", src_set->GetSet(),
1860 error_msg)) ||
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001861 (!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(dst_layout, update->dstBinding),
John Zulaufd9435c32019-06-05 15:55:36 -06001862 update->dstArrayElement, update->descriptorCount, "copy update to", dst_set->GetSet(),
1863 error_msg))) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001864 return false;
1865 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001866
Mike Schuchardt2df08912020-12-15 16:28:09 -08001867 if ((src_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) &&
1868 !(dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001869 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01918";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001870 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001871 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001872 << ") layout was created with the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001873 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001874 "set, then pname:dstSet's ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001875 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001876 << ") layout must: also have been created with the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001877 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001878 *error_msg = error_str.str();
1879 return false;
1880 }
1881
sfricke-samsung45996a42021-09-16 13:45:27 -07001882 if (IsExtEnabled(device_extensions.vk_valve_mutable_descriptor_type)) {
Mike Schuchardt294a1592021-05-12 15:38:00 -07001883 if (!(src_layout->GetCreateFlags() & (VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT |
1884 VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE)) &&
1885 (dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
1886 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04885";
1887 std::stringstream error_str;
1888 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
1889 << ") layout was created with neither ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT nor "
1890 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE flags set, then pname:dstSet's ("
1891 << report_data->FormatHandle(update->dstSet)
1892 << ") layout must: have been created without the "
1893 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
1894 *error_msg = error_str.str();
1895 return false;
1896 }
1897 } else {
1898 if (!(src_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) &&
1899 (dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
1900 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04886";
1901 std::stringstream error_str;
1902 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
1903 << ") layout was created without the ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag "
1904 "set, then pname:dstSet's ("
1905 << report_data->FormatHandle(update->dstSet)
1906 << ") layout must: also have been created without the "
1907 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
1908 *error_msg = error_str.str();
1909 return false;
1910 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001911 }
1912
Mike Schuchardt2df08912020-12-15 16:28:09 -08001913 if ((src_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT) &&
1914 !(dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001915 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01920";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001916 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001917 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001918 << ") was allocated was created "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001919 "with the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001920 "set, then the descriptor pool from which pname:dstSet ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001921 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001922 << ") was allocated must: "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001923 "also have been created with the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001924 *error_msg = error_str.str();
1925 return false;
1926 }
1927
sfricke-samsung45996a42021-09-16 13:45:27 -07001928 if (IsExtEnabled(device_extensions.vk_valve_mutable_descriptor_type)) {
Mike Schuchardt294a1592021-05-12 15:38:00 -07001929 if (!(src_set->GetPoolState()->createInfo.flags &
1930 (VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) &&
1931 (dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
1932 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04887";
1933 std::stringstream error_str;
1934 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
1935 << ") was allocated was created with neither ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT nor "
1936 "ename:VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE flags set, then the descriptor pool from which "
1937 "pname:dstSet ("
1938 << report_data->FormatHandle(update->dstSet)
1939 << ") was allocated must: have been created without the "
1940 "ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
1941 *error_msg = error_str.str();
1942 return false;
1943 }
1944 } else {
1945 if (!(src_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT) &&
1946 (dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
1947 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04888";
1948 std::stringstream error_str;
1949 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
1950 << ") was allocated was created without the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set, "
1951 "then the descriptor pool from which pname:dstSet ("
1952 << report_data->FormatHandle(update->dstSet)
1953 << ") was allocated must: also have been created without the "
1954 "ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
1955 *error_msg = error_str.str();
1956 return false;
1957 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001958 }
1959
Jeff Bolze54ae892018-09-08 12:16:29 -05001960 if (src_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
1961 if ((update->srcArrayElement % 4) != 0) {
1962 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-02223";
1963 std::stringstream error_str;
1964 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
1965 << "srcArrayElement " << update->srcArrayElement << " not a multiple of 4";
1966 *error_msg = error_str.str();
1967 return false;
1968 }
1969 if ((update->dstArrayElement % 4) != 0) {
1970 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02224";
1971 std::stringstream error_str;
1972 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
1973 << "dstArrayElement " << update->dstArrayElement << " not a multiple of 4";
1974 *error_msg = error_str.str();
1975 return false;
1976 }
1977 if ((update->descriptorCount % 4) != 0) {
1978 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-02225";
1979 std::stringstream error_str;
1980 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
1981 << "descriptorCount " << update->descriptorCount << " not a multiple of 4";
1982 *error_msg = error_str.str();
1983 return false;
1984 }
1985 }
1986
ziga-lunarge5d28542021-10-24 21:14:25 +02001987 if (dst_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
1988 if (src_type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
1989 if (!dst_layout->IsTypeMutable(src_type, update->dstBinding)) {
1990 *error_code = "VUID-VkCopyDescriptorSet-dstSet-04612";
1991 std::stringstream error_str;
1992 error_str << "Attempting copy update with dstBinding descriptor type VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, but the new "
1993 "active descriptor type "
1994 << string_VkDescriptorType(src_type)
1995 << " is not in the corresponding pMutableDescriptorTypeLists list.";
1996 *error_msg = error_str.str();
1997 return false;
1998 }
1999 }
2000 } else if (src_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2001 const auto *descriptor = src_set->GetDescriptorFromGlobalIndex(update->srcBinding);
2002 if (descriptor->active_descriptor_type != dst_type) {
2003 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04613";
2004 std::stringstream error_str;
2005 error_str << "Attempting copy update with srcBinding descriptor type VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, but the "
2006 "active descriptor type ("
2007 << string_VkDescriptorType(descriptor->active_descriptor_type)
2008 << ") does not match the dstBinding descriptor type " << string_VkDescriptorType(dst_type) << ".";
2009 *error_msg = error_str.str();
2010 return false;
2011 }
2012 }
2013
2014 if (dst_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2015 if (src_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2016 const auto &mutable_src_types = src_layout->GetMutableTypes(update->srcBinding);
2017 const auto &mutable_dst_types = dst_layout->GetMutableTypes(update->dstBinding);
2018 bool complete_match = mutable_src_types.size() == mutable_dst_types.size();
2019 if (complete_match) {
2020 for (const auto mutable_src_type : mutable_src_types) {
2021 if (std::find(mutable_dst_types.begin(), mutable_dst_types.end(), mutable_src_type) ==
2022 mutable_dst_types.end()) {
2023 complete_match = false;
2024 break;
2025 }
2026 }
2027 }
2028 if (!complete_match) {
2029 *error_code = "VUID-VkCopyDescriptorSet-dstSet-04614";
2030 std::stringstream error_str;
2031 error_str << "Attempting copy update with dstBinding and new active descriptor type being "
2032 "VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, but their corresponding pMutableDescriptorTypeLists do not match.";
2033 *error_msg = error_str.str();
2034 return false;
2035 }
2036 }
2037 }
2038
Tobin Ehlisd41e7b62016-05-19 07:56:18 -06002039 // Update parameters all look good and descriptor updated so verify update contents
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002040 if (!VerifyCopyUpdateContents(update, src_set, src_type, src_start_idx, dst_set, dst_type, dst_start_idx, func_name, error_code,
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002041 error_msg)) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002042 return false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002043 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002044
2045 // All checks passed so update is good
2046 return true;
2047}
2048// Perform Copy update
Jeff Bolz41a1ced2019-10-11 11:40:49 -05002049void cvdescriptorset::DescriptorSet::PerformCopyUpdate(ValidationStateTracker *dev_data, const VkCopyDescriptorSet *update,
2050 const DescriptorSet *src_set) {
John Zulaufc483f442017-12-15 14:02:06 -07002051 auto src_start_idx = src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start + update->srcArrayElement;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002052 auto dst_start_idx = layout_->GetGlobalIndexRangeFromBinding(update->dstBinding).start + update->dstArrayElement;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002053 // Update parameters all look good so perform update
2054 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Józef Kucia5297e372017-10-13 22:31:34 +02002055 auto src = src_set->descriptors_[src_start_idx + di].get();
2056 auto dst = descriptors_[dst_start_idx + di].get();
2057 if (src->updated) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002058 dst->CopyUpdate(this, state_data_, src);
Józef Kucia5297e372017-10-13 22:31:34 +02002059 some_update_ = true;
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05002060 change_count_++;
Józef Kucia5297e372017-10-13 22:31:34 +02002061 } else {
2062 dst->updated = false;
2063 }
ziga-lunarge5d28542021-10-24 21:14:25 +02002064 dst->active_descriptor_type = src->active_descriptor_type;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002065 }
Tobin Ehlis56a30942016-05-19 08:00:00 -06002066
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002067 if (!(layout_->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08002068 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002069 Invalidate(false);
Jeff Bolzfdf96072018-04-10 14:32:18 -05002070 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002071}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002072
John Zulauf6f3d2bd2018-10-29 17:08:42 -06002073// Update the drawing state for the affected descriptors.
2074// Set cb_node to this set and this set to cb_node.
2075// Add the bindings of the descriptor
2076// Set the layout based on the current descriptor layout (will mask subsequent layer mismatch errors)
2077// TODO: Modify the UpdateDrawState virtural functions to *only* set initial layout and not change layouts
Tobin Ehlisf9519102016-08-17 09:49:13 -06002078// Prereq: This should be called for a set that has been confirmed to be active for the given cb_node, meaning it's going
2079// to be used in a draw by the given cb_node
Jeremy Kniagere6827432020-04-01 09:05:56 -06002080void cvdescriptorset::DescriptorSet::UpdateDrawState(ValidationStateTracker *device_data, CMD_BUFFER_STATE *cb_node,
2081 CMD_TYPE cmd_type, const PIPELINE_STATE *pipe,
sfricke-samsung85584a72021-09-30 21:43:38 -07002082 const BindingReqMap &binding_req_map) {
Tony-LunarG77822802020-05-28 16:35:46 -06002083 if (!device_data->disabled[command_buffer_state] && !IsPushDescriptor()) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002084 cb_node->AddChild(this);
Jeff Bolzafa429a2019-08-14 09:59:22 -05002085 }
Jeff Bolze18e7242019-08-12 20:55:22 -05002086
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002087 // Descriptor UpdateDrawState only call image layout validation callbacks. If it is disabled, skip the entire loop.
2088 if (device_data->disabled[image_layout_validation]) {
Jeff Bolze18e7242019-08-12 20:55:22 -05002089 return;
2090 }
2091
Tobin Ehlisf9519102016-08-17 09:49:13 -06002092 // For the active slots, use set# to look up descriptorSet from boundDescriptorSets, and bind all of that descriptor set's
2093 // resources
locke-lunarg540b2252020-08-03 13:23:36 -06002094 CMD_BUFFER_STATE::CmdDrawDispatchInfo cmd_info = {};
John Zulauf79f06582021-02-27 18:38:39 -07002095 for (const auto &binding_req_pair : binding_req_map) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002096 auto index = layout_->GetIndexFromBinding(binding_req_pair.first);
locke-gb3ce08f2019-09-30 12:30:56 -06002097
Tony-LunarG62c5dba2018-12-20 14:27:23 -07002098 // We aren't validating descriptors created with PARTIALLY_BOUND or UPDATE_AFTER_BIND, so don't record state
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002099 auto flags = layout_->GetDescriptorBindingFlagsFromIndex(index);
Mike Schuchardt2df08912020-12-15 16:28:09 -08002100 if (flags & (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT)) {
2101 if (!(flags & VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT)) {
locke-lunarg36045992020-08-20 16:54:37 -06002102 cmd_info.binding_infos.emplace_back(binding_req_pair);
locke-gb3ce08f2019-09-30 12:30:56 -06002103 }
Tony-LunarG62c5dba2018-12-20 14:27:23 -07002104 continue;
2105 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002106 auto range = layout_->GetGlobalIndexRangeFromIndex(index);
John Zulaufc483f442017-12-15 14:02:06 -07002107 for (uint32_t i = range.start; i < range.end; ++i) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002108 const auto descriptor_class = descriptors_[i]->GetClass();
2109 switch (descriptor_class) {
2110 case DescriptorClass::Image:
2111 case DescriptorClass::ImageSampler: {
2112 auto *image_desc = static_cast<ImageDescriptor *>(descriptors_[i].get());
2113 image_desc->UpdateDrawState(device_data, cb_node);
2114 break;
2115 }
2116 default:
2117 break;
2118 }
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06002119 }
2120 }
locke-lunarg540b2252020-08-03 13:23:36 -06002121
2122 if (cmd_info.binding_infos.size() > 0) {
2123 cmd_info.cmd_type = cmd_type;
locke-lunarg540b2252020-08-03 13:23:36 -06002124 if (cb_node->activeFramebuffer) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002125 cmd_info.framebuffer = cb_node->activeFramebuffer->framebuffer();
locke-lunargfc78e932020-11-19 17:06:24 -07002126 cmd_info.attachments = cb_node->active_attachments;
2127 cmd_info.subpasses = cb_node->active_subpasses;
locke-lunarg540b2252020-08-03 13:23:36 -06002128 }
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002129 cb_node->validate_descriptorsets_in_queuesubmit[GetSet()].emplace_back(cmd_info);
locke-lunarg540b2252020-08-03 13:23:36 -06002130 }
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06002131}
2132
John Zulauffbf3c202019-07-17 14:57:14 -06002133void cvdescriptorset::DescriptorSet::FilterOneBindingReq(const BindingReqMap::value_type &binding_req_pair, BindingReqMap *out_req,
2134 const TrackedBindings &bindings, uint32_t limit) {
2135 if (bindings.size() < limit) {
2136 const auto it = bindings.find(binding_req_pair.first);
2137 if (it == bindings.cend()) out_req->emplace(binding_req_pair);
John Zulauf48a6a702017-12-22 17:14:54 -07002138 }
2139}
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06002140
John Zulauffbf3c202019-07-17 14:57:14 -06002141void cvdescriptorset::DescriptorSet::FilterBindingReqs(const CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline,
2142 const BindingReqMap &in_req, BindingReqMap *out_req) const {
2143 // For const cleanliness we have to find in the maps...
Jeremy Gebben87db52f2021-10-14 13:55:09 -06002144 const auto validated_it = cb_state.descriptorset_cache.find(this);
2145 if (validated_it == cb_state.descriptorset_cache.end()) {
John Zulauffbf3c202019-07-17 14:57:14 -06002146 // We have nothing validated, copy in to out
2147 for (const auto &binding_req_pair : in_req) {
2148 out_req->emplace(binding_req_pair);
John Zulauf48a6a702017-12-22 17:14:54 -07002149 }
John Zulauffbf3c202019-07-17 14:57:14 -06002150 return;
John Zulauf48a6a702017-12-22 17:14:54 -07002151 }
John Zulauffbf3c202019-07-17 14:57:14 -06002152 const auto &validated = validated_it->second;
John Zulauf48a6a702017-12-22 17:14:54 -07002153
John Zulauffbf3c202019-07-17 14:57:14 -06002154 const auto image_sample_version_it = validated.image_samplers.find(&pipeline);
2155 const VersionedBindings *image_sample_version = nullptr;
2156 if (image_sample_version_it != validated.image_samplers.cend()) {
2157 image_sample_version = &(image_sample_version_it->second);
2158 }
2159 const auto &dynamic_buffers = validated.dynamic_buffers;
2160 const auto &non_dynamic_buffers = validated.non_dynamic_buffers;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002161 const auto &stats = layout_->GetBindingTypeStats();
John Zulauf48a6a702017-12-22 17:14:54 -07002162 for (const auto &binding_req_pair : in_req) {
2163 auto binding = binding_req_pair.first;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002164 VkDescriptorSetLayoutBinding const *layout_binding = layout_->GetDescriptorSetLayoutBindingPtrFromBinding(binding);
John Zulauf48a6a702017-12-22 17:14:54 -07002165 if (!layout_binding) {
2166 continue;
2167 }
2168 // Caching criteria differs per type.
2169 // If image_layout have changed , the image descriptors need to be validated against them.
sfricke-samsung60f29ec2021-03-10 20:37:25 -08002170 if (IsBufferDescriptor(layout_binding->descriptorType)) {
2171 if (IsDynamicDescriptor(layout_binding->descriptorType)) {
2172 FilterOneBindingReq(binding_req_pair, out_req, dynamic_buffers, stats.dynamic_buffer_count);
2173 } else {
2174 FilterOneBindingReq(binding_req_pair, out_req, non_dynamic_buffers, stats.non_dynamic_buffer_count);
2175 }
John Zulauf48a6a702017-12-22 17:14:54 -07002176 } else {
2177 // This is rather crude, as the changed layouts may not impact the bound descriptors,
2178 // but the simple "versioning" is a simple "dirt" test.
John Zulauffbf3c202019-07-17 14:57:14 -06002179 bool stale = true;
2180 if (image_sample_version) {
2181 const auto version_it = image_sample_version->find(binding);
2182 if (version_it != image_sample_version->cend() && (version_it->second == cb_state.image_layout_change_count)) {
2183 stale = false;
2184 }
2185 }
2186 if (stale) {
John Zulauf48a6a702017-12-22 17:14:54 -07002187 out_req->emplace(binding_req_pair);
2188 }
2189 }
2190 }
2191}
Tobin Ehlis9252c2b2016-07-21 14:40:22 -06002192
Jeremy Gebben87db52f2021-10-14 13:55:09 -06002193void cvdescriptorset::DescriptorSet::UpdateValidationCache(CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline,
John Zulauffbf3c202019-07-17 14:57:14 -06002194 const BindingReqMap &updated_bindings) {
Jeremy Gebben87db52f2021-10-14 13:55:09 -06002195 auto &validated = cb_state.descriptorset_cache[this];
John Zulauffbf3c202019-07-17 14:57:14 -06002196
2197 auto &image_sample_version = validated.image_samplers[&pipeline];
2198 auto &dynamic_buffers = validated.dynamic_buffers;
2199 auto &non_dynamic_buffers = validated.non_dynamic_buffers;
2200 for (const auto &binding_req_pair : updated_bindings) {
2201 auto binding = binding_req_pair.first;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002202 VkDescriptorSetLayoutBinding const *layout_binding = layout_->GetDescriptorSetLayoutBindingPtrFromBinding(binding);
John Zulauffbf3c202019-07-17 14:57:14 -06002203 if (!layout_binding) {
2204 continue;
2205 }
2206 // Caching criteria differs per type.
sfricke-samsung60f29ec2021-03-10 20:37:25 -08002207 if (IsBufferDescriptor(layout_binding->descriptorType)) {
2208 if (IsDynamicDescriptor(layout_binding->descriptorType)) {
2209 dynamic_buffers.emplace(binding);
2210 } else {
2211 non_dynamic_buffers.emplace(binding);
2212 }
John Zulauffbf3c202019-07-17 14:57:14 -06002213 } else {
2214 // Save the layout change version...
2215 image_sample_version[binding] = cb_state.image_layout_change_count;
2216 }
2217 }
2218}
2219
John Zulaufd2c3dae2019-12-12 11:02:17 -07002220cvdescriptorset::SamplerDescriptor::SamplerDescriptor(const ValidationStateTracker *dev_data, const VkSampler *immut)
Jeremy Gebben059ab502021-04-26 11:25:02 -06002221 : Descriptor(PlainSampler), immutable_(false) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002222 if (immut) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002223 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(*immut);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002224 immutable_ = true;
2225 updated = true;
2226 }
2227}
Tobin Ehlise2f80292016-06-02 10:08:53 -06002228// Validate given sampler. Currently this only checks to make sure it exists in the samplerMap
John Zulaufc93c4252019-06-25 09:19:49 -06002229bool CoreChecks::ValidateSampler(const VkSampler sampler) const { return (GetSamplerState(sampler) != nullptr); }
Tobin Ehlis56a30942016-05-19 08:00:00 -06002230
John Zulaufc93c4252019-06-25 09:19:49 -06002231bool CoreChecks::ValidateImageUpdate(VkImageView image_view, VkImageLayout image_layout, VkDescriptorType type,
John Zulaufbd9b3412019-08-22 17:16:11 -06002232 const char *func_name, std::string *error_code, std::string *error_msg) const {
John Zulaufc93c4252019-06-25 09:19:49 -06002233 auto iv_state = GetImageViewState(image_view);
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002234 assert(iv_state);
2235
Tobin Ehlis81280962016-07-20 14:04:20 -06002236 // Note that when an imageview is created, we validated that memory is bound so no need to re-check here
Tobin Ehlis1809f912016-05-25 09:24:36 -06002237 // Validate that imageLayout is compatible with aspect_mask and image format
2238 // and validate that image usage bits are correct for given usage
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06002239 VkImageAspectFlags aspect_mask = iv_state->normalized_subresource_range.aspectMask;
Tobin Ehlis8b26a382016-09-14 08:02:49 -06002240 VkImage image = iv_state->create_info.image;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002241 VkFormat format = VK_FORMAT_MAX_ENUM;
2242 VkImageUsageFlags usage = 0;
John Zulaufc93c4252019-06-25 09:19:49 -06002243 auto image_node = GetImageState(image);
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002244 assert(image_node);
Chris Forbes67757ff2017-07-21 13:59:01 -07002245
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002246 format = image_node->createInfo.format;
2247 usage = image_node->createInfo.usage;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002248 const auto stencil_usage_info = LvlFindInChain<VkImageStencilUsageCreateInfo>(image_node->createInfo.pNext);
Ricardo Garcia3f5984c2020-04-09 10:56:34 +02002249 if (stencil_usage_info) {
2250 usage |= stencil_usage_info->stencilUsage;
2251 }
Mark Lobodzinski03d00062020-06-15 14:35:45 -06002252
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002253 // Validate that memory is bound to image
sfricke-samsung52dbd082021-09-23 11:17:58 -07002254 if (ValidateMemoryIsBoundToImage(image_node, func_name, kVUID_Core_Bound_Resource_FreedMemoryAccess)) {
2255 *error_code = kVUID_Core_Bound_Resource_FreedMemoryAccess;
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002256 *error_msg = "No memory bound to image.";
Tobin Ehlis1809f912016-05-25 09:24:36 -06002257 return false;
2258 }
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002259
2260 // KHR_maintenance1 allows rendering into 2D or 2DArray views which slice a 3D image,
2261 // but not binding them to descriptor sets.
Jeremy Gebben11a68a32021-07-29 11:59:22 -06002262 if (iv_state->IsDepthSliced()) {
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002263 *error_code = "VUID-VkDescriptorImageInfo-imageView-00343";
2264 *error_msg = "ImageView must not be a 2D or 2DArray view of a 3D image";
2265 return false;
2266 }
2267
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002268 // TODO : The various image aspect and format checks here are based on general spec language in 11.5 Image Views section under
2269 // vkCreateImageView(). What's the best way to create unique id for these cases?
sfricke-samsung52dbd082021-09-23 11:17:58 -07002270 *error_code = kVUID_Core_DrawState_InvalidImageView;
Dave Houlton1d2022c2017-03-29 11:43:58 -06002271 bool ds = FormatIsDepthOrStencil(format);
Tobin Ehlis1809f912016-05-25 09:24:36 -06002272 switch (image_layout) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002273 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
2274 // Only Color bit must be set
2275 if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
Tobin Ehlis1809f912016-05-25 09:24:36 -06002276 std::stringstream error_str;
Dave Houltona9df0ce2018-02-07 10:51:23 -07002277 error_str
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002278 << "ImageView (" << report_data->FormatHandle(image_view)
Dave Houltona9df0ce2018-02-07 10:51:23 -07002279 << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but does not have VK_IMAGE_ASPECT_COLOR_BIT set.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002280 *error_msg = error_str.str();
Tobin Ehlis1809f912016-05-25 09:24:36 -06002281 return false;
2282 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002283 // format must NOT be DS
2284 if (ds) {
2285 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002286 error_str << "ImageView (" << report_data->FormatHandle(image_view)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002287 << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but the image format is "
2288 << string_VkFormat(format) << " which is not a color format.";
2289 *error_msg = error_str.str();
2290 return false;
2291 }
2292 break;
2293 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
2294 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
2295 // Depth or stencil bit must be set, but both must NOT be set
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06002296 if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
2297 if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2298 // both must NOT be set
2299 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002300 error_str << "ImageView (" << report_data->FormatHandle(image_view)
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002301 << ") has both STENCIL and DEPTH aspects set";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002302 *error_msg = error_str.str();
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06002303 return false;
2304 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002305 } else if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
2306 // Neither were set
2307 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002308 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002309 << string_VkImageLayout(image_layout) << " but does not have STENCIL or DEPTH aspects set";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002310 *error_msg = error_str.str();
2311 return false;
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06002312 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002313 // format must be DS
2314 if (!ds) {
2315 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002316 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002317 << string_VkImageLayout(image_layout) << " but the image format is " << string_VkFormat(format)
2318 << " which is not a depth/stencil format.";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002319 *error_msg = error_str.str();
2320 return false;
2321 }
2322 break;
2323 default:
2324 // For other layouts if the source is depth/stencil image, both aspect bits must not be set
2325 if (ds) {
2326 if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
2327 if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2328 // both must NOT be set
2329 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002330 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002331 << string_VkImageLayout(image_layout) << " and is using depth/stencil image of format "
2332 << string_VkFormat(format)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002333 << " but it has both STENCIL and DEPTH aspects set, which is illegal. When using a depth/stencil "
2334 "image in a descriptor set, please only set either VK_IMAGE_ASPECT_DEPTH_BIT or "
2335 "VK_IMAGE_ASPECT_STENCIL_BIT depending on whether it will be used for depth reads or stencil "
2336 "reads respectively.";
Mark Lobodzinski4d05d7a2019-06-25 09:12:06 -06002337 *error_code = "VUID-VkDescriptorImageInfo-imageView-01976";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002338 *error_msg = error_str.str();
2339 return false;
2340 }
2341 }
2342 }
2343 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002344 }
2345 // Now validate that usage flags are correctly set for given type of update
Tobin Ehlisfb4cf712016-10-10 14:02:48 -06002346 // As we're switching per-type, if any type has specific layout requirements, check those here as well
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002347 // TODO : The various image usage bit requirements are in general spec language for VkImageUsageFlags bit block in 11.3 Images
2348 // under vkCreateImage()
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002349 const char *error_usage_bit = nullptr;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002350 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002351 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
sfricke-samsung088f1242020-06-06 02:15:35 -07002352 if (iv_state->samplerConversion != VK_NULL_HANDLE) {
2353 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-01946";
2354 std::stringstream error_str;
2355 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ")"
2356 << "used as a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE can't be created with VkSamplerYcbcrConversion";
2357 *error_msg = error_str.str();
2358 return false;
2359 }
2360 // drop through
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002361 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
2362 if (!(usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
2363 error_usage_bit = "VK_IMAGE_USAGE_SAMPLED_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002364 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00337";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002365 }
2366 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002367 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002368 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
2369 if (!(usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
2370 error_usage_bit = "VK_IMAGE_USAGE_STORAGE_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002371 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00339";
sfricke-samsung45996a42021-09-16 13:45:27 -07002372 } else if ((VK_IMAGE_LAYOUT_GENERAL != image_layout) &&
2373 (!IsExtEnabled(device_extensions.vk_khr_shared_presentable_image) ||
2374 (VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR != image_layout))) {
sfricke-samsungf1058982020-09-10 22:36:49 -07002375 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04152";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002376 std::stringstream error_str;
sfricke-samsungada55a12020-08-15 03:39:41 -07002377 error_str << "Descriptor update with descriptorType VK_DESCRIPTOR_TYPE_STORAGE_IMAGE"
2378 << " is being updated with invalid imageLayout " << string_VkImageLayout(image_layout) << " for image "
2379 << report_data->FormatHandle(image) << " in imageView " << report_data->FormatHandle(image_view)
2380 << ". Allowed layouts are: VK_IMAGE_LAYOUT_GENERAL";
sfricke-samsung45996a42021-09-16 13:45:27 -07002381 if (IsExtEnabled(device_extensions.vk_khr_shared_presentable_image)) {
sfricke-samsungada55a12020-08-15 03:39:41 -07002382 error_str << " or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR";
Tobin Ehlisbb03e5f2017-05-11 08:52:51 -06002383 }
sfricke-samsungada55a12020-08-15 03:39:41 -07002384 *error_msg = error_str.str();
2385 return false;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002386 }
2387 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002388 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002389 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
2390 if (!(usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
2391 error_usage_bit = "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002392 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00338";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002393 }
2394 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002395 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002396 default:
2397 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002398 }
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002399 if (error_usage_bit) {
Tobin Ehlis1809f912016-05-25 09:24:36 -06002400 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002401 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") with usage mask " << std::hex << std::showbase
2402 << usage << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
2403 << error_usage_bit << " set.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002404 *error_msg = error_str.str();
Tobin Ehlis1809f912016-05-25 09:24:36 -06002405 return false;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002406 }
John Zulauff4c07882019-01-24 14:03:36 -07002407
sfricke-samsungada55a12020-08-15 03:39:41 -07002408 // All the following types share the same image layouts
2409 // checkf or Storage Images above
2410 if ((type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
2411 (type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
John Zulauff4c07882019-01-24 14:03:36 -07002412 // Test that the layout is compatible with the descriptorType for the two sampled image types
2413 const static std::array<VkImageLayout, 3> valid_layouts = {
Jeremy Hayesd0549f62019-06-05 10:15:36 -06002414 {VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL}};
John Zulauff4c07882019-01-24 14:03:36 -07002415
2416 struct ExtensionLayout {
2417 VkImageLayout layout;
Tony-LunarG2ec96bb2019-11-26 13:43:02 -07002418 ExtEnabled DeviceExtensions::*extension;
John Zulauff4c07882019-01-24 14:03:36 -07002419 };
Ricardo Garcia602c2022021-07-30 10:42:17 +02002420 const static std::array<ExtensionLayout, 7> extended_layouts{{
Jeremy Gebben579aaca2021-02-15 13:36:18 -07002421 // Note double brace req'd for aggregate initialization
2422 {VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, &DeviceExtensions::vk_khr_shared_presentable_image},
2423 {VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, &DeviceExtensions::vk_khr_maintenance2},
2424 {VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, &DeviceExtensions::vk_khr_maintenance2},
Mike Schuchardtc57de4a2021-07-20 17:26:32 -07002425 {VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, &DeviceExtensions::vk_khr_synchronization2},
2426 {VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, &DeviceExtensions::vk_khr_synchronization2},
Ricardo Garcia602c2022021-07-30 10:42:17 +02002427 {VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, &DeviceExtensions::vk_khr_separate_depth_stencil_layouts},
2428 {VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, &DeviceExtensions::vk_khr_separate_depth_stencil_layouts},
Jeremy Gebben579aaca2021-02-15 13:36:18 -07002429 }};
John Zulaufc93c4252019-06-25 09:19:49 -06002430 auto is_layout = [image_layout, this](const ExtensionLayout &ext_layout) {
sfricke-samsung45996a42021-09-16 13:45:27 -07002431 return IsExtEnabled(device_extensions.*(ext_layout.extension)) && (ext_layout.layout == image_layout);
John Zulauff4c07882019-01-24 14:03:36 -07002432 };
2433
2434 bool valid_layout = (std::find(valid_layouts.cbegin(), valid_layouts.cend(), image_layout) != valid_layouts.cend()) ||
2435 std::any_of(extended_layouts.cbegin(), extended_layouts.cend(), is_layout);
2436
2437 if (!valid_layout) {
sfricke-samsungf1058982020-09-10 22:36:49 -07002438 // The following works as currently all 3 descriptor types share the same set of valid layouts
sfricke-samsungada55a12020-08-15 03:39:41 -07002439 switch (type) {
2440 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002441 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04149";
sfricke-samsungada55a12020-08-15 03:39:41 -07002442 break;
2443 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002444 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04150";
sfricke-samsungada55a12020-08-15 03:39:41 -07002445 break;
2446 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
sfricke-samsungf1058982020-09-10 22:36:49 -07002447 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04151";
sfricke-samsungada55a12020-08-15 03:39:41 -07002448 break;
2449 default:
2450 break;
2451 }
John Zulauff4c07882019-01-24 14:03:36 -07002452 std::stringstream error_str;
2453 error_str << "Descriptor update with descriptorType " << string_VkDescriptorType(type)
Mark Lobodzinski74eddba2019-06-21 14:16:33 -06002454 << " is being updated with invalid imageLayout " << string_VkImageLayout(image_layout) << " for image "
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002455 << report_data->FormatHandle(image) << " in imageView " << report_data->FormatHandle(image_view)
John Zulauff4c07882019-01-24 14:03:36 -07002456 << ". Allowed layouts are: VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "
2457 << "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL";
2458 for (auto &ext_layout : extended_layouts) {
sfricke-samsung45996a42021-09-16 13:45:27 -07002459 if (IsExtEnabled(device_extensions.*(ext_layout.extension))) {
John Zulauff4c07882019-01-24 14:03:36 -07002460 error_str << ", " << string_VkImageLayout(ext_layout.layout);
2461 }
2462 }
2463 *error_msg = error_str.str();
2464 return false;
2465 }
2466 }
2467
sfricke-samsungbd0e8052020-06-06 01:36:39 -07002468 if ((type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) || (type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
2469 const VkComponentMapping components = iv_state->create_info.components;
2470 if (IsIdentitySwizzle(components) == false) {
2471 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00336";
2472 std::stringstream error_str;
2473 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has a non-identiy swizzle component, "
2474 << " r swizzle = " << string_VkComponentSwizzle(components.r) << ","
2475 << " g swizzle = " << string_VkComponentSwizzle(components.g) << ","
2476 << " b swizzle = " << string_VkComponentSwizzle(components.b) << ","
2477 << " a swizzle = " << string_VkComponentSwizzle(components.a) << ".";
2478 *error_msg = error_str.str();
2479 return false;
2480 }
2481 }
2482
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002483 return true;
2484}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002485
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002486// Helper template to change shared pointer members of a Descriptor, while
2487// correctly managing links to the parent DescriptorSet.
2488// src and dst are shared pointers.
2489template <typename T>
2490static void ReplaceStatePtr(DescriptorSet *set_state, T &dst, const T &src) {
2491 if (dst) {
2492 dst->RemoveParent(set_state);
2493 }
2494 dst = src;
2495 if (dst) {
2496 dst->AddParent(set_state);
2497 }
2498}
2499
2500void cvdescriptorset::SamplerDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2501 const VkWriteDescriptorSet *update, const uint32_t index) {
Chris Forbesfea2c542018-04-13 09:34:15 -07002502 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002503 ReplaceStatePtr(set_state, sampler_state_ , dev_data->GetConstCastShared<SAMPLER_STATE>(update->pImageInfo[index].sampler));
Chris Forbesfea2c542018-04-13 09:34:15 -07002504 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002505 updated = true;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002506}
2507
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002508void cvdescriptorset::SamplerDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2509 const Descriptor *src) {
Tony-LunarG80358322021-04-16 07:58:13 -06002510 updated = true;
2511 // Mutable descriptors not currently tracked or validated. If copied from mutable, set to mutable to keep from validating.
2512 if (src->descriptor_class == Mutable) {
2513 this->descriptor_class = Mutable;
2514 return;
2515 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002516 auto *sampler_src = static_cast<const SamplerDescriptor *>(src);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002517 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002518 ReplaceStatePtr(set_state, sampler_state_, sampler_src->sampler_state_);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002519 }
2520}
2521
John Zulaufd2c3dae2019-12-12 11:02:17 -07002522cvdescriptorset::ImageSamplerDescriptor::ImageSamplerDescriptor(const ValidationStateTracker *dev_data, const VkSampler *immut)
Jeremy Gebben059ab502021-04-26 11:25:02 -06002523 : ImageDescriptor(ImageSampler), immutable_(false) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002524 if (immut) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002525 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(*immut);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002526 immutable_ = true;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002527 }
2528}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002529
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002530void cvdescriptorset::ImageSamplerDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
John Zulaufd2c3dae2019-12-12 11:02:17 -07002531 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002532 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002533 const auto &image_info = update->pImageInfo[index];
Chris Forbesfea2c542018-04-13 09:34:15 -07002534 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002535 ReplaceStatePtr(set_state, sampler_state_, dev_data->GetConstCastShared<SAMPLER_STATE>(image_info.sampler));
Chris Forbesfea2c542018-04-13 09:34:15 -07002536 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002537 image_layout_ = image_info.imageLayout;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002538 ReplaceStatePtr(set_state, image_view_state_, dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView));
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002539}
2540
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002541void cvdescriptorset::ImageSamplerDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2542 const Descriptor *src) {
Tony-LunarG80358322021-04-16 07:58:13 -06002543 updated = true;
2544 // Mutable descriptors not currently tracked or validated. If copied from mutable, set to mutable to keep from validating.
2545 if (src->descriptor_class == Mutable) {
2546 this->descriptor_class = Mutable;
2547 return;
2548 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002549 auto *image_src = static_cast<const ImageSamplerDescriptor *>(src);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002550 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002551 ReplaceStatePtr(set_state, sampler_state_, image_src->sampler_state_);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002552 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002553 ImageDescriptor::CopyUpdate(set_state, dev_data, src);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002554}
2555
Jeremy Gebben059ab502021-04-26 11:25:02 -06002556cvdescriptorset::ImageDescriptor::ImageDescriptor(const VkDescriptorType type)
2557 : Descriptor(Image), image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) {}
2558
2559cvdescriptorset::ImageDescriptor::ImageDescriptor(DescriptorClass class_)
2560 : Descriptor(class_), image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) {}
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002561
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002562void cvdescriptorset::ImageDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2563 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002564 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002565 const auto &image_info = update->pImageInfo[index];
Tobin Ehlis300888c2016-05-18 13:43:26 -06002566 image_layout_ = image_info.imageLayout;
Karl Schultz76d16a42020-11-11 05:05:33 -07002567 image_view_state_ = dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002568}
2569
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002570void cvdescriptorset::ImageDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2571 const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002572 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002573 // Mutable descriptors not currently tracked or validated. If copied from mutable, set to mutable to keep from validating.
2574 if (src->descriptor_class == Mutable) {
2575 this->descriptor_class = Mutable;
2576 return;
2577 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002578 auto *image_src = static_cast<const ImageDescriptor *>(src);
Tony-LunarG80358322021-04-16 07:58:13 -06002579
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002580 image_layout_ = image_src->image_layout_;
2581 ReplaceStatePtr(set_state, image_view_state_, image_src->image_view_state_);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002582}
2583
John Zulauffbf3c202019-07-17 14:57:14 -06002584void cvdescriptorset::ImageDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) {
Tobin Ehlis81e46372016-08-17 13:33:44 -06002585 // Add binding for image
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002586 auto iv_state = GetImageViewState();
Tobin Ehlis8b26a382016-09-14 08:02:49 -06002587 if (iv_state) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002588 dev_data->CallSetImageViewInitialLayoutCallback(cb_node, *iv_state, image_layout_);
Jeff Bolz148d94e2018-12-13 21:25:56 -06002589 }
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002590}
2591
Jeremy Gebben059ab502021-04-26 11:25:02 -06002592cvdescriptorset::BufferDescriptor::BufferDescriptor(const VkDescriptorType type)
2593 : Descriptor(GeneralBuffer), offset_(0), range_(0) {}
2594
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002595void cvdescriptorset::BufferDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2596 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002597 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002598 const auto &buffer_info = update->pBufferInfo[index];
Tobin Ehlis300888c2016-05-18 13:43:26 -06002599 offset_ = buffer_info.offset;
2600 range_ = buffer_info.range;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002601 ReplaceStatePtr(set_state, buffer_state_, dev_data->GetConstCastShared<BUFFER_STATE>(buffer_info.buffer));
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002602}
2603
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002604void cvdescriptorset::BufferDescriptor::CopyUpdate(DescriptorSet* set_state, const ValidationStateTracker *dev_data,
2605 const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002606 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002607 // Mutable descriptors not currently tracked or validated. If copied from mutable, set to mutable to keep from validating.
2608 if (src->descriptor_class == Mutable) {
2609 this->descriptor_class = Mutable;
2610 return;
2611 }
Karl Schultz76d16a42020-11-11 05:05:33 -07002612 const auto buff_desc = static_cast<const BufferDescriptor *>(src);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002613 offset_ = buff_desc->offset_;
2614 range_ = buff_desc->range_;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002615 ReplaceStatePtr(set_state, buffer_state_, buff_desc->buffer_state_);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002616}
2617
Jeremy Gebben059ab502021-04-26 11:25:02 -06002618cvdescriptorset::TexelDescriptor::TexelDescriptor(const VkDescriptorType type) : Descriptor(TexelBuffer) {}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002619
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002620void cvdescriptorset::TexelDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2621 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002622 updated = true;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002623 ReplaceStatePtr(set_state, buffer_view_state_,
2624 dev_data->GetConstCastShared<BUFFER_VIEW_STATE>(update->pTexelBufferView[index]));
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002625}
2626
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002627void cvdescriptorset::TexelDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2628 const Descriptor *src) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002629 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002630 // Mutable descriptors not currently tracked or validated. If copied from mutable, set to mutable to keep from validating.
2631 if (src->descriptor_class == Mutable) {
2632 this->descriptor_class = Mutable;
2633 return;
2634 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002635 ReplaceStatePtr(set_state, buffer_view_state_, static_cast<const TexelDescriptor *>(src)->buffer_view_state_);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002636}
2637
Jeff Bolz95176d02020-04-01 00:36:16 -05002638cvdescriptorset::AccelerationStructureDescriptor::AccelerationStructureDescriptor(const VkDescriptorType type)
Jeremy Gebben059ab502021-04-26 11:25:02 -06002639 : Descriptor(AccelerationStructure), acc_(VK_NULL_HANDLE), acc_nv_(VK_NULL_HANDLE) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002640 is_khr_ = false;
Jeff Bolz95176d02020-04-01 00:36:16 -05002641}
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002642void cvdescriptorset::AccelerationStructureDescriptor::WriteUpdate(DescriptorSet *set_state,
2643 const ValidationStateTracker *dev_data,
Jeff Bolz95176d02020-04-01 00:36:16 -05002644 const VkWriteDescriptorSet *update, const uint32_t index) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002645 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(update->pNext);
2646 const auto *acc_info_nv = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(update->pNext);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002647 assert(acc_info || acc_info_nv);
2648 is_khr_ = (acc_info != NULL);
Jeff Bolz95176d02020-04-01 00:36:16 -05002649 updated = true;
sourav parmarcd5fb182020-07-17 12:58:44 -07002650 if (is_khr_) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002651 acc_ = acc_info->pAccelerationStructures[index];
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002652 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002653 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002654 acc_nv_ = acc_info_nv->pAccelerationStructures[index];
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002655 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002656 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002657}
2658
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002659void cvdescriptorset::AccelerationStructureDescriptor::CopyUpdate(DescriptorSet *set_state,
2660 const ValidationStateTracker *dev_data, const Descriptor *src) {
Jeff Bolz95176d02020-04-01 00:36:16 -05002661 auto acc_desc = static_cast<const AccelerationStructureDescriptor *>(src);
2662 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002663 // Mutable descriptors not currently tracked or validated. If copied from mutable, set to mutable to keep from validating.
2664 if (src->descriptor_class == Mutable) {
2665 this->descriptor_class = Mutable;
2666 return;
2667 }
sourav parmarcd5fb182020-07-17 12:58:44 -07002668 if (is_khr_) {
2669 acc_ = acc_desc->acc_;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002670 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002671 } else {
2672 acc_nv_ = acc_desc->acc_nv_;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002673 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002674 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002675}
2676
Jeremy Gebben059ab502021-04-26 11:25:02 -06002677cvdescriptorset::MutableDescriptor::MutableDescriptor() : Descriptor(Mutable) { active_descriptor_class_ = NoDescriptorClass; }
Tony-LunarGf563b362021-03-18 16:13:18 -06002678
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002679void cvdescriptorset::MutableDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
Tony-LunarGf563b362021-03-18 16:13:18 -06002680 const VkWriteDescriptorSet *update, const uint32_t index) {
2681 updated = true;
2682}
2683
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002684void cvdescriptorset::MutableDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2685 const Descriptor *src) {
Tony-LunarGf563b362021-03-18 16:13:18 -06002686 updated = true;
2687}
2688
Tobin Ehlis300888c2016-05-18 13:43:26 -06002689// This is a helper function that iterates over a set of Write and Copy updates, pulls the DescriptorSet* for updated
2690// sets, and then calls their respective Validate[Write|Copy]Update functions.
2691// If the update hits an issue for which the callback returns "true", meaning that the call down the chain should
2692// be skipped, then true is returned.
2693// If there is no issue with the update, then false is returned.
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002694bool CoreChecks::ValidateUpdateDescriptorSets(uint32_t write_count, const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002695 const VkCopyDescriptorSet *p_cds, const char *func_name) const {
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06002696 bool skip = false;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002697 // Validate Write updates
Tobin Ehlis56a30942016-05-19 08:00:00 -06002698 for (uint32_t i = 0; i < write_count; i++) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002699 auto dest_set = p_wds[i].dstSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002700 auto set_node = GetSetNode(dest_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06002701 if (!set_node) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08002702 skip |= LogError(dest_set, kVUID_Core_DrawState_InvalidDescriptorSet,
2703 "Cannot call %s on %s that has not been allocated in pDescriptorWrites[%u].", func_name,
2704 report_data->FormatHandle(dest_set).c_str(), i);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002705 } else {
Dave Houltond8ed0212018-05-16 17:18:24 -06002706 std::string error_code;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002707 std::string error_str;
ziga-lunarg6c46b242021-09-13 18:33:37 +02002708 if (!ValidateWriteUpdate(set_node, &p_wds[i], func_name, &error_code, &error_str, false)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08002709 skip |=
2710 LogError(dest_set, error_code, "%s pDescriptorWrites[%u] failed write update validation for %s with error: %s.",
2711 func_name, i, report_data->FormatHandle(dest_set).c_str(), error_str.c_str());
Tobin Ehlis300888c2016-05-18 13:43:26 -06002712 }
2713 }
sourav parmara24fb7b2020-05-26 10:50:04 -07002714 if (p_wds[i].pNext) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002715 const auto *pnext_struct = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(p_wds[i].pNext);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002716 if (pnext_struct) {
2717 for (uint32_t j = 0; j < pnext_struct->accelerationStructureCount; ++j) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002718 const ACCELERATION_STRUCTURE_STATE_KHR *as_state =
2719 GetAccelerationStructureStateKHR(pnext_struct->pAccelerationStructures[j]);
2720 if (as_state && (as_state->create_infoKHR.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR &&
sourav parmar766e2a72020-12-03 16:17:11 -08002721 (as_state->create_infoKHR.type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR &&
2722 as_state->create_infoKHR.type != VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR))) {
sourav parmara24fb7b2020-05-26 10:50:04 -07002723 skip |=
sourav parmarcd5fb182020-07-17 12:58:44 -07002724 LogError(dest_set, "VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-03579",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002725 "%s: For pDescriptorWrites[%u] acceleration structure in pAccelerationStructures[%u] must "
2726 "have been created with "
sourav parmarbcee7512020-12-28 14:34:49 -08002727 "VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR or VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002728 func_name, i, j);
sourav parmara24fb7b2020-05-26 10:50:04 -07002729 }
2730 }
2731 }
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002732 const auto *pnext_struct_nv = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(p_wds[i].pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07002733 if (pnext_struct_nv) {
2734 for (uint32_t j = 0; j < pnext_struct_nv->accelerationStructureCount; ++j) {
2735 const ACCELERATION_STRUCTURE_STATE *as_state =
2736 GetAccelerationStructureStateNV(pnext_struct_nv->pAccelerationStructures[j]);
2737 if (as_state && (as_state->create_infoNV.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV &&
2738 as_state->create_infoNV.info.type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV)) {
2739 skip |= LogError(dest_set, "VUID-VkWriteDescriptorSetAccelerationStructureNV-pAccelerationStructures-03748",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002740 "%s: For pDescriptorWrites[%u] acceleration structure in pAccelerationStructures[%u] must "
2741 "have been created with"
sourav parmarcd5fb182020-07-17 12:58:44 -07002742 " VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002743 func_name, i, j);
sourav parmarcd5fb182020-07-17 12:58:44 -07002744 }
2745 }
2746 }
sourav parmara24fb7b2020-05-26 10:50:04 -07002747 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002748 }
2749 // Now validate copy updates
Tobin Ehlis56a30942016-05-19 08:00:00 -06002750 for (uint32_t i = 0; i < copy_count; ++i) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002751 auto dst_set = p_cds[i].dstSet;
2752 auto src_set = p_cds[i].srcSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002753 auto src_node = GetSetNode(src_set);
2754 auto dst_node = GetSetNode(dst_set);
Tobin Ehlisa1712752017-01-04 09:41:47 -07002755 // Object_tracker verifies that src & dest descriptor set are valid
2756 assert(src_node);
2757 assert(dst_node);
Dave Houltond8ed0212018-05-16 17:18:24 -06002758 std::string error_code;
Tobin Ehlisa1712752017-01-04 09:41:47 -07002759 std::string error_str;
John Zulaufc93c4252019-06-25 09:19:49 -06002760 if (!ValidateCopyUpdate(&p_cds[i], dst_node, src_node, func_name, &error_code, &error_str)) {
Mark Lobodzinski9d38ea22020-03-16 18:22:16 -06002761 LogObjectList objlist(dst_set);
2762 objlist.add(src_set);
sfricke-samsungbda4a852021-03-06 20:58:01 -08002763 skip |= LogError(objlist, error_code, "%s pDescriptorCopies[%u] failed copy update from %s to %s with error: %s.",
2764 func_name, i, report_data->FormatHandle(src_set).c_str(), report_data->FormatHandle(dst_set).c_str(),
2765 error_str.c_str());
Tobin Ehlis300888c2016-05-18 13:43:26 -06002766 }
2767 }
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06002768 return skip;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002769}
2770// This is a helper function that iterates over a set of Write and Copy updates, pulls the DescriptorSet* for updated
2771// sets, and then calls their respective Perform[Write|Copy]Update functions.
2772// Prerequisite : ValidateUpdateDescriptorSets() should be called and return "false" prior to calling PerformUpdateDescriptorSets()
2773// with the same set of updates.
2774// This is split from the validate code to allow validation prior to calling down the chain, and then update after
2775// calling down the chain.
John Zulaufe3b35f32019-06-25 14:21:21 -06002776void cvdescriptorset::PerformUpdateDescriptorSets(ValidationStateTracker *dev_data, uint32_t write_count,
2777 const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
2778 const VkCopyDescriptorSet *p_cds) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002779 // Write updates first
2780 uint32_t i = 0;
2781 for (i = 0; i < write_count; ++i) {
2782 auto dest_set = p_wds[i].dstSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002783 auto set_node = dev_data->GetSetNode(dest_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06002784 if (set_node) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05002785 set_node->PerformWriteUpdate(dev_data, &p_wds[i]);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002786 }
2787 }
2788 // Now copy updates
2789 for (i = 0; i < copy_count; ++i) {
2790 auto dst_set = p_cds[i].dstSet;
2791 auto src_set = p_cds[i].srcSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002792 auto src_node = dev_data->GetSetNode(src_set);
2793 auto dst_node = dev_data->GetSetNode(dst_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06002794 if (src_node && dst_node) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05002795 dst_node->PerformCopyUpdate(dev_data, &p_cds[i], src_node);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002796 }
2797 }
2798}
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002799
John Zulaufe3b35f32019-06-25 14:21:21 -06002800cvdescriptorset::DecodedTemplateUpdate::DecodedTemplateUpdate(const ValidationStateTracker *device_data,
2801 VkDescriptorSet descriptorSet, const TEMPLATE_STATE *template_state,
2802 const void *pData, VkDescriptorSetLayout push_layout) {
John Zulaufb845eb22018-10-12 11:41:06 -06002803 auto const &create_info = template_state->create_info;
2804 inline_infos.resize(create_info.descriptorUpdateEntryCount); // Make sure we have one if we need it
sourav parmar480d2772021-01-24 22:24:54 -08002805 inline_infos_khr.resize(create_info.descriptorUpdateEntryCount);
2806 inline_infos_nv.resize(create_info.descriptorUpdateEntryCount);
John Zulaufb845eb22018-10-12 11:41:06 -06002807 desc_writes.reserve(create_info.descriptorUpdateEntryCount); // emplaced, so reserved without initialization
John Zulauf1d27e0a2018-11-05 10:12:48 -07002808 VkDescriptorSetLayout effective_dsl = create_info.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET
2809 ? create_info.descriptorSetLayout
2810 : push_layout;
Jeff Bolz6ae39612019-10-11 20:57:36 -05002811 auto layout_obj = device_data->GetDescriptorSetLayoutShared(effective_dsl);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002812
2813 // Create a WriteDescriptorSet struct for each template update entry
2814 for (uint32_t i = 0; i < create_info.descriptorUpdateEntryCount; i++) {
2815 auto binding_count = layout_obj->GetDescriptorCountFromBinding(create_info.pDescriptorUpdateEntries[i].dstBinding);
2816 auto binding_being_updated = create_info.pDescriptorUpdateEntries[i].dstBinding;
2817 auto dst_array_element = create_info.pDescriptorUpdateEntries[i].dstArrayElement;
2818
John Zulaufb6d71202017-12-22 16:47:09 -07002819 desc_writes.reserve(desc_writes.size() + create_info.pDescriptorUpdateEntries[i].descriptorCount);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002820 for (uint32_t j = 0; j < create_info.pDescriptorUpdateEntries[i].descriptorCount; j++) {
2821 desc_writes.emplace_back();
2822 auto &write_entry = desc_writes.back();
2823
2824 size_t offset = create_info.pDescriptorUpdateEntries[i].offset + j * create_info.pDescriptorUpdateEntries[i].stride;
2825 char *update_entry = (char *)(pData) + offset;
2826
2827 if (dst_array_element >= binding_count) {
2828 dst_array_element = 0;
Mark Lobodzinski4aa479d2017-03-10 09:14:00 -07002829 binding_being_updated = layout_obj->GetNextValidBinding(binding_being_updated);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002830 }
2831
2832 write_entry.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2833 write_entry.pNext = NULL;
2834 write_entry.dstSet = descriptorSet;
2835 write_entry.dstBinding = binding_being_updated;
2836 write_entry.dstArrayElement = dst_array_element;
2837 write_entry.descriptorCount = 1;
2838 write_entry.descriptorType = create_info.pDescriptorUpdateEntries[i].descriptorType;
2839
2840 switch (create_info.pDescriptorUpdateEntries[i].descriptorType) {
2841 case VK_DESCRIPTOR_TYPE_SAMPLER:
2842 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2843 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2844 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2845 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2846 write_entry.pImageInfo = reinterpret_cast<VkDescriptorImageInfo *>(update_entry);
2847 break;
2848
2849 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2850 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2851 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2852 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2853 write_entry.pBufferInfo = reinterpret_cast<VkDescriptorBufferInfo *>(update_entry);
2854 break;
2855
2856 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2857 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2858 write_entry.pTexelBufferView = reinterpret_cast<VkBufferView *>(update_entry);
2859 break;
Dave Houlton142c4cb2018-10-17 15:04:41 -06002860 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
2861 VkWriteDescriptorSetInlineUniformBlockEXT *inline_info = &inline_infos[i];
2862 inline_info->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
2863 inline_info->pNext = nullptr;
2864 inline_info->dataSize = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2865 inline_info->pData = update_entry;
2866 write_entry.pNext = inline_info;
Ricardo Garciafee15732019-05-28 11:13:31 +02002867 // descriptorCount must match the dataSize member of the VkWriteDescriptorSetInlineUniformBlockEXT structure
2868 write_entry.descriptorCount = inline_info->dataSize;
Dave Houlton142c4cb2018-10-17 15:04:41 -06002869 // skip the rest of the array, they just represent bytes in the update
2870 j = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2871 break;
2872 }
sourav parmar480d2772021-01-24 22:24:54 -08002873 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
2874 VkWriteDescriptorSetAccelerationStructureKHR *inline_info_khr = &inline_infos_khr[i];
2875 inline_info_khr->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
2876 inline_info_khr->pNext = nullptr;
2877 inline_info_khr->accelerationStructureCount = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2878 inline_info_khr->pAccelerationStructures = reinterpret_cast<VkAccelerationStructureKHR *>(update_entry);
2879 write_entry.pNext = inline_info_khr;
2880 break;
2881 }
2882 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: {
2883 VkWriteDescriptorSetAccelerationStructureNV *inline_info_nv = &inline_infos_nv[i];
2884 inline_info_nv->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV;
2885 inline_info_nv->pNext = nullptr;
2886 inline_info_nv->accelerationStructureCount = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2887 inline_info_nv->pAccelerationStructures = reinterpret_cast<VkAccelerationStructureNV *>(update_entry);
2888 write_entry.pNext = inline_info_nv;
2889 break;
2890 }
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002891 default:
2892 assert(0);
2893 break;
2894 }
2895 dst_array_element++;
2896 }
2897 }
John Zulaufb845eb22018-10-12 11:41:06 -06002898}
John Zulaufb45fdc32018-10-12 15:14:17 -06002899// These helper functions carry out the validate and record descriptor updates peformed via update templates. They decode
2900// the templatized data and leverage the non-template UpdateDescriptor helper functions.
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002901bool CoreChecks::ValidateUpdateDescriptorSetsWithTemplateKHR(VkDescriptorSet descriptorSet, const TEMPLATE_STATE *template_state,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002902 const void *pData) const {
John Zulaufb45fdc32018-10-12 15:14:17 -06002903 // Translate the templated update into a normal update for validation...
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002904 cvdescriptorset::DecodedTemplateUpdate decoded_update(this, descriptorSet, template_state, pData);
2905 return ValidateUpdateDescriptorSets(static_cast<uint32_t>(decoded_update.desc_writes.size()), decoded_update.desc_writes.data(),
2906 0, NULL, "vkUpdateDescriptorSetWithTemplate()");
John Zulaufb45fdc32018-10-12 15:14:17 -06002907}
John Zulaufb845eb22018-10-12 11:41:06 -06002908
John Zulauf4e7bcb52018-11-02 10:46:30 -06002909std::string cvdescriptorset::DescriptorSet::StringifySetAndLayout() const {
2910 std::string out;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002911 auto layout_handle = layout_->GetDescriptorSetLayout();
John Zulauf4e7bcb52018-11-02 10:46:30 -06002912 if (IsPushDescriptor()) {
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002913 std::ostringstream str;
Tony-LunarG1d3ee2d2020-10-27 15:54:52 -06002914 str << "Push Descriptors defined with " << state_data_->report_data->FormatHandle(layout_handle);
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002915 out = str.str();
John Zulauf4e7bcb52018-11-02 10:46:30 -06002916 } else {
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002917 std::ostringstream str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002918 str << state_data_->report_data->FormatHandle(GetSet()) << " allocated with "
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002919 << state_data_->report_data->FormatHandle(layout_handle);
2920 out = str.str();
John Zulauf4e7bcb52018-11-02 10:46:30 -06002921 }
2922 return out;
2923};
2924
John Zulauf1d27e0a2018-11-05 10:12:48 -07002925// Loop through the write updates to validate for a push descriptor set, ignoring dstSet
John Zulaufc93c4252019-06-25 09:19:49 -06002926bool CoreChecks::ValidatePushDescriptorsUpdate(const DescriptorSet *push_set, uint32_t write_count,
John Zulaufbd9b3412019-08-22 17:16:11 -06002927 const VkWriteDescriptorSet *p_wds, const char *func_name) const {
John Zulaufd9435c32019-06-05 15:55:36 -06002928 assert(push_set->IsPushDescriptor());
John Zulauf1d27e0a2018-11-05 10:12:48 -07002929 bool skip = false;
2930 for (uint32_t i = 0; i < write_count; i++) {
2931 std::string error_code;
2932 std::string error_str;
ziga-lunarg6c46b242021-09-13 18:33:37 +02002933 if (!ValidateWriteUpdate(push_set, &p_wds[i], func_name, &error_code, &error_str, true)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08002934 skip |= LogError(push_set->GetDescriptorSetLayout(), error_code,
2935 "%s VkWriteDescriptorSet[%u] failed update validation: %s.", func_name, i, error_str.c_str());
John Zulauf1d27e0a2018-11-05 10:12:48 -07002936 }
2937 }
2938 return skip;
2939}
2940
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002941// For the given buffer, verify that its creation parameters are appropriate for the given type
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002942// If there's an error, update the error_msg string with details and return false, else return true
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002943bool cvdescriptorset::ValidateBufferUsage(debug_report_data *report_data, BUFFER_STATE const *buffer_node, VkDescriptorType type,
2944 std::string *error_code, std::string *error_msg) {
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002945 // Verify that usage bits set correctly for given type
Tobin Ehlis94bc5d22016-06-02 07:46:52 -06002946 auto usage = buffer_node->createInfo.usage;
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002947 const char *error_usage_bit = nullptr;
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002948 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002949 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2950 if (!(usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002951 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00334";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002952 error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT";
2953 }
2954 break;
2955 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2956 if (!(usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002957 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00335";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002958 error_usage_bit = "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT";
2959 }
2960 break;
2961 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2962 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2963 if (!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002964 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00330";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002965 error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT";
2966 }
2967 break;
2968 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2969 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2970 if (!(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002971 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00331";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002972 error_usage_bit = "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT";
2973 }
2974 break;
2975 default:
2976 break;
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002977 }
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002978 if (error_usage_bit) {
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002979 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002980 error_str << "Buffer (" << report_data->FormatHandle(buffer_node->buffer()) << ") with usage mask " << std::hex
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002981 << std::showbase << usage << " being used for a descriptor update of type " << string_VkDescriptorType(type)
2982 << " does not have " << error_usage_bit << " set.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002983 *error_msg = error_str.str();
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002984 return false;
2985 }
2986 return true;
2987}
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002988// For buffer descriptor updates, verify the buffer usage and VkDescriptorBufferInfo struct which includes:
2989// 1. buffer is valid
2990// 2. buffer was created with correct usage flags
2991// 3. offset is less than buffer size
2992// 4. range is either VK_WHOLE_SIZE or falls in (0, (buffer size - offset)]
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002993// 5. range and offset are within the device's limits
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002994// If there's an error, update the error_msg string with details and return false, else return true
John Zulaufc93c4252019-06-25 09:19:49 -06002995bool CoreChecks::ValidateBufferUpdate(VkDescriptorBufferInfo const *buffer_info, VkDescriptorType type, const char *func_name,
John Zulaufbd9b3412019-08-22 17:16:11 -06002996 std::string *error_code, std::string *error_msg) const {
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002997 // First make sure that buffer is valid
John Zulaufc93c4252019-06-25 09:19:49 -06002998 auto buffer_node = GetBufferState(buffer_info->buffer);
Tobin Ehlisfa8b6182016-12-22 13:40:45 -07002999 // Any invalid buffer should already be caught by object_tracker
3000 assert(buffer_node);
John Zulaufc93c4252019-06-25 09:19:49 -06003001 if (ValidateMemoryIsBoundToBuffer(buffer_node, func_name, "VUID-VkWriteDescriptorSet-descriptorType-00329")) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003002 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00329";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003003 *error_msg = "No memory bound to buffer.";
Tobin Ehlis81280962016-07-20 14:04:20 -06003004 return false;
Tobin Ehlisfed999f2016-09-21 15:09:45 -06003005 }
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003006 // Verify usage bits
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003007 if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_node, type, error_code, error_msg)) {
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003008 // error_msg will have been updated by ValidateBufferUsage()
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003009 return false;
3010 }
3011 // offset must be less than buffer size
Jeremy Hayesd1a6a822017-03-09 14:39:45 -07003012 if (buffer_info->offset >= buffer_node->createInfo.size) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003013 *error_code = "VUID-VkDescriptorBufferInfo-offset-00340";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003014 std::stringstream error_str;
Jeremy Hayesd1a6a822017-03-09 14:39:45 -07003015 error_str << "VkDescriptorBufferInfo offset of " << buffer_info->offset << " is greater than or equal to buffer "
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003016 << report_data->FormatHandle(buffer_node->buffer()) << " size of " << buffer_node->createInfo.size;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003017 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003018 return false;
3019 }
3020 if (buffer_info->range != VK_WHOLE_SIZE) {
3021 // Range must be VK_WHOLE_SIZE or > 0
3022 if (!buffer_info->range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003023 *error_code = "VUID-VkDescriptorBufferInfo-range-00341";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003024 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003025 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003026 << " VkDescriptorBufferInfo range is not VK_WHOLE_SIZE and is zero, which is not allowed.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003027 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003028 return false;
3029 }
3030 // Range must be VK_WHOLE_SIZE or <= (buffer size - offset)
3031 if (buffer_info->range > (buffer_node->createInfo.size - buffer_info->offset)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003032 *error_code = "VUID-VkDescriptorBufferInfo-range-00342";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003033 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003034 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer()) << " VkDescriptorBufferInfo range is "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003035 << buffer_info->range << " which is greater than buffer size (" << buffer_node->createInfo.size
3036 << ") minus requested offset of " << buffer_info->offset;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003037 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003038 return false;
3039 }
3040 }
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003041 // Check buffer update sizes against device limits
John Zulaufc93c4252019-06-25 09:19:49 -06003042 const auto &limits = phys_dev_props.limits;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003043 if (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type || VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC == type) {
John Zulaufd9435c32019-06-05 15:55:36 -06003044 auto max_ub_range = limits.maxUniformBufferRange;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003045 if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_ub_range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003046 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00332";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003047 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003048 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer()) << " VkDescriptorBufferInfo range is "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003049 << buffer_info->range << " which is greater than this device's maxUniformBufferRange (" << max_ub_range
3050 << ")";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003051 *error_msg = error_str.str();
3052 return false;
Peter Kohaut2794a292018-07-13 11:13:47 +02003053 } else if (buffer_info->range == VK_WHOLE_SIZE && (buffer_node->createInfo.size - buffer_info->offset) > max_ub_range) {
3054 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00332";
3055 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003056 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003057 << " VkDescriptorBufferInfo range is VK_WHOLE_SIZE but effective range "
Peter Kohaut18f413d2018-07-16 13:15:42 +02003058 << "(" << (buffer_node->createInfo.size - buffer_info->offset) << ") is greater than this device's "
Peter Kohaut2794a292018-07-13 11:13:47 +02003059 << "maxUniformBufferRange (" << max_ub_range << ")";
3060 *error_msg = error_str.str();
3061 return false;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003062 }
3063 } else if (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == type || VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC == type) {
John Zulaufd9435c32019-06-05 15:55:36 -06003064 auto max_sb_range = limits.maxStorageBufferRange;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003065 if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_sb_range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003066 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00333";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003067 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003068 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer()) << " VkDescriptorBufferInfo range is "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003069 << buffer_info->range << " which is greater than this device's maxStorageBufferRange (" << max_sb_range
3070 << ")";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003071 *error_msg = error_str.str();
3072 return false;
Peter Kohaut2794a292018-07-13 11:13:47 +02003073 } else if (buffer_info->range == VK_WHOLE_SIZE && (buffer_node->createInfo.size - buffer_info->offset) > max_sb_range) {
3074 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00333";
3075 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003076 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003077 << " VkDescriptorBufferInfo range is VK_WHOLE_SIZE but effective range "
Peter Kohaut18f413d2018-07-16 13:15:42 +02003078 << "(" << (buffer_node->createInfo.size - buffer_info->offset) << ") is greater than this device's "
Peter Kohaut2794a292018-07-13 11:13:47 +02003079 << "maxStorageBufferRange (" << max_sb_range << ")";
3080 *error_msg = error_str.str();
3081 return false;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003082 }
3083 }
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003084 return true;
3085}
sourav parmarcd5fb182020-07-17 12:58:44 -07003086template <typename T>
3087bool CoreChecks::ValidateAccelerationStructureUpdate(T acc_node, const char *func_name, std::string *error_code,
Jeff Bolz95176d02020-04-01 00:36:16 -05003088 std::string *error_msg) const {
Jeff Bolz95176d02020-04-01 00:36:16 -05003089 // Any invalid acc struct should already be caught by object_tracker
3090 assert(acc_node);
3091 if (ValidateMemoryIsBoundToAccelerationStructure(acc_node, func_name, kVUIDUndefined)) {
3092 *error_code = kVUIDUndefined;
3093 *error_msg = "No memory bound to acceleration structure.";
3094 return false;
3095 }
3096 return true;
3097}
3098
Tobin Ehlis300888c2016-05-18 13:43:26 -06003099// Verify that the contents of the update are ok, but don't perform actual update
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003100bool CoreChecks::VerifyCopyUpdateContents(const VkCopyDescriptorSet *update, const DescriptorSet *src_set,
3101 VkDescriptorType src_type, uint32_t src_index, const DescriptorSet *dst_set,
3102 VkDescriptorType dst_type, uint32_t dst_index, const char *func_name,
3103 std::string *error_code, std::string *error_msg) const {
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003104 // Note : Repurposing some Write update error codes here as specific details aren't called out for copy updates like they are
3105 // for write updates
John Zulaufc93c4252019-06-25 09:19:49 -06003106 using DescriptorClass = cvdescriptorset::DescriptorClass;
3107 using BufferDescriptor = cvdescriptorset::BufferDescriptor;
3108 using ImageDescriptor = cvdescriptorset::ImageDescriptor;
3109 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
3110 using SamplerDescriptor = cvdescriptorset::SamplerDescriptor;
3111 using TexelDescriptor = cvdescriptorset::TexelDescriptor;
3112
3113 auto device_data = this;
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003114
3115 if (dst_type == VK_DESCRIPTOR_TYPE_SAMPLER) {
3116 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3117 const auto dst_desc = dst_set->GetDescriptorFromGlobalIndex(dst_index + di);
3118 if (!dst_desc->updated) continue;
3119 if (dst_desc->IsImmutableSampler()) {
3120 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02753";
3121 std::stringstream error_str;
3122 error_str << "Attempted copy update to an immutable sampler descriptor.";
3123 *error_msg = error_str.str();
3124 return false;
3125 }
3126 }
3127 }
3128
3129 switch (src_set->GetDescriptorFromGlobalIndex(src_index)->descriptor_class) {
John Zulaufc93c4252019-06-25 09:19:49 -06003130 case DescriptorClass::PlainSampler: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003131 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003132 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003133 if (!src_desc->updated) continue;
3134 if (!src_desc->IsImmutableSampler()) {
John Zulaufd9435c32019-06-05 15:55:36 -06003135 auto update_sampler = static_cast<const SamplerDescriptor *>(src_desc)->GetSampler();
John Zulaufc93c4252019-06-25 09:19:49 -06003136 if (!ValidateSampler(update_sampler)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003137 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003138 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003139 error_str << "Attempted copy update to sampler descriptor with invalid sampler: "
3140 << report_data->FormatHandle(update_sampler) << ".";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003141 *error_msg = error_str.str();
3142 return false;
3143 }
3144 } else {
3145 // TODO : Warn here
3146 }
3147 }
3148 break;
3149 }
John Zulaufc93c4252019-06-25 09:19:49 -06003150 case DescriptorClass::ImageSampler: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003151 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003152 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003153 if (!src_desc->updated) continue;
3154 auto img_samp_desc = static_cast<const ImageSamplerDescriptor *>(src_desc);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003155 // First validate sampler
3156 if (!img_samp_desc->IsImmutableSampler()) {
3157 auto update_sampler = img_samp_desc->GetSampler();
John Zulaufc93c4252019-06-25 09:19:49 -06003158 if (!ValidateSampler(update_sampler)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003159 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003160 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003161 error_str << "Attempted copy update to sampler descriptor with invalid sampler: "
3162 << report_data->FormatHandle(update_sampler) << ".";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003163 *error_msg = error_str.str();
3164 return false;
3165 }
3166 } else {
3167 // TODO : Warn here
3168 }
3169 // Validate image
3170 auto image_view = img_samp_desc->GetImageView();
3171 auto image_layout = img_samp_desc->GetImageLayout();
Jeff Bolz165818a2020-05-08 11:19:03 -05003172 if (image_view) {
3173 if (!ValidateImageUpdate(image_view, image_layout, src_type, func_name, error_code, error_msg)) {
3174 std::stringstream error_str;
3175 error_str << "Attempted copy update to combined image sampler descriptor failed due to: "
3176 << error_msg->c_str();
3177 *error_msg = error_str.str();
3178 return false;
3179 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003180 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003181 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003182 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003183 }
John Zulaufc93c4252019-06-25 09:19:49 -06003184 case DescriptorClass::Image: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003185 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003186 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003187 if (!src_desc->updated) continue;
3188 auto img_desc = static_cast<const ImageDescriptor *>(src_desc);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003189 auto image_view = img_desc->GetImageView();
3190 auto image_layout = img_desc->GetImageLayout();
Jeff Bolz165818a2020-05-08 11:19:03 -05003191 if (image_view) {
3192 if (!ValidateImageUpdate(image_view, image_layout, src_type, func_name, error_code, error_msg)) {
3193 std::stringstream error_str;
3194 error_str << "Attempted copy update to image descriptor failed due to: " << error_msg->c_str();
3195 *error_msg = error_str.str();
3196 return false;
3197 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003198 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003199 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003200 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003201 }
John Zulaufc93c4252019-06-25 09:19:49 -06003202 case DescriptorClass::TexelBuffer: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003203 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003204 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003205 if (!src_desc->updated) continue;
John Zulaufd9435c32019-06-05 15:55:36 -06003206 auto buffer_view = static_cast<const TexelDescriptor *>(src_desc)->GetBufferView();
Jeff Bolz165818a2020-05-08 11:19:03 -05003207 if (buffer_view) {
3208 auto bv_state = device_data->GetBufferViewState(buffer_view);
3209 if (!bv_state) {
3210 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
3211 std::stringstream error_str;
3212 error_str << "Attempted copy update to texel buffer descriptor with invalid buffer view: "
3213 << report_data->FormatHandle(buffer_view);
3214 *error_msg = error_str.str();
3215 return false;
3216 }
3217 auto buffer = bv_state->create_info.buffer;
3218 if (!cvdescriptorset::ValidateBufferUsage(report_data, GetBufferState(buffer), src_type, error_code,
3219 error_msg)) {
3220 std::stringstream error_str;
3221 error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error_msg->c_str();
3222 *error_msg = error_str.str();
3223 return false;
3224 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003225 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003226 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003227 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003228 }
John Zulaufc93c4252019-06-25 09:19:49 -06003229 case DescriptorClass::GeneralBuffer: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003230 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003231 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003232 if (!src_desc->updated) continue;
John Zulaufd9435c32019-06-05 15:55:36 -06003233 auto buffer = static_cast<const BufferDescriptor *>(src_desc)->GetBuffer();
Jeff Bolz165818a2020-05-08 11:19:03 -05003234 if (buffer) {
3235 if (!cvdescriptorset::ValidateBufferUsage(report_data, GetBufferState(buffer), src_type, error_code,
3236 error_msg)) {
3237 std::stringstream error_str;
3238 error_str << "Attempted copy update to buffer descriptor failed due to: " << error_msg->c_str();
3239 *error_msg = error_str.str();
3240 return false;
3241 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003242 }
Tobin Ehliscbcf2342016-05-24 13:07:12 -06003243 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003244 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003245 }
John Zulaufc93c4252019-06-25 09:19:49 -06003246 case DescriptorClass::InlineUniform:
3247 case DescriptorClass::AccelerationStructure:
Ricardo Garcia14f4f762021-04-13 11:36:12 +02003248 case DescriptorClass::Mutable:
Jeff Bolze54ae892018-09-08 12:16:29 -05003249 break;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003250 default:
3251 assert(0); // We've already verified update type so should never get here
3252 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003253 }
3254 // All checks passed so update contents are good
3255 return true;
Chris Forbesb4e0bdb2016-05-31 16:34:40 +12003256}
Tobin Ehlisee471462016-05-26 11:21:59 -06003257// Verify that the state at allocate time is correct, but don't actually allocate the sets yet
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07003258bool CoreChecks::ValidateAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05003259 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) const {
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06003260 bool skip = false;
Mark Lobodzinski7804bd42019-03-06 11:28:48 -07003261 auto pool_state = GetDescriptorPoolState(p_alloc_info->descriptorPool);
Tobin Ehlisee471462016-05-26 11:21:59 -06003262
3263 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05003264 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
John Zulauf5562d062018-01-24 11:54:05 -07003265 if (layout) { // nullptr layout indicates no valid layout handle for this device, validated/logged in object_tracker
John Zulauf1d27e0a2018-11-05 10:12:48 -07003266 if (layout->IsPushDescriptor()) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003267 skip |= LogError(p_alloc_info->pSetLayouts[i], "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-00308",
3268 "%s specified at pSetLayouts[%" PRIu32
3269 "] in vkAllocateDescriptorSets() was created with invalid flag %s set.",
3270 report_data->FormatHandle(p_alloc_info->pSetLayouts[i]).c_str(), i,
3271 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR");
John Zulauf5562d062018-01-24 11:54:05 -07003272 }
Mike Schuchardt2df08912020-12-15 16:28:09 -08003273 if (layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT &&
3274 !(pool_state->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08003275 skip |= LogError(
3276 device, "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-03044",
3277 "vkAllocateDescriptorSets(): Descriptor set layout create flags and pool create flags mismatch for index (%d)",
3278 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003279 }
ziga-lunarg2ab96532021-07-19 11:06:41 +02003280 if (layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE &&
3281 !(pool_state->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) {
3282 skip |= LogError(device, "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-04610",
3283 "vkAllocateDescriptorSets(): pSetLayouts[%d].flags contain "
3284 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE bit, but the pool was not created "
3285 "with the VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE bit.",
3286 i);
3287 }
Tobin Ehlisee471462016-05-26 11:21:59 -06003288 }
3289 }
sfricke-samsung45996a42021-09-16 13:45:27 -07003290 if (!IsExtEnabled(device_extensions.vk_khr_maintenance1)) {
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06003291 // Track number of descriptorSets allowable in this pool
3292 if (pool_state->availableSets < p_alloc_info->descriptorSetCount) {
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003293 skip |= LogError(pool_state->Handle(), "VUID-VkDescriptorSetAllocateInfo-descriptorSetCount-00306",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003294 "vkAllocateDescriptorSets(): Unable to allocate %u descriptorSets from %s"
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003295 ". This pool only has %d descriptorSets remaining.",
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003296 p_alloc_info->descriptorSetCount, report_data->FormatHandle(pool_state->Handle()).c_str(),
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003297 pool_state->availableSets);
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06003298 }
3299 // Determine whether descriptor counts are satisfiable
Jeff Bolze54ae892018-09-08 12:16:29 -05003300 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
Jeff Bolz46c0ea02019-10-09 13:06:29 -05003301 auto count_iter = pool_state->availableDescriptorTypeCount.find(it->first);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003302 uint32_t available_count = (count_iter != pool_state->availableDescriptorTypeCount.end()) ? count_iter->second : 0;
Jeff Bolz46c0ea02019-10-09 13:06:29 -05003303
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003304 if (ds_data->required_descriptors_by_type.at(it->first) > available_count) {
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003305 skip |= LogError(pool_state->Handle(), "VUID-VkDescriptorSetAllocateInfo-descriptorPool-00307",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003306 "vkAllocateDescriptorSets(): Unable to allocate %u descriptors of type %s from %s"
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003307 ". This pool only has %d descriptors of this type remaining.",
3308 ds_data->required_descriptors_by_type.at(it->first),
3309 string_VkDescriptorType(VkDescriptorType(it->first)),
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003310 report_data->FormatHandle(pool_state->Handle()).c_str(), available_count);
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06003311 }
Tobin Ehlisee471462016-05-26 11:21:59 -06003312 }
3313 }
Tobin Ehlis5d749ea2016-07-18 13:14:01 -06003314
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003315 const auto *count_allocate_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(p_alloc_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003316
3317 if (count_allocate_info) {
3318 if (count_allocate_info->descriptorSetCount != 0 &&
3319 count_allocate_info->descriptorSetCount != p_alloc_info->descriptorSetCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003320 skip |= LogError(device, "VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-descriptorSetCount-03045",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003321 "vkAllocateDescriptorSets(): VkDescriptorSetAllocateInfo::descriptorSetCount (%d) != "
Mike Schuchardt2df08912020-12-15 16:28:09 -08003322 "VkDescriptorSetVariableDescriptorCountAllocateInfo::descriptorSetCount (%d)",
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003323 p_alloc_info->descriptorSetCount, count_allocate_info->descriptorSetCount);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003324 }
3325 if (count_allocate_info->descriptorSetCount == p_alloc_info->descriptorSetCount) {
3326 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05003327 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003328 if (count_allocate_info->pDescriptorCounts[i] > layout->GetDescriptorCountFromBinding(layout->GetMaxBinding())) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003329 skip |= LogError(device, "VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-pSetLayouts-03046",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003330 "vkAllocateDescriptorSets(): pDescriptorCounts[%d] = (%d), binding's descriptorCount = (%d)",
3331 i, count_allocate_info->pDescriptorCounts[i],
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003332 layout->GetDescriptorCountFromBinding(layout->GetMaxBinding()));
Jeff Bolzfdf96072018-04-10 14:32:18 -05003333 }
3334 }
3335 }
3336 }
3337
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06003338 return skip;
Tobin Ehlisee471462016-05-26 11:21:59 -06003339}
John Zulauf48a6a702017-12-22 17:14:54 -07003340
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05003341const BindingReqMap &cvdescriptorset::PrefilterBindRequestMap::FilteredMap(const CMD_BUFFER_STATE &cb_state,
3342 const PIPELINE_STATE &pipeline) {
John Zulauffbf3c202019-07-17 14:57:14 -06003343 if (IsManyDescriptors()) {
Karl Schultz7090a052020-11-10 08:54:21 -07003344 filtered_map_.reset(new BindingReqMap);
John Zulauffbf3c202019-07-17 14:57:14 -06003345 descriptor_set_.FilterBindingReqs(cb_state, pipeline, orig_map_, filtered_map_.get());
3346 return *filtered_map_;
John Zulauf48a6a702017-12-22 17:14:54 -07003347 }
John Zulauffbf3c202019-07-17 14:57:14 -06003348 return orig_map_;
Artem Kharytoniuk2456f992018-01-12 14:17:41 +01003349}
John Zulauf4a015c92019-06-04 09:50:05 -06003350
3351// Starting at offset descriptor of given binding, parse over update_count
3352// descriptor updates and verify that for any binding boundaries that are crossed, the next binding(s) are all consistent
3353// Consistency means that their type, stage flags, and whether or not they use immutable samplers matches
3354// If so, return true. If not, fill in error_msg and return false
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003355bool cvdescriptorset::VerifyUpdateConsistency(debug_report_data *report_data,
3356 DescriptorSetLayout::ConstBindingIterator current_binding, uint32_t offset,
John Zulauf4a015c92019-06-04 09:50:05 -06003357 uint32_t update_count, const char *type, const VkDescriptorSet set,
3358 std::string *error_msg) {
locke-lunarge46b7782019-09-10 01:44:20 -06003359 bool pass = true;
John Zulauf4a015c92019-06-04 09:50:05 -06003360 // Verify consecutive bindings match (if needed)
3361 auto orig_binding = current_binding;
locke-lunarge46b7782019-09-10 01:44:20 -06003362
3363 while (pass && update_count) {
3364 // First, it's legal to offset beyond your own binding so handle that case
3365 if (offset > 0) {
3366 const auto &index_range = current_binding.GetGlobalIndexRange();
3367 // index_range.start + offset is which descriptor is needed to update. If it > index_range.end, it means the descriptor
3368 // isn't in this binding, maybe in next binding.
3369 if ((index_range.start + offset) >= index_range.end) {
3370 // Advance to next binding, decrement offset by binding size
3371 offset -= current_binding.GetDescriptorCount();
3372 ++current_binding;
3373 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
3374 if (!orig_binding.IsConsistent(current_binding)) {
3375 pass = false;
3376 }
3377 continue;
John Zulauf4a015c92019-06-04 09:50:05 -06003378 }
John Zulauf4a015c92019-06-04 09:50:05 -06003379 }
locke-lunarge46b7782019-09-10 01:44:20 -06003380
3381 update_count -= std::min(update_count, current_binding.GetDescriptorCount() - offset);
3382 if (update_count) {
3383 // Starting offset is beyond the current binding. Check consistency, update counters and advance to the next binding,
3384 // looking for the start point. All bindings (even those skipped) must be consistent with the update and with the
3385 // original binding.
3386 offset = 0;
3387 ++current_binding;
3388 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
3389 if (!orig_binding.IsConsistent(current_binding)) {
3390 pass = false;
3391 }
3392 }
John Zulauf4a015c92019-06-04 09:50:05 -06003393 }
locke-lunarge46b7782019-09-10 01:44:20 -06003394
3395 if (!pass) {
3396 std::stringstream error_str;
3397 error_str << "Attempting " << type;
3398 if (current_binding.Layout()->IsPushDescriptor()) {
3399 error_str << " push descriptors";
3400 } else {
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003401 error_str << " descriptor set " << report_data->FormatHandle(set);
locke-lunarge46b7782019-09-10 01:44:20 -06003402 }
3403 error_str << " binding #" << orig_binding.Binding() << " with #" << update_count
3404 << " descriptors being updated but this update oversteps the bounds of this binding and the next binding is "
sfricke-samsung5de34882021-04-15 22:33:23 -07003405 "not consistent with current binding";
3406
3407 // Get what was not consistent in IsConsistent() as a more detailed error message
3408 const auto *binding_ci = orig_binding.GetDescriptorSetLayoutBindingPtr();
3409 const auto *other_binding_ci = current_binding.GetDescriptorSetLayoutBindingPtr();
3410 if (binding_ci == nullptr || other_binding_ci == nullptr) {
3411 error_str << " (No two valid DescriptorSetLayoutBinding to compare)";
3412 } else if (binding_ci->descriptorType != other_binding_ci->descriptorType) {
3413 error_str << " (" << string_VkDescriptorType(binding_ci->descriptorType)
3414 << " != " << string_VkDescriptorType(other_binding_ci->descriptorType) << ")";
3415 } else if (binding_ci->stageFlags != other_binding_ci->stageFlags) {
3416 error_str << " (" << string_VkShaderStageFlags(binding_ci->stageFlags)
3417 << " != " << string_VkShaderStageFlags(other_binding_ci->stageFlags) << ")";
3418 } else if (!hash_util::similar_for_nullity(binding_ci->pImmutableSamplers, other_binding_ci->pImmutableSamplers)) {
3419 error_str << " (pImmutableSamplers don't match)";
3420 } else if (orig_binding.GetDescriptorBindingFlags() != current_binding.GetDescriptorBindingFlags()) {
3421 error_str << " (" << string_VkDescriptorBindingFlags(orig_binding.GetDescriptorBindingFlags())
3422 << " != " << string_VkDescriptorBindingFlags(current_binding.GetDescriptorBindingFlags()) << ")";
3423 }
3424
3425 error_str << " so this update is invalid";
locke-lunarge46b7782019-09-10 01:44:20 -06003426 *error_msg = error_str.str();
3427 }
3428 return pass;
John Zulauf4a015c92019-06-04 09:50:05 -06003429}
John Zulauf4956fff2019-06-04 16:54:38 -06003430
3431// Validate the state for a given write update but don't actually perform the update
3432// If an error would occur for this update, return false and fill in details in error_msg string
John Zulaufc93c4252019-06-25 09:19:49 -06003433bool CoreChecks::ValidateWriteUpdate(const DescriptorSet *dest_set, const VkWriteDescriptorSet *update, const char *func_name,
ziga-lunarg6c46b242021-09-13 18:33:37 +02003434 std::string *error_code, std::string *error_msg, bool push) const {
Jeff Bolz6aad1742019-10-16 11:10:09 -05003435 const auto dest_layout = dest_set->GetLayout().get();
John Zulauf4956fff2019-06-04 16:54:38 -06003436
3437 // Verify dst layout still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003438 if (dest_layout->Destroyed()) {
John Zulauf4956fff2019-06-04 16:54:38 -06003439 *error_code = "VUID-VkWriteDescriptorSet-dstSet-00320";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06003440 std::ostringstream str;
3441 str << "Cannot call " << func_name << " to perform write update on " << dest_set->StringifySetAndLayout()
3442 << " which has been destroyed";
3443 *error_msg = str.str();
John Zulauf4956fff2019-06-04 16:54:38 -06003444 return false;
3445 }
3446 // Verify dst binding exists
3447 if (!dest_layout->HasBinding(update->dstBinding)) {
3448 *error_code = "VUID-VkWriteDescriptorSet-dstBinding-00315";
3449 std::stringstream error_str;
3450 error_str << dest_set->StringifySetAndLayout() << " does not have binding " << update->dstBinding;
3451 *error_msg = error_str.str();
3452 return false;
3453 }
3454
Jeff Bolz6aad1742019-10-16 11:10:09 -05003455 DescriptorSetLayout::ConstBindingIterator dest(dest_layout, update->dstBinding);
John Zulauf4956fff2019-06-04 16:54:38 -06003456 // Make sure binding isn't empty
3457 if (0 == dest.GetDescriptorCount()) {
3458 *error_code = "VUID-VkWriteDescriptorSet-dstBinding-00316";
3459 std::stringstream error_str;
3460 error_str << dest_set->StringifySetAndLayout() << " cannot updated binding " << update->dstBinding
3461 << " that has 0 descriptors";
3462 *error_msg = error_str.str();
3463 return false;
3464 }
3465
3466 // Verify idle ds
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003467 if (dest_set->InUse() && !(dest.GetDescriptorBindingFlags() & (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT |
Mike Schuchardt2df08912020-12-15 16:28:09 -08003468 VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
John Zulauf4956fff2019-06-04 16:54:38 -06003469 // TODO : Re-using Free Idle error code, need write update idle error code
3470 *error_code = "VUID-vkFreeDescriptorSets-pDescriptorSets-00309";
3471 std::stringstream error_str;
3472 error_str << "Cannot call " << func_name << " to perform write update on " << dest_set->StringifySetAndLayout()
3473 << " that is in use by a command buffer";
3474 *error_msg = error_str.str();
3475 return false;
3476 }
3477 // We know that binding is valid, verify update and do update on each descriptor
3478 auto start_idx = dest.GetGlobalIndexRange().start + update->dstArrayElement;
3479 auto type = dest.GetType();
Tony-LunarGf563b362021-03-18 16:13:18 -06003480 if ((type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) && (type != update->descriptorType)) {
John Zulauf4956fff2019-06-04 16:54:38 -06003481 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00319";
3482 std::stringstream error_str;
3483 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3484 << " with type " << string_VkDescriptorType(type) << " but update type is "
3485 << string_VkDescriptorType(update->descriptorType);
3486 *error_msg = error_str.str();
3487 return false;
3488 }
John Zulauf4956fff2019-06-04 16:54:38 -06003489 if (type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
3490 if ((update->dstArrayElement % 4) != 0) {
3491 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02219";
3492 std::stringstream error_str;
3493 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3494 << " with "
3495 << "dstArrayElement " << update->dstArrayElement << " not a multiple of 4";
3496 *error_msg = error_str.str();
3497 return false;
3498 }
3499 if ((update->descriptorCount % 4) != 0) {
3500 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02220";
3501 std::stringstream error_str;
3502 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3503 << " with "
3504 << "descriptorCount " << update->descriptorCount << " not a multiple of 4";
3505 *error_msg = error_str.str();
3506 return false;
3507 }
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003508 const auto *write_inline_info = LvlFindInChain<VkWriteDescriptorSetInlineUniformBlockEXT>(update->pNext);
John Zulauf4956fff2019-06-04 16:54:38 -06003509 if (!write_inline_info || write_inline_info->dataSize != update->descriptorCount) {
3510 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02221";
3511 std::stringstream error_str;
3512 if (!write_inline_info) {
3513 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #"
3514 << update->dstBinding << " with "
3515 << "VkWriteDescriptorSetInlineUniformBlockEXT missing";
3516 } else {
3517 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #"
3518 << update->dstBinding << " with "
3519 << "VkWriteDescriptorSetInlineUniformBlockEXT dataSize " << write_inline_info->dataSize
3520 << " not equal to "
3521 << "VkWriteDescriptorSet descriptorCount " << update->descriptorCount;
3522 }
3523 *error_msg = error_str.str();
3524 return false;
3525 }
3526 // This error is probably unreachable due to the previous two errors
3527 if (write_inline_info && (write_inline_info->dataSize % 4) != 0) {
3528 *error_code = "VUID-VkWriteDescriptorSetInlineUniformBlockEXT-dataSize-02222";
3529 std::stringstream error_str;
3530 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3531 << " with "
3532 << "VkWriteDescriptorSetInlineUniformBlockEXT dataSize " << write_inline_info->dataSize
3533 << " not a multiple of 4";
3534 *error_msg = error_str.str();
3535 return false;
3536 }
3537 }
sfricke-samsung941d48b2020-02-10 00:20:01 -08003538 // Verify all bindings update share identical properties across all items
3539 if (update->descriptorCount > 0) {
3540 // Save first binding information and error if something different is found
3541 DescriptorSetLayout::ConstBindingIterator current_binding(dest_layout, update->dstBinding);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003542 VkShaderStageFlags stage_flags = current_binding.GetStageFlags();
3543 VkDescriptorType descriptor_type = current_binding.GetType();
3544 bool immutable_samplers = (current_binding.GetImmutableSamplerPtr() == nullptr);
3545 uint32_t dst_array_element = update->dstArrayElement;
sfricke-samsung941d48b2020-02-10 00:20:01 -08003546
Jeff Bolz9198e882020-03-18 13:03:30 -05003547 for (uint32_t i = 0; i < update->descriptorCount;) {
sfricke-samsung941d48b2020-02-10 00:20:01 -08003548 if (current_binding.AtEnd() == true) {
3549 break; // prevents setting error here if bindings don't exist
3550 }
3551
Quentin Huot-Marchand98d84dd2021-06-24 09:54:58 +02003552 // All consecutive bindings updated, except those with a descriptorCount of zero, must have identical descType and stageFlags
3553 if(current_binding.GetDescriptorCount() > 0) {
3554 // Check for consistent stageFlags and descriptorType
3555 if ((current_binding.GetStageFlags() != stage_flags) || (current_binding.GetType() != descriptor_type)) {
3556 *error_code = "VUID-VkWriteDescriptorSet-descriptorCount-00317";
3557 std::stringstream error_str;
3558 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3559 << current_binding.GetIndex() << " (" << i << " from dstBinding offset)"
3560 << " with a different stageFlag and/or descriptorType from previous bindings."
3561 << " All bindings must have consecutive stageFlag and/or descriptorType across a VkWriteDescriptorSet";
3562 *error_msg = error_str.str();
3563 return false;
3564 }
3565 // Check if all immutableSamplers or not
3566 if ((current_binding.GetImmutableSamplerPtr() == nullptr) != immutable_samplers) {
3567 *error_code = "VUID-VkWriteDescriptorSet-descriptorCount-00318";
3568 std::stringstream error_str;
3569 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3570 << current_binding.GetIndex() << " (" << i << " from dstBinding offset)"
3571 << " with a different usage of immutable samplers from previous bindings."
3572 << " All bindings must have all or none usage of immutable samplers across a VkWriteDescriptorSet";
3573 *error_msg = error_str.str();
3574 return false;
3575 }
sfricke-samsung941d48b2020-02-10 00:20:01 -08003576 }
Jeff Bolz9198e882020-03-18 13:03:30 -05003577
3578 // Skip the remaining descriptors for this binding, and move to the next binding
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003579 i += (current_binding.GetDescriptorCount() - dst_array_element);
3580 dst_array_element = 0;
sfricke-samsung941d48b2020-02-10 00:20:01 -08003581 ++current_binding;
3582 }
3583 }
3584
John Zulauf4956fff2019-06-04 16:54:38 -06003585 // Verify consecutive bindings match (if needed)
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003586 if (!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(dest_layout, update->dstBinding),
John Zulauf4956fff2019-06-04 16:54:38 -06003587 update->dstArrayElement, update->descriptorCount, "write update to", dest_set->GetSet(),
3588 error_msg)) {
John Zulauf4956fff2019-06-04 16:54:38 -06003589 *error_code = "VUID-VkWriteDescriptorSet-dstArrayElement-00321";
3590 return false;
3591 }
Tony-LunarG1f79c952020-10-27 15:55:51 -06003592 // Verify write to variable descriptor
3593 if (dest_set->IsVariableDescriptorCount(update->dstBinding)) {
3594 if ((update->dstArrayElement + update->descriptorCount) > dest_set->GetVariableDescriptorCount()) {
3595 std::stringstream error_str;
3596 *error_code = "VUID-VkWriteDescriptorSet-dstArrayElement-00321";
3597 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3598 << update->dstBinding << " array element " << update->dstArrayElement << " with " << update->descriptorCount
3599 << " writes but variable descriptor size is " << dest_set->GetVariableDescriptorCount();
3600 *error_msg = error_str.str();
3601 return false;
3602 }
3603 }
John Zulauf4956fff2019-06-04 16:54:38 -06003604 // Update is within bounds and consistent so last step is to validate update contents
ziga-lunarg6c46b242021-09-13 18:33:37 +02003605 if (!VerifyWriteUpdateContents(dest_set, update, start_idx, func_name, error_code, error_msg, push)) {
John Zulauf4956fff2019-06-04 16:54:38 -06003606 std::stringstream error_str;
3607 error_str << "Write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3608 << " failed with error message: " << error_msg->c_str();
3609 *error_msg = error_str.str();
3610 return false;
3611 }
ziga-lunargd67b5f52021-10-16 23:52:59 +02003612 const auto orig_binding = DescriptorSetLayout::ConstBindingIterator(dest_set->GetLayout().get(), update->dstBinding);
3613 if (!orig_binding.AtEnd() && orig_binding.GetType() == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
3614 // Check if the new descriptor descriptor type is in the list of allowed mutable types for this binding
3615 if (!orig_binding.Layout()->IsTypeMutable(update->descriptorType, update->dstBinding)) {
3616 *error_code = "VUID-VkWriteDescriptorSet-dstSet-04611";
3617 std::stringstream error_str;
3618 error_str << "Write update type is " << string_VkDescriptorType(update->descriptorType)
3619 << ", but descriptor set layout binding was created with type VK_DESCRIPTOR_TYPE_MUTABLE_VALVE and used type "
3620 "is not in VkMutableDescriptorTypeListVALVE::pDescriptorTypes for this binding.";
3621 *error_msg = error_str.str();
3622 return false;
3623 }
3624 }
John Zulauf4956fff2019-06-04 16:54:38 -06003625 // All checks passed, update is clean
3626 return true;
3627}
John Zulaufadb3f542019-06-04 17:01:00 -06003628
3629// Verify that the contents of the update are ok, but don't perform actual update
John Zulaufc93c4252019-06-25 09:19:49 -06003630bool CoreChecks::VerifyWriteUpdateContents(const DescriptorSet *dest_set, const VkWriteDescriptorSet *update, const uint32_t index,
ziga-lunarg6c46b242021-09-13 18:33:37 +02003631 const char *func_name, std::string *error_code, std::string *error_msg,
3632 bool push) const {
John Zulaufc93c4252019-06-25 09:19:49 -06003633 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
Nathaniel Cesarioff521512020-12-11 16:00:26 -07003634 using Descriptor = cvdescriptorset::Descriptor;
John Zulaufc93c4252019-06-25 09:19:49 -06003635
John Zulaufadb3f542019-06-04 17:01:00 -06003636 switch (update->descriptorType) {
3637 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
3638 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3639 // Validate image
3640 auto image_view = update->pImageInfo[di].imageView;
3641 auto image_layout = update->pImageInfo[di].imageLayout;
Mark Lobodzinski3ca937b2020-02-14 14:56:06 -07003642 auto sampler = update->pImageInfo[di].sampler;
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08003643 auto iv_state = GetImageViewState(image_view);
Nathaniel Cesarioff521512020-12-11 16:00:26 -07003644 const ImageSamplerDescriptor *desc =
3645 (const ImageSamplerDescriptor *)dest_set->GetDescriptorFromGlobalIndex(index + di);
Jeff Bolz165818a2020-05-08 11:19:03 -05003646 if (image_view) {
3647 auto image_state = iv_state->image_state.get();
3648 if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, func_name, error_code, error_msg)) {
3649 std::stringstream error_str;
3650 error_str << "Attempted write update to combined image sampler descriptor failed due to: "
3651 << error_msg->c_str();
3652 *error_msg = error_str.str();
3653 return false;
3654 }
sfricke-samsung45996a42021-09-16 13:45:27 -07003655 if (IsExtEnabled(device_extensions.vk_khr_sampler_ycbcr_conversion)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003656 if (desc->IsImmutableSampler()) {
3657 auto sampler_state = GetSamplerState(desc->GetSampler());
3658 if (iv_state && sampler_state) {
3659 if (iv_state->samplerConversion != sampler_state->samplerConversion) {
3660 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-01948";
3661 std::stringstream error_str;
3662 error_str
3663 << "Attempted write update to combined image sampler and image view and sampler ycbcr "
3664 "conversions are not identical, sampler: "
3665 << report_data->FormatHandle(desc->GetSampler())
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003666 << " image view: " << report_data->FormatHandle(iv_state->image_view()) << ".";
Jeff Bolz165818a2020-05-08 11:19:03 -05003667 *error_msg = error_str.str();
3668 return false;
3669 }
3670 }
3671 } else {
3672 if (iv_state && (iv_state->samplerConversion != VK_NULL_HANDLE)) {
3673 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02738";
John Zulaufadb3f542019-06-04 17:01:00 -06003674 std::stringstream error_str;
Jeff Bolz165818a2020-05-08 11:19:03 -05003675 error_str << "Because dstSet (" << report_data->FormatHandle(update->dstSet)
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003676 << ") is bound to image view (" << report_data->FormatHandle(iv_state->image_view())
Jeff Bolz165818a2020-05-08 11:19:03 -05003677 << ") that includes a YCBCR conversion, it must have been allocated with a layout that "
3678 "includes an immutable sampler.";
John Zulaufadb3f542019-06-04 17:01:00 -06003679 *error_msg = error_str.str();
3680 return false;
3681 }
3682 }
Jeff Bolz165818a2020-05-08 11:19:03 -05003683 }
John Baumanda8abff2020-10-19 21:25:21 +00003684 // If there is an immutable sampler then |sampler| isn't used, so the following VU does not apply.
3685 if (sampler && !desc->IsImmutableSampler() && FormatIsMultiplane(image_state->createInfo.format)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003686 // multiplane formats must be created with mutable format bit
3687 if (0 == (image_state->createInfo.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) {
3688 *error_code = "VUID-VkDescriptorImageInfo-sampler-01564";
John Zulaufadb3f542019-06-04 17:01:00 -06003689 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003690 error_str << "image " << report_data->FormatHandle(image_state->image())
Jeff Bolz165818a2020-05-08 11:19:03 -05003691 << " combined image sampler is a multi-planar "
3692 << "format and was not was not created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT";
John Zulaufadb3f542019-06-04 17:01:00 -06003693 *error_msg = error_str.str();
3694 return false;
3695 }
Jeff Bolz165818a2020-05-08 11:19:03 -05003696 // image view need aspect mask for only the planes supported of format
3697 VkImageAspectFlags legal_aspect_flags = (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT);
3698 legal_aspect_flags |=
3699 (FormatPlaneCount(image_state->createInfo.format) == 3) ? VK_IMAGE_ASPECT_PLANE_2_BIT : 0;
3700 if (0 != (iv_state->create_info.subresourceRange.aspectMask & (~legal_aspect_flags))) {
3701 *error_code = "VUID-VkDescriptorImageInfo-sampler-01564";
3702 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003703 error_str << "image " << report_data->FormatHandle(image_state->image())
Jeff Bolz165818a2020-05-08 11:19:03 -05003704 << " combined image sampler is a multi-planar "
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003705 << "format and " << report_data->FormatHandle(iv_state->image_view())
Jeff Bolz165818a2020-05-08 11:19:03 -05003706 << " aspectMask must only include " << string_VkImageAspectFlags(legal_aspect_flags);
3707 *error_msg = error_str.str();
3708 return false;
3709 }
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08003710 }
Nathaniel Cesario23afadd2020-11-17 12:51:45 -07003711
3712 // Verify portability
3713 auto sampler_state = GetSamplerState(sampler);
3714 if (sampler_state) {
sfricke-samsung45996a42021-09-16 13:45:27 -07003715 if (IsExtEnabled(device_extensions.vk_khr_portability_subset)) {
Nathaniel Cesario23afadd2020-11-17 12:51:45 -07003716 if ((VK_FALSE == enabled_features.portability_subset_features.mutableComparisonSamplers) &&
3717 (VK_FALSE != sampler_state->createInfo.compareEnable)) {
3718 LogError(device, "VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450",
3719 "%s (portability error): sampler comparison not available.", func_name);
3720 }
3721 }
3722 }
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08003723 }
John Zulaufadb3f542019-06-04 17:01:00 -06003724 }
3725 }
Mark Lobodzinskiac727772020-01-08 10:47:30 -07003726 // Fall through
John Zulaufadb3f542019-06-04 17:01:00 -06003727 case VK_DESCRIPTOR_TYPE_SAMPLER: {
3728 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003729 const auto *desc = static_cast<const Descriptor *>(dest_set->GetDescriptorFromGlobalIndex(index + di));
John Zulaufadb3f542019-06-04 17:01:00 -06003730 if (!desc->IsImmutableSampler()) {
John Zulaufc93c4252019-06-25 09:19:49 -06003731 if (!ValidateSampler(update->pImageInfo[di].sampler)) {
John Zulaufadb3f542019-06-04 17:01:00 -06003732 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
3733 std::stringstream error_str;
3734 error_str << "Attempted write update to sampler descriptor with invalid sampler: "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003735 << report_data->FormatHandle(update->pImageInfo[di].sampler) << ".";
John Zulaufadb3f542019-06-04 17:01:00 -06003736 *error_msg = error_str.str();
3737 return false;
3738 }
ziga-lunarg6c46b242021-09-13 18:33:37 +02003739 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER && !push) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003740 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02752";
3741 std::stringstream error_str;
3742 error_str << "Attempted write update to an immutable sampler descriptor.";
3743 *error_msg = error_str.str();
3744 return false;
John Zulaufadb3f542019-06-04 17:01:00 -06003745 }
3746 }
3747 break;
3748 }
3749 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3750 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
3751 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
3752 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3753 auto image_view = update->pImageInfo[di].imageView;
3754 auto image_layout = update->pImageInfo[di].imageLayout;
Jeff Bolz165818a2020-05-08 11:19:03 -05003755 if (image_view) {
3756 if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, func_name, error_code, error_msg)) {
3757 std::stringstream error_str;
3758 error_str << "Attempted write update to image descriptor failed due to: " << error_msg->c_str();
3759 *error_msg = error_str.str();
3760 return false;
3761 }
John Zulaufadb3f542019-06-04 17:01:00 -06003762 }
3763 }
3764 break;
3765 }
3766 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3767 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
3768 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3769 auto buffer_view = update->pTexelBufferView[di];
Jeff Bolz165818a2020-05-08 11:19:03 -05003770 if (buffer_view) {
3771 auto bv_state = GetBufferViewState(buffer_view);
3772 if (!bv_state) {
3773 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
3774 std::stringstream error_str;
3775 error_str << "Attempted write update to texel buffer descriptor with invalid buffer view: "
3776 << report_data->FormatHandle(buffer_view);
3777 *error_msg = error_str.str();
3778 return false;
3779 }
3780 auto buffer = bv_state->create_info.buffer;
3781 auto buffer_state = GetBufferState(buffer);
3782 // Verify that buffer underlying the view hasn't been destroyed prematurely
3783 if (!buffer_state) {
3784 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
3785 std::stringstream error_str;
3786 error_str << "Attempted write update to texel buffer descriptor failed because underlying buffer ("
3787 << report_data->FormatHandle(buffer) << ") has been destroyed: " << error_msg->c_str();
3788 *error_msg = error_str.str();
3789 return false;
3790 } else if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_state, update->descriptorType, error_code,
3791 error_msg)) {
3792 std::stringstream error_str;
3793 error_str << "Attempted write update to texel buffer descriptor failed due to: " << error_msg->c_str();
3794 *error_msg = error_str.str();
3795 return false;
3796 }
John Zulaufadb3f542019-06-04 17:01:00 -06003797 }
3798 }
3799 break;
3800 }
3801 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3802 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3803 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3804 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
3805 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003806 if (update->pBufferInfo[di].buffer) {
3807 if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, func_name, error_code, error_msg)) {
3808 std::stringstream error_str;
3809 error_str << "Attempted write update to buffer descriptor failed due to: " << error_msg->c_str();
3810 *error_msg = error_str.str();
3811 return false;
3812 }
John Zulaufadb3f542019-06-04 17:01:00 -06003813 }
3814 }
3815 break;
3816 }
3817 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
3818 break;
Jeff Bolz95176d02020-04-01 00:36:16 -05003819 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003820 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(update->pNext);
Jeff Bolz95176d02020-04-01 00:36:16 -05003821 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003822 if (!ValidateAccelerationStructureUpdate(GetAccelerationStructureStateNV(acc_info->pAccelerationStructures[di]),
Mark Lobodzinski85ebd402020-12-03 12:56:07 -07003823 func_name, error_code, error_msg)) {
Jeff Bolz95176d02020-04-01 00:36:16 -05003824 std::stringstream error_str;
3825 error_str << "Attempted write update to acceleration structure descriptor failed due to: "
3826 << error_msg->c_str();
3827 *error_msg = error_str.str();
3828 return false;
3829 }
3830 }
3831
3832 } break;
sourav parmarcd5fb182020-07-17 12:58:44 -07003833 // KHR acceleration structures don't require memory to be bound manually to them.
3834 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
3835 break;
John Zulaufadb3f542019-06-04 17:01:00 -06003836 default:
3837 assert(0); // We've already verified update type so should never get here
3838 break;
3839 }
3840 // All checks passed so update contents are good
3841 return true;
3842}