blob: 5634018b7bfc091bac2e443eff3191372fc8a2dc [file] [log] [blame]
Jeremy Gebben0d9143e2022-01-01 12:29:36 -07001/* Copyright (c) 2015-2022 The Khronos Group Inc.
2 * Copyright (c) 2015-2022 Valve Corporation
3 * Copyright (c) 2015-2022 LunarG, Inc.
4 * Copyright (C) 2015-2022 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),
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060052 maxSets(pCreateInfo->maxSets),
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060053 createInfo(pCreateInfo),
54 maxDescriptorTypeCount(GetMaxTypeCounts(pCreateInfo)),
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070055 available_sets_(pCreateInfo->maxSets),
56 available_counts_(maxDescriptorTypeCount),
57 dev_data_(dev) {}
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060058
59void DESCRIPTOR_POOL_STATE::Allocate(const VkDescriptorSetAllocateInfo *alloc_info, const VkDescriptorSet *descriptor_sets,
60 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) {
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070061 auto guard = WriteLock();
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060062 // Account for sets and individual descriptors allocated from pool
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070063 available_sets_ -= alloc_info->descriptorSetCount;
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060064 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070065 available_counts_[it->first] -= ds_data->required_descriptors_by_type.at(it->first);
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060066 }
67
68 const auto *variable_count_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(alloc_info->pNext);
69 bool variable_count_valid = variable_count_info && variable_count_info->descriptorSetCount == alloc_info->descriptorSetCount;
70
71 // Create tracking object for each descriptor set; insert into global map and the pool's set.
72 for (uint32_t i = 0; i < alloc_info->descriptorSetCount; i++) {
73 uint32_t variable_count = variable_count_valid ? variable_count_info->pDescriptorCounts[i] : 0;
74
75 auto new_ds = std::make_shared<cvdescriptorset::DescriptorSet>(descriptor_sets[i], this, ds_data->layout_nodes[i],
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070076 variable_count, dev_data_);
77 sets_.emplace(descriptor_sets[i], new_ds.get());
78 dev_data_->Add(std::move(new_ds));
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060079 }
80}
81
82void DESCRIPTOR_POOL_STATE::Free(uint32_t count, const VkDescriptorSet *descriptor_sets) {
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070083 auto guard = WriteLock();
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060084 // Update available descriptor sets in pool
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070085 available_sets_ += count;
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060086
Jeremy Gebben082a9832021-10-28 13:40:11 -060087 // For each freed descriptor add its resources back into the pool as available and remove from pool and device data
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060088 for (uint32_t i = 0; i < count; ++i) {
89 if (descriptor_sets[i] != VK_NULL_HANDLE) {
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070090 auto iter = sets_.find(descriptor_sets[i]);
91 assert(iter != sets_.end());
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060092 auto *set_state = iter->second;
93 uint32_t type_index = 0, descriptor_count = 0;
94 for (uint32_t j = 0; j < set_state->GetBindingCount(); ++j) {
95 type_index = static_cast<uint32_t>(set_state->GetTypeFromIndex(j));
96 descriptor_count = set_state->GetDescriptorCountFromIndex(j);
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070097 available_counts_[type_index] += descriptor_count;
Jeremy Gebben1fbebb82021-10-27 10:27:27 -060098 }
Jeremy Gebben0d9143e2022-01-01 12:29:36 -070099 dev_data_->Destroy<cvdescriptorset::DescriptorSet>(iter->first);
100 sets_.erase(iter);
Jeremy Gebben1fbebb82021-10-27 10:27:27 -0600101 }
102 }
103}
104
105void DESCRIPTOR_POOL_STATE::Reset() {
Jeremy Gebben0d9143e2022-01-01 12:29:36 -0700106 auto guard = WriteLock();
Jeremy Gebben1fbebb82021-10-27 10:27:27 -0600107 // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
Jeremy Gebben0d9143e2022-01-01 12:29:36 -0700108 for (auto entry : sets_) {
109 dev_data_->Destroy<cvdescriptorset::DescriptorSet>(entry.first);
Jeremy Gebben1fbebb82021-10-27 10:27:27 -0600110 }
Jeremy Gebben0d9143e2022-01-01 12:29:36 -0700111 sets_.clear();
Jeremy Gebben1fbebb82021-10-27 10:27:27 -0600112 // Reset available count for each type and available sets for this pool
Jeremy Gebben0d9143e2022-01-01 12:29:36 -0700113 available_counts_ = maxDescriptorTypeCount;
114 available_sets_ = maxSets;
115}
116
117bool DESCRIPTOR_POOL_STATE::InUse() const {
118 auto guard = ReadLock();
119 for (const auto &entry : sets_) {
120 const auto *ds = entry.second;
121 if (ds && ds->InUse()) {
122 return true;
123 }
124 }
125 return false;
Jeremy Gebben1fbebb82021-10-27 10:27:27 -0600126}
127
128void DESCRIPTOR_POOL_STATE::Destroy() {
129 Reset();
130 BASE_NODE::Destroy();
131}
132
Jeff Bolzfdf96072018-04-10 14:32:18 -0500133// ExtendedBinding collects a VkDescriptorSetLayoutBinding and any extended
134// state that comes from a different array/structure so they can stay together
135// while being sorted by binding number.
136struct ExtendedBinding {
Mike Schuchardt2df08912020-12-15 16:28:09 -0800137 ExtendedBinding(const VkDescriptorSetLayoutBinding *l, VkDescriptorBindingFlags f) : layout_binding(l), binding_flags(f) {}
Jeff Bolzfdf96072018-04-10 14:32:18 -0500138
139 const VkDescriptorSetLayoutBinding *layout_binding;
Mike Schuchardt2df08912020-12-15 16:28:09 -0800140 VkDescriptorBindingFlags binding_flags;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500141};
142
John Zulauf508d13a2018-01-05 15:10:34 -0700143struct BindingNumCmp {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500144 bool operator()(const ExtendedBinding &a, const ExtendedBinding &b) const {
145 return a.layout_binding->binding < b.layout_binding->binding;
John Zulauf508d13a2018-01-05 15:10:34 -0700146 }
147};
148
John Zulauf613fd982019-06-04 15:14:41 -0600149using DescriptorSet = cvdescriptorset::DescriptorSet;
John Zulauf4a015c92019-06-04 09:50:05 -0600150using DescriptorSetLayout = cvdescriptorset::DescriptorSetLayout;
John Zulaufd47d0612018-02-16 13:00:34 -0700151using DescriptorSetLayoutDef = cvdescriptorset::DescriptorSetLayoutDef;
152using DescriptorSetLayoutId = cvdescriptorset::DescriptorSetLayoutId;
153
John Zulauf34ebf272018-02-16 13:08:47 -0700154// Canonical dictionary of DescriptorSetLayoutDef (without any handle/device specific information)
155cvdescriptorset::DescriptorSetLayoutDict descriptor_set_layout_dict;
John Zulaufd47d0612018-02-16 13:00:34 -0700156
Shannon McPhersonc06c33d2018-06-28 17:21:12 -0600157DescriptorSetLayoutId GetCanonicalId(const VkDescriptorSetLayoutCreateInfo *p_create_info) {
John Zulauf34ebf272018-02-16 13:08:47 -0700158 return descriptor_set_layout_dict.look_up(DescriptorSetLayoutDef(p_create_info));
John Zulaufd47d0612018-02-16 13:00:34 -0700159}
John Zulauf34ebf272018-02-16 13:08:47 -0700160
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600161// Construct DescriptorSetLayout instance from given create info
John Zulauf48a6a702017-12-22 17:14:54 -0700162// Proactively reserve and resize as possible, as the reallocation was visible in profiling
John Zulauf1f8174b2018-02-16 12:58:37 -0700163cvdescriptorset::DescriptorSetLayoutDef::DescriptorSetLayoutDef(const VkDescriptorSetLayoutCreateInfo *p_create_info)
164 : flags_(p_create_info->flags), binding_count_(0), descriptor_count_(0), dynamic_descriptor_count_(0) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700165 const auto *flags_create_info = LvlFindInChain<VkDescriptorSetLayoutBindingFlagsCreateInfo>(p_create_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500166
sfricke-samsung0d00aed2021-03-08 23:31:17 -0800167 binding_type_stats_ = {0, 0};
Jeff Bolzfdf96072018-04-10 14:32:18 -0500168 std::set<ExtendedBinding, BindingNumCmp> sorted_bindings;
John Zulauf508d13a2018-01-05 15:10:34 -0700169 const uint32_t input_bindings_count = p_create_info->bindingCount;
170 // Sort the input bindings in binding number order, eliminating duplicates
171 for (uint32_t i = 0; i < input_bindings_count; i++) {
Mike Schuchardt2df08912020-12-15 16:28:09 -0800172 VkDescriptorBindingFlags flags = 0;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500173 if (flags_create_info && flags_create_info->bindingCount == p_create_info->bindingCount) {
174 flags = flags_create_info->pBindingFlags[i];
175 }
Jeremy Gebbenfc6f8152021-03-18 16:58:55 -0600176 sorted_bindings.emplace(p_create_info->pBindings + i, flags);
John Zulaufb6d71202017-12-22 16:47:09 -0700177 }
178
ziga-lunargd67b5f52021-10-16 23:52:59 +0200179 const auto *mutable_descriptor_type_create_info = LvlFindInChain<VkMutableDescriptorTypeCreateInfoVALVE>(p_create_info->pNext);
180 if (mutable_descriptor_type_create_info) {
181 mutable_types_.resize(mutable_descriptor_type_create_info->mutableDescriptorTypeListCount);
182 for (uint32_t i = 0; i < mutable_descriptor_type_create_info->mutableDescriptorTypeListCount; ++i) {
183 const auto &list = mutable_descriptor_type_create_info->pMutableDescriptorTypeLists[i];
184 mutable_types_[i].reserve(list.descriptorTypeCount);
185 for (uint32_t j = 0; j < list.descriptorTypeCount; ++j) {
186 mutable_types_[i].push_back(list.pDescriptorTypes[j]);
187 }
ziga-lunarg2ab8c472021-10-27 22:54:02 +0200188 std::sort(mutable_types_[i].begin(), mutable_types_[i].end());
ziga-lunargd67b5f52021-10-16 23:52:59 +0200189 }
190 }
191
John Zulaufb6d71202017-12-22 16:47:09 -0700192 // Store the create info in the sorted order from above
John Zulauf508d13a2018-01-05 15:10:34 -0700193 uint32_t index = 0;
194 binding_count_ = static_cast<uint32_t>(sorted_bindings.size());
195 bindings_.reserve(binding_count_);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500196 binding_flags_.reserve(binding_count_);
John Zulauf508d13a2018-01-05 15:10:34 -0700197 binding_to_index_map_.reserve(binding_count_);
John Zulauf79f06582021-02-27 18:38:39 -0700198 for (const auto &input_binding : sorted_bindings) {
John Zulauf508d13a2018-01-05 15:10:34 -0700199 // Add to binding and map, s.t. it is robust to invalid duplication of binding_num
Jeff Bolzfdf96072018-04-10 14:32:18 -0500200 const auto binding_num = input_binding.layout_binding->binding;
John Zulauf508d13a2018-01-05 15:10:34 -0700201 binding_to_index_map_[binding_num] = index++;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500202 bindings_.emplace_back(input_binding.layout_binding);
John Zulauf508d13a2018-01-05 15:10:34 -0700203 auto &binding_info = bindings_.back();
Jeff Bolzfdf96072018-04-10 14:32:18 -0500204 binding_flags_.emplace_back(input_binding.binding_flags);
John Zulauf508d13a2018-01-05 15:10:34 -0700205
John Zulaufb6d71202017-12-22 16:47:09 -0700206 descriptor_count_ += binding_info.descriptorCount;
207 if (binding_info.descriptorCount > 0) {
208 non_empty_bindings_.insert(binding_num);
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700209 }
John Zulaufb6d71202017-12-22 16:47:09 -0700210
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800211 if (IsDynamicDescriptor(binding_info.descriptorType)) {
sfricke-samsung0d00aed2021-03-08 23:31:17 -0800212 dynamic_descriptor_count_ += binding_info.descriptorCount;
213 }
214
215 // Get stats depending on descriptor type for caching later
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800216 if (IsBufferDescriptor(binding_info.descriptorType)) {
217 if (IsDynamicDescriptor(binding_info.descriptorType)) {
218 binding_type_stats_.dynamic_buffer_count++;
219 } else {
220 binding_type_stats_.non_dynamic_buffer_count++;
221 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600222 }
223 }
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700224 assert(bindings_.size() == binding_count_);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500225 assert(binding_flags_.size() == binding_count_);
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700226 uint32_t global_index = 0;
John Zulauf7705bfc2019-06-10 09:52:04 -0600227 global_index_range_.reserve(binding_count_);
228 // Vector order is finalized so build vectors of descriptors and dynamic offsets by binding index
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700229 for (uint32_t i = 0; i < binding_count_; ++i) {
John Zulaufc483f442017-12-15 14:02:06 -0700230 auto final_index = global_index + bindings_[i].descriptorCount;
John Zulauf7705bfc2019-06-10 09:52:04 -0600231 global_index_range_.emplace_back(global_index, final_index);
John Zulaufc483f442017-12-15 14:02:06 -0700232 global_index = final_index;
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700233 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600234}
Tobin Ehlis154c2692016-10-25 09:36:53 -0600235
John Zulaufd47d0612018-02-16 13:00:34 -0700236size_t cvdescriptorset::DescriptorSetLayoutDef::hash() const {
237 hash_util::HashCombiner hc;
238 hc << flags_;
239 hc.Combine(bindings_);
John Zulauf223b69d2018-11-09 16:00:59 -0700240 hc.Combine(binding_flags_);
John Zulaufd47d0612018-02-16 13:00:34 -0700241 return hc.Value();
242}
243//
244
John Zulauf1f8174b2018-02-16 12:58:37 -0700245// Return valid index or "end" i.e. binding_count_;
246// The asserts in "Get" are reduced to the set where no valid answer(like null or 0) could be given
247// Common code for all binding lookups.
248uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetIndexFromBinding(uint32_t binding) const {
249 const auto &bi_itr = binding_to_index_map_.find(binding);
250 if (bi_itr != binding_to_index_map_.cend()) return bi_itr->second;
251 return GetBindingCount();
252}
253VkDescriptorSetLayoutBinding const *cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorSetLayoutBindingPtrFromIndex(
254 const uint32_t index) const {
255 if (index >= bindings_.size()) return nullptr;
256 return bindings_[index].ptr();
257}
258// Return descriptorCount for given index, 0 if index is unavailable
259uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorCountFromIndex(const uint32_t index) const {
260 if (index >= bindings_.size()) return 0;
261 return bindings_[index].descriptorCount;
262}
263// For the given index, return descriptorType
264VkDescriptorType cvdescriptorset::DescriptorSetLayoutDef::GetTypeFromIndex(const uint32_t index) const {
265 assert(index < bindings_.size());
266 if (index < bindings_.size()) return bindings_[index].descriptorType;
267 return VK_DESCRIPTOR_TYPE_MAX_ENUM;
268}
269// For the given index, return stageFlags
270VkShaderStageFlags cvdescriptorset::DescriptorSetLayoutDef::GetStageFlagsFromIndex(const uint32_t index) const {
271 assert(index < bindings_.size());
272 if (index < bindings_.size()) return bindings_[index].stageFlags;
273 return VkShaderStageFlags(0);
274}
Jeff Bolzfdf96072018-04-10 14:32:18 -0500275// Return binding flags for given index, 0 if index is unavailable
Mike Schuchardt2df08912020-12-15 16:28:09 -0800276VkDescriptorBindingFlags cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorBindingFlagsFromIndex(const uint32_t index) const {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500277 if (index >= binding_flags_.size()) return 0;
278 return binding_flags_[index];
279}
John Zulauf1f8174b2018-02-16 12:58:37 -0700280
John Zulauf7705bfc2019-06-10 09:52:04 -0600281const cvdescriptorset::IndexRange &cvdescriptorset::DescriptorSetLayoutDef::GetGlobalIndexRangeFromIndex(uint32_t index) const {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700282 const static IndexRange k_invalid_range = {0xFFFFFFFF, 0xFFFFFFFF};
283 if (index >= binding_flags_.size()) return k_invalid_range;
John Zulauf7705bfc2019-06-10 09:52:04 -0600284 return global_index_range_[index];
John Zulauf1f8174b2018-02-16 12:58:37 -0700285}
286
John Zulauf7705bfc2019-06-10 09:52:04 -0600287// For the given binding, return the global index range (half open)
288// As start and end are often needed in pairs, get both with a single lookup.
John Zulauf1f8174b2018-02-16 12:58:37 -0700289const cvdescriptorset::IndexRange &cvdescriptorset::DescriptorSetLayoutDef::GetGlobalIndexRangeFromBinding(
290 const uint32_t binding) const {
John Zulauf7705bfc2019-06-10 09:52:04 -0600291 uint32_t index = GetIndexFromBinding(binding);
292 return GetGlobalIndexRangeFromIndex(index);
John Zulauf1f8174b2018-02-16 12:58:37 -0700293}
294
295// For given binding, return ptr to ImmutableSampler array
296VkSampler const *cvdescriptorset::DescriptorSetLayoutDef::GetImmutableSamplerPtrFromBinding(const uint32_t binding) const {
297 const auto &bi_itr = binding_to_index_map_.find(binding);
298 if (bi_itr != binding_to_index_map_.end()) {
299 return bindings_[bi_itr->second].pImmutableSamplers;
300 }
301 return nullptr;
302}
303// Move to next valid binding having a non-zero binding count
304uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetNextValidBinding(const uint32_t binding) const {
305 auto it = non_empty_bindings_.upper_bound(binding);
306 assert(it != non_empty_bindings_.cend());
307 if (it != non_empty_bindings_.cend()) return *it;
308 return GetMaxBinding() + 1;
309}
310// For given index, return ptr to ImmutableSampler array
311VkSampler const *cvdescriptorset::DescriptorSetLayoutDef::GetImmutableSamplerPtrFromIndex(const uint32_t index) const {
312 if (index < bindings_.size()) {
313 return bindings_[index].pImmutableSamplers;
314 }
315 return nullptr;
316}
John Zulauf9ce3b252019-06-06 15:20:22 -0600317
ziga-lunargd67b5f52021-10-16 23:52:59 +0200318bool cvdescriptorset::DescriptorSetLayoutDef::IsTypeMutable(const VkDescriptorType type, uint32_t binding) const {
319 if (binding < mutable_types_.size()) {
320 if (mutable_types_[binding].size() > 0) {
321 for (const auto mutable_type : mutable_types_[binding]) {
322 if (type == mutable_type) {
323 return true;
324 }
325 }
326 return false;
327 }
328 }
329 // If mutableDescriptorTypeListCount is zero or if VkMutableDescriptorTypeCreateInfoVALVE structure is not included in the pNext
330 // chain, the VkMutableDescriptorTypeListVALVE for each element is considered to be zero or NULL for each member.
331 return false;
332}
333
ziga-lunarg2ab8c472021-10-27 22:54:02 +0200334const std::vector<std::vector<VkDescriptorType>>& cvdescriptorset::DescriptorSetLayoutDef::GetMutableTypes() const {
335 return mutable_types_;
336}
337
ziga-lunarge5d28542021-10-24 21:14:25 +0200338const std::vector<VkDescriptorType> &cvdescriptorset::DescriptorSetLayoutDef::GetMutableTypes(uint32_t binding) const {
339 if (binding >= mutable_types_.size()) {
340 static const std::vector<VkDescriptorType> empty = {};
341 return empty;
342 }
343 return mutable_types_[binding];
344}
345
John Zulauf9ce3b252019-06-06 15:20:22 -0600346// If our layout is compatible with rh_ds_layout, return true.
347bool cvdescriptorset::DescriptorSetLayout::IsCompatible(DescriptorSetLayout const *rh_ds_layout) const {
348 bool compatible = (this == rh_ds_layout) || (GetLayoutDef() == rh_ds_layout->GetLayoutDef());
349 return compatible;
350}
John Zulauf1f8174b2018-02-16 12:58:37 -0700351
John Zulauff43695f2019-09-13 17:56:26 -0600352// TODO: Find a way to add smarts to the autogenerated version of this
353static std::string smart_string_VkShaderStageFlags(VkShaderStageFlags stage_flags) {
354 if (stage_flags == VK_SHADER_STAGE_ALL) {
355 return string_VkShaderStageFlagBits(VK_SHADER_STAGE_ALL);
356 }
357
358 return string_VkShaderStageFlags(stage_flags);
359}
360
361// If our layout is compatible with bound_dsl, return true,
362// else return false and fill in error_msg will description of what causes incompatibility
363bool cvdescriptorset::VerifySetLayoutCompatibility(const debug_report_data *report_data, DescriptorSetLayout const *layout_dsl,
364 DescriptorSetLayout const *bound_dsl, std::string *error_msg) {
365 // Short circuit the detailed check.
366 if (layout_dsl->IsCompatible(bound_dsl)) return true;
367
368 // 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 -0600369 // Should only be run if trivial accept has failed, and in that context should return false.
John Zulauff43695f2019-09-13 17:56:26 -0600370 VkDescriptorSetLayout layout_dsl_handle = layout_dsl->GetDescriptorSetLayout();
371 VkDescriptorSetLayout bound_dsl_handle = bound_dsl->GetDescriptorSetLayout();
372 DescriptorSetLayoutDef const *layout_ds_layout_def = layout_dsl->GetLayoutDef();
373 DescriptorSetLayoutDef const *bound_ds_layout_def = bound_dsl->GetLayoutDef();
John Zulauf9ce3b252019-06-06 15:20:22 -0600374
375 // Check descriptor counts
John Zulauff43695f2019-09-13 17:56:26 -0600376 const auto bound_total_count = bound_ds_layout_def->GetTotalDescriptorCount();
377 if (layout_ds_layout_def->GetTotalDescriptorCount() != bound_ds_layout_def->GetTotalDescriptorCount()) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700378 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600379 error_str << report_data->FormatHandle(layout_dsl_handle) << " from pipeline layout has "
380 << layout_ds_layout_def->GetTotalDescriptorCount() << " total descriptors, but "
381 << report_data->FormatHandle(bound_dsl_handle) << ", which is bound, has " << bound_total_count
382 << " total descriptors.";
John Zulauf1f8174b2018-02-16 12:58:37 -0700383 *error_msg = error_str.str();
384 return false; // trivial fail case
385 }
John Zulaufd47d0612018-02-16 13:00:34 -0700386
John Zulauf1f8174b2018-02-16 12:58:37 -0700387 // Descriptor counts match so need to go through bindings one-by-one
388 // and verify that type and stageFlags match
John Zulauff43695f2019-09-13 17:56:26 -0600389 for (const auto &layout_binding : layout_ds_layout_def->GetBindings()) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700390 // TODO : Do we also need to check immutable samplers?
John Zulauff43695f2019-09-13 17:56:26 -0600391 const auto bound_binding = bound_ds_layout_def->GetBindingInfoFromBinding(layout_binding.binding);
392 if (layout_binding.descriptorCount != bound_binding->descriptorCount) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700393 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600394 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
395 << " from pipeline layout has a descriptorCount of " << layout_binding.descriptorCount << " but binding "
396 << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
397 << ", which is bound, has a descriptorCount of " << bound_binding->descriptorCount;
John Zulauf1f8174b2018-02-16 12:58:37 -0700398 *error_msg = error_str.str();
399 return false;
John Zulauff43695f2019-09-13 17:56:26 -0600400 } else if (layout_binding.descriptorType != bound_binding->descriptorType) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700401 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600402 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
403 << " from pipeline layout is type '" << string_VkDescriptorType(layout_binding.descriptorType)
404 << "' but binding " << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
405 << ", which is bound, is type '" << string_VkDescriptorType(bound_binding->descriptorType) << "'";
John Zulauf1f8174b2018-02-16 12:58:37 -0700406 *error_msg = error_str.str();
407 return false;
John Zulauff43695f2019-09-13 17:56:26 -0600408 } else if (layout_binding.stageFlags != bound_binding->stageFlags) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700409 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600410 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
411 << " from pipeline layout has stageFlags " << smart_string_VkShaderStageFlags(layout_binding.stageFlags)
412 << " but binding " << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
413 << ", which is bound, has stageFlags " << smart_string_VkShaderStageFlags(bound_binding->stageFlags);
John Zulauf1f8174b2018-02-16 12:58:37 -0700414 *error_msg = error_str.str();
415 return false;
416 }
417 }
Tony-LunarG692b8b42019-09-30 16:07:26 -0600418
419 const auto &ds_layout_flags = layout_ds_layout_def->GetBindingFlags();
420 const auto &bound_layout_flags = bound_ds_layout_def->GetBindingFlags();
421 if (bound_layout_flags != ds_layout_flags) {
422 std::stringstream error_str;
423 assert(ds_layout_flags.size() == bound_layout_flags.size());
424 size_t i;
425 for (i = 0; i < ds_layout_flags.size(); i++) {
426 if (ds_layout_flags[i] != bound_layout_flags[i]) break;
427 }
428 error_str << report_data->FormatHandle(layout_dsl_handle)
429 << " from pipeline layout does not have the same binding flags at binding " << i << " ( "
430 << string_VkDescriptorBindingFlagsEXT(ds_layout_flags[i]) << " ) as "
431 << report_data->FormatHandle(bound_dsl_handle) << " ( "
432 << string_VkDescriptorBindingFlagsEXT(bound_layout_flags[i]) << " ), which is bound";
433 *error_msg = error_str.str();
434 return false;
435 }
436
John Zulauf9ce3b252019-06-06 15:20:22 -0600437 // No detailed check should succeed if the trivial check failed -- or the dictionary has failed somehow.
438 bool compatible = true;
439 assert(!compatible);
440 return compatible;
John Zulauf1f8174b2018-02-16 12:58:37 -0700441}
442
443bool cvdescriptorset::DescriptorSetLayoutDef::IsNextBindingConsistent(const uint32_t binding) const {
444 if (!binding_to_index_map_.count(binding + 1)) return false;
445 auto const &bi_itr = binding_to_index_map_.find(binding);
446 if (bi_itr != binding_to_index_map_.end()) {
447 const auto &next_bi_itr = binding_to_index_map_.find(binding + 1);
448 if (next_bi_itr != binding_to_index_map_.end()) {
449 auto type = bindings_[bi_itr->second].descriptorType;
450 auto stage_flags = bindings_[bi_itr->second].stageFlags;
451 auto immut_samp = bindings_[bi_itr->second].pImmutableSamplers ? true : false;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500452 auto flags = binding_flags_[bi_itr->second];
John Zulauf1f8174b2018-02-16 12:58:37 -0700453 if ((type != bindings_[next_bi_itr->second].descriptorType) ||
454 (stage_flags != bindings_[next_bi_itr->second].stageFlags) ||
Jeff Bolzfdf96072018-04-10 14:32:18 -0500455 (immut_samp != (bindings_[next_bi_itr->second].pImmutableSamplers ? true : false)) ||
456 (flags != binding_flags_[next_bi_itr->second])) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700457 return false;
458 }
459 return true;
460 }
461 }
462 return false;
463}
John Zulauf1f8174b2018-02-16 12:58:37 -0700464
465// The DescriptorSetLayout stores the per handle data for a descriptor set layout, and references the common defintion for the
466// handle invariant portion
467cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *p_create_info,
468 const VkDescriptorSetLayout layout)
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600469 : BASE_NODE(layout, kVulkanObjectTypeDescriptorSetLayout), layout_id_(GetCanonicalId(p_create_info)) {}
John Zulauf1f8174b2018-02-16 12:58:37 -0700470
Tobin Ehlis154c2692016-10-25 09:36:53 -0600471// Validate descriptor set layout create info
John Zulaufd9435c32019-06-05 15:55:36 -0600472bool cvdescriptorset::ValidateDescriptorSetLayoutCreateInfo(
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700473 const ValidationObject *val_obj, const VkDescriptorSetLayoutCreateInfo *create_info, const bool push_descriptor_ext,
Jeff Bolzfdf96072018-04-10 14:32:18 -0500474 const uint32_t max_push_descriptors, const bool descriptor_indexing_ext,
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700475 const VkPhysicalDeviceVulkan12Features *core12_features,
Tony-LunarG273f32f2021-09-28 08:56:30 -0600476 const VkPhysicalDeviceVulkan13Features* core13_features,
ziga-lunarg637356a2021-07-19 12:36:34 +0200477 const VkPhysicalDeviceInlineUniformBlockPropertiesEXT *inline_uniform_block_props,
478 const VkPhysicalDeviceAccelerationStructureFeaturesKHR *acceleration_structure_features,
479 const DeviceExtensions *device_extensions) {
Tobin Ehlis154c2692016-10-25 09:36:53 -0600480 bool skip = false;
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700481 layer_data::unordered_set<uint32_t> bindings;
John Zulauf0fdeab32018-01-23 11:27:35 -0700482 uint64_t total_descriptors = 0;
483
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700484 const auto *flags_create_info = LvlFindInChain<VkDescriptorSetLayoutBindingFlagsCreateInfo>(create_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500485
486 const bool push_descriptor_set = !!(create_info->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
John Zulauf0fdeab32018-01-23 11:27:35 -0700487 if (push_descriptor_set && !push_descriptor_ext) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800488 skip |= val_obj->LogError(
489 val_obj->device, kVUID_Core_DrawState_ExtensionNotEnabled,
490 "vkCreateDescriptorSetLayout(): Attempted to use %s in %s but its required extension %s has not been enabled.\n",
491 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR", "VkDescriptorSetLayoutCreateInfo::flags",
492 VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
John Zulauf0fdeab32018-01-23 11:27:35 -0700493 }
494
Mike Schuchardt2df08912020-12-15 16:28:09 -0800495 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 -0500496 if (update_after_bind_set && !descriptor_indexing_ext) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800497 skip |= val_obj->LogError(
498 val_obj->device, kVUID_Core_DrawState_ExtensionNotEnabled,
499 "vkCreateDescriptorSetLayout(): Attemped to use %s in %s but its required extension %s has not been enabled.\n",
500 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT", "VkDescriptorSetLayoutCreateInfo::flags",
501 VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500502 }
503
John Zulauf0fdeab32018-01-23 11:27:35 -0700504 auto valid_type = [push_descriptor_set](const VkDescriptorType type) {
505 return !push_descriptor_set ||
Dave Houlton142c4cb2018-10-17 15:04:41 -0600506 ((type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) && (type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) &&
Jeff Bolze54ae892018-09-08 12:16:29 -0500507 (type != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT));
John Zulauf0fdeab32018-01-23 11:27:35 -0700508 };
509
Jeff Bolzfdf96072018-04-10 14:32:18 -0500510 uint32_t max_binding = 0;
511
ziga-lunarg185ef282021-07-19 13:13:28 +0200512 uint32_t update_after_bind = create_info->bindingCount;
513 uint32_t uniform_buffer_dynamic = create_info->bindingCount;
514 uint32_t storage_buffer_dynamic = create_info->bindingCount;
515
Tobin Ehlis154c2692016-10-25 09:36:53 -0600516 for (uint32_t i = 0; i < create_info->bindingCount; ++i) {
John Zulauf0fdeab32018-01-23 11:27:35 -0700517 const auto &binding_info = create_info->pBindings[i];
Jeff Bolzfdf96072018-04-10 14:32:18 -0500518 max_binding = std::max(max_binding, binding_info.binding);
519
John Zulauf0fdeab32018-01-23 11:27:35 -0700520 if (!bindings.insert(binding_info.binding).second) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700521 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-binding-00279",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800522 "vkCreateDescriptorSetLayout(): pBindings[%u] has duplicated binding number (%u).", i,
523 binding_info.binding);
Tobin Ehlis154c2692016-10-25 09:36:53 -0600524 }
John Zulauf0fdeab32018-01-23 11:27:35 -0700525 if (!valid_type(binding_info.descriptorType)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700526 skip |= val_obj->LogError(val_obj->device,
527 (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
528 ? "VUID-VkDescriptorSetLayoutCreateInfo-flags-02208"
529 : "VUID-VkDescriptorSetLayoutCreateInfo-flags-00280",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800530 "vkCreateDescriptorSetLayout(): pBindings[%u] has invalid type %s , for push descriptors.", i,
531 string_VkDescriptorType(binding_info.descriptorType));
John Zulauf0fdeab32018-01-23 11:27:35 -0700532 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500533
534 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG273f32f2021-09-28 08:56:30 -0600535 if (!core13_features->inlineUniformBlock) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800536 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-04604",
537 "vkCreateDescriptorSetLayout(): pBindings[%u] is creating VkDescriptorSetLayout with "
538 "descriptor type VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT "
Jeremy Gebbenda6b48f2021-05-13 10:46:18 -0600539 "but the inlineUniformBlock feature is not enabled",
540 i);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600541 } else {
542 if ((binding_info.descriptorCount % 4) != 0) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800543 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02209",
544 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorCount =(%" PRIu32
545 ") but must be a multiple of 4",
546 i, binding_info.descriptorCount);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600547 }
548 if (binding_info.descriptorCount > inline_uniform_block_props->maxInlineUniformBlockSize) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700549 skip |=
550 val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02210",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800551 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorCount =(%" PRIu32
552 ") but must be less than or equal to maxInlineUniformBlockSize (%u)",
553 i, binding_info.descriptorCount, inline_uniform_block_props->maxInlineUniformBlockSize);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600554 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500555 }
ziga-lunarg185ef282021-07-19 13:13:28 +0200556 } else if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
557 uniform_buffer_dynamic = i;
558 } else if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
559 storage_buffer_dynamic = i;
Jeff Bolze54ae892018-09-08 12:16:29 -0500560 }
561
Tony-LunarG7337b312020-04-15 16:40:25 -0600562 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
563 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
sfricke-samsung45996a42021-09-16 13:45:27 -0700564 binding_info.pImmutableSamplers && IsExtEnabled(device_extensions->vk_ext_custom_border_color)) {
Tony-LunarG7337b312020-04-15 16:40:25 -0600565 const CoreChecks *core_checks = reinterpret_cast<const CoreChecks *>(val_obj);
566 for (uint32_t j = 0; j < binding_info.descriptorCount; j++) {
Jeremy Gebbenf4449392022-01-28 10:09:10 -0700567 auto sampler_state = core_checks->Get<SAMPLER_STATE>(binding_info.pImmutableSamplers[j]);
Tony-LunarG7337b312020-04-15 16:40:25 -0600568 if (sampler_state && (sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
569 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800570 skip |= val_obj->LogError(
571 val_obj->device, "VUID-VkDescriptorSetLayoutBinding-pImmutableSamplers-04009",
Jeremy Gebbenda6b48f2021-05-13 10:46:18 -0600572 "vkCreateDescriptorSetLayout(): pBindings[%u].pImmutableSamplers[%u] has VkSampler %s"
sfricke-samsungbda4a852021-03-06 20:58:01 -0800573 " presented as immutable has a custom border color",
Jeremy Gebbenda6b48f2021-05-13 10:46:18 -0600574 i, j, val_obj->report_data->FormatHandle(binding_info.pImmutableSamplers[j]).c_str());
Tony-LunarG7337b312020-04-15 16:40:25 -0600575 }
576 }
577 }
578
ziga-lunarg6d770792021-07-19 11:27:18 +0200579 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE && binding_info.pImmutableSamplers != nullptr) {
580 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-04605",
581 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorType "
582 "VK_DESCRIPTOR_TYPE_MUTABLE_VALVE but pImmutableSamplers is not NULL.",
583 i);
584 }
585
John Zulauf0fdeab32018-01-23 11:27:35 -0700586 total_descriptors += binding_info.descriptorCount;
Tobin Ehlis154c2692016-10-25 09:36:53 -0600587 }
John Zulauf0fdeab32018-01-23 11:27:35 -0700588
Jeff Bolzfdf96072018-04-10 14:32:18 -0500589 if (flags_create_info) {
590 if (flags_create_info->bindingCount != 0 && flags_create_info->bindingCount != create_info->bindingCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700591 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-bindingCount-03002",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800592 "vkCreateDescriptorSetLayout(): VkDescriptorSetLayoutCreateInfo::bindingCount (%d) != "
Mike Schuchardt2df08912020-12-15 16:28:09 -0800593 "VkDescriptorSetLayoutBindingFlagsCreateInfo::bindingCount (%d)",
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700594 create_info->bindingCount, flags_create_info->bindingCount);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500595 }
596
597 if (flags_create_info->bindingCount == create_info->bindingCount) {
598 for (uint32_t i = 0; i < create_info->bindingCount; ++i) {
599 const auto &binding_info = create_info->pBindings[i];
600
Mike Schuchardt2df08912020-12-15 16:28:09 -0800601 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT) {
ziga-lunarg185ef282021-07-19 13:13:28 +0200602 update_after_bind = i;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500603 if (!update_after_bind_set) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700604 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-flags-03000",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800605 "vkCreateDescriptorSetLayout(): pBindings[%u] does not have "
606 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT.",
607 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500608 }
609
610 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700611 !core12_features->descriptorBindingUniformBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800612 skip |= val_obj->LogError(
613 val_obj->device,
614 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
615 "descriptorBindingUniformBufferUpdateAfterBind-03005",
616 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
617 "for %s since descriptorBindingUniformBufferUpdateAfterBind is not enabled.",
618 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500619 }
620 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
621 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
622 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700623 !core12_features->descriptorBindingSampledImageUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800624 skip |= val_obj->LogError(
625 val_obj->device,
626 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
627 "descriptorBindingSampledImageUpdateAfterBind-03006",
628 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
629 "for %s since descriptorBindingSampledImageUpdateAfterBind is not enabled.",
630 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500631 }
632 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700633 !core12_features->descriptorBindingStorageImageUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800634 skip |= val_obj->LogError(
635 val_obj->device,
636 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
637 "descriptorBindingStorageImageUpdateAfterBind-03007",
638 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
639 "for %s since descriptorBindingStorageImageUpdateAfterBind is not enabled.",
640 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500641 }
642 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700643 !core12_features->descriptorBindingStorageBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800644 skip |= val_obj->LogError(
645 val_obj->device,
646 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
647 "descriptorBindingStorageBufferUpdateAfterBind-03008",
648 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
649 "for %s since descriptorBindingStorageBufferUpdateAfterBind is not enabled.",
650 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500651 }
652 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700653 !core12_features->descriptorBindingUniformTexelBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800654 skip |= val_obj->LogError(
655 val_obj->device,
656 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
657 "descriptorBindingUniformTexelBufferUpdateAfterBind-03009",
658 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
659 "for %s since descriptorBindingUniformTexelBufferUpdateAfterBind is not enabled.",
660 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500661 }
662 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700663 !core12_features->descriptorBindingStorageTexelBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800664 skip |= val_obj->LogError(
665 val_obj->device,
666 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
667 "descriptorBindingStorageTexelBufferUpdateAfterBind-03010",
668 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
669 "for %s since descriptorBindingStorageTexelBufferUpdateAfterBind is not enabled.",
670 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500671 }
672 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
673 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
674 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700675 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-None-03011",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800676 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
677 "VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT for %s.",
678 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500679 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500680
681 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
Tony-LunarG273f32f2021-09-28 08:56:30 -0600682 !core13_features->descriptorBindingInlineUniformBlockUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800683 skip |= val_obj->LogError(
684 val_obj->device,
685 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
686 "descriptorBindingInlineUniformBlockUpdateAfterBind-02211",
687 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
688 "for %s since descriptorBindingInlineUniformBlockUpdateAfterBind is not enabled.",
689 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolze54ae892018-09-08 12:16:29 -0500690 }
ziga-lunarg637356a2021-07-19 12:36:34 +0200691 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR ||
692 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV) &&
693 !acceleration_structure_features->descriptorBindingAccelerationStructureUpdateAfterBind) {
694 skip |= val_obj->LogError(val_obj->device,
695 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
696 "descriptorBindingAccelerationStructureUpdateAfterBind-03570",
697 "vkCreateDescriptorSetLayout(): pBindings[%" PRIu32
698 "] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
699 "for %s if "
700 "VkPhysicalDeviceAccelerationStructureFeaturesKHR::"
701 "descriptorBindingAccelerationStructureUpdateAfterBind is not enabled.",
702 i, string_VkDescriptorType(binding_info.descriptorType));
703 }
Jeff Bolzfdf96072018-04-10 14:32:18 -0500704 }
705
Mike Schuchardt2df08912020-12-15 16:28:09 -0800706 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700707 if (!core12_features->descriptorBindingUpdateUnusedWhilePending) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700708 skip |= val_obj->LogError(
709 val_obj->device,
Mike Schuchardt65847d92019-12-20 13:50:47 -0800710 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingUpdateUnusedWhilePending-03012",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800711 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
712 "VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT for %s since "
713 "descriptorBindingUpdateUnusedWhilePending is not enabled.",
714 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500715 }
716 }
717
Mike Schuchardt2df08912020-12-15 16:28:09 -0800718 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700719 if (!core12_features->descriptorBindingPartiallyBound) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700720 skip |= val_obj->LogError(
721 val_obj->device,
722 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingPartiallyBound-03013",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800723 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT for "
724 "%s since descriptorBindingPartiallyBound is not enabled.",
725 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500726 }
727 }
728
Mike Schuchardt2df08912020-12-15 16:28:09 -0800729 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT) {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500730 if (binding_info.binding != max_binding) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800731 skip |= val_obj->LogError(
732 val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004",
733 "vkCreateDescriptorSetLayout(): pBindings[%u] has VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT "
734 "but %u is the largest value of all the bindings.",
735 i, binding_info.binding);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500736 }
737
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700738 if (!core12_features->descriptorBindingVariableDescriptorCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700739 skip |= val_obj->LogError(
740 val_obj->device,
Mike Schuchardt65847d92019-12-20 13:50:47 -0800741 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingVariableDescriptorCount-03014",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800742 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
743 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for %s since "
744 "descriptorBindingVariableDescriptorCount is not enabled.",
745 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500746 }
sfricke-samsung4ba7d6e2021-03-06 20:56:35 -0800747 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
748 (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700749 skip |= val_obj->LogError(val_obj->device,
750 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03015",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800751 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
752 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for %s.",
753 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500754 }
755 }
756
757 if (push_descriptor_set &&
758 (flags_create_info->pBindingFlags[i] &
Mike Schuchardt2df08912020-12-15 16:28:09 -0800759 (VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT |
760 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT))) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800761 skip |= val_obj->LogError(
762 val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-flags-03003",
763 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, "
764 "VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, or "
765 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for with "
766 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR.",
767 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500768 }
769 }
770 }
771 }
772
ziga-lunarg185ef282021-07-19 13:13:28 +0200773 if (update_after_bind < create_info->bindingCount) {
774 if (uniform_buffer_dynamic < create_info->bindingCount) {
775 skip |=
776 val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-descriptorType-03001",
777 "vkCreateDescriptorSetLayout(): binding (%" PRIi32
778 ") has VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
779 "flag, but binding (%" PRIi32 ") has descriptor type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC.",
780 update_after_bind, uniform_buffer_dynamic);
781 }
782 if (storage_buffer_dynamic < create_info->bindingCount) {
783 skip |=
784 val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-descriptorType-03001",
785 "vkCreateDescriptorSetLayout(): binding (%" PRIi32
786 ") has VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
787 "flag, but binding (%" PRIi32 ") has descriptor type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC.",
788 update_after_bind, storage_buffer_dynamic);
789 }
790 }
791
John Zulauf0fdeab32018-01-23 11:27:35 -0700792 if ((push_descriptor_set) && (total_descriptors > max_push_descriptors)) {
793 const char *undefined = push_descriptor_ext ? "" : " -- undefined";
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700794 skip |= val_obj->LogError(
795 val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-flags-00281",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800796 "vkCreateDescriptorSetLayout(): for push descriptor, total descriptor count in layout (%" PRIu64
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700797 ") must not be greater than VkPhysicalDevicePushDescriptorPropertiesKHR::maxPushDescriptors (%" PRIu32 "%s).",
798 total_descriptors, max_push_descriptors, undefined);
John Zulauf0fdeab32018-01-23 11:27:35 -0700799 }
800
Tobin Ehlis154c2692016-10-25 09:36:53 -0600801 return skip;
802}
803
Mark Lobodzinskie12b6e32020-06-29 11:44:15 -0600804void cvdescriptorset::AllocateDescriptorSetsData::Init(uint32_t count) {
805 layout_nodes.resize(count);
Mark Lobodzinskie12b6e32020-06-29 11:44:15 -0600806}
Tobin Ehlis68d0adf2016-06-01 11:33:50 -0600807
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500808cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, DESCRIPTOR_POOL_STATE *pool_state,
Jeff Bolzfdf96072018-04-10 14:32:18 -0500809 const std::shared_ptr<DescriptorSetLayout const> &layout, uint32_t variable_count,
John Zulaufd2c3dae2019-12-12 11:02:17 -0700810 const cvdescriptorset::DescriptorSet::StateTracker *state_data)
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -0600811 : BASE_NODE(set, kVulkanObjectTypeDescriptorSet),
812 some_update_(false),
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500813 pool_state_(pool_state),
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700814 layout_(layout),
John Zulaufd2c3dae2019-12-12 11:02:17 -0700815 state_data_(state_data),
Jeff Bolzdd4cfa12019-08-11 20:57:51 -0500816 variable_count_(variable_count),
817 change_count_(0) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600818 // Foreach binding, create default descriptors of given type
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700819 descriptors_.reserve(layout_->GetTotalDescriptorCount());
820 descriptor_store_.resize(layout_->GetTotalDescriptorCount());
John Zulaufe4850d42019-12-30 16:10:55 -0700821 auto free_descriptor = descriptor_store_.data();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700822 for (uint32_t i = 0; i < layout_->GetBindingCount(); ++i) {
823 auto type = layout_->GetTypeFromIndex(i);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600824 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700825 case VK_DESCRIPTOR_TYPE_SAMPLER: {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700826 auto immut_sampler = layout_->GetImmutableSamplerPtrFromIndex(i);
827 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
Tobin Ehlis082c7512017-05-08 11:24:57 -0600828 if (immut_sampler) {
John Zulaufe4850d42019-12-30 16:10:55 -0700829 descriptors_.emplace_back(new ((free_descriptor++)->Sampler())
830 SamplerDescriptor(state_data, immut_sampler + 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++)->Sampler()) SamplerDescriptor(state_data, nullptr));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700834 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700835 }
836 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600837 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700838 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700839 auto immut = layout_->GetImmutableSamplerPtrFromIndex(i);
840 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
Tobin Ehlis082c7512017-05-08 11:24:57 -0600841 if (immut) {
John Zulaufe4850d42019-12-30 16:10:55 -0700842 descriptors_.emplace_back(new ((free_descriptor++)->ImageSampler())
843 ImageSamplerDescriptor(state_data, immut + di));
Tobin Ehlis082c7512017-05-08 11:24:57 -0600844 some_update_ = true; // Immutable samplers are updated at creation
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700845 } else {
John Zulaufe4850d42019-12-30 16:10:55 -0700846 descriptors_.emplace_back(new ((free_descriptor++)->ImageSampler())
847 ImageSamplerDescriptor(state_data, nullptr));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700848 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700849 }
850 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600851 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700852 // ImageDescriptors
853 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
854 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
855 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700856 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700857 descriptors_.emplace_back(new ((free_descriptor++)->Image()) ImageDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700858 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700859 break;
860 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
861 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700862 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700863 descriptors_.emplace_back(new ((free_descriptor++)->Texel()) TexelDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700864 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700865 break;
sfricke-samsung4ca35652021-03-05 02:22:10 -0800866 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
867 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
868 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700869 descriptors_.emplace_back(new ((free_descriptor++)->Buffer()) BufferDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700870 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700871 break;
Jeff Bolze54ae892018-09-08 12:16:29 -0500872 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700873 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700874 descriptors_.emplace_back(new ((free_descriptor++)->InlineUniform()) InlineUniformDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700875 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500876 break;
Eric Werness30127fd2018-10-31 21:01:03 -0700877 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
sourav parmarcd5fb182020-07-17 12:58:44 -0700878 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700879 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700880 descriptors_.emplace_back(new ((free_descriptor++)->AccelerationStructure())
881 AccelerationStructureDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700882 }
Jeff Bolzfbe51582018-09-13 10:01:35 -0500883 break;
Tony-LunarGf563b362021-03-18 16:13:18 -0600884 case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
885 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
ziga-lunarge5d28542021-10-24 21:14:25 +0200886 descriptors_.emplace_back(new ((free_descriptor++)->Mutable()) MutableDescriptor());
Tony-LunarGf563b362021-03-18 16:13:18 -0600887 }
888 break;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700889 default:
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800890 if (IsDynamicDescriptor(type) && IsBufferDescriptor(type)) {
891 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
892 dynamic_offset_idx_to_descriptor_list_.push_back(descriptors_.size());
893 descriptors_.emplace_back(new ((free_descriptor++)->Buffer()) BufferDescriptor(type));
894 }
895 } else {
896 assert(0); // Bad descriptor type specified
897 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700898 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600899 }
900 }
901}
Tobin Ehlis56a30942016-05-19 08:00:00 -0600902
Jeremy Gebben610d3a62022-01-01 12:53:17 -0700903void cvdescriptorset::DescriptorSet::LinkChildNodes() {
904 // Connect child node(s), which cannot safely be done in the constructor.
905 for (auto &desc : descriptors_) {
906 desc->AddParent(this);
907 }
908}
909
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600910void cvdescriptorset::DescriptorSet::Destroy() {
Jeremy Gebben5570abe2021-05-16 18:35:13 -0600911 for (auto &desc: descriptors_) {
912 desc->RemoveParent(this);
913 }
914 BASE_NODE::Destroy();
915}
Chris Forbes57989132016-07-26 17:06:10 +1200916
Jeremy Gebben90ce4162021-08-25 14:23:07 -0600917static std::string StringDescriptorReqViewType(DescriptorReqFlags req) {
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700918 std::string result("");
Mark Lobodzinski29f451a2020-02-10 16:15:30 -0700919 for (unsigned i = 0; i <= VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; i++) {
Chris Forbes57989132016-07-26 17:06:10 +1200920 if (req & (1 << i)) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700921 if (result.size()) result += ", ";
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700922 result += string_VkImageViewType(VkImageViewType(i));
Chris Forbes57989132016-07-26 17:06:10 +1200923 }
924 }
925
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700926 if (!result.size()) result = "(none)";
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700927
928 return result;
Chris Forbes57989132016-07-26 17:06:10 +1200929}
930
Jeremy Gebben90ce4162021-08-25 14:23:07 -0600931static char const *StringDescriptorReqComponentType(DescriptorReqFlags req) {
Chris Forbesda01e8d2018-08-27 15:36:57 -0700932 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_SINT) return "SINT";
933 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_UINT) return "UINT";
934 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT) return "FLOAT";
935 return "(none)";
936}
937
Jeff Bolz6cede832019-08-09 23:30:39 -0500938unsigned DescriptorRequirementsBitsFromFormat(VkFormat fmt) {
sfricke-samsunge3086292021-11-18 23:02:35 -0800939 if (FormatIsSINT(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_SINT;
940 if (FormatIsUINT(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_UINT;
sfricke-samsunged028b02021-09-06 23:14:51 -0700941 // Formats such as VK_FORMAT_D16_UNORM_S8_UINT are both
Chris Forbesda01e8d2018-08-27 15:36:57 -0700942 if (FormatIsDepthAndStencil(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT | DESCRIPTOR_REQ_COMPONENT_TYPE_UINT;
943 if (fmt == VK_FORMAT_UNDEFINED) return 0;
944 // everything else -- UNORM/SNORM/FLOAT/USCALED/SSCALED is all float in the shader.
945 return DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT;
946}
947
Tobin Ehlis3066db62016-08-22 08:12:23 -0600948// 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 -0600949// This includes validating that all descriptors in the given bindings are updated,
950// that any update buffers are valid, and that any dynamic offsets are within the bounds of their buffers.
951// Return true if state is acceptable, or false and write an error message into error string
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600952bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const BindingReqMap &bindings,
953 const std::vector<uint32_t> &dynamic_offsets, const CMD_BUFFER_STATE *cb_node,
Niels Möller1f945f62021-07-12 15:06:02 +0200954 const std::vector<IMAGE_VIEW_STATE *> *attachments, const std::vector<SUBPASS_INFO> *subpasses,
locke-lunargfc78e932020-11-19 17:06:24 -0700955 const char *caller, const DrawDispatchVuid &vuids) const {
Jeremy Gebben37ed31e2021-04-23 12:12:10 -0600956 layer_data::optional<layer_data::unordered_map<VkImageView, VkImageLayout>> checked_layouts;
Karl Schultz2171f932021-03-19 10:47:01 -0600957 if (descriptor_set->GetTotalDescriptorCount() > cvdescriptorset::PrefilterBindRequestMap::kManyDescriptors_) {
958 checked_layouts.emplace();
959 }
Tony-LunarGace473a2020-05-06 12:48:04 -0600960 bool result = false;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600961 VkFramebuffer framebuffer = cb_node->activeFramebuffer ? cb_node->activeFramebuffer->framebuffer() : VK_NULL_HANDLE;
John Zulauf79f06582021-02-27 18:38:39 -0700962 for (const auto &binding_pair : bindings) {
963 const auto binding = binding_pair.first;
John Zulauf382e1912019-06-10 15:27:44 -0600964 DescriptorSetLayout::ConstBindingIterator binding_it(descriptor_set->GetLayout().get(), binding);
965 if (binding_it.AtEnd()) { // End at construction is the condition for an invalid binding.
Tony-LunarGace473a2020-05-06 12:48:04 -0600966 auto set = descriptor_set->GetSet();
locke-lunarg1328e8e2020-08-20 12:40:08 -0600967 result |= LogError(set, vuids.descriptor_valid,
Tony-LunarGace473a2020-05-06 12:48:04 -0600968 "%s encountered the following validation error at %s time: Attempting to "
969 "validate DrawState for binding #%u which is an invalid binding for this descriptor set.",
970 report_data->FormatHandle(set).c_str(), caller, binding);
971 return result;
Tobin Ehlis58c59582016-06-21 12:34:33 -0600972 }
Jeff Bolz6cede832019-08-09 23:30:39 -0500973
974 if (binding_it.GetDescriptorBindingFlags() &
Mike Schuchardt2df08912020-12-15 16:28:09 -0800975 (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT)) {
Jeff Bolz6cede832019-08-09 23:30:39 -0500976 // Can't validate the descriptor because it may not have been updated,
977 // or the view could have been destroyed
978 continue;
979 }
John Zulauf81dd1f12021-01-26 16:49:16 -0700980 // // This is a record time only path
981 const bool record_time_validate = true;
locke-lunargfc78e932020-11-19 17:06:24 -0700982 result |= ValidateDescriptorSetBindingData(cb_node, descriptor_set, dynamic_offsets, binding_pair, framebuffer, attachments,
Karl Schultz2171f932021-03-19 10:47:01 -0600983 subpasses, record_time_validate, caller, vuids, checked_layouts);
unknown3087a642019-09-26 17:21:05 -0600984 }
Tony-LunarGace473a2020-05-06 12:48:04 -0600985 return result;
unknown3087a642019-09-26 17:21:05 -0600986}
Jeff Bolz6cede832019-08-09 23:30:39 -0500987
locke-lunargb8be8222020-10-20 00:34:37 -0600988bool CoreChecks::ValidateDescriptorSetBindingData(const CMD_BUFFER_STATE *cb_node, const DescriptorSet *descriptor_set,
989 const std::vector<uint32_t> &dynamic_offsets,
John Zulauf79f06582021-02-27 18:38:39 -0700990 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
Mark Lobodzinski85ebd402020-12-03 12:56:07 -0700991 VkFramebuffer framebuffer, const std::vector<IMAGE_VIEW_STATE *> *attachments,
Niels Möller1f945f62021-07-12 15:06:02 +0200992 const std::vector<SUBPASS_INFO> *subpasses, bool record_time_validate,
Karl Schultz2171f932021-03-19 10:47:01 -0600993 const char *caller, const DrawDispatchVuid &vuids,
Jeremy Gebben37ed31e2021-04-23 12:12:10 -0600994 layer_data::optional<layer_data::unordered_map<VkImageView, VkImageLayout>> &checked_layouts) const {
unknown3087a642019-09-26 17:21:05 -0600995 using DescriptorClass = cvdescriptorset::DescriptorClass;
996 using BufferDescriptor = cvdescriptorset::BufferDescriptor;
997 using ImageDescriptor = cvdescriptorset::ImageDescriptor;
998 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
999 using SamplerDescriptor = cvdescriptorset::SamplerDescriptor;
1000 using TexelDescriptor = cvdescriptorset::TexelDescriptor;
Jeff Bolz95176d02020-04-01 00:36:16 -05001001 using AccelerationStructureDescriptor = cvdescriptorset::AccelerationStructureDescriptor;
locke-lunarg36045992020-08-20 16:54:37 -06001002 const auto binding = binding_info.first;
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001003 bool skip = false;
unknown3087a642019-09-26 17:21:05 -06001004 DescriptorSetLayout::ConstBindingIterator binding_it(descriptor_set->GetLayout().get(), binding);
1005 {
John Zulauf382e1912019-06-10 15:27:44 -06001006 // Copy the range, the end range is subject to update based on variable length descriptor arrays.
1007 cvdescriptorset::IndexRange index_range = binding_it.GetGlobalIndexRange();
Chris Forbes1f7f3ca2017-05-08 13:54:50 -07001008 auto array_idx = 0; // Track array idx if we're dealing with array descriptors
Jeff Bolzfdf96072018-04-10 14:32:18 -05001009
John Zulauf382e1912019-06-10 15:27:44 -06001010 if (binding_it.IsVariableDescriptorCount()) {
Jeff Bolzfdf96072018-04-10 14:32:18 -05001011 // Only validate the first N descriptors if it uses variable_count
John Zulauf382e1912019-06-10 15:27:44 -06001012 index_range.end = index_range.start + descriptor_set->GetVariableDescriptorCount();
Jeff Bolzfdf96072018-04-10 14:32:18 -05001013 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001014 for (uint32_t i = index_range.start; !skip && i < index_range.end; ++i, ++array_idx) {
Lockeb994adf2019-03-29 23:52:31 -06001015 uint32_t index = i - index_range.start;
John Zulauf382e1912019-06-10 15:27:44 -06001016 const auto *descriptor = descriptor_set->GetDescriptorFromGlobalIndex(i);
Jeremy Gebben550ebbd2021-03-11 05:04:52 -07001017 const auto descriptor_class = descriptor->GetClass();
Lockeb994adf2019-03-29 23:52:31 -06001018
Jeremy Gebben550ebbd2021-03-11 05:04:52 -07001019 if (descriptor_class == DescriptorClass::InlineUniform) {
Jeff Bolz6cede832019-08-09 23:30:39 -05001020 // Can't validate the descriptor because it may not have been updated.
Jeff Bolzfdf96072018-04-10 14:32:18 -05001021 continue;
John Zulauf382e1912019-06-10 15:27:44 -06001022 } else if (!descriptor->updated) {
Tony-LunarGace473a2020-05-06 12:48:04 -06001023 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001024 return LogError(
1025 set, vuids.descriptor_valid,
1026 "Descriptor set %s encountered the following validation error at %s time: Descriptor in binding #%" PRIu32
1027 " index %" PRIu32
1028 " is being used in draw but has never been updated via vkUpdateDescriptorSets() or a similar call.",
1029 report_data->FormatHandle(set).c_str(), caller, binding, index);
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001030 }
1031 switch (descriptor_class) {
1032 case DescriptorClass::GeneralBuffer: {
1033 const auto *buffer_desc = static_cast<const BufferDescriptor *>(descriptor);
1034 skip =
1035 ValidateGeneralBufferDescriptor(caller, vuids, cb_node, descriptor_set, *buffer_desc, binding_info, index);
1036 } break;
1037 case DescriptorClass::ImageSampler: {
1038 const auto *image_sampler_desc = static_cast<const ImageSamplerDescriptor *>(descriptor);
1039 skip = ValidateImageDescriptor(caller, vuids, cb_node, descriptor_set, *image_sampler_desc, binding_info, index,
1040 record_time_validate, attachments, subpasses, framebuffer, binding_it.GetType(),
1041 checked_layouts);
1042 if (!skip) {
1043 skip = ValidateSamplerDescriptor(caller, vuids, cb_node, descriptor_set, binding_info, index,
1044 image_sampler_desc->GetSampler(), image_sampler_desc->IsImmutableSampler(),
1045 image_sampler_desc->GetSamplerState());
Karl Schultz76d16a42020-11-11 05:05:33 -07001046 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001047 } break;
1048 case DescriptorClass::Image: {
1049 const auto *image_desc = static_cast<const ImageDescriptor *>(descriptor);
1050 skip = ValidateImageDescriptor(caller, vuids, cb_node, descriptor_set, *image_desc, binding_info, index,
1051 record_time_validate, attachments, subpasses, framebuffer, binding_it.GetType(),
1052 checked_layouts);
1053 } break;
1054 case DescriptorClass::PlainSampler: {
1055 const auto *sampler_desc = static_cast<const SamplerDescriptor *>(descriptor);
1056 skip = ValidateSamplerDescriptor(caller, vuids, cb_node, descriptor_set, binding_info, index,
1057 sampler_desc->GetSampler(), sampler_desc->IsImmutableSampler(),
1058 sampler_desc->GetSamplerState());
1059 } break;
1060 case DescriptorClass::TexelBuffer: {
1061 const auto *texel_desc = static_cast<const TexelDescriptor *>(descriptor);
1062 skip = ValidateTexelDescriptor(caller, vuids, cb_node, descriptor_set, *texel_desc, binding_info, index);
1063 } break;
1064 case DescriptorClass::AccelerationStructure: {
1065 const auto *accel_desc = static_cast<const AccelerationStructureDescriptor *>(descriptor);
1066 skip = ValidateAccelerationDescriptor(caller, vuids, cb_node, descriptor_set, *accel_desc, binding_info, index);
1067 } break;
1068 default:
1069 break;
1070 }
1071 }
1072 }
1073 return skip;
1074}
locke-lunarg36045992020-08-20 16:54:37 -06001075
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001076bool CoreChecks::ValidateGeneralBufferDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1077 const cvdescriptorset::DescriptorSet *descriptor_set,
1078 const cvdescriptorset::BufferDescriptor &descriptor,
1079 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
1080 uint32_t index) const {
1081 // Verify that buffers are valid
1082 auto buffer = descriptor.GetBuffer();
1083 auto buffer_node = descriptor.GetBufferState();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001084 if ((!buffer_node && !enabled_features.robustness2_features.nullDescriptor) || (buffer_node && buffer_node->Destroyed())) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001085 auto set = descriptor_set->GetSet();
1086 return LogError(set, vuids.descriptor_valid,
1087 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1088 "binding #%" PRIu32 " index %" PRIu32 " is using buffer %s that is invalid or has been destroyed.",
1089 report_data->FormatHandle(set).c_str(), caller, binding_info.first, index,
1090 report_data->FormatHandle(buffer).c_str());
1091 }
1092 if (buffer) {
1093 if (buffer_node && !buffer_node->sparse) {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001094 for (const auto &item: buffer_node->GetBoundMemory()) {
1095 auto &binding = item.second;
1096 if (binding.mem_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001097 auto set = descriptor_set->GetSet();
1098 return LogError(set, vuids.descriptor_valid,
1099 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1100 "binding #%" PRIu32 " index %" PRIu32 " is uses buffer %s that references invalid memory %s.",
1101 report_data->FormatHandle(set).c_str(), caller, binding_info.first, index,
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001102 report_data->FormatHandle(buffer).c_str(),
1103 report_data->FormatHandle(binding.mem_state->mem()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001104 }
1105 }
1106 }
1107 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1108 if (ValidateProtectedBuffer(cb_node, buffer_node, caller, vuids.unprotected_command_buffer,
1109 "Buffer is in a descriptorSet")) {
1110 return true;
1111 }
1112 if (binding_info.second.is_writable &&
1113 ValidateUnprotectedBuffer(cb_node, buffer_node, caller, vuids.protected_command_buffer,
1114 "Buffer is in a descriptorSet")) {
1115 return true;
1116 }
1117 }
1118 }
1119 return false;
1120}
Chris Forbes1f7f3ca2017-05-08 13:54:50 -07001121
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001122bool CoreChecks::ValidateImageDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1123 const cvdescriptorset::DescriptorSet *descriptor_set,
1124 const cvdescriptorset::ImageDescriptor &image_descriptor,
1125 const std::pair<const uint32_t, DescriptorRequirement> &binding_info, uint32_t index,
1126 bool record_time_validate, const std::vector<IMAGE_VIEW_STATE *> *attachments,
Niels Möller1f945f62021-07-12 15:06:02 +02001127 const std::vector<SUBPASS_INFO> *subpasses, VkFramebuffer framebuffer,
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001128 VkDescriptorType descriptor_type,
Jeremy Gebben37ed31e2021-04-23 12:12:10 -06001129 layer_data::optional<layer_data::unordered_map<VkImageView, VkImageLayout>> &checked_layouts) const {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001130 std::vector<const SAMPLER_STATE *> sampler_states;
1131 VkImageView image_view = image_descriptor.GetImageView();
1132 const IMAGE_VIEW_STATE *image_view_state = image_descriptor.GetImageViewState();
1133 VkImageLayout image_layout = image_descriptor.GetImageLayout();
1134 const auto binding = binding_info.first;
1135 const auto reqs = binding_info.second.reqs;
Karl Schultz76d16a42020-11-11 05:05:33 -07001136
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001137 if (image_descriptor.GetClass() == cvdescriptorset::DescriptorClass::ImageSampler) {
1138 sampler_states.emplace_back(
1139 static_cast<const cvdescriptorset::ImageSamplerDescriptor &>(image_descriptor).GetSamplerState());
1140 } else {
1141 if (binding_info.second.samplers_used_by_image.size() > index) {
Jeremy Gebben856b8c62021-12-01 15:20:07 -07001142 for (const auto &desc_index : binding_info.second.samplers_used_by_image[index]) {
1143 const auto *desc = descriptor_set->GetDescriptorFromBinding(desc_index.sampler_slot.binding, desc_index.sampler_index);
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001144 // NOTE: This check _shouldn't_ be necessary due to the checks made in IsSpecificDescriptorType in
1145 // shader_validation.cpp. However, without this check some traces still crash.
Jeremy Gebben856b8c62021-12-01 15:20:07 -07001146 if (desc && (desc->GetClass() == cvdescriptorset::DescriptorClass::PlainSampler)) {
1147 const auto *sampler_state = static_cast<const cvdescriptorset::SamplerDescriptor *>(desc)->GetSamplerState();
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001148 if (sampler_state) sampler_states.emplace_back(sampler_state);
1149 }
1150 }
1151 }
1152 }
locke-lunarg4e1e4632020-10-26 01:52:19 -06001153
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001154 if ((!image_view_state && !enabled_features.robustness2_features.nullDescriptor) ||
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001155 (image_view_state && image_view_state->Destroyed())) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001156 // Image view must have been destroyed since initial update. Could potentially flag the descriptor
1157 // as "invalid" (updated = false) at DestroyImageView() time and detect this error at bind time
Jeff Bolz165818a2020-05-08 11:19:03 -05001158
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001159 auto set = descriptor_set->GetSet();
1160 return LogError(set, vuids.descriptor_valid,
1161 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1162 "binding #%" PRIu32 " index %" PRIu32 " is using imageView %s that is invalid or has been destroyed.",
1163 report_data->FormatHandle(set).c_str(), caller, binding, index,
1164 report_data->FormatHandle(image_view).c_str());
1165 }
1166 if (image_view) {
1167 const auto &image_view_ci = image_view_state->create_info;
1168 const auto *image_state = image_view_state->image_state.get();
Jeff Bolz165818a2020-05-08 11:19:03 -05001169
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001170 if (reqs & DESCRIPTOR_REQ_ALL_VIEW_TYPE_BITS) {
1171 if (~reqs & (1 << image_view_ci.viewType)) {
1172 auto set = descriptor_set->GetSet();
1173 return LogError(set, vuids.descriptor_valid,
1174 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1175 "in binding #%" PRIu32 " index %" PRIu32 " requires an image view of type %s but got %s.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08001176 report_data->FormatHandle(set).c_str(), caller, binding, index,
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001177 StringDescriptorReqViewType(reqs).c_str(), string_VkImageViewType(image_view_ci.viewType));
1178 }
locke-lunarg25b6c352020-08-06 17:44:18 -06001179
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001180 if (!(reqs & image_view_state->descriptor_format_bits)) {
1181 // bad component type
1182 auto set = descriptor_set->GetSet();
1183 return LogError(set, vuids.descriptor_valid,
1184 "Descriptor set %s encountered the following validation error at %s time: "
1185 "Descriptor in binding "
1186 "#%" PRIu32 " index %" PRIu32 " requires %s component type, but bound descriptor format is %s.",
1187 report_data->FormatHandle(set).c_str(), caller, binding, index,
1188 StringDescriptorReqComponentType(reqs), string_VkFormat(image_view_ci.format));
1189 }
1190 }
locke-lunarg540b2252020-08-03 13:23:36 -06001191
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001192 // NOTE: Submit time validation of UPDATE_AFTER_BIND image layout is not possible with the
1193 // image layout tracking as currently implemented, so only record_time_validation is done
1194 if (!disabled[image_layout_validation] && record_time_validate) {
1195 // Verify Image Layout
1196 // No "invalid layout" VUID required for this call, since the optimal_layout parameter is UNDEFINED.
1197 // The caller provides a checked_layouts map when there are a large number of layouts to check,
1198 // making it worthwhile to keep track of verified layouts and not recheck them.
1199 bool already_validated = false;
1200 if (checked_layouts) {
1201 auto search = checked_layouts->find(image_view);
1202 if (search != checked_layouts->end() && search->second == image_layout) {
1203 already_validated = true;
1204 }
1205 }
1206 if (!already_validated) {
1207 bool hit_error = false;
1208 VerifyImageLayout(cb_node, image_state, image_view_state->normalized_subresource_range,
1209 image_view_ci.subresourceRange.aspectMask, image_layout, VK_IMAGE_LAYOUT_UNDEFINED, caller,
1210 kVUIDUndefined, "VUID-VkDescriptorImageInfo-imageLayout-00344", &hit_error);
1211 if (hit_error) {
1212 auto set = descriptor_set->GetSet();
1213 return LogError(set, vuids.descriptor_valid,
1214 "Descriptor set %s encountered the following validation error at %s time: Image layout "
1215 "specified "
1216 "at vkUpdateDescriptorSet* or vkCmdPushDescriptorSet* time "
1217 "doesn't match actual image layout at time descriptor is used. See previous error callback for "
1218 "specific details.",
1219 report_data->FormatHandle(set).c_str(), caller);
1220 }
1221 if (checked_layouts) {
1222 checked_layouts->emplace(image_view, image_layout);
1223 }
1224 }
1225 }
locke-lunarg540b2252020-08-03 13:23:36 -06001226
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001227 // Verify Sample counts
1228 if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) && image_view_state->samples != VK_SAMPLE_COUNT_1_BIT) {
1229 auto set = descriptor_set->GetSet();
1230 return LogError(set, vuids.descriptor_valid,
1231 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1232 "binding #%" PRIu32 " index %" PRIu32 " requires bound image to have VK_SAMPLE_COUNT_1_BIT but got %s.",
1233 report_data->FormatHandle(set).c_str(), caller, binding, index,
1234 string_VkSampleCountFlagBits(image_view_state->samples));
1235 }
1236 if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) && image_view_state->samples == VK_SAMPLE_COUNT_1_BIT) {
1237 auto set = descriptor_set->GetSet();
1238 return LogError(set, vuids.descriptor_valid,
1239 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1240 "in binding #%" PRIu32 " index %" PRIu32
1241 " requires bound image to have multiple samples, but got VK_SAMPLE_COUNT_1_BIT.",
1242 report_data->FormatHandle(set).c_str(), caller, binding, index);
1243 }
locke-lunarg36045992020-08-20 16:54:37 -06001244
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001245 // Verify VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
1246 if ((reqs & DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION) && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) &&
1247 !(image_view_state->format_features & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) {
1248 auto set = descriptor_set->GetSet();
1249 LogObjectList objlist(set);
1250 objlist.add(image_view);
1251 return LogError(objlist, vuids.imageview_atomic,
1252 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1253 "in binding #%" PRIu32 " index %" PRIu32
1254 ", %s, format %s, doesn't "
1255 "contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT.",
1256 report_data->FormatHandle(set).c_str(), caller, binding, index,
1257 report_data->FormatHandle(image_view).c_str(), string_VkFormat(image_view_ci.format));
1258 }
locke-lunarg654a9052020-10-13 16:28:42 -06001259
Lionel Landwerlin6a9f89c2021-12-07 15:46:46 +02001260 // When KHR_format_feature_flags2 is supported, the read/write without
1261 // format support is reported per format rather as a blankey physical
1262 // device feature.
1263 if (has_format_feature2) {
1264 const VkFormatFeatureFlags2KHR img_format_feats = image_view_state->image_state->format_features;
1265
1266 if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
1267 if ((reqs & DESCRIPTOR_REQ_IMAGE_READ_WITHOUT_FORMAT) &&
1268 !(img_format_feats & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR)) {
1269 auto set = descriptor_set->GetSet();
1270 LogObjectList objlist(set);
1271 objlist.add(image_view);
1272 return LogError(objlist, vuids.storage_image_read_without_format,
1273 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1274 "in binding #%" PRIu32 " index %" PRIu32
1275 ", %s, format %s, doesn't "
1276 "contain VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR",
1277 report_data->FormatHandle(set).c_str(), caller, binding, index,
1278 report_data->FormatHandle(image_view).c_str(), string_VkFormat(image_view_ci.format));
1279 }
1280
1281 if ((reqs & DESCRIPTOR_REQ_IMAGE_WRITE_WITHOUT_FORMAT) &&
1282 !(img_format_feats & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR)) {
1283 auto set = descriptor_set->GetSet();
1284 LogObjectList objlist(set);
1285 objlist.add(image_view);
1286 return LogError(objlist, vuids.storage_image_write_without_format,
1287 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1288 "in binding #%" PRIu32 " index %" PRIu32
1289 ", %s, format %s, doesn't "
1290 "contain VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR",
1291 report_data->FormatHandle(set).c_str(), caller, binding, index,
1292 report_data->FormatHandle(image_view).c_str(), string_VkFormat(image_view_ci.format));
1293 }
1294 }
Lionel Landwerlincdbe8682021-12-08 15:10:37 +02001295
1296 if ((reqs & DESCRIPTOR_REQ_IMAGE_DREF) &&
1297 !(img_format_feats & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR)) {
1298 auto set = descriptor_set->GetSet();
1299 LogObjectList objlist(set);
1300 objlist.add(image_view);
1301 return LogError(objlist, vuids.depth_compare_sample,
1302 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1303 "in binding #%" PRIu32 " index %" PRIu32
1304 ", %s, format %s, doesn't "
1305 "contain VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR",
1306 report_data->FormatHandle(set).c_str(), caller, binding, index,
1307 report_data->FormatHandle(image_view).c_str(), string_VkFormat(image_view_ci.format));
1308 }
Lionel Landwerlin6a9f89c2021-12-07 15:46:46 +02001309 }
1310
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001311 // Verify if attachments are used in DescriptorSet
Niels Möller1f945f62021-07-12 15:06:02 +02001312 if (attachments && attachments->size() > 0 && subpasses && (descriptor_type != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06001313 bool ds_aspect = (image_view_state->normalized_subresource_range.aspectMask &
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001314 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1315 ? true
1316 : false;
1317 uint32_t att_index = 0;
1318 for (const auto &view_state : *attachments) {
Niels Möller1f945f62021-07-12 15:06:02 +02001319 const SUBPASS_INFO& subpass = (*subpasses)[att_index];
1320 if (!subpass.used || !view_state || view_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001321 continue;
1322 }
Ricardo Garciafe2b7682021-07-30 10:44:57 +02001323 if (ds_aspect && (subpass.usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ||
1324 subpass.usage == VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001325 if ((image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1326 image_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
1327 image_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL) &&
Niels Möller1f945f62021-07-12 15:06:02 +02001328 (subpass.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1329 subpass.layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
1330 subpass.layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL)) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001331 continue;
Chris Forbes1f7f3ca2017-05-08 13:54:50 -07001332 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001333 if ((image_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL &&
Niels Möller1f945f62021-07-12 15:06:02 +02001334 subpass.layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) ||
1335 (subpass.layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL &&
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001336 image_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)) {
1337 continue;
1338 }
1339 }
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001340 if (view_state->image_view() == image_view) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001341 auto set = descriptor_set->GetSet();
1342 LogObjectList objlist(set);
1343 objlist.add(image_view);
1344 objlist.add(framebuffer);
1345 return LogError(objlist, vuids.image_subresources,
1346 "Descriptor set %s encountered the following validation error at %s time: %s is used in "
1347 "Descriptor in binding #%" PRIu32 " index %" PRIu32 " and %s attachment # %" PRIu32 ".",
1348 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
1349 binding, index, report_data->FormatHandle(framebuffer).c_str(), att_index);
1350 } else {
1351 if (image_view_state->OverlapSubresource(*view_state)) {
Karl Schultz76d16a42020-11-11 05:05:33 -07001352 auto set = descriptor_set->GetSet();
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001353 LogObjectList objlist(set);
1354 objlist.add(image_view);
1355 objlist.add(framebuffer);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001356 objlist.add(view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001357 return LogError(
1358 objlist, vuids.image_subresources,
1359 "Descriptor set %s encountered the following validation error at %s time: "
1360 "Image subresources of %s in "
1361 "Descriptor in binding #%" PRIu32 " index %" PRIu32 " and %s in %s attachment # %" PRIu32 " overlap.",
1362 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(), binding,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001363 index, report_data->FormatHandle(view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001364 report_data->FormatHandle(framebuffer).c_str(), att_index);
Karl Schultz76d16a42020-11-11 05:05:33 -07001365 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001366 }
1367 ++att_index;
1368 }
1369 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1370 if (ValidateProtectedImage(cb_node, image_view_state->image_state.get(), caller, vuids.unprotected_command_buffer,
1371 "Image is in a descriptorSet")) {
1372 return true;
1373 }
1374 if (binding_info.second.is_writable &&
1375 ValidateUnprotectedImage(cb_node, image_view_state->image_state.get(), caller, vuids.protected_command_buffer,
1376 "Image is in a descriptorSet")) {
1377 return true;
1378 }
1379 }
1380 }
Chris Forbese92dd1d2019-01-21 15:58:57 -08001381
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001382 for (const auto *sampler_state : sampler_states) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001383 if (!sampler_state || sampler_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001384 continue;
1385 }
locke-lunarg25b6c352020-08-06 17:44:18 -06001386
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001387 // TODO: Validate 04015 for DescriptorClass::PlainSampler
1388 if ((sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
1389 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) &&
1390 (sampler_state->customCreateInfo.format == VK_FORMAT_UNDEFINED)) {
1391 if (image_view_state->create_info.format == VK_FORMAT_B4G4R4A4_UNORM_PACK16 ||
1392 image_view_state->create_info.format == VK_FORMAT_B5G6R5_UNORM_PACK16 ||
1393 image_view_state->create_info.format == VK_FORMAT_B5G5R5A1_UNORM_PACK16) {
1394 auto set = descriptor_set->GetSet();
1395 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001396 objlist.add(sampler_state->sampler());
1397 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001398 return LogError(objlist, "VUID-VkSamplerCustomBorderColorCreateInfoEXT-format-04015",
1399 "Descriptor set %s encountered the following validation error at %s time: Sampler %s in "
1400 "binding #%" PRIu32 " index %" PRIu32
1401 " has a custom border color with format = VK_FORMAT_UNDEFINED and is used to "
1402 "sample an image view %s with format %s",
1403 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001404 report_data->FormatHandle(sampler_state->sampler()).c_str(), binding, index,
1405 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001406 string_VkFormat(image_view_state->create_info.format));
1407 }
1408 }
1409 VkFilter sampler_mag_filter = sampler_state->createInfo.magFilter;
1410 VkFilter sampler_min_filter = sampler_state->createInfo.minFilter;
1411 VkBool32 sampler_compare_enable = sampler_state->createInfo.compareEnable;
1412 if ((sampler_mag_filter == VK_FILTER_LINEAR || sampler_min_filter == VK_FILTER_LINEAR) &&
1413 (sampler_compare_enable == VK_FALSE) &&
1414 !(image_view_state->format_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) {
1415 auto set = descriptor_set->GetSet();
1416 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001417 objlist.add(sampler_state->sampler());
1418 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001419 return LogError(objlist, vuids.linear_sampler,
1420 "Descriptor set %s encountered the following validation error at %s time: Sampler "
1421 "(%s) is set to use VK_FILTER_LINEAR with "
Tony-LunarG81195df2021-12-02 15:01:58 -07001422 "compareEnable is set to VK_FALSE, but image view's (%s) format (%s) does not "
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001423 "contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT in its format features.",
1424 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001425 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1426 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001427 string_VkFormat(image_view_state->create_info.format));
1428 }
1429 if (sampler_mag_filter == VK_FILTER_CUBIC_EXT || sampler_min_filter == VK_FILTER_CUBIC_EXT) {
1430 if (!(image_view_state->format_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) {
1431 auto set = descriptor_set->GetSet();
1432 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001433 objlist.add(sampler_state->sampler());
1434 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001435 return LogError(objlist, vuids.cubic_sampler,
1436 "Descriptor set %s encountered the following validation error at %s time: "
1437 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT, then "
1438 "image view's (%s) format (%s) MUST contain "
1439 "VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT in its format features.",
1440 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001441 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1442 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001443 string_VkFormat(image_view_state->create_info.format));
1444 }
1445
1446 if (IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
1447 const auto reduction_mode_info =
1448 LvlFindInChain<VkSamplerReductionModeCreateInfo>(sampler_state->createInfo.pNext);
1449 if (reduction_mode_info &&
1450 (reduction_mode_info->reductionMode == VK_SAMPLER_REDUCTION_MODE_MIN ||
1451 reduction_mode_info->reductionMode == VK_SAMPLER_REDUCTION_MODE_MAX) &&
1452 !image_view_state->filter_cubic_props.filterCubicMinmax) {
1453 auto set = descriptor_set->GetSet();
1454 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001455 objlist.add(sampler_state->sampler());
1456 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001457 return LogError(objlist, vuids.filter_cubic_min_max,
1458 "Descriptor set %s encountered the following validation error at %s time: "
1459 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT & %s, "
1460 "but image view (%s) doesn't support filterCubicMinmax.",
1461 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001462 report_data->FormatHandle(sampler_state->sampler()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001463 string_VkSamplerReductionMode(reduction_mode_info->reductionMode),
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001464 report_data->FormatHandle(image_view_state->image_view()).c_str());
Chris Forbese92dd1d2019-01-21 15:58:57 -08001465 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001466
1467 if (!image_view_state->filter_cubic_props.filterCubic) {
1468 auto set = descriptor_set->GetSet();
1469 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001470 objlist.add(sampler_state->sampler());
1471 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001472 return LogError(objlist, vuids.filter_cubic,
1473 "Descriptor set %s encountered the following validation error at %s time: "
1474 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT, "
1475 "but image view (%s) doesn't support filterCubic.",
1476 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001477 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1478 report_data->FormatHandle(image_view_state->image_view()).c_str());
Jeff Bolz95176d02020-04-01 00:36:16 -05001479 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001480 }
locke-lunarg4e1e4632020-10-26 01:52:19 -06001481
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001482 if (IsExtEnabled(device_extensions.vk_img_filter_cubic)) {
Clemens Kern5a42ea62021-09-29 16:30:23 +02001483 if (image_view_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_3D ||
1484 image_view_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1485 image_view_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
Tony-LunarGace473a2020-05-06 12:48:04 -06001486 auto set = descriptor_set->GetSet();
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001487 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001488 objlist.add(sampler_state->sampler());
1489 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001490 return LogError(objlist, vuids.img_filter_cubic,
1491 "Descriptor set %s encountered the following validation error at %s time: Sampler "
1492 "(%s)is set to use VK_FILTER_CUBIC_EXT while the VK_IMG_filter_cubic extension "
1493 "is enabled, but image view (%s) has an invalid imageViewType (%s).",
1494 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001495 report_data->FormatHandle(sampler_state->sampler()).c_str(),
1496 report_data->FormatHandle(image_view_state->image_view()).c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001497 string_VkImageViewType(image_view_state->create_info.viewType));
Tobin Ehlisb1a2e4b2018-03-16 07:54:24 -06001498 }
1499 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001500 }
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001501
1502 if ((image_state->createInfo.flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) &&
1503 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE ||
1504 sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE ||
1505 sampler_state->createInfo.addressModeW != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)) {
1506 std::string address_mode_letter =
1507 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1508 ? "U"
1509 : (sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) ? "V" : "W";
1510 VkSamplerAddressMode address_mode =
1511 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1512 ? sampler_state->createInfo.addressModeU
1513 : (sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1514 ? sampler_state->createInfo.addressModeV
1515 : sampler_state->createInfo.addressModeW;
1516 auto set = descriptor_set->GetSet();
1517 LogObjectList objlist(set);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001518 objlist.add(sampler_state->sampler());
1519 objlist.add(image_state->image());
1520 objlist.add(image_view_state->image_view());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001521 return LogError(objlist, vuids.corner_sampled_address_mode,
1522 "Descriptor set %s encountered the following validation error at %s time: Image "
1523 "(%s) in image view (%s) is created with flag "
1524 "VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and can only be sampled using "
1525 "VK_SAMPLER_ADDRESS_MODE_CLAMP_EDGE, but sampler (%s) has "
1526 "createInfo.addressMode%s set to %s.",
1527 report_data->FormatHandle(set).c_str(), caller,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001528 report_data->FormatHandle(image_state->image()).c_str(),
1529 report_data->FormatHandle(image_view_state->image_view()).c_str(),
1530 report_data->FormatHandle(sampler_state->sampler()).c_str(), address_mode_letter.c_str(),
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001531 string_VkSamplerAddressMode(address_mode));
1532 }
1533
1534 // UnnormalizedCoordinates sampler validations
1535 if (sampler_state->createInfo.unnormalizedCoordinates) {
1536 // If ImageView is used by a unnormalizedCoordinates sampler, it needs to check ImageView type
1537 if (image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_3D || image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1538 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY ||
1539 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY ||
1540 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
1541 auto set = descriptor_set->GetSet();
1542 LogObjectList objlist(set);
1543 objlist.add(image_view);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001544 objlist.add(sampler_state->sampler());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001545 return LogError(objlist, vuids.sampler_imageview_type,
1546 "Descriptor set %s encountered the following validation error at %s time: %s, type: %s in "
1547 "Descriptor in binding #%" PRIu32 " index %" PRIu32 "is used by %s.",
1548 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
1549 string_VkImageViewType(image_view_ci.viewType), binding, index,
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001550 report_data->FormatHandle(sampler_state->sampler()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001551 }
1552
1553 // sampler must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample*
1554 // instructions with ImplicitLod, Dref or Proj in their name
1555 if (reqs & DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ) {
1556 auto set = descriptor_set->GetSet();
1557 LogObjectList objlist(set);
1558 objlist.add(image_view);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001559 objlist.add(sampler_state->sampler());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001560 return LogError(objlist, vuids.sampler_implicitLod_dref_proj,
1561 "Descriptor set %s encountered the following validation error at %s time: %s in "
1562 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1563 " is used by %s that uses invalid operator.",
1564 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001565 binding, index, report_data->FormatHandle(sampler_state->sampler()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001566 }
1567
1568 // sampler must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample*
1569 // instructions that includes a LOD bias or any offset values
1570 if (reqs & DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET) {
1571 auto set = descriptor_set->GetSet();
1572 LogObjectList objlist(set);
1573 objlist.add(image_view);
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001574 objlist.add(sampler_state->sampler());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001575 return LogError(objlist, vuids.sampler_bias_offset,
1576 "Descriptor set %s encountered the following validation error at %s time: %s in "
1577 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1578 " is used by %s that uses invalid bias or offset operator.",
1579 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(image_view).c_str(),
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001580 binding, index, report_data->FormatHandle(sampler_state->sampler()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001581 }
1582 }
1583 }
1584 }
1585 return false;
1586}
1587
1588bool CoreChecks::ValidateTexelDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1589 const cvdescriptorset::DescriptorSet *descriptor_set,
1590 const cvdescriptorset::TexelDescriptor &texel_descriptor,
1591 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
1592 uint32_t index) const {
1593 auto buffer_view = texel_descriptor.GetBufferView();
1594 auto buffer_view_state = texel_descriptor.GetBufferViewState();
1595 const auto binding = binding_info.first;
1596 const auto reqs = binding_info.second.reqs;
1597 if ((!buffer_view_state && !enabled_features.robustness2_features.nullDescriptor) ||
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001598 (buffer_view_state && buffer_view_state->Destroyed())) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001599 auto set = descriptor_set->GetSet();
1600 return LogError(set, vuids.descriptor_valid,
1601 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1602 "binding #%" PRIu32 " index %" PRIu32 " is using bufferView %s that is invalid or has been destroyed.",
1603 report_data->FormatHandle(set).c_str(), caller, binding, index,
1604 report_data->FormatHandle(buffer_view).c_str());
1605 }
1606 if (buffer_view) {
1607 auto buffer = buffer_view_state->create_info.buffer;
Jeremy Gebben9d0dda32022-01-28 10:16:56 -07001608 const auto *buffer_state = buffer_view_state->buffer_state.get();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001609 if (buffer_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001610 auto set = descriptor_set->GetSet();
1611 return LogError(set, vuids.descriptor_valid,
1612 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1613 "binding #%" PRIu32 " index %" PRIu32 " is using buffer %s that has been destroyed.",
1614 report_data->FormatHandle(set).c_str(), caller, binding, index,
1615 report_data->FormatHandle(buffer).c_str());
1616 }
1617 auto format_bits = DescriptorRequirementsBitsFromFormat(buffer_view_state->create_info.format);
1618
1619 if (!(reqs & format_bits)) {
1620 // bad component type
1621 auto set = descriptor_set->GetSet();
1622 return LogError(set, vuids.descriptor_valid,
1623 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1624 "binding #%" PRIu32 " index %" PRIu32 " requires %s component type, but bound descriptor format is %s.",
1625 report_data->FormatHandle(set).c_str(), caller, binding, index, StringDescriptorReqComponentType(reqs),
1626 string_VkFormat(buffer_view_state->create_info.format));
1627 }
1628
1629 // Verify VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
1630 if ((reqs & DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION) &&
1631 (descriptor_set->GetTypeFromBinding(binding) == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) &&
1632 !(buffer_view_state->format_features & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)) {
1633 auto set = descriptor_set->GetSet();
1634 LogObjectList objlist(set);
1635 objlist.add(buffer_view);
1636 return LogError(objlist, "UNASSIGNED-None-MismatchAtomicBufferFeature",
1637 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1638 "in binding #%" PRIu32 " index %" PRIu32
1639 ", %s, format %s, doesn't "
1640 "contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT.",
1641 report_data->FormatHandle(set).c_str(), caller, binding, index,
1642 report_data->FormatHandle(buffer_view).c_str(), string_VkFormat(buffer_view_state->create_info.format));
1643 }
1644 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1645 if (ValidateProtectedBuffer(cb_node, buffer_view_state->buffer_state.get(), caller, vuids.unprotected_command_buffer,
1646 "Buffer is in a descriptorSet")) {
1647 return true;
1648 }
1649 if (binding_info.second.is_writable &&
1650 ValidateUnprotectedBuffer(cb_node, buffer_view_state->buffer_state.get(), caller, vuids.protected_command_buffer,
1651 "Buffer is in a descriptorSet")) {
1652 return true;
1653 }
1654 }
1655 }
1656 return false;
1657}
1658
1659bool CoreChecks::ValidateAccelerationDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1660 const cvdescriptorset::DescriptorSet *descriptor_set,
1661 const cvdescriptorset::AccelerationStructureDescriptor &descriptor,
1662 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
1663 uint32_t index) const {
1664 // Verify that acceleration structures are valid
1665 const auto binding = binding_info.first;
1666 if (descriptor.is_khr()) {
1667 auto acc = descriptor.GetAccelerationStructure();
1668 auto acc_node = descriptor.GetAccelerationStructureStateKHR();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001669 if (!acc_node || acc_node->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001670 if (acc != VK_NULL_HANDLE || !enabled_features.robustness2_features.nullDescriptor) {
1671 auto set = descriptor_set->GetSet();
1672 return LogError(set, vuids.descriptor_valid,
1673 "Descriptor set %s encountered the following validation error at %s time: "
1674 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1675 " is using acceleration structure %s that is invalid or has been destroyed.",
1676 report_data->FormatHandle(set).c_str(), caller, binding, index,
1677 report_data->FormatHandle(acc).c_str());
1678 }
1679 } else {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001680 for (const auto &item: acc_node->GetBoundMemory()) {
1681 auto &mem_binding = item.second;
1682 if (mem_binding.mem_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001683 auto set = descriptor_set->GetSet();
1684 return LogError(set, vuids.descriptor_valid,
1685 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1686 "binding #%" PRIu32 " index %" PRIu32
1687 " is using acceleration structure %s that references invalid memory %s.",
1688 report_data->FormatHandle(set).c_str(), caller, binding, index,
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001689 report_data->FormatHandle(acc).c_str(),
1690 report_data->FormatHandle(mem_binding.mem_state->mem()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001691 }
1692 }
1693 }
1694 } else {
1695 auto acc = descriptor.GetAccelerationStructureNV();
1696 auto acc_node = descriptor.GetAccelerationStructureStateNV();
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001697 if (!acc_node || acc_node->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001698 if (acc != VK_NULL_HANDLE || !enabled_features.robustness2_features.nullDescriptor) {
1699 auto set = descriptor_set->GetSet();
1700 return LogError(set, vuids.descriptor_valid,
1701 "Descriptor set %s encountered the following validation error at %s time: "
1702 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1703 " is using acceleration structure %s that is invalid or has been destroyed.",
1704 report_data->FormatHandle(set).c_str(), caller, binding, index,
1705 report_data->FormatHandle(acc).c_str());
1706 }
1707 } else {
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001708 for (const auto &item : acc_node->GetBoundMemory()) {
1709 auto &mem_binding = item.second;
1710 if (mem_binding.mem_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001711 auto set = descriptor_set->GetSet();
1712 return LogError(set, vuids.descriptor_valid,
1713 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1714 "binding #%" PRIu32 " index %" PRIu32
1715 " is using acceleration structure %s that references invalid memory %s.",
1716 report_data->FormatHandle(set).c_str(), caller, binding, index,
Jeremy Gebben6fbf8242021-06-21 09:14:46 -06001717 report_data->FormatHandle(acc).c_str(),
1718 report_data->FormatHandle(mem_binding.mem_state->mem()).c_str());
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001719 }
1720 }
1721 }
1722 }
1723 return false;
1724}
1725
1726// If the validation is related to both of image and sampler,
1727// please leave it in (descriptor_class == DescriptorClass::ImageSampler || descriptor_class ==
1728// DescriptorClass::Image) Here is to validate for only sampler.
1729bool CoreChecks::ValidateSamplerDescriptor(const char *caller, const DrawDispatchVuid &vuids, const CMD_BUFFER_STATE *cb_node,
1730 const cvdescriptorset::DescriptorSet *descriptor_set,
1731 const std::pair<const uint32_t, DescriptorRequirement> &binding_info, uint32_t index,
1732 VkSampler sampler, bool is_immutable, const SAMPLER_STATE *sampler_state) const {
1733 // Verify Sampler still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001734 if (!sampler_state || sampler_state->Destroyed()) {
Jeremy Gebbene151b6b2021-04-09 18:03:06 -06001735 auto set = descriptor_set->GetSet();
1736 return LogError(set, vuids.descriptor_valid,
1737 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1738 "binding #%" PRIu32 " index %" PRIu32 " is using sampler %s that is invalid or has been destroyed.",
1739 report_data->FormatHandle(set).c_str(), caller, binding_info.first, index,
1740 report_data->FormatHandle(sampler).c_str());
1741 } else {
1742 if (sampler_state->samplerConversion && !is_immutable) {
1743 auto set = descriptor_set->GetSet();
1744 return LogError(set, vuids.descriptor_valid,
1745 "Descriptor set %s encountered the following validation error at %s time: sampler (%s) "
1746 "in the descriptor set (%s) contains a YCBCR conversion (%s), then the sampler MUST "
1747 "also exist as an immutable sampler.",
1748 report_data->FormatHandle(set).c_str(), caller, report_data->FormatHandle(sampler).c_str(),
1749 report_data->FormatHandle(descriptor_set->GetSet()).c_str(),
1750 report_data->FormatHandle(sampler_state->samplerConversion).c_str());
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001751 }
1752 }
Tony-LunarGace473a2020-05-06 12:48:04 -06001753 return false;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001754}
Chris Forbes57989132016-07-26 17:06:10 +12001755
John Zulauf1d27e0a2018-11-05 10:12:48 -07001756// Loop through the write updates to do for a push descriptor set, ignoring dstSet
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001757void cvdescriptorset::DescriptorSet::PerformPushDescriptorsUpdate(ValidationStateTracker *dev_data, uint32_t write_count,
1758 const VkWriteDescriptorSet *p_wds) {
John Zulauf1d27e0a2018-11-05 10:12:48 -07001759 assert(IsPushDescriptor());
1760 for (uint32_t i = 0; i < write_count; i++) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001761 PerformWriteUpdate(dev_data, &p_wds[i]);
John Zulauf1d27e0a2018-11-05 10:12:48 -07001762 }
Jason Macnak83cfd582019-07-31 10:14:24 -07001763
1764 push_descriptor_set_writes.clear();
1765 push_descriptor_set_writes.reserve(static_cast<std::size_t>(write_count));
1766 for (uint32_t i = 0; i < write_count; i++) {
1767 push_descriptor_set_writes.push_back(safe_VkWriteDescriptorSet(&p_wds[i]));
1768 }
John Zulauf1d27e0a2018-11-05 10:12:48 -07001769}
1770
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001771// Perform write update in given update struct
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001772void cvdescriptorset::DescriptorSet::PerformWriteUpdate(ValidationStateTracker *dev_data, const VkWriteDescriptorSet *update) {
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001773 // Perform update on a per-binding basis as consecutive updates roll over to next binding
1774 auto descriptors_remaining = update->descriptorCount;
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001775 auto offset = update->dstArrayElement;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001776 auto orig_binding = DescriptorSetLayout::ConstBindingIterator(layout_.get(), update->dstBinding);
locke-lunarge46b7782019-09-10 01:44:20 -06001777 auto current_binding = orig_binding;
1778
Tobin Ehlise16805c2017-08-09 09:10:37 -06001779 uint32_t update_index = 0;
locke-lunarge46b7782019-09-10 01:44:20 -06001780 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
1781 while (descriptors_remaining && orig_binding.IsConsistent(current_binding)) {
1782 const auto &index_range = current_binding.GetGlobalIndexRange();
1783 auto global_idx = index_range.start + offset;
1784 // global_idx is which descriptor is needed to update. If global_idx > index_range.end, it means the descriptor isn't in
1785 // this binding, maybe in next binding.
1786 if (global_idx >= index_range.end) {
1787 offset -= current_binding.GetDescriptorCount();
1788 ++current_binding;
1789 continue;
1790 }
1791
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001792 // Loop over the updates for a single binding at a time
locke-lunarge46b7782019-09-10 01:44:20 -06001793 uint32_t update_count = std::min(descriptors_remaining, current_binding.GetDescriptorCount() - offset);
Tobin Ehlise16805c2017-08-09 09:10:37 -06001794 for (uint32_t di = 0; di < update_count; ++di, ++update_index) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001795 descriptors_[global_idx + di]->WriteUpdate(this, state_data_, update, update_index);
ziga7a255fb2021-11-20 21:17:07 +01001796 VkDeviceSize buffer_size = 0;
1797 if ((update->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1798 update->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1799 update->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1800 update->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) &&
1801 update->pBufferInfo) {
1802 const auto buffer_state = dev_data->GetConstCastShared<BUFFER_STATE>(update->pBufferInfo->buffer);
1803 if (buffer_state) {
1804 buffer_size = buffer_state->createInfo.size;
1805 }
1806 } else if ((update->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1807 update->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) &&
1808 update->pTexelBufferView) {
1809 const auto buffer_view = dev_data->GetConstCastShared<BUFFER_VIEW_STATE>(update->pTexelBufferView[di]);
1810 if (buffer_view) {
1811 buffer_size = buffer_view->buffer_state->createInfo.size;
1812 }
1813 }
1814 descriptors_[global_idx + di]->SetDescriptorType(update->descriptorType, buffer_size);
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001815 }
1816 // Roll over to next binding in case of consecutive update
1817 descriptors_remaining -= update_count;
locke-lunarge46b7782019-09-10 01:44:20 -06001818 if (descriptors_remaining) {
1819 // Starting offset is beyond the current binding. Check consistency, update counters and advance to the next binding,
1820 // looking for the start point. All bindings (even those skipped) must be consistent with the update and with the
1821 // original binding.
1822 offset = 0;
1823 ++current_binding;
1824 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001825 }
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05001826 if (update->descriptorCount) {
1827 some_update_ = true;
1828 change_count_++;
1829 }
Tobin Ehlis56a30942016-05-19 08:00:00 -06001830
Jeremy Gebben5570abe2021-05-16 18:35:13 -06001831 if (!IsPushDescriptor() && !(layout_->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08001832 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001833 Invalidate(false);
Jeff Bolzfdf96072018-04-10 14:32:18 -05001834 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001835}
Tobin Ehlis300888c2016-05-18 13:43:26 -06001836// Validate Copy update
John Zulaufc93c4252019-06-25 09:19:49 -06001837bool CoreChecks::ValidateCopyUpdate(const VkCopyDescriptorSet *update, const DescriptorSet *dst_set, const DescriptorSet *src_set,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001838 const char *func_name, std::string *error_code, std::string *error_msg) const {
Jeremy Gebben9d0dda32022-01-28 10:16:56 -07001839 const auto *dst_layout = dst_set->GetLayout().get();
1840 const auto *src_layout = src_set->GetLayout().get();
John Zulaufd9435c32019-06-05 15:55:36 -06001841
John Zulauf5dfd45c2018-01-17 11:06:34 -07001842 // Verify dst layout still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001843 if (dst_layout->Destroyed()) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001844 *error_code = "VUID-VkCopyDescriptorSet-dstSet-parameter";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06001845 std::ostringstream str;
1846 str << "Cannot call " << func_name << " to perform copy update on dstSet " << report_data->FormatHandle(dst_set->GetSet())
1847 << " created with destroyed " << report_data->FormatHandle(dst_layout->GetDescriptorSetLayout()) << ".";
1848 *error_msg = str.str();
John Zulauf5dfd45c2018-01-17 11:06:34 -07001849 return false;
1850 }
1851
1852 // Verify src layout still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001853 if (src_layout->Destroyed()) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001854 *error_code = "VUID-VkCopyDescriptorSet-srcSet-parameter";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06001855 std::ostringstream str;
1856 str << "Cannot call " << func_name << " to perform copy update on dstSet " << report_data->FormatHandle(dst_set->GetSet())
1857 << " from srcSet " << report_data->FormatHandle(src_set->GetSet()) << " created with destroyed "
1858 << report_data->FormatHandle(src_layout->GetDescriptorSetLayout()) << ".";
1859 *error_msg = str.str();
John Zulauf5dfd45c2018-01-17 11:06:34 -07001860 return false;
1861 }
1862
John Zulaufd9435c32019-06-05 15:55:36 -06001863 if (!dst_layout->HasBinding(update->dstBinding)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001864 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-00347";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001865 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001866 error_str << "DescriptorSet " << report_data->FormatHandle(dst_set->GetSet())
1867 << " does not have copy update dest binding of " << update->dstBinding;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001868 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001869 return false;
1870 }
1871 if (!src_set->HasBinding(update->srcBinding)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001872 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-00345";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001873 std::stringstream error_str;
sourav parmarf4a78252020-04-10 13:04:21 -07001874 error_str << "DescriptorSet " << report_data->FormatHandle(src_set->GetSet())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001875 << " does not have copy update src binding of " << update->srcBinding;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001876 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001877 return false;
1878 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001879 // Verify idle ds
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06001880 if (dst_set->InUse() &&
John Zulaufd9435c32019-06-05 15:55:36 -06001881 !(dst_layout->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08001882 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
aitor-lunarg9f859002022-01-27 19:33:35 +01001883 *error_code = "VUID-vkUpdateDescriptorSets-None-03047";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001884 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001885 error_str << "Cannot call " << func_name << " to perform copy update on descriptor set "
1886 << report_data->FormatHandle(dst_set->GetSet()) << " that is in use by a command buffer";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001887 *error_msg = error_str.str();
1888 return false;
1889 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001890 // src & dst set bindings are valid
1891 // Check bounds of src & dst
John Zulaufc483f442017-12-15 14:02:06 -07001892 auto src_start_idx = src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start + update->srcArrayElement;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001893 if ((src_start_idx + update->descriptorCount) > src_set->GetTotalDescriptorCount()) {
1894 // SRC update out of bounds
Dave Houlton00c154e2018-05-24 13:20:50 -06001895 *error_code = "VUID-VkCopyDescriptorSet-srcArrayElement-00346";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001896 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001897 error_str << "Attempting copy update from descriptorSet " << report_data->FormatHandle(update->srcSet) << " binding#"
1898 << update->srcBinding << " with offset index of "
1899 << src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start << " plus update array offset of "
1900 << update->srcArrayElement << " and update of " << update->descriptorCount
Tobin Ehlis1d81edd2016-11-21 09:50:49 -07001901 << " descriptors oversteps total number of descriptors in set: " << src_set->GetTotalDescriptorCount();
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001902 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001903 return false;
1904 }
John Zulaufd9435c32019-06-05 15:55:36 -06001905 auto dst_start_idx = dst_layout->GetGlobalIndexRangeFromBinding(update->dstBinding).start + update->dstArrayElement;
1906 if ((dst_start_idx + update->descriptorCount) > dst_layout->GetTotalDescriptorCount()) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001907 // DST update out of bounds
Dave Houlton00c154e2018-05-24 13:20:50 -06001908 *error_code = "VUID-VkCopyDescriptorSet-dstArrayElement-00348";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001909 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001910 error_str << "Attempting copy update to descriptorSet " << report_data->FormatHandle(dst_set->GetSet()) << " binding#"
1911 << update->dstBinding << " with offset index of "
1912 << dst_layout->GetGlobalIndexRangeFromBinding(update->dstBinding).start << " plus update array offset of "
1913 << update->dstArrayElement << " and update of " << update->descriptorCount
John Zulaufd9435c32019-06-05 15:55:36 -06001914 << " descriptors oversteps total number of descriptors in set: " << dst_layout->GetTotalDescriptorCount();
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001915 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001916 return false;
1917 }
1918 // Check that types match
Shannon McPhersonafe55122020-05-25 16:20:19 -06001919 // TODO : Base default error case going from here is "VUID-VkAcquireNextImageInfoKHR-semaphore-parameter" 2ba which covers all
Dave Houltond8ed0212018-05-16 17:18:24 -06001920 // consistency issues, need more fine-grained error codes
Dave Houlton00c154e2018-05-24 13:20:50 -06001921 *error_code = "VUID-VkCopyDescriptorSet-srcSet-00349";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001922 auto src_type = src_set->GetTypeFromBinding(update->srcBinding);
John Zulaufd9435c32019-06-05 15:55:36 -06001923 auto dst_type = dst_layout->GetTypeFromBinding(update->dstBinding);
Ricardo Garcia14f4f762021-04-13 11:36:12 +02001924 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 -07001925 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02632";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001926 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001927 error_str << "Attempting copy update to descriptorSet " << report_data->FormatHandle(dst_set->GetSet()) << " binding #"
1928 << update->dstBinding << " with type " << string_VkDescriptorType(dst_type) << " from descriptorSet "
1929 << report_data->FormatHandle(src_set->GetSet()) << " binding #" << update->srcBinding << " with type "
1930 << string_VkDescriptorType(src_type) << ". Types do not match";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001931 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001932 return false;
1933 }
1934 // Verify consistency of src & dst bindings if update crosses binding boundaries
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001935 if ((!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(src_layout, update->srcBinding),
John Zulauf4a015c92019-06-04 09:50:05 -06001936 update->srcArrayElement, update->descriptorCount, "copy update from", src_set->GetSet(),
1937 error_msg)) ||
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001938 (!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(dst_layout, update->dstBinding),
John Zulaufd9435c32019-06-05 15:55:36 -06001939 update->dstArrayElement, update->descriptorCount, "copy update to", dst_set->GetSet(),
1940 error_msg))) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001941 return false;
1942 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001943
Mike Schuchardt2df08912020-12-15 16:28:09 -08001944 if ((src_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) &&
1945 !(dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001946 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01918";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001947 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001948 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001949 << ") layout was created with the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001950 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001951 "set, then pname:dstSet's ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001952 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001953 << ") layout must: also have been created with the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001954 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001955 *error_msg = error_str.str();
1956 return false;
1957 }
1958
sfricke-samsung45996a42021-09-16 13:45:27 -07001959 if (IsExtEnabled(device_extensions.vk_valve_mutable_descriptor_type)) {
Mike Schuchardt294a1592021-05-12 15:38:00 -07001960 if (!(src_layout->GetCreateFlags() & (VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT |
1961 VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE)) &&
1962 (dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
1963 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04885";
1964 std::stringstream error_str;
1965 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
1966 << ") layout was created with neither ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT nor "
1967 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE flags set, then pname:dstSet's ("
1968 << report_data->FormatHandle(update->dstSet)
1969 << ") layout must: have been created without the "
1970 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
1971 *error_msg = error_str.str();
1972 return false;
1973 }
1974 } else {
1975 if (!(src_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) &&
1976 (dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
1977 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04886";
1978 std::stringstream error_str;
1979 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
1980 << ") layout was created without the ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag "
1981 "set, then pname:dstSet's ("
1982 << report_data->FormatHandle(update->dstSet)
1983 << ") layout must: also have been created without the "
1984 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
1985 *error_msg = error_str.str();
1986 return false;
1987 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001988 }
1989
Mike Schuchardt2df08912020-12-15 16:28:09 -08001990 if ((src_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT) &&
1991 !(dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001992 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01920";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001993 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001994 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001995 << ") was allocated was created "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001996 "with the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001997 "set, then the descriptor pool from which pname:dstSet ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001998 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001999 << ") was allocated must: "
Mike Schuchardt2df08912020-12-15 16:28:09 -08002000 "also have been created with the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05002001 *error_msg = error_str.str();
2002 return false;
2003 }
2004
sfricke-samsung45996a42021-09-16 13:45:27 -07002005 if (IsExtEnabled(device_extensions.vk_valve_mutable_descriptor_type)) {
Mike Schuchardt294a1592021-05-12 15:38:00 -07002006 if (!(src_set->GetPoolState()->createInfo.flags &
2007 (VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) &&
2008 (dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
2009 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04887";
2010 std::stringstream error_str;
2011 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
2012 << ") was allocated was created with neither ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT nor "
2013 "ename:VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE flags set, then the descriptor pool from which "
2014 "pname:dstSet ("
2015 << report_data->FormatHandle(update->dstSet)
2016 << ") was allocated must: have been created without the "
2017 "ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
2018 *error_msg = error_str.str();
2019 return false;
2020 }
2021 } else {
2022 if (!(src_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT) &&
2023 (dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
2024 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04888";
2025 std::stringstream error_str;
2026 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
2027 << ") was allocated was created without the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set, "
2028 "then the descriptor pool from which pname:dstSet ("
2029 << report_data->FormatHandle(update->dstSet)
2030 << ") was allocated must: also have been created without the "
2031 "ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
2032 *error_msg = error_str.str();
2033 return false;
2034 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05002035 }
2036
Jeff Bolze54ae892018-09-08 12:16:29 -05002037 if (src_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
2038 if ((update->srcArrayElement % 4) != 0) {
2039 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-02223";
2040 std::stringstream error_str;
2041 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
2042 << "srcArrayElement " << update->srcArrayElement << " not a multiple of 4";
2043 *error_msg = error_str.str();
2044 return false;
2045 }
2046 if ((update->dstArrayElement % 4) != 0) {
2047 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02224";
2048 std::stringstream error_str;
2049 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
2050 << "dstArrayElement " << update->dstArrayElement << " not a multiple of 4";
2051 *error_msg = error_str.str();
2052 return false;
2053 }
2054 if ((update->descriptorCount % 4) != 0) {
2055 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-02225";
2056 std::stringstream error_str;
2057 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
2058 << "descriptorCount " << update->descriptorCount << " not a multiple of 4";
2059 *error_msg = error_str.str();
2060 return false;
2061 }
2062 }
2063
ziga-lunarge5d28542021-10-24 21:14:25 +02002064 if (dst_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2065 if (src_type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2066 if (!dst_layout->IsTypeMutable(src_type, update->dstBinding)) {
2067 *error_code = "VUID-VkCopyDescriptorSet-dstSet-04612";
2068 std::stringstream error_str;
2069 error_str << "Attempting copy update with dstBinding descriptor type VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, but the new "
2070 "active descriptor type "
2071 << string_VkDescriptorType(src_type)
2072 << " is not in the corresponding pMutableDescriptorTypeLists list.";
2073 *error_msg = error_str.str();
2074 return false;
2075 }
2076 }
2077 } else if (src_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2078 const auto *descriptor = src_set->GetDescriptorFromGlobalIndex(update->srcBinding);
2079 if (descriptor->active_descriptor_type != dst_type) {
2080 *error_code = "VUID-VkCopyDescriptorSet-srcSet-04613";
2081 std::stringstream error_str;
2082 error_str << "Attempting copy update with srcBinding descriptor type VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, but the "
2083 "active descriptor type ("
2084 << string_VkDescriptorType(descriptor->active_descriptor_type)
2085 << ") does not match the dstBinding descriptor type " << string_VkDescriptorType(dst_type) << ".";
2086 *error_msg = error_str.str();
2087 return false;
2088 }
2089 }
2090
2091 if (dst_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2092 if (src_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2093 const auto &mutable_src_types = src_layout->GetMutableTypes(update->srcBinding);
2094 const auto &mutable_dst_types = dst_layout->GetMutableTypes(update->dstBinding);
2095 bool complete_match = mutable_src_types.size() == mutable_dst_types.size();
2096 if (complete_match) {
2097 for (const auto mutable_src_type : mutable_src_types) {
2098 if (std::find(mutable_dst_types.begin(), mutable_dst_types.end(), mutable_src_type) ==
2099 mutable_dst_types.end()) {
2100 complete_match = false;
2101 break;
2102 }
2103 }
2104 }
2105 if (!complete_match) {
2106 *error_code = "VUID-VkCopyDescriptorSet-dstSet-04614";
2107 std::stringstream error_str;
2108 error_str << "Attempting copy update with dstBinding and new active descriptor type being "
2109 "VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, but their corresponding pMutableDescriptorTypeLists do not match.";
2110 *error_msg = error_str.str();
2111 return false;
2112 }
2113 }
2114 }
2115
ziga-lunarg5b2bede2021-11-08 11:54:17 +01002116 // Update mutable types
2117 if (src_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2118 src_type = src_set->GetDescriptorFromGlobalIndex(update->srcBinding)->active_descriptor_type;
2119 }
2120 if (dst_type == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
2121 dst_type = dst_set->GetDescriptorFromGlobalIndex(update->dstBinding)->active_descriptor_type;
2122 }
2123
Tobin Ehlisd41e7b62016-05-19 07:56:18 -06002124 // Update parameters all look good and descriptor updated so verify update contents
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002125 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 -07002126 error_msg)) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002127 return false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002128 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002129
2130 // All checks passed so update is good
2131 return true;
2132}
2133// Perform Copy update
Jeff Bolz41a1ced2019-10-11 11:40:49 -05002134void cvdescriptorset::DescriptorSet::PerformCopyUpdate(ValidationStateTracker *dev_data, const VkCopyDescriptorSet *update,
2135 const DescriptorSet *src_set) {
John Zulaufc483f442017-12-15 14:02:06 -07002136 auto src_start_idx = src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start + update->srcArrayElement;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002137 auto dst_start_idx = layout_->GetGlobalIndexRangeFromBinding(update->dstBinding).start + update->dstArrayElement;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002138 // Update parameters all look good so perform update
2139 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Jeremy Gebben9d0dda32022-01-28 10:16:56 -07002140 auto *src = src_set->descriptors_[src_start_idx + di].get();
2141 auto *dst = descriptors_[dst_start_idx + di].get();
Józef Kucia5297e372017-10-13 22:31:34 +02002142 if (src->updated) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002143 dst->CopyUpdate(this, state_data_, src);
Józef Kucia5297e372017-10-13 22:31:34 +02002144 some_update_ = true;
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05002145 change_count_++;
Józef Kucia5297e372017-10-13 22:31:34 +02002146 } else {
2147 dst->updated = false;
2148 }
ziga7a255fb2021-11-20 21:17:07 +01002149 dst->SetDescriptorType(src);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002150 }
Tobin Ehlis56a30942016-05-19 08:00:00 -06002151
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002152 if (!(layout_->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08002153 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002154 Invalidate(false);
Jeff Bolzfdf96072018-04-10 14:32:18 -05002155 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002156}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002157
John Zulauf6f3d2bd2018-10-29 17:08:42 -06002158// Update the drawing state for the affected descriptors.
2159// Set cb_node to this set and this set to cb_node.
2160// Add the bindings of the descriptor
2161// Set the layout based on the current descriptor layout (will mask subsequent layer mismatch errors)
2162// TODO: Modify the UpdateDrawState virtural functions to *only* set initial layout and not change layouts
Tobin Ehlisf9519102016-08-17 09:49:13 -06002163// Prereq: This should be called for a set that has been confirmed to be active for the given cb_node, meaning it's going
2164// to be used in a draw by the given cb_node
Jeremy Kniagere6827432020-04-01 09:05:56 -06002165void cvdescriptorset::DescriptorSet::UpdateDrawState(ValidationStateTracker *device_data, CMD_BUFFER_STATE *cb_node,
2166 CMD_TYPE cmd_type, const PIPELINE_STATE *pipe,
sfricke-samsung85584a72021-09-30 21:43:38 -07002167 const BindingReqMap &binding_req_map) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002168 // Descriptor UpdateDrawState only call image layout validation callbacks. If it is disabled, skip the entire loop.
2169 if (device_data->disabled[image_layout_validation]) {
Jeff Bolze18e7242019-08-12 20:55:22 -05002170 return;
2171 }
2172
Tobin Ehlisf9519102016-08-17 09:49:13 -06002173 // For the active slots, use set# to look up descriptorSet from boundDescriptorSets, and bind all of that descriptor set's
2174 // resources
locke-lunarg540b2252020-08-03 13:23:36 -06002175 CMD_BUFFER_STATE::CmdDrawDispatchInfo cmd_info = {};
John Zulauf79f06582021-02-27 18:38:39 -07002176 for (const auto &binding_req_pair : binding_req_map) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002177 auto index = layout_->GetIndexFromBinding(binding_req_pair.first);
locke-gb3ce08f2019-09-30 12:30:56 -06002178
Tony-LunarG62c5dba2018-12-20 14:27:23 -07002179 // 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 -07002180 auto flags = layout_->GetDescriptorBindingFlagsFromIndex(index);
Mike Schuchardt2df08912020-12-15 16:28:09 -08002181 if (flags & (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT)) {
2182 if (!(flags & VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT)) {
locke-lunarg36045992020-08-20 16:54:37 -06002183 cmd_info.binding_infos.emplace_back(binding_req_pair);
locke-gb3ce08f2019-09-30 12:30:56 -06002184 }
Tony-LunarG62c5dba2018-12-20 14:27:23 -07002185 continue;
2186 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002187 auto range = layout_->GetGlobalIndexRangeFromIndex(index);
John Zulaufc483f442017-12-15 14:02:06 -07002188 for (uint32_t i = range.start; i < range.end; ++i) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002189 const auto descriptor_class = descriptors_[i]->GetClass();
2190 switch (descriptor_class) {
2191 case DescriptorClass::Image:
2192 case DescriptorClass::ImageSampler: {
2193 auto *image_desc = static_cast<ImageDescriptor *>(descriptors_[i].get());
2194 image_desc->UpdateDrawState(device_data, cb_node);
2195 break;
2196 }
2197 default:
2198 break;
2199 }
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06002200 }
2201 }
locke-lunarg540b2252020-08-03 13:23:36 -06002202
2203 if (cmd_info.binding_infos.size() > 0) {
2204 cmd_info.cmd_type = cmd_type;
locke-lunarg540b2252020-08-03 13:23:36 -06002205 if (cb_node->activeFramebuffer) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002206 cmd_info.framebuffer = cb_node->activeFramebuffer->framebuffer();
locke-lunargfc78e932020-11-19 17:06:24 -07002207 cmd_info.attachments = cb_node->active_attachments;
2208 cmd_info.subpasses = cb_node->active_subpasses;
locke-lunarg540b2252020-08-03 13:23:36 -06002209 }
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002210 cb_node->validate_descriptorsets_in_queuesubmit[GetSet()].emplace_back(cmd_info);
locke-lunarg540b2252020-08-03 13:23:36 -06002211 }
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06002212}
2213
John Zulauffbf3c202019-07-17 14:57:14 -06002214void cvdescriptorset::DescriptorSet::FilterOneBindingReq(const BindingReqMap::value_type &binding_req_pair, BindingReqMap *out_req,
2215 const TrackedBindings &bindings, uint32_t limit) {
2216 if (bindings.size() < limit) {
2217 const auto it = bindings.find(binding_req_pair.first);
2218 if (it == bindings.cend()) out_req->emplace(binding_req_pair);
John Zulauf48a6a702017-12-22 17:14:54 -07002219 }
2220}
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06002221
John Zulauffbf3c202019-07-17 14:57:14 -06002222void cvdescriptorset::DescriptorSet::FilterBindingReqs(const CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline,
2223 const BindingReqMap &in_req, BindingReqMap *out_req) const {
2224 // For const cleanliness we have to find in the maps...
Jeremy Gebben87db52f2021-10-14 13:55:09 -06002225 const auto validated_it = cb_state.descriptorset_cache.find(this);
2226 if (validated_it == cb_state.descriptorset_cache.end()) {
John Zulauffbf3c202019-07-17 14:57:14 -06002227 // We have nothing validated, copy in to out
2228 for (const auto &binding_req_pair : in_req) {
2229 out_req->emplace(binding_req_pair);
John Zulauf48a6a702017-12-22 17:14:54 -07002230 }
John Zulauffbf3c202019-07-17 14:57:14 -06002231 return;
John Zulauf48a6a702017-12-22 17:14:54 -07002232 }
John Zulauffbf3c202019-07-17 14:57:14 -06002233 const auto &validated = validated_it->second;
John Zulauf48a6a702017-12-22 17:14:54 -07002234
John Zulauffbf3c202019-07-17 14:57:14 -06002235 const auto image_sample_version_it = validated.image_samplers.find(&pipeline);
2236 const VersionedBindings *image_sample_version = nullptr;
2237 if (image_sample_version_it != validated.image_samplers.cend()) {
2238 image_sample_version = &(image_sample_version_it->second);
2239 }
2240 const auto &dynamic_buffers = validated.dynamic_buffers;
2241 const auto &non_dynamic_buffers = validated.non_dynamic_buffers;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002242 const auto &stats = layout_->GetBindingTypeStats();
John Zulauf48a6a702017-12-22 17:14:54 -07002243 for (const auto &binding_req_pair : in_req) {
2244 auto binding = binding_req_pair.first;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002245 VkDescriptorSetLayoutBinding const *layout_binding = layout_->GetDescriptorSetLayoutBindingPtrFromBinding(binding);
John Zulauf48a6a702017-12-22 17:14:54 -07002246 if (!layout_binding) {
2247 continue;
2248 }
2249 // Caching criteria differs per type.
2250 // If image_layout have changed , the image descriptors need to be validated against them.
sfricke-samsung60f29ec2021-03-10 20:37:25 -08002251 if (IsBufferDescriptor(layout_binding->descriptorType)) {
2252 if (IsDynamicDescriptor(layout_binding->descriptorType)) {
2253 FilterOneBindingReq(binding_req_pair, out_req, dynamic_buffers, stats.dynamic_buffer_count);
2254 } else {
2255 FilterOneBindingReq(binding_req_pair, out_req, non_dynamic_buffers, stats.non_dynamic_buffer_count);
2256 }
John Zulauf48a6a702017-12-22 17:14:54 -07002257 } else {
2258 // This is rather crude, as the changed layouts may not impact the bound descriptors,
2259 // but the simple "versioning" is a simple "dirt" test.
John Zulauffbf3c202019-07-17 14:57:14 -06002260 bool stale = true;
2261 if (image_sample_version) {
2262 const auto version_it = image_sample_version->find(binding);
2263 if (version_it != image_sample_version->cend() && (version_it->second == cb_state.image_layout_change_count)) {
2264 stale = false;
2265 }
2266 }
2267 if (stale) {
John Zulauf48a6a702017-12-22 17:14:54 -07002268 out_req->emplace(binding_req_pair);
2269 }
2270 }
2271 }
2272}
Tobin Ehlis9252c2b2016-07-21 14:40:22 -06002273
Jeremy Gebben87db52f2021-10-14 13:55:09 -06002274void cvdescriptorset::DescriptorSet::UpdateValidationCache(CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline,
John Zulauffbf3c202019-07-17 14:57:14 -06002275 const BindingReqMap &updated_bindings) {
Jeremy Gebben87db52f2021-10-14 13:55:09 -06002276 auto &validated = cb_state.descriptorset_cache[this];
John Zulauffbf3c202019-07-17 14:57:14 -06002277
2278 auto &image_sample_version = validated.image_samplers[&pipeline];
2279 auto &dynamic_buffers = validated.dynamic_buffers;
2280 auto &non_dynamic_buffers = validated.non_dynamic_buffers;
2281 for (const auto &binding_req_pair : updated_bindings) {
2282 auto binding = binding_req_pair.first;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002283 VkDescriptorSetLayoutBinding const *layout_binding = layout_->GetDescriptorSetLayoutBindingPtrFromBinding(binding);
John Zulauffbf3c202019-07-17 14:57:14 -06002284 if (!layout_binding) {
2285 continue;
2286 }
2287 // Caching criteria differs per type.
sfricke-samsung60f29ec2021-03-10 20:37:25 -08002288 if (IsBufferDescriptor(layout_binding->descriptorType)) {
2289 if (IsDynamicDescriptor(layout_binding->descriptorType)) {
2290 dynamic_buffers.emplace(binding);
2291 } else {
2292 non_dynamic_buffers.emplace(binding);
2293 }
John Zulauffbf3c202019-07-17 14:57:14 -06002294 } else {
2295 // Save the layout change version...
2296 image_sample_version[binding] = cb_state.image_layout_change_count;
2297 }
2298 }
2299}
2300
John Zulaufd2c3dae2019-12-12 11:02:17 -07002301cvdescriptorset::SamplerDescriptor::SamplerDescriptor(const ValidationStateTracker *dev_data, const VkSampler *immut)
Jeremy Gebben059ab502021-04-26 11:25:02 -06002302 : Descriptor(PlainSampler), immutable_(false) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002303 if (immut) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002304 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(*immut);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002305 immutable_ = true;
2306 updated = true;
2307 }
2308}
Tobin Ehlise2f80292016-06-02 10:08:53 -06002309// Validate given sampler. Currently this only checks to make sure it exists in the samplerMap
Jeremy Gebben9f537102021-10-05 16:37:12 -06002310bool CoreChecks::ValidateSampler(const VkSampler sampler) const { return Get<SAMPLER_STATE>(sampler).get() != nullptr; }
Tobin Ehlis56a30942016-05-19 08:00:00 -06002311
John Zulaufc93c4252019-06-25 09:19:49 -06002312bool CoreChecks::ValidateImageUpdate(VkImageView image_view, VkImageLayout image_layout, VkDescriptorType type,
John Zulaufbd9b3412019-08-22 17:16:11 -06002313 const char *func_name, std::string *error_code, std::string *error_msg) const {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06002314 auto iv_state = Get<IMAGE_VIEW_STATE>(image_view);
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002315 assert(iv_state);
2316
Tobin Ehlis81280962016-07-20 14:04:20 -06002317 // 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 -06002318 // Validate that imageLayout is compatible with aspect_mask and image format
2319 // and validate that image usage bits are correct for given usage
Jeremy Gebbenb4d17012021-07-08 13:18:15 -06002320 VkImageAspectFlags aspect_mask = iv_state->normalized_subresource_range.aspectMask;
Tobin Ehlis8b26a382016-09-14 08:02:49 -06002321 VkImage image = iv_state->create_info.image;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002322 VkFormat format = VK_FORMAT_MAX_ENUM;
2323 VkImageUsageFlags usage = 0;
Jeremy Gebben057f9d52021-11-05 14:12:31 -06002324 auto *image_node = iv_state->image_state.get();
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002325 assert(image_node);
Chris Forbes67757ff2017-07-21 13:59:01 -07002326
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002327 format = image_node->createInfo.format;
2328 usage = image_node->createInfo.usage;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002329 const auto stencil_usage_info = LvlFindInChain<VkImageStencilUsageCreateInfo>(image_node->createInfo.pNext);
Ricardo Garcia3f5984c2020-04-09 10:56:34 +02002330 if (stencil_usage_info) {
2331 usage |= stencil_usage_info->stencilUsage;
2332 }
Mark Lobodzinski03d00062020-06-15 14:35:45 -06002333
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002334 // Validate that memory is bound to image
sfricke-samsung52dbd082021-09-23 11:17:58 -07002335 if (ValidateMemoryIsBoundToImage(image_node, func_name, kVUID_Core_Bound_Resource_FreedMemoryAccess)) {
2336 *error_code = kVUID_Core_Bound_Resource_FreedMemoryAccess;
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002337 *error_msg = "No memory bound to image.";
Tobin Ehlis1809f912016-05-25 09:24:36 -06002338 return false;
2339 }
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002340
2341 // KHR_maintenance1 allows rendering into 2D or 2DArray views which slice a 3D image,
2342 // but not binding them to descriptor sets.
Jeremy Gebben11a68a32021-07-29 11:59:22 -06002343 if (iv_state->IsDepthSliced()) {
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06002344 *error_code = "VUID-VkDescriptorImageInfo-imageView-00343";
2345 *error_msg = "ImageView must not be a 2D or 2DArray view of a 3D image";
2346 return false;
2347 }
2348
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002349 // TODO : The various image aspect and format checks here are based on general spec language in 11.5 Image Views section under
2350 // vkCreateImageView(). What's the best way to create unique id for these cases?
sfricke-samsung52dbd082021-09-23 11:17:58 -07002351 *error_code = kVUID_Core_DrawState_InvalidImageView;
Dave Houlton1d2022c2017-03-29 11:43:58 -06002352 bool ds = FormatIsDepthOrStencil(format);
Tobin Ehlis1809f912016-05-25 09:24:36 -06002353 switch (image_layout) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002354 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
2355 // Only Color bit must be set
2356 if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
Tobin Ehlis1809f912016-05-25 09:24:36 -06002357 std::stringstream error_str;
Dave Houltona9df0ce2018-02-07 10:51:23 -07002358 error_str
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002359 << "ImageView (" << report_data->FormatHandle(image_view)
Dave Houltona9df0ce2018-02-07 10:51:23 -07002360 << ") 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 -06002361 *error_msg = error_str.str();
Tobin Ehlis1809f912016-05-25 09:24:36 -06002362 return false;
2363 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002364 // format must NOT be DS
2365 if (ds) {
2366 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002367 error_str << "ImageView (" << report_data->FormatHandle(image_view)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002368 << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but the image format is "
2369 << string_VkFormat(format) << " which is not a color format.";
2370 *error_msg = error_str.str();
2371 return false;
2372 }
2373 break;
2374 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
2375 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
2376 // Depth or stencil bit must be set, but both must NOT be set
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06002377 if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
2378 if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2379 // both must NOT be set
2380 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002381 error_str << "ImageView (" << report_data->FormatHandle(image_view)
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002382 << ") has both STENCIL and DEPTH aspects set";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002383 *error_msg = error_str.str();
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06002384 return false;
2385 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002386 } else if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
2387 // Neither were set
2388 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002389 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002390 << string_VkImageLayout(image_layout) << " but does not have STENCIL or DEPTH aspects set";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002391 *error_msg = error_str.str();
2392 return false;
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06002393 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002394 // format must be DS
2395 if (!ds) {
2396 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002397 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002398 << string_VkImageLayout(image_layout) << " but the image format is " << string_VkFormat(format)
2399 << " which is not a depth/stencil format.";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002400 *error_msg = error_str.str();
2401 return false;
2402 }
2403 break;
2404 default:
2405 // For other layouts if the source is depth/stencil image, both aspect bits must not be set
2406 if (ds) {
2407 if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
2408 if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2409 // both must NOT be set
2410 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002411 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002412 << string_VkImageLayout(image_layout) << " and is using depth/stencil image of format "
2413 << string_VkFormat(format)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002414 << " but it has both STENCIL and DEPTH aspects set, which is illegal. When using a depth/stencil "
2415 "image in a descriptor set, please only set either VK_IMAGE_ASPECT_DEPTH_BIT or "
2416 "VK_IMAGE_ASPECT_STENCIL_BIT depending on whether it will be used for depth reads or stencil "
2417 "reads respectively.";
Mark Lobodzinski4d05d7a2019-06-25 09:12:06 -06002418 *error_code = "VUID-VkDescriptorImageInfo-imageView-01976";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002419 *error_msg = error_str.str();
2420 return false;
2421 }
2422 }
2423 }
2424 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002425 }
2426 // Now validate that usage flags are correctly set for given type of update
Tobin Ehlisfb4cf712016-10-10 14:02:48 -06002427 // 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 -06002428 // TODO : The various image usage bit requirements are in general spec language for VkImageUsageFlags bit block in 11.3 Images
2429 // under vkCreateImage()
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002430 const char *error_usage_bit = nullptr;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002431 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002432 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
sfricke-samsung088f1242020-06-06 02:15:35 -07002433 if (iv_state->samplerConversion != VK_NULL_HANDLE) {
2434 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-01946";
2435 std::stringstream error_str;
2436 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ")"
2437 << "used as a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE can't be created with VkSamplerYcbcrConversion";
2438 *error_msg = error_str.str();
2439 return false;
2440 }
2441 // drop through
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002442 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
2443 if (!(usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
2444 error_usage_bit = "VK_IMAGE_USAGE_SAMPLED_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002445 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00337";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002446 }
2447 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002448 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002449 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
2450 if (!(usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
2451 error_usage_bit = "VK_IMAGE_USAGE_STORAGE_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002452 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00339";
sfricke-samsung45996a42021-09-16 13:45:27 -07002453 } else if ((VK_IMAGE_LAYOUT_GENERAL != image_layout) &&
2454 (!IsExtEnabled(device_extensions.vk_khr_shared_presentable_image) ||
2455 (VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR != image_layout))) {
sfricke-samsungf1058982020-09-10 22:36:49 -07002456 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04152";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002457 std::stringstream error_str;
sfricke-samsungada55a12020-08-15 03:39:41 -07002458 error_str << "Descriptor update with descriptorType VK_DESCRIPTOR_TYPE_STORAGE_IMAGE"
2459 << " is being updated with invalid imageLayout " << string_VkImageLayout(image_layout) << " for image "
2460 << report_data->FormatHandle(image) << " in imageView " << report_data->FormatHandle(image_view)
2461 << ". Allowed layouts are: VK_IMAGE_LAYOUT_GENERAL";
sfricke-samsung45996a42021-09-16 13:45:27 -07002462 if (IsExtEnabled(device_extensions.vk_khr_shared_presentable_image)) {
sfricke-samsungada55a12020-08-15 03:39:41 -07002463 error_str << " or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR";
Tobin Ehlisbb03e5f2017-05-11 08:52:51 -06002464 }
sfricke-samsungada55a12020-08-15 03:39:41 -07002465 *error_msg = error_str.str();
2466 return false;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002467 }
2468 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002469 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002470 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
2471 if (!(usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
2472 error_usage_bit = "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002473 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00338";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002474 }
2475 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002476 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002477 default:
2478 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002479 }
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002480 if (error_usage_bit) {
Tobin Ehlis1809f912016-05-25 09:24:36 -06002481 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002482 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") with usage mask " << std::hex << std::showbase
2483 << usage << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
2484 << error_usage_bit << " set.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002485 *error_msg = error_str.str();
Tobin Ehlis1809f912016-05-25 09:24:36 -06002486 return false;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002487 }
John Zulauff4c07882019-01-24 14:03:36 -07002488
sfricke-samsungada55a12020-08-15 03:39:41 -07002489 // All the following types share the same image layouts
2490 // checkf or Storage Images above
2491 if ((type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
2492 (type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
John Zulauff4c07882019-01-24 14:03:36 -07002493 // Test that the layout is compatible with the descriptorType for the two sampled image types
2494 const static std::array<VkImageLayout, 3> valid_layouts = {
Jeremy Hayesd0549f62019-06-05 10:15:36 -06002495 {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 -07002496
2497 struct ExtensionLayout {
2498 VkImageLayout layout;
Tony-LunarG2ec96bb2019-11-26 13:43:02 -07002499 ExtEnabled DeviceExtensions::*extension;
John Zulauff4c07882019-01-24 14:03:36 -07002500 };
Ricardo Garcia602c2022021-07-30 10:42:17 +02002501 const static std::array<ExtensionLayout, 7> extended_layouts{{
Jeremy Gebben579aaca2021-02-15 13:36:18 -07002502 // Note double brace req'd for aggregate initialization
2503 {VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, &DeviceExtensions::vk_khr_shared_presentable_image},
2504 {VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, &DeviceExtensions::vk_khr_maintenance2},
2505 {VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, &DeviceExtensions::vk_khr_maintenance2},
Mike Schuchardtc57de4a2021-07-20 17:26:32 -07002506 {VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, &DeviceExtensions::vk_khr_synchronization2},
2507 {VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, &DeviceExtensions::vk_khr_synchronization2},
Ricardo Garcia602c2022021-07-30 10:42:17 +02002508 {VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, &DeviceExtensions::vk_khr_separate_depth_stencil_layouts},
2509 {VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, &DeviceExtensions::vk_khr_separate_depth_stencil_layouts},
Jeremy Gebben579aaca2021-02-15 13:36:18 -07002510 }};
John Zulaufc93c4252019-06-25 09:19:49 -06002511 auto is_layout = [image_layout, this](const ExtensionLayout &ext_layout) {
sfricke-samsung45996a42021-09-16 13:45:27 -07002512 return IsExtEnabled(device_extensions.*(ext_layout.extension)) && (ext_layout.layout == image_layout);
John Zulauff4c07882019-01-24 14:03:36 -07002513 };
2514
2515 bool valid_layout = (std::find(valid_layouts.cbegin(), valid_layouts.cend(), image_layout) != valid_layouts.cend()) ||
2516 std::any_of(extended_layouts.cbegin(), extended_layouts.cend(), is_layout);
2517
2518 if (!valid_layout) {
sfricke-samsungf1058982020-09-10 22:36:49 -07002519 // The following works as currently all 3 descriptor types share the same set of valid layouts
sfricke-samsungada55a12020-08-15 03:39:41 -07002520 switch (type) {
2521 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002522 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04149";
sfricke-samsungada55a12020-08-15 03:39:41 -07002523 break;
2524 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002525 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04150";
sfricke-samsungada55a12020-08-15 03:39:41 -07002526 break;
2527 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
sfricke-samsungf1058982020-09-10 22:36:49 -07002528 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04151";
sfricke-samsungada55a12020-08-15 03:39:41 -07002529 break;
2530 default:
2531 break;
2532 }
John Zulauff4c07882019-01-24 14:03:36 -07002533 std::stringstream error_str;
2534 error_str << "Descriptor update with descriptorType " << string_VkDescriptorType(type)
Mark Lobodzinski74eddba2019-06-21 14:16:33 -06002535 << " is being updated with invalid imageLayout " << string_VkImageLayout(image_layout) << " for image "
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002536 << report_data->FormatHandle(image) << " in imageView " << report_data->FormatHandle(image_view)
John Zulauff4c07882019-01-24 14:03:36 -07002537 << ". Allowed layouts are: VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "
2538 << "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL";
2539 for (auto &ext_layout : extended_layouts) {
sfricke-samsung45996a42021-09-16 13:45:27 -07002540 if (IsExtEnabled(device_extensions.*(ext_layout.extension))) {
John Zulauff4c07882019-01-24 14:03:36 -07002541 error_str << ", " << string_VkImageLayout(ext_layout.layout);
2542 }
2543 }
2544 *error_msg = error_str.str();
2545 return false;
2546 }
2547 }
2548
sfricke-samsungbd0e8052020-06-06 01:36:39 -07002549 if ((type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) || (type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
2550 const VkComponentMapping components = iv_state->create_info.components;
2551 if (IsIdentitySwizzle(components) == false) {
2552 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00336";
2553 std::stringstream error_str;
2554 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has a non-identiy swizzle component, "
2555 << " r swizzle = " << string_VkComponentSwizzle(components.r) << ","
2556 << " g swizzle = " << string_VkComponentSwizzle(components.g) << ","
2557 << " b swizzle = " << string_VkComponentSwizzle(components.b) << ","
2558 << " a swizzle = " << string_VkComponentSwizzle(components.a) << ".";
2559 *error_msg = error_str.str();
2560 return false;
2561 }
2562 }
2563
Tony-LunarG69604c42021-11-22 16:00:12 -07002564 if ((type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) && (iv_state->min_lod != 0.0f)) {
2565 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-06450";
2566 std::stringstream error_str;
2567 error_str << "ImageView (" << report_data->FormatHandle(image_view)
2568 << ") , written to a descriptor of type VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT with a minLod (" << iv_state->min_lod
2569 << ") that is not 0.0";
2570 *error_msg = error_str.str();
2571 return false;
2572 }
2573
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002574 return true;
2575}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002576
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002577// Helper template to change shared pointer members of a Descriptor, while
2578// correctly managing links to the parent DescriptorSet.
2579// src and dst are shared pointers.
2580template <typename T>
2581static void ReplaceStatePtr(DescriptorSet *set_state, T &dst, const T &src) {
2582 if (dst) {
2583 dst->RemoveParent(set_state);
2584 }
2585 dst = src;
2586 if (dst) {
2587 dst->AddParent(set_state);
2588 }
2589}
2590
2591void cvdescriptorset::SamplerDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2592 const VkWriteDescriptorSet *update, const uint32_t index) {
Chris Forbesfea2c542018-04-13 09:34:15 -07002593 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002594 ReplaceStatePtr(set_state, sampler_state_ , dev_data->GetConstCastShared<SAMPLER_STATE>(update->pImageInfo[index].sampler));
Chris Forbesfea2c542018-04-13 09:34:15 -07002595 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002596 updated = true;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002597}
2598
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002599void cvdescriptorset::SamplerDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2600 const Descriptor *src) {
Tony-LunarG80358322021-04-16 07:58:13 -06002601 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002602 if (src->descriptor_class == Mutable) {
zigada4b1512021-11-28 15:53:06 +01002603 auto *sampler_src = static_cast<const MutableDescriptor *>(src);
2604 if (!immutable_) {
2605 ReplaceStatePtr(set_state, sampler_state_, sampler_src->GetSharedSamplerState());
2606 }
Tony-LunarG80358322021-04-16 07:58:13 -06002607 return;
2608 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002609 auto *sampler_src = static_cast<const SamplerDescriptor *>(src);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002610 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002611 ReplaceStatePtr(set_state, sampler_state_, sampler_src->sampler_state_);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002612 }
2613}
2614
John Zulaufd2c3dae2019-12-12 11:02:17 -07002615cvdescriptorset::ImageSamplerDescriptor::ImageSamplerDescriptor(const ValidationStateTracker *dev_data, const VkSampler *immut)
Jeremy Gebben059ab502021-04-26 11:25:02 -06002616 : ImageDescriptor(ImageSampler), immutable_(false) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002617 if (immut) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002618 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(*immut);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002619 immutable_ = true;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002620 }
2621}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002622
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002623void cvdescriptorset::ImageSamplerDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
John Zulaufd2c3dae2019-12-12 11:02:17 -07002624 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002625 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002626 const auto &image_info = update->pImageInfo[index];
Chris Forbesfea2c542018-04-13 09:34:15 -07002627 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002628 ReplaceStatePtr(set_state, sampler_state_, dev_data->GetConstCastShared<SAMPLER_STATE>(image_info.sampler));
Chris Forbesfea2c542018-04-13 09:34:15 -07002629 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002630 image_layout_ = image_info.imageLayout;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002631 ReplaceStatePtr(set_state, image_view_state_, dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView));
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002632}
2633
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002634void cvdescriptorset::ImageSamplerDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2635 const Descriptor *src) {
Tony-LunarG80358322021-04-16 07:58:13 -06002636 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002637 if (src->descriptor_class == Mutable) {
zigada4b1512021-11-28 15:53:06 +01002638 auto *image_src = static_cast<const MutableDescriptor *>(src);
2639 if (!immutable_) {
2640 ReplaceStatePtr(set_state, sampler_state_, image_src->GetSharedSamplerState());
2641 }
2642 ImageDescriptor::CopyUpdate(set_state, dev_data, src);
Tony-LunarG80358322021-04-16 07:58:13 -06002643 return;
2644 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002645 auto *image_src = static_cast<const ImageSamplerDescriptor *>(src);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002646 if (!immutable_) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002647 ReplaceStatePtr(set_state, sampler_state_, image_src->sampler_state_);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002648 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002649 ImageDescriptor::CopyUpdate(set_state, dev_data, src);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002650}
2651
Jeremy Gebben059ab502021-04-26 11:25:02 -06002652cvdescriptorset::ImageDescriptor::ImageDescriptor(const VkDescriptorType type)
2653 : Descriptor(Image), image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) {}
2654
2655cvdescriptorset::ImageDescriptor::ImageDescriptor(DescriptorClass class_)
2656 : Descriptor(class_), image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) {}
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002657
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002658void cvdescriptorset::ImageDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2659 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002660 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002661 const auto &image_info = update->pImageInfo[index];
Tobin Ehlis300888c2016-05-18 13:43:26 -06002662 image_layout_ = image_info.imageLayout;
zigada4b1512021-11-28 15:53:06 +01002663 ReplaceStatePtr(set_state, image_view_state_, dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView));
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002664}
2665
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002666void cvdescriptorset::ImageDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2667 const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002668 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002669 if (src->descriptor_class == Mutable) {
zigada4b1512021-11-28 15:53:06 +01002670 auto *image_src = static_cast<const MutableDescriptor *>(src);
2671
2672 image_layout_ = image_src->GetImageLayout();
2673 ReplaceStatePtr(set_state, image_view_state_, image_src->GetSharedImageViewState());
Tony-LunarG80358322021-04-16 07:58:13 -06002674 return;
2675 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002676 auto *image_src = static_cast<const ImageDescriptor *>(src);
Tony-LunarG80358322021-04-16 07:58:13 -06002677
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002678 image_layout_ = image_src->image_layout_;
2679 ReplaceStatePtr(set_state, image_view_state_, image_src->image_view_state_);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002680}
2681
John Zulauffbf3c202019-07-17 14:57:14 -06002682void cvdescriptorset::ImageDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) {
Tobin Ehlis81e46372016-08-17 13:33:44 -06002683 // Add binding for image
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002684 auto iv_state = GetImageViewState();
Tobin Ehlis8b26a382016-09-14 08:02:49 -06002685 if (iv_state) {
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002686 dev_data->CallSetImageViewInitialLayoutCallback(cb_node, *iv_state, image_layout_);
Jeff Bolz148d94e2018-12-13 21:25:56 -06002687 }
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002688}
2689
Jeremy Gebben059ab502021-04-26 11:25:02 -06002690cvdescriptorset::BufferDescriptor::BufferDescriptor(const VkDescriptorType type)
2691 : Descriptor(GeneralBuffer), offset_(0), range_(0) {}
2692
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002693void cvdescriptorset::BufferDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2694 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002695 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002696 const auto &buffer_info = update->pBufferInfo[index];
Tobin Ehlis300888c2016-05-18 13:43:26 -06002697 offset_ = buffer_info.offset;
2698 range_ = buffer_info.range;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002699 ReplaceStatePtr(set_state, buffer_state_, dev_data->GetConstCastShared<BUFFER_STATE>(buffer_info.buffer));
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002700}
2701
zigada4b1512021-11-28 15:53:06 +01002702void cvdescriptorset::BufferDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002703 const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002704 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002705 if (src->descriptor_class == Mutable) {
zigada4b1512021-11-28 15:53:06 +01002706 const auto buff_desc = static_cast<const MutableDescriptor *>(src);
2707 offset_ = buff_desc->GetOffset();
2708 range_ = buff_desc->GetRange();
2709 ReplaceStatePtr(set_state, buffer_state_, buff_desc->GetSharedBufferState());
Tony-LunarG80358322021-04-16 07:58:13 -06002710 return;
2711 }
Karl Schultz76d16a42020-11-11 05:05:33 -07002712 const auto buff_desc = static_cast<const BufferDescriptor *>(src);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002713 offset_ = buff_desc->offset_;
2714 range_ = buff_desc->range_;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002715 ReplaceStatePtr(set_state, buffer_state_, buff_desc->buffer_state_);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002716}
2717
Jeremy Gebben059ab502021-04-26 11:25:02 -06002718cvdescriptorset::TexelDescriptor::TexelDescriptor(const VkDescriptorType type) : Descriptor(TexelBuffer) {}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002719
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002720void cvdescriptorset::TexelDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2721 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002722 updated = true;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002723 ReplaceStatePtr(set_state, buffer_view_state_,
2724 dev_data->GetConstCastShared<BUFFER_VIEW_STATE>(update->pTexelBufferView[index]));
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002725}
2726
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002727void cvdescriptorset::TexelDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2728 const Descriptor *src) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002729 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002730 if (src->descriptor_class == Mutable) {
zigada4b1512021-11-28 15:53:06 +01002731 ReplaceStatePtr(set_state, buffer_view_state_, static_cast<const MutableDescriptor *>(src)->GetSharedBufferViewState());
Tony-LunarG80358322021-04-16 07:58:13 -06002732 return;
2733 }
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002734 ReplaceStatePtr(set_state, buffer_view_state_, static_cast<const TexelDescriptor *>(src)->buffer_view_state_);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002735}
2736
Jeff Bolz95176d02020-04-01 00:36:16 -05002737cvdescriptorset::AccelerationStructureDescriptor::AccelerationStructureDescriptor(const VkDescriptorType type)
Jeremy Gebben059ab502021-04-26 11:25:02 -06002738 : Descriptor(AccelerationStructure), acc_(VK_NULL_HANDLE), acc_nv_(VK_NULL_HANDLE) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002739 is_khr_ = false;
Jeff Bolz95176d02020-04-01 00:36:16 -05002740}
zigada4b1512021-11-28 15:53:06 +01002741void cvdescriptorset::AccelerationStructureDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
Jeff Bolz95176d02020-04-01 00:36:16 -05002742 const VkWriteDescriptorSet *update, const uint32_t index) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002743 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(update->pNext);
2744 const auto *acc_info_nv = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(update->pNext);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002745 assert(acc_info || acc_info_nv);
2746 is_khr_ = (acc_info != NULL);
Jeff Bolz95176d02020-04-01 00:36:16 -05002747 updated = true;
sourav parmarcd5fb182020-07-17 12:58:44 -07002748 if (is_khr_) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002749 acc_ = acc_info->pAccelerationStructures[index];
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002750 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002751 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002752 acc_nv_ = acc_info_nv->pAccelerationStructures[index];
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002753 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002754 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002755}
2756
zigada4b1512021-11-28 15:53:06 +01002757void cvdescriptorset::AccelerationStructureDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2758 const Descriptor *src) {
Jeff Bolz95176d02020-04-01 00:36:16 -05002759 updated = true;
Tony-LunarG80358322021-04-16 07:58:13 -06002760 if (src->descriptor_class == Mutable) {
zigada4b1512021-11-28 15:53:06 +01002761 auto acc_desc = static_cast<const MutableDescriptor *>(src);
2762 if (is_khr_) {
2763 acc_ = acc_desc->GetAccelerationStructure();
2764 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
2765 } else {
2766 acc_nv_ = acc_desc->GetAccelerationStructureNV();
2767 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
2768 }
Tony-LunarG80358322021-04-16 07:58:13 -06002769 return;
2770 }
zigada4b1512021-11-28 15:53:06 +01002771 auto acc_desc = static_cast<const AccelerationStructureDescriptor *>(src);
sourav parmarcd5fb182020-07-17 12:58:44 -07002772 if (is_khr_) {
2773 acc_ = acc_desc->acc_;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002774 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002775 } else {
2776 acc_nv_ = acc_desc->acc_nv_;
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002777 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
sourav parmarcd5fb182020-07-17 12:58:44 -07002778 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002779}
2780
zigada4b1512021-11-28 15:53:06 +01002781cvdescriptorset::MutableDescriptor::MutableDescriptor()
2782 : Descriptor(Mutable),
2783 buffer_size_(0),
2784 immutable_(false),
2785 image_layout_(VK_IMAGE_LAYOUT_UNDEFINED),
2786 offset_(0),
2787 range_(0),
2788 is_khr_(false),
2789 acc_(VK_NULL_HANDLE),
2790 acc_nv_(VK_NULL_HANDLE) {
ziga7a255fb2021-11-20 21:17:07 +01002791 active_descriptor_class_ = NoDescriptorClass;
2792}
Tony-LunarGf563b362021-03-18 16:13:18 -06002793
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002794void cvdescriptorset::MutableDescriptor::WriteUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
zigada4b1512021-11-28 15:53:06 +01002795 const VkWriteDescriptorSet *update, const uint32_t index) {
Tony-LunarGf563b362021-03-18 16:13:18 -06002796 updated = true;
zigada4b1512021-11-28 15:53:06 +01002797 if (update->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) {
2798 if (!immutable_) {
2799 ReplaceStatePtr(set_state, sampler_state_,
2800 dev_data->GetConstCastShared<SAMPLER_STATE>(update->pImageInfo[index].sampler));
2801 }
2802 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
2803 const auto &image_info = update->pImageInfo[index];
2804 if (!immutable_) {
2805 ReplaceStatePtr(set_state, sampler_state_, dev_data->GetConstCastShared<SAMPLER_STATE>(image_info.sampler));
2806 }
2807 image_layout_ = image_info.imageLayout;
2808 ReplaceStatePtr(set_state, image_view_state_, dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView));
2809 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
2810 update->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
2811 update->descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
2812 const auto &image_info = update->pImageInfo[index];
2813 image_layout_ = image_info.imageLayout;
2814 ReplaceStatePtr(set_state, image_view_state_, dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView));
2815 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
2816 update->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
2817 update->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2818 update->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
2819 const auto &buffer_info = update->pBufferInfo[index];
2820 offset_ = buffer_info.offset;
2821 range_ = buffer_info.range;
2822 ReplaceStatePtr(set_state, buffer_state_, dev_data->GetConstCastShared<BUFFER_STATE>(buffer_info.buffer));
2823 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2824 update->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
2825 ReplaceStatePtr(set_state, buffer_view_state_,
2826 dev_data->GetConstCastShared<BUFFER_VIEW_STATE>(update->pTexelBufferView[index]));
2827 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
2828 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(update->pNext);
2829 const auto *acc_info_nv = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(update->pNext);
2830 assert(acc_info || acc_info_nv);
2831 is_khr_ = (acc_info != NULL);
2832 updated = true;
2833 if (is_khr_) {
2834 acc_ = acc_info->pAccelerationStructures[index];
2835 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
2836 } else {
2837 acc_nv_ = acc_info_nv->pAccelerationStructures[index];
2838 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
2839 }
2840 }
Tony-LunarGf563b362021-03-18 16:13:18 -06002841}
2842
Jeremy Gebben5570abe2021-05-16 18:35:13 -06002843void cvdescriptorset::MutableDescriptor::CopyUpdate(DescriptorSet *set_state, const ValidationStateTracker *dev_data,
2844 const Descriptor *src) {
Tony-LunarGf563b362021-03-18 16:13:18 -06002845 updated = true;
zigada4b1512021-11-28 15:53:06 +01002846 if (src->descriptor_class == DescriptorClass::PlainSampler) {
2847 auto *sampler_src = static_cast<const SamplerDescriptor *>(src);
2848 if (!immutable_) {
2849 ReplaceStatePtr(set_state, sampler_state_, sampler_src->GetSharedSamplerState());
2850 }
2851 } else if (src->descriptor_class == DescriptorClass::ImageSampler) {
2852 auto *image_src = static_cast<const ImageSamplerDescriptor *>(src);
2853 if (!immutable_) {
2854 ReplaceStatePtr(set_state, sampler_state_, image_src->GetSharedSamplerState());
2855 }
2856
2857 image_layout_ = image_src->GetImageLayout();
2858 ReplaceStatePtr(set_state, image_view_state_, image_src->GetSharedImageViewState());
2859 } else if (src->descriptor_class == DescriptorClass::Image) {
2860 auto *image_src = static_cast<const ImageDescriptor *>(src);
2861
2862 image_layout_ = image_src->GetImageLayout();
2863 ReplaceStatePtr(set_state, image_view_state_, image_src->GetSharedImageViewState());
2864 } else if (src->descriptor_class == DescriptorClass::TexelBuffer) {
2865 ReplaceStatePtr(set_state, buffer_view_state_, static_cast<const TexelDescriptor *>(src)->GetSharedBufferViewState());
2866 } else if (src->descriptor_class == DescriptorClass::GeneralBuffer) {
2867 const auto buff_desc = static_cast<const BufferDescriptor *>(src);
2868 offset_ = buff_desc->GetOffset();
2869 range_ = buff_desc->GetRange();
2870 ReplaceStatePtr(set_state, buffer_state_, buff_desc->GetSharedBufferState());
2871 } else if (src->descriptor_class == DescriptorClass::AccelerationStructure) {
2872 auto acc_desc = static_cast<const AccelerationStructureDescriptor *>(src);
2873 if (is_khr_) {
2874 acc_ = acc_desc->GetAccelerationStructure();
2875 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
2876 } else {
2877 acc_nv_ = acc_desc->GetAccelerationStructureNV();
2878 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
2879 }
2880 } else if (src->descriptor_class == DescriptorClass::Mutable) {
2881 if (src->active_descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLER) {
2882 auto *sampler_src = static_cast<const MutableDescriptor *>(src);
2883 if (!immutable_) {
2884 ReplaceStatePtr(set_state, sampler_state_, sampler_src->GetSharedSamplerState());
2885 }
2886 } else if (src->active_descriptor_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
2887 auto *image_src = static_cast<const MutableDescriptor *>(src);
2888 if (!immutable_) {
2889 ReplaceStatePtr(set_state, sampler_state_, image_src->GetSharedSamplerState());
2890 }
2891
2892 image_layout_ = image_src->GetImageLayout();
2893 ReplaceStatePtr(set_state, image_view_state_, image_src->GetSharedImageViewState());
2894 } else if (src->active_descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
2895 src->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
2896 src->active_descriptor_type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
2897 auto *image_src = static_cast<const MutableDescriptor *>(src);
2898
2899 image_layout_ = image_src->GetImageLayout();
2900 ReplaceStatePtr(set_state, image_view_state_, image_src->GetSharedImageViewState());
2901 } else if (src->active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
2902 src->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
2903 src->active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2904 src->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
2905 const auto buff_desc = static_cast<const MutableDescriptor *>(src);
2906 offset_ = buff_desc->GetOffset();
2907 range_ = buff_desc->GetRange();
2908 ReplaceStatePtr(set_state, buffer_state_, buff_desc->GetSharedBufferState());
2909 } else if (src->active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2910 src->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
2911 ReplaceStatePtr(set_state, buffer_view_state_, static_cast<const MutableDescriptor *>(src)->GetSharedBufferViewState());
2912 } else if (src->active_descriptor_type == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR ||
2913 src->active_descriptor_type == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV) {
2914 auto acc_desc = static_cast<const MutableDescriptor *>(src);
2915 if (is_khr_) {
2916 acc_ = acc_desc->GetAccelerationStructure();
2917 ReplaceStatePtr(set_state, acc_state_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_));
2918 } else {
2919 acc_nv_ = acc_desc->GetAccelerationStructureNV();
2920 ReplaceStatePtr(set_state, acc_state_nv_, dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_));
2921 }
2922 }
2923 }
2924}
2925
2926bool cvdescriptorset::MutableDescriptor::AddParent(BASE_NODE *base_node) {
2927 bool result = false;
2928 if (active_descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLER) {
2929 if (sampler_state_) {
2930 result |= sampler_state_->AddParent(base_node);
2931 }
2932 } else if (active_descriptor_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
2933 if (sampler_state_) {
2934 result |= sampler_state_->AddParent(base_node);
2935 }
2936 if (image_view_state_) {
2937 result = image_view_state_->AddParent(base_node);
2938 }
2939 } else if (active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2940 active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
2941 if (buffer_view_state_) {
2942 result = buffer_view_state_->AddParent(base_node);
2943 }
2944 } else if (active_descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
2945 active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
2946 active_descriptor_type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
2947 if (image_view_state_) {
2948 result = image_view_state_->AddParent(base_node);
2949 }
2950 } else if (active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
2951 active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
2952 active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2953 active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
2954 if (buffer_state_) {
2955 result = buffer_state_->AddParent(base_node);
2956 }
2957 } else if (active_descriptor_type == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR ||
2958 active_descriptor_type == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV) {
2959 if (acc_state_) {
2960 result |= acc_state_->AddParent(base_node);
2961 }
2962 if (acc_state_nv_) {
2963 result |= acc_state_nv_->AddParent(base_node);
2964 }
2965 }
2966 return result;
2967}
2968void cvdescriptorset::MutableDescriptor::RemoveParent(BASE_NODE *base_node) {
2969 if (sampler_state_) {
2970 sampler_state_->RemoveParent(base_node);
2971 }
2972 if (image_view_state_) {
2973 image_view_state_->RemoveParent(base_node);
2974 }
2975 if (buffer_view_state_) {
2976 buffer_view_state_->RemoveParent(base_node);
2977 }
2978 if (buffer_state_) {
2979 buffer_state_->RemoveParent(base_node);
2980 }
2981 if (acc_state_) {
2982 acc_state_->RemoveParent(base_node);
2983 }
2984 if (acc_state_nv_) {
2985 acc_state_nv_->RemoveParent(base_node);
2986 }
Tony-LunarGf563b362021-03-18 16:13:18 -06002987}
2988
Tobin Ehlis300888c2016-05-18 13:43:26 -06002989// This is a helper function that iterates over a set of Write and Copy updates, pulls the DescriptorSet* for updated
2990// sets, and then calls their respective Validate[Write|Copy]Update functions.
2991// If the update hits an issue for which the callback returns "true", meaning that the call down the chain should
2992// be skipped, then true is returned.
2993// If there is no issue with the update, then false is returned.
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002994bool CoreChecks::ValidateUpdateDescriptorSets(uint32_t write_count, const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002995 const VkCopyDescriptorSet *p_cds, const char *func_name) const {
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06002996 bool skip = false;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002997 // Validate Write updates
Tobin Ehlis56a30942016-05-19 08:00:00 -06002998 for (uint32_t i = 0; i < write_count; i++) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002999 auto dest_set = p_wds[i].dstSet;
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003000 auto set_node = Get<cvdescriptorset::DescriptorSet>(dest_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06003001 if (!set_node) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08003002 skip |= LogError(dest_set, kVUID_Core_DrawState_InvalidDescriptorSet,
3003 "Cannot call %s on %s that has not been allocated in pDescriptorWrites[%u].", func_name,
3004 report_data->FormatHandle(dest_set).c_str(), i);
Tobin Ehlis300888c2016-05-18 13:43:26 -06003005 } else {
Dave Houltond8ed0212018-05-16 17:18:24 -06003006 std::string error_code;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003007 std::string error_str;
Jeremy Gebben9f537102021-10-05 16:37:12 -06003008 if (!ValidateWriteUpdate(set_node.get(), &p_wds[i], func_name, &error_code, &error_str, false)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08003009 skip |=
3010 LogError(dest_set, error_code, "%s pDescriptorWrites[%u] failed write update validation for %s with error: %s.",
3011 func_name, i, report_data->FormatHandle(dest_set).c_str(), error_str.c_str());
Tobin Ehlis300888c2016-05-18 13:43:26 -06003012 }
3013 }
sourav parmara24fb7b2020-05-26 10:50:04 -07003014 if (p_wds[i].pNext) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003015 const auto *pnext_struct = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(p_wds[i].pNext);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06003016 if (pnext_struct) {
3017 for (uint32_t j = 0; j < pnext_struct->accelerationStructureCount; ++j) {
Jeremy Gebbenf4449392022-01-28 10:09:10 -07003018 auto as_state = Get<ACCELERATION_STRUCTURE_STATE_KHR>(pnext_struct->pAccelerationStructures[j]);
sourav parmarcd5fb182020-07-17 12:58:44 -07003019 if (as_state && (as_state->create_infoKHR.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR &&
sourav parmar766e2a72020-12-03 16:17:11 -08003020 (as_state->create_infoKHR.type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR &&
3021 as_state->create_infoKHR.type != VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR))) {
sourav parmara24fb7b2020-05-26 10:50:04 -07003022 skip |=
sourav parmarcd5fb182020-07-17 12:58:44 -07003023 LogError(dest_set, "VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-03579",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003024 "%s: For pDescriptorWrites[%u] acceleration structure in pAccelerationStructures[%u] must "
3025 "have been created with "
sourav parmarbcee7512020-12-28 14:34:49 -08003026 "VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR or VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003027 func_name, i, j);
sourav parmara24fb7b2020-05-26 10:50:04 -07003028 }
3029 }
3030 }
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003031 const auto *pnext_struct_nv = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(p_wds[i].pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07003032 if (pnext_struct_nv) {
3033 for (uint32_t j = 0; j < pnext_struct_nv->accelerationStructureCount; ++j) {
Jeremy Gebbenf4449392022-01-28 10:09:10 -07003034 auto as_state = Get<ACCELERATION_STRUCTURE_STATE>(pnext_struct_nv->pAccelerationStructures[j]);
sourav parmarcd5fb182020-07-17 12:58:44 -07003035 if (as_state && (as_state->create_infoNV.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV &&
3036 as_state->create_infoNV.info.type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV)) {
3037 skip |= LogError(dest_set, "VUID-VkWriteDescriptorSetAccelerationStructureNV-pAccelerationStructures-03748",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003038 "%s: For pDescriptorWrites[%u] acceleration structure in pAccelerationStructures[%u] must "
3039 "have been created with"
sourav parmarcd5fb182020-07-17 12:58:44 -07003040 " VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003041 func_name, i, j);
sourav parmarcd5fb182020-07-17 12:58:44 -07003042 }
3043 }
3044 }
sourav parmara24fb7b2020-05-26 10:50:04 -07003045 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003046 }
3047 // Now validate copy updates
Tobin Ehlis56a30942016-05-19 08:00:00 -06003048 for (uint32_t i = 0; i < copy_count; ++i) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06003049 auto dst_set = p_cds[i].dstSet;
3050 auto src_set = p_cds[i].srcSet;
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003051 auto src_node = Get<cvdescriptorset::DescriptorSet>(src_set);
3052 auto dst_node = Get<cvdescriptorset::DescriptorSet>(dst_set);
Tobin Ehlisa1712752017-01-04 09:41:47 -07003053 // Object_tracker verifies that src & dest descriptor set are valid
3054 assert(src_node);
3055 assert(dst_node);
Dave Houltond8ed0212018-05-16 17:18:24 -06003056 std::string error_code;
Tobin Ehlisa1712752017-01-04 09:41:47 -07003057 std::string error_str;
Jeremy Gebben9f537102021-10-05 16:37:12 -06003058 if (!ValidateCopyUpdate(&p_cds[i], dst_node.get(), src_node.get(), func_name, &error_code, &error_str)) {
Mark Lobodzinski9d38ea22020-03-16 18:22:16 -06003059 LogObjectList objlist(dst_set);
3060 objlist.add(src_set);
sfricke-samsungbda4a852021-03-06 20:58:01 -08003061 skip |= LogError(objlist, error_code, "%s pDescriptorCopies[%u] failed copy update from %s to %s with error: %s.",
3062 func_name, i, report_data->FormatHandle(src_set).c_str(), report_data->FormatHandle(dst_set).c_str(),
3063 error_str.c_str());
Tobin Ehlis300888c2016-05-18 13:43:26 -06003064 }
3065 }
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06003066 return skip;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003067}
3068// This is a helper function that iterates over a set of Write and Copy updates, pulls the DescriptorSet* for updated
3069// sets, and then calls their respective Perform[Write|Copy]Update functions.
3070// Prerequisite : ValidateUpdateDescriptorSets() should be called and return "false" prior to calling PerformUpdateDescriptorSets()
3071// with the same set of updates.
3072// This is split from the validate code to allow validation prior to calling down the chain, and then update after
3073// calling down the chain.
John Zulaufe3b35f32019-06-25 14:21:21 -06003074void cvdescriptorset::PerformUpdateDescriptorSets(ValidationStateTracker *dev_data, uint32_t write_count,
3075 const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
3076 const VkCopyDescriptorSet *p_cds) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06003077 // Write updates first
3078 uint32_t i = 0;
3079 for (i = 0; i < write_count; ++i) {
3080 auto dest_set = p_wds[i].dstSet;
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003081 auto set_node = dev_data->Get<cvdescriptorset::DescriptorSet>(dest_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06003082 if (set_node) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05003083 set_node->PerformWriteUpdate(dev_data, &p_wds[i]);
Tobin Ehlis300888c2016-05-18 13:43:26 -06003084 }
3085 }
3086 // Now copy updates
3087 for (i = 0; i < copy_count; ++i) {
3088 auto dst_set = p_cds[i].dstSet;
3089 auto src_set = p_cds[i].srcSet;
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003090 auto src_node = dev_data->Get<cvdescriptorset::DescriptorSet>(src_set);
3091 auto dst_node = dev_data->Get<cvdescriptorset::DescriptorSet>(dst_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06003092 if (src_node && dst_node) {
Jeremy Gebben9f537102021-10-05 16:37:12 -06003093 dst_node->PerformCopyUpdate(dev_data, &p_cds[i], src_node.get());
Tobin Ehlis300888c2016-05-18 13:43:26 -06003094 }
3095 }
3096}
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07003097
John Zulaufe3b35f32019-06-25 14:21:21 -06003098cvdescriptorset::DecodedTemplateUpdate::DecodedTemplateUpdate(const ValidationStateTracker *device_data,
Jeremy Gebbenfc890452021-10-27 10:56:49 -06003099 VkDescriptorSet descriptorSet,
3100 const UPDATE_TEMPLATE_STATE *template_state, const void *pData,
3101 VkDescriptorSetLayout push_layout) {
John Zulaufb845eb22018-10-12 11:41:06 -06003102 auto const &create_info = template_state->create_info;
3103 inline_infos.resize(create_info.descriptorUpdateEntryCount); // Make sure we have one if we need it
sourav parmar480d2772021-01-24 22:24:54 -08003104 inline_infos_khr.resize(create_info.descriptorUpdateEntryCount);
3105 inline_infos_nv.resize(create_info.descriptorUpdateEntryCount);
John Zulaufb845eb22018-10-12 11:41:06 -06003106 desc_writes.reserve(create_info.descriptorUpdateEntryCount); // emplaced, so reserved without initialization
John Zulauf1d27e0a2018-11-05 10:12:48 -07003107 VkDescriptorSetLayout effective_dsl = create_info.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET
3108 ? create_info.descriptorSetLayout
3109 : push_layout;
Jeremy Gebben9f537102021-10-05 16:37:12 -06003110 auto layout_obj = device_data->Get<cvdescriptorset::DescriptorSetLayout>(effective_dsl);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07003111
3112 // Create a WriteDescriptorSet struct for each template update entry
3113 for (uint32_t i = 0; i < create_info.descriptorUpdateEntryCount; i++) {
3114 auto binding_count = layout_obj->GetDescriptorCountFromBinding(create_info.pDescriptorUpdateEntries[i].dstBinding);
3115 auto binding_being_updated = create_info.pDescriptorUpdateEntries[i].dstBinding;
3116 auto dst_array_element = create_info.pDescriptorUpdateEntries[i].dstArrayElement;
3117
John Zulaufb6d71202017-12-22 16:47:09 -07003118 desc_writes.reserve(desc_writes.size() + create_info.pDescriptorUpdateEntries[i].descriptorCount);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07003119 for (uint32_t j = 0; j < create_info.pDescriptorUpdateEntries[i].descriptorCount; j++) {
3120 desc_writes.emplace_back();
3121 auto &write_entry = desc_writes.back();
3122
3123 size_t offset = create_info.pDescriptorUpdateEntries[i].offset + j * create_info.pDescriptorUpdateEntries[i].stride;
3124 char *update_entry = (char *)(pData) + offset;
3125
3126 if (dst_array_element >= binding_count) {
3127 dst_array_element = 0;
Mark Lobodzinski4aa479d2017-03-10 09:14:00 -07003128 binding_being_updated = layout_obj->GetNextValidBinding(binding_being_updated);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07003129 }
3130
3131 write_entry.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3132 write_entry.pNext = NULL;
3133 write_entry.dstSet = descriptorSet;
3134 write_entry.dstBinding = binding_being_updated;
3135 write_entry.dstArrayElement = dst_array_element;
3136 write_entry.descriptorCount = 1;
3137 write_entry.descriptorType = create_info.pDescriptorUpdateEntries[i].descriptorType;
3138
3139 switch (create_info.pDescriptorUpdateEntries[i].descriptorType) {
3140 case VK_DESCRIPTOR_TYPE_SAMPLER:
3141 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3142 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3143 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3144 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
3145 write_entry.pImageInfo = reinterpret_cast<VkDescriptorImageInfo *>(update_entry);
3146 break;
3147
3148 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3149 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3150 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3151 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
3152 write_entry.pBufferInfo = reinterpret_cast<VkDescriptorBufferInfo *>(update_entry);
3153 break;
3154
3155 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3156 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
3157 write_entry.pTexelBufferView = reinterpret_cast<VkBufferView *>(update_entry);
3158 break;
Dave Houlton142c4cb2018-10-17 15:04:41 -06003159 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
3160 VkWriteDescriptorSetInlineUniformBlockEXT *inline_info = &inline_infos[i];
3161 inline_info->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
3162 inline_info->pNext = nullptr;
3163 inline_info->dataSize = create_info.pDescriptorUpdateEntries[i].descriptorCount;
3164 inline_info->pData = update_entry;
3165 write_entry.pNext = inline_info;
Ricardo Garciafee15732019-05-28 11:13:31 +02003166 // descriptorCount must match the dataSize member of the VkWriteDescriptorSetInlineUniformBlockEXT structure
3167 write_entry.descriptorCount = inline_info->dataSize;
Dave Houlton142c4cb2018-10-17 15:04:41 -06003168 // skip the rest of the array, they just represent bytes in the update
3169 j = create_info.pDescriptorUpdateEntries[i].descriptorCount;
3170 break;
3171 }
sourav parmar480d2772021-01-24 22:24:54 -08003172 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
3173 VkWriteDescriptorSetAccelerationStructureKHR *inline_info_khr = &inline_infos_khr[i];
3174 inline_info_khr->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
3175 inline_info_khr->pNext = nullptr;
3176 inline_info_khr->accelerationStructureCount = create_info.pDescriptorUpdateEntries[i].descriptorCount;
3177 inline_info_khr->pAccelerationStructures = reinterpret_cast<VkAccelerationStructureKHR *>(update_entry);
3178 write_entry.pNext = inline_info_khr;
3179 break;
3180 }
3181 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: {
3182 VkWriteDescriptorSetAccelerationStructureNV *inline_info_nv = &inline_infos_nv[i];
3183 inline_info_nv->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV;
3184 inline_info_nv->pNext = nullptr;
3185 inline_info_nv->accelerationStructureCount = create_info.pDescriptorUpdateEntries[i].descriptorCount;
3186 inline_info_nv->pAccelerationStructures = reinterpret_cast<VkAccelerationStructureNV *>(update_entry);
3187 write_entry.pNext = inline_info_nv;
3188 break;
3189 }
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07003190 default:
3191 assert(0);
3192 break;
3193 }
3194 dst_array_element++;
3195 }
3196 }
John Zulaufb845eb22018-10-12 11:41:06 -06003197}
John Zulaufb45fdc32018-10-12 15:14:17 -06003198// These helper functions carry out the validate and record descriptor updates peformed via update templates. They decode
3199// the templatized data and leverage the non-template UpdateDescriptor helper functions.
Jeremy Gebbenfc890452021-10-27 10:56:49 -06003200bool CoreChecks::ValidateUpdateDescriptorSetsWithTemplateKHR(VkDescriptorSet descriptorSet,
3201 const UPDATE_TEMPLATE_STATE *template_state, const void *pData) const {
John Zulaufb45fdc32018-10-12 15:14:17 -06003202 // Translate the templated update into a normal update for validation...
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07003203 cvdescriptorset::DecodedTemplateUpdate decoded_update(this, descriptorSet, template_state, pData);
3204 return ValidateUpdateDescriptorSets(static_cast<uint32_t>(decoded_update.desc_writes.size()), decoded_update.desc_writes.data(),
3205 0, NULL, "vkUpdateDescriptorSetWithTemplate()");
John Zulaufb45fdc32018-10-12 15:14:17 -06003206}
John Zulaufb845eb22018-10-12 11:41:06 -06003207
John Zulauf4e7bcb52018-11-02 10:46:30 -06003208std::string cvdescriptorset::DescriptorSet::StringifySetAndLayout() const {
3209 std::string out;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003210 auto layout_handle = layout_->GetDescriptorSetLayout();
John Zulauf4e7bcb52018-11-02 10:46:30 -06003211 if (IsPushDescriptor()) {
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06003212 std::ostringstream str;
Tony-LunarG1d3ee2d2020-10-27 15:54:52 -06003213 str << "Push Descriptors defined with " << state_data_->report_data->FormatHandle(layout_handle);
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06003214 out = str.str();
John Zulauf4e7bcb52018-11-02 10:46:30 -06003215 } else {
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06003216 std::ostringstream str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003217 str << state_data_->report_data->FormatHandle(GetSet()) << " allocated with "
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06003218 << state_data_->report_data->FormatHandle(layout_handle);
3219 out = str.str();
John Zulauf4e7bcb52018-11-02 10:46:30 -06003220 }
3221 return out;
3222};
3223
John Zulauf1d27e0a2018-11-05 10:12:48 -07003224// Loop through the write updates to validate for a push descriptor set, ignoring dstSet
John Zulaufc93c4252019-06-25 09:19:49 -06003225bool CoreChecks::ValidatePushDescriptorsUpdate(const DescriptorSet *push_set, uint32_t write_count,
John Zulaufbd9b3412019-08-22 17:16:11 -06003226 const VkWriteDescriptorSet *p_wds, const char *func_name) const {
John Zulaufd9435c32019-06-05 15:55:36 -06003227 assert(push_set->IsPushDescriptor());
John Zulauf1d27e0a2018-11-05 10:12:48 -07003228 bool skip = false;
3229 for (uint32_t i = 0; i < write_count; i++) {
3230 std::string error_code;
3231 std::string error_str;
ziga-lunarg6c46b242021-09-13 18:33:37 +02003232 if (!ValidateWriteUpdate(push_set, &p_wds[i], func_name, &error_code, &error_str, true)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08003233 skip |= LogError(push_set->GetDescriptorSetLayout(), error_code,
3234 "%s VkWriteDescriptorSet[%u] failed update validation: %s.", func_name, i, error_str.c_str());
John Zulauf1d27e0a2018-11-05 10:12:48 -07003235 }
3236 }
3237 return skip;
3238}
3239
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06003240// For the given buffer, verify that its creation parameters are appropriate for the given type
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003241// 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 -06003242bool cvdescriptorset::ValidateBufferUsage(debug_report_data *report_data, BUFFER_STATE const *buffer_node, VkDescriptorType type,
3243 std::string *error_code, std::string *error_msg) {
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06003244 // Verify that usage bits set correctly for given type
Tobin Ehlis94bc5d22016-06-02 07:46:52 -06003245 auto usage = buffer_node->createInfo.usage;
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06003246 const char *error_usage_bit = nullptr;
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06003247 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003248 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3249 if (!(usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003250 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00334";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003251 error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT";
3252 }
3253 break;
3254 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
3255 if (!(usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003256 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00335";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003257 error_usage_bit = "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT";
3258 }
3259 break;
3260 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3261 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3262 if (!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003263 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00330";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003264 error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT";
3265 }
3266 break;
3267 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3268 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
3269 if (!(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003270 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00331";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003271 error_usage_bit = "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT";
3272 }
3273 break;
3274 default:
3275 break;
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06003276 }
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06003277 if (error_usage_bit) {
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06003278 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003279 error_str << "Buffer (" << report_data->FormatHandle(buffer_node->buffer()) << ") with usage mask " << std::hex
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003280 << std::showbase << usage << " being used for a descriptor update of type " << string_VkDescriptorType(type)
3281 << " does not have " << error_usage_bit << " set.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003282 *error_msg = error_str.str();
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06003283 return false;
3284 }
3285 return true;
3286}
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003287// For buffer descriptor updates, verify the buffer usage and VkDescriptorBufferInfo struct which includes:
3288// 1. buffer is valid
3289// 2. buffer was created with correct usage flags
3290// 3. offset is less than buffer size
3291// 4. range is either VK_WHOLE_SIZE or falls in (0, (buffer size - offset)]
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003292// 5. range and offset are within the device's limits
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003293// 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 -06003294bool CoreChecks::ValidateBufferUpdate(VkDescriptorBufferInfo const *buffer_info, VkDescriptorType type, const char *func_name,
John Zulaufbd9b3412019-08-22 17:16:11 -06003295 std::string *error_code, std::string *error_msg) const {
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003296 // First make sure that buffer is valid
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003297 auto buffer_node = Get<BUFFER_STATE>(buffer_info->buffer);
Tobin Ehlisfa8b6182016-12-22 13:40:45 -07003298 // Any invalid buffer should already be caught by object_tracker
3299 assert(buffer_node);
Jeremy Gebben9f537102021-10-05 16:37:12 -06003300 if (ValidateMemoryIsBoundToBuffer(buffer_node.get(), func_name, "VUID-VkWriteDescriptorSet-descriptorType-00329")) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003301 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00329";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003302 *error_msg = "No memory bound to buffer.";
Tobin Ehlis81280962016-07-20 14:04:20 -06003303 return false;
Tobin Ehlisfed999f2016-09-21 15:09:45 -06003304 }
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003305 // Verify usage bits
Jeremy Gebben9f537102021-10-05 16:37:12 -06003306 if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_node.get(), type, error_code, error_msg)) {
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003307 // error_msg will have been updated by ValidateBufferUsage()
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003308 return false;
3309 }
3310 // offset must be less than buffer size
Jeremy Hayesd1a6a822017-03-09 14:39:45 -07003311 if (buffer_info->offset >= buffer_node->createInfo.size) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003312 *error_code = "VUID-VkDescriptorBufferInfo-offset-00340";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003313 std::stringstream error_str;
Jeremy Hayesd1a6a822017-03-09 14:39:45 -07003314 error_str << "VkDescriptorBufferInfo offset of " << buffer_info->offset << " is greater than or equal to buffer "
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003315 << report_data->FormatHandle(buffer_node->buffer()) << " size of " << buffer_node->createInfo.size;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003316 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003317 return false;
3318 }
3319 if (buffer_info->range != VK_WHOLE_SIZE) {
3320 // Range must be VK_WHOLE_SIZE or > 0
3321 if (!buffer_info->range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003322 *error_code = "VUID-VkDescriptorBufferInfo-range-00341";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003323 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003324 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003325 << " VkDescriptorBufferInfo range is not VK_WHOLE_SIZE and is zero, which is not allowed.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003326 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003327 return false;
3328 }
3329 // Range must be VK_WHOLE_SIZE or <= (buffer size - offset)
3330 if (buffer_info->range > (buffer_node->createInfo.size - buffer_info->offset)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003331 *error_code = "VUID-VkDescriptorBufferInfo-range-00342";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003332 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003333 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer()) << " VkDescriptorBufferInfo range is "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003334 << buffer_info->range << " which is greater than buffer size (" << buffer_node->createInfo.size
3335 << ") minus requested offset of " << buffer_info->offset;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003336 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003337 return false;
3338 }
3339 }
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003340 // Check buffer update sizes against device limits
John Zulaufc93c4252019-06-25 09:19:49 -06003341 const auto &limits = phys_dev_props.limits;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003342 if (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type || VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC == type) {
John Zulaufd9435c32019-06-05 15:55:36 -06003343 auto max_ub_range = limits.maxUniformBufferRange;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003344 if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_ub_range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003345 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00332";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003346 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003347 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer()) << " VkDescriptorBufferInfo range is "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003348 << buffer_info->range << " which is greater than this device's maxUniformBufferRange (" << max_ub_range
3349 << ")";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003350 *error_msg = error_str.str();
3351 return false;
Peter Kohaut2794a292018-07-13 11:13:47 +02003352 } else if (buffer_info->range == VK_WHOLE_SIZE && (buffer_node->createInfo.size - buffer_info->offset) > max_ub_range) {
3353 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00332";
3354 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003355 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003356 << " VkDescriptorBufferInfo range is VK_WHOLE_SIZE but effective range "
Peter Kohaut18f413d2018-07-16 13:15:42 +02003357 << "(" << (buffer_node->createInfo.size - buffer_info->offset) << ") is greater than this device's "
Peter Kohaut2794a292018-07-13 11:13:47 +02003358 << "maxUniformBufferRange (" << max_ub_range << ")";
3359 *error_msg = error_str.str();
3360 return false;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003361 }
3362 } else if (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == type || VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC == type) {
John Zulaufd9435c32019-06-05 15:55:36 -06003363 auto max_sb_range = limits.maxStorageBufferRange;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003364 if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_sb_range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003365 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00333";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003366 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003367 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer()) << " VkDescriptorBufferInfo range is "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003368 << buffer_info->range << " which is greater than this device's maxStorageBufferRange (" << max_sb_range
3369 << ")";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003370 *error_msg = error_str.str();
3371 return false;
Peter Kohaut2794a292018-07-13 11:13:47 +02003372 } else if (buffer_info->range == VK_WHOLE_SIZE && (buffer_node->createInfo.size - buffer_info->offset) > max_sb_range) {
3373 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00333";
3374 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003375 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003376 << " VkDescriptorBufferInfo range is VK_WHOLE_SIZE but effective range "
Peter Kohaut18f413d2018-07-16 13:15:42 +02003377 << "(" << (buffer_node->createInfo.size - buffer_info->offset) << ") is greater than this device's "
Peter Kohaut2794a292018-07-13 11:13:47 +02003378 << "maxStorageBufferRange (" << max_sb_range << ")";
3379 *error_msg = error_str.str();
3380 return false;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07003381 }
3382 }
Tobin Ehlis3d38f082016-07-01 17:36:48 -06003383 return true;
3384}
sourav parmarcd5fb182020-07-17 12:58:44 -07003385template <typename T>
3386bool CoreChecks::ValidateAccelerationStructureUpdate(T acc_node, const char *func_name, std::string *error_code,
Jeff Bolz95176d02020-04-01 00:36:16 -05003387 std::string *error_msg) const {
ziga-lunarg5f3a0912021-11-06 19:18:45 +01003388 // nullDescriptor feature allows this to be VK_NULL_HANDLE
3389 if (acc_node) {
3390 if (ValidateMemoryIsBoundToAccelerationStructure(acc_node, func_name, kVUIDUndefined)) {
3391 *error_code = kVUIDUndefined;
3392 *error_msg = "No memory bound to acceleration structure.";
3393 return false;
3394 }
Jeff Bolz95176d02020-04-01 00:36:16 -05003395 }
3396 return true;
3397}
3398
Tobin Ehlis300888c2016-05-18 13:43:26 -06003399// Verify that the contents of the update are ok, but don't perform actual update
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003400bool CoreChecks::VerifyCopyUpdateContents(const VkCopyDescriptorSet *update, const DescriptorSet *src_set,
3401 VkDescriptorType src_type, uint32_t src_index, const DescriptorSet *dst_set,
3402 VkDescriptorType dst_type, uint32_t dst_index, const char *func_name,
3403 std::string *error_code, std::string *error_msg) const {
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06003404 // Note : Repurposing some Write update error codes here as specific details aren't called out for copy updates like they are
3405 // for write updates
John Zulaufc93c4252019-06-25 09:19:49 -06003406 using DescriptorClass = cvdescriptorset::DescriptorClass;
3407 using BufferDescriptor = cvdescriptorset::BufferDescriptor;
3408 using ImageDescriptor = cvdescriptorset::ImageDescriptor;
3409 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
3410 using SamplerDescriptor = cvdescriptorset::SamplerDescriptor;
3411 using TexelDescriptor = cvdescriptorset::TexelDescriptor;
3412
3413 auto device_data = this;
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003414
3415 if (dst_type == VK_DESCRIPTOR_TYPE_SAMPLER) {
3416 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3417 const auto dst_desc = dst_set->GetDescriptorFromGlobalIndex(dst_index + di);
3418 if (!dst_desc->updated) continue;
3419 if (dst_desc->IsImmutableSampler()) {
3420 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02753";
3421 std::stringstream error_str;
3422 error_str << "Attempted copy update to an immutable sampler descriptor.";
3423 *error_msg = error_str.str();
3424 return false;
3425 }
3426 }
3427 }
3428
3429 switch (src_set->GetDescriptorFromGlobalIndex(src_index)->descriptor_class) {
John Zulaufc93c4252019-06-25 09:19:49 -06003430 case DescriptorClass::PlainSampler: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003431 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003432 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003433 if (!src_desc->updated) continue;
3434 if (!src_desc->IsImmutableSampler()) {
John Zulaufd9435c32019-06-05 15:55:36 -06003435 auto update_sampler = static_cast<const SamplerDescriptor *>(src_desc)->GetSampler();
John Zulaufc93c4252019-06-25 09:19:49 -06003436 if (!ValidateSampler(update_sampler)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003437 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003438 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003439 error_str << "Attempted copy update to sampler descriptor with invalid sampler: "
3440 << report_data->FormatHandle(update_sampler) << ".";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003441 *error_msg = error_str.str();
3442 return false;
3443 }
3444 } else {
3445 // TODO : Warn here
3446 }
3447 }
3448 break;
3449 }
John Zulaufc93c4252019-06-25 09:19:49 -06003450 case DescriptorClass::ImageSampler: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003451 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003452 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003453 if (!src_desc->updated) continue;
3454 auto img_samp_desc = static_cast<const ImageSamplerDescriptor *>(src_desc);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003455 // First validate sampler
3456 if (!img_samp_desc->IsImmutableSampler()) {
3457 auto update_sampler = img_samp_desc->GetSampler();
John Zulaufc93c4252019-06-25 09:19:49 -06003458 if (!ValidateSampler(update_sampler)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06003459 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003460 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003461 error_str << "Attempted copy update to sampler descriptor with invalid sampler: "
3462 << report_data->FormatHandle(update_sampler) << ".";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003463 *error_msg = error_str.str();
3464 return false;
3465 }
3466 } else {
3467 // TODO : Warn here
3468 }
3469 // Validate image
3470 auto image_view = img_samp_desc->GetImageView();
3471 auto image_layout = img_samp_desc->GetImageLayout();
Jeff Bolz165818a2020-05-08 11:19:03 -05003472 if (image_view) {
3473 if (!ValidateImageUpdate(image_view, image_layout, src_type, func_name, error_code, error_msg)) {
3474 std::stringstream error_str;
3475 error_str << "Attempted copy update to combined image sampler descriptor failed due to: "
3476 << error_msg->c_str();
3477 *error_msg = error_str.str();
3478 return false;
3479 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003480 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003481 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003482 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003483 }
John Zulaufc93c4252019-06-25 09:19:49 -06003484 case DescriptorClass::Image: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003485 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003486 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003487 if (!src_desc->updated) continue;
3488 auto img_desc = static_cast<const ImageDescriptor *>(src_desc);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003489 auto image_view = img_desc->GetImageView();
3490 auto image_layout = img_desc->GetImageLayout();
Jeff Bolz165818a2020-05-08 11:19:03 -05003491 if (image_view) {
3492 if (!ValidateImageUpdate(image_view, image_layout, src_type, func_name, error_code, error_msg)) {
3493 std::stringstream error_str;
3494 error_str << "Attempted copy update to image descriptor failed due to: " << error_msg->c_str();
3495 *error_msg = error_str.str();
3496 return false;
3497 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003498 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003499 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003500 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003501 }
John Zulaufc93c4252019-06-25 09:19:49 -06003502 case DescriptorClass::TexelBuffer: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003503 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003504 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003505 if (!src_desc->updated) continue;
John Zulaufd9435c32019-06-05 15:55:36 -06003506 auto buffer_view = static_cast<const TexelDescriptor *>(src_desc)->GetBufferView();
Jeff Bolz165818a2020-05-08 11:19:03 -05003507 if (buffer_view) {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003508 auto bv_state = device_data->Get<BUFFER_VIEW_STATE>(buffer_view);
Jeff Bolz165818a2020-05-08 11:19:03 -05003509 if (!bv_state) {
3510 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
3511 std::stringstream error_str;
3512 error_str << "Attempted copy update to texel buffer descriptor with invalid buffer view: "
3513 << report_data->FormatHandle(buffer_view);
3514 *error_msg = error_str.str();
3515 return false;
3516 }
3517 auto buffer = bv_state->create_info.buffer;
Jeremy Gebben9f537102021-10-05 16:37:12 -06003518 auto buffer_state = Get<BUFFER_STATE>(buffer);
3519 if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_state.get(), src_type, error_code, error_msg)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003520 std::stringstream error_str;
3521 error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error_msg->c_str();
3522 *error_msg = error_str.str();
3523 return false;
3524 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003525 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06003526 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003527 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003528 }
John Zulaufc93c4252019-06-25 09:19:49 -06003529 case DescriptorClass::GeneralBuffer: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003530 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003531 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02003532 if (!src_desc->updated) continue;
Jeremy Gebben9f537102021-10-05 16:37:12 -06003533 auto buffer_state = static_cast<const BufferDescriptor *>(src_desc)->GetBufferState();
3534 if (buffer_state) {
3535 if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_state, src_type, error_code, error_msg)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003536 std::stringstream error_str;
3537 error_str << "Attempted copy update to buffer descriptor failed due to: " << error_msg->c_str();
3538 *error_msg = error_str.str();
3539 return false;
3540 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003541 }
Tobin Ehliscbcf2342016-05-24 13:07:12 -06003542 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003543 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003544 }
John Zulaufc93c4252019-06-25 09:19:49 -06003545 case DescriptorClass::InlineUniform:
3546 case DescriptorClass::AccelerationStructure:
Ricardo Garcia14f4f762021-04-13 11:36:12 +02003547 case DescriptorClass::Mutable:
Jeff Bolze54ae892018-09-08 12:16:29 -05003548 break;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07003549 default:
3550 assert(0); // We've already verified update type so should never get here
3551 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06003552 }
3553 // All checks passed so update contents are good
3554 return true;
Chris Forbesb4e0bdb2016-05-31 16:34:40 +12003555}
Tobin Ehlisee471462016-05-26 11:21:59 -06003556// Verify that the state at allocate time is correct, but don't actually allocate the sets yet
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07003557bool CoreChecks::ValidateAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05003558 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) const {
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06003559 bool skip = false;
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003560 auto pool_state = Get<DESCRIPTOR_POOL_STATE>(p_alloc_info->descriptorPool);
Tobin Ehlisee471462016-05-26 11:21:59 -06003561
3562 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeremy Gebben9f537102021-10-05 16:37:12 -06003563 auto layout = Get<cvdescriptorset::DescriptorSetLayout>(p_alloc_info->pSetLayouts[i]);
John Zulauf5562d062018-01-24 11:54:05 -07003564 if (layout) { // nullptr layout indicates no valid layout handle for this device, validated/logged in object_tracker
John Zulauf1d27e0a2018-11-05 10:12:48 -07003565 if (layout->IsPushDescriptor()) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003566 skip |= LogError(p_alloc_info->pSetLayouts[i], "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-00308",
3567 "%s specified at pSetLayouts[%" PRIu32
3568 "] in vkAllocateDescriptorSets() was created with invalid flag %s set.",
3569 report_data->FormatHandle(p_alloc_info->pSetLayouts[i]).c_str(), i,
3570 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR");
John Zulauf5562d062018-01-24 11:54:05 -07003571 }
Mike Schuchardt2df08912020-12-15 16:28:09 -08003572 if (layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT &&
3573 !(pool_state->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08003574 skip |= LogError(
3575 device, "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-03044",
3576 "vkAllocateDescriptorSets(): Descriptor set layout create flags and pool create flags mismatch for index (%d)",
3577 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003578 }
ziga-lunarg2ab96532021-07-19 11:06:41 +02003579 if (layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE &&
3580 !(pool_state->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) {
3581 skip |= LogError(device, "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-04610",
3582 "vkAllocateDescriptorSets(): pSetLayouts[%d].flags contain "
3583 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE bit, but the pool was not created "
3584 "with the VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE bit.",
3585 i);
3586 }
Tobin Ehlisee471462016-05-26 11:21:59 -06003587 }
3588 }
sfricke-samsung45996a42021-09-16 13:45:27 -07003589 if (!IsExtEnabled(device_extensions.vk_khr_maintenance1)) {
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06003590 // Track number of descriptorSets allowable in this pool
Jeremy Gebben0d9143e2022-01-01 12:29:36 -07003591 if (pool_state->GetAvailableSets() < p_alloc_info->descriptorSetCount) {
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003592 skip |= LogError(pool_state->Handle(), "VUID-VkDescriptorSetAllocateInfo-descriptorSetCount-00306",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003593 "vkAllocateDescriptorSets(): Unable to allocate %u descriptorSets from %s"
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003594 ". This pool only has %d descriptorSets remaining.",
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003595 p_alloc_info->descriptorSetCount, report_data->FormatHandle(pool_state->Handle()).c_str(),
Jeremy Gebben0d9143e2022-01-01 12:29:36 -07003596 pool_state->GetAvailableSets());
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06003597 }
3598 // Determine whether descriptor counts are satisfiable
Jeff Bolze54ae892018-09-08 12:16:29 -05003599 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
Jeremy Gebben0d9143e2022-01-01 12:29:36 -07003600 auto available_count = pool_state->GetAvailableCount(it->first);
Jeff Bolz46c0ea02019-10-09 13:06:29 -05003601
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003602 if (ds_data->required_descriptors_by_type.at(it->first) > available_count) {
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003603 skip |= LogError(pool_state->Handle(), "VUID-VkDescriptorSetAllocateInfo-descriptorPool-00307",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003604 "vkAllocateDescriptorSets(): Unable to allocate %u descriptors of type %s from %s"
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003605 ". This pool only has %d descriptors of this type remaining.",
3606 ds_data->required_descriptors_by_type.at(it->first),
3607 string_VkDescriptorType(VkDescriptorType(it->first)),
Jeremy Gebben1fbebb82021-10-27 10:27:27 -06003608 report_data->FormatHandle(pool_state->Handle()).c_str(), available_count);
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06003609 }
Tobin Ehlisee471462016-05-26 11:21:59 -06003610 }
3611 }
Tobin Ehlis5d749ea2016-07-18 13:14:01 -06003612
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003613 const auto *count_allocate_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(p_alloc_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003614
3615 if (count_allocate_info) {
3616 if (count_allocate_info->descriptorSetCount != 0 &&
3617 count_allocate_info->descriptorSetCount != p_alloc_info->descriptorSetCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003618 skip |= LogError(device, "VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-descriptorSetCount-03045",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003619 "vkAllocateDescriptorSets(): VkDescriptorSetAllocateInfo::descriptorSetCount (%d) != "
Mike Schuchardt2df08912020-12-15 16:28:09 -08003620 "VkDescriptorSetVariableDescriptorCountAllocateInfo::descriptorSetCount (%d)",
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003621 p_alloc_info->descriptorSetCount, count_allocate_info->descriptorSetCount);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003622 }
3623 if (count_allocate_info->descriptorSetCount == p_alloc_info->descriptorSetCount) {
3624 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003625 auto layout = Get<cvdescriptorset::DescriptorSetLayout>(p_alloc_info->pSetLayouts[i]);
Jeff Bolzfdf96072018-04-10 14:32:18 -05003626 if (count_allocate_info->pDescriptorCounts[i] > layout->GetDescriptorCountFromBinding(layout->GetMaxBinding())) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003627 skip |= LogError(device, "VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-pSetLayouts-03046",
sfricke-samsungbda4a852021-03-06 20:58:01 -08003628 "vkAllocateDescriptorSets(): pDescriptorCounts[%d] = (%d), binding's descriptorCount = (%d)",
3629 i, count_allocate_info->pDescriptorCounts[i],
Mark Lobodzinskid18de902020-01-15 12:20:37 -07003630 layout->GetDescriptorCountFromBinding(layout->GetMaxBinding()));
Jeff Bolzfdf96072018-04-10 14:32:18 -05003631 }
3632 }
3633 }
3634 }
3635
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06003636 return skip;
Tobin Ehlisee471462016-05-26 11:21:59 -06003637}
John Zulauf48a6a702017-12-22 17:14:54 -07003638
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05003639const BindingReqMap &cvdescriptorset::PrefilterBindRequestMap::FilteredMap(const CMD_BUFFER_STATE &cb_state,
3640 const PIPELINE_STATE &pipeline) {
John Zulauffbf3c202019-07-17 14:57:14 -06003641 if (IsManyDescriptors()) {
Karl Schultz7090a052020-11-10 08:54:21 -07003642 filtered_map_.reset(new BindingReqMap);
John Zulauffbf3c202019-07-17 14:57:14 -06003643 descriptor_set_.FilterBindingReqs(cb_state, pipeline, orig_map_, filtered_map_.get());
3644 return *filtered_map_;
John Zulauf48a6a702017-12-22 17:14:54 -07003645 }
John Zulauffbf3c202019-07-17 14:57:14 -06003646 return orig_map_;
Artem Kharytoniuk2456f992018-01-12 14:17:41 +01003647}
John Zulauf4a015c92019-06-04 09:50:05 -06003648
3649// Starting at offset descriptor of given binding, parse over update_count
3650// descriptor updates and verify that for any binding boundaries that are crossed, the next binding(s) are all consistent
3651// Consistency means that their type, stage flags, and whether or not they use immutable samplers matches
3652// If so, return true. If not, fill in error_msg and return false
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003653bool cvdescriptorset::VerifyUpdateConsistency(debug_report_data *report_data,
3654 DescriptorSetLayout::ConstBindingIterator current_binding, uint32_t offset,
John Zulauf4a015c92019-06-04 09:50:05 -06003655 uint32_t update_count, const char *type, const VkDescriptorSet set,
3656 std::string *error_msg) {
locke-lunarge46b7782019-09-10 01:44:20 -06003657 bool pass = true;
John Zulauf4a015c92019-06-04 09:50:05 -06003658 // Verify consecutive bindings match (if needed)
3659 auto orig_binding = current_binding;
locke-lunarge46b7782019-09-10 01:44:20 -06003660
3661 while (pass && update_count) {
3662 // First, it's legal to offset beyond your own binding so handle that case
3663 if (offset > 0) {
3664 const auto &index_range = current_binding.GetGlobalIndexRange();
3665 // index_range.start + offset is which descriptor is needed to update. If it > index_range.end, it means the descriptor
3666 // isn't in this binding, maybe in next binding.
3667 if ((index_range.start + offset) >= index_range.end) {
3668 // Advance to next binding, decrement offset by binding size
3669 offset -= current_binding.GetDescriptorCount();
3670 ++current_binding;
3671 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
3672 if (!orig_binding.IsConsistent(current_binding)) {
3673 pass = false;
3674 }
3675 continue;
John Zulauf4a015c92019-06-04 09:50:05 -06003676 }
John Zulauf4a015c92019-06-04 09:50:05 -06003677 }
locke-lunarge46b7782019-09-10 01:44:20 -06003678
3679 update_count -= std::min(update_count, current_binding.GetDescriptorCount() - offset);
3680 if (update_count) {
3681 // Starting offset is beyond the current binding. Check consistency, update counters and advance to the next binding,
3682 // looking for the start point. All bindings (even those skipped) must be consistent with the update and with the
3683 // original binding.
3684 offset = 0;
3685 ++current_binding;
3686 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
3687 if (!orig_binding.IsConsistent(current_binding)) {
3688 pass = false;
3689 }
3690 }
John Zulauf4a015c92019-06-04 09:50:05 -06003691 }
locke-lunarge46b7782019-09-10 01:44:20 -06003692
3693 if (!pass) {
3694 std::stringstream error_str;
3695 error_str << "Attempting " << type;
3696 if (current_binding.Layout()->IsPushDescriptor()) {
3697 error_str << " push descriptors";
3698 } else {
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003699 error_str << " descriptor set " << report_data->FormatHandle(set);
locke-lunarge46b7782019-09-10 01:44:20 -06003700 }
3701 error_str << " binding #" << orig_binding.Binding() << " with #" << update_count
3702 << " descriptors being updated but this update oversteps the bounds of this binding and the next binding is "
sfricke-samsung5de34882021-04-15 22:33:23 -07003703 "not consistent with current binding";
3704
3705 // Get what was not consistent in IsConsistent() as a more detailed error message
3706 const auto *binding_ci = orig_binding.GetDescriptorSetLayoutBindingPtr();
3707 const auto *other_binding_ci = current_binding.GetDescriptorSetLayoutBindingPtr();
3708 if (binding_ci == nullptr || other_binding_ci == nullptr) {
3709 error_str << " (No two valid DescriptorSetLayoutBinding to compare)";
3710 } else if (binding_ci->descriptorType != other_binding_ci->descriptorType) {
3711 error_str << " (" << string_VkDescriptorType(binding_ci->descriptorType)
3712 << " != " << string_VkDescriptorType(other_binding_ci->descriptorType) << ")";
3713 } else if (binding_ci->stageFlags != other_binding_ci->stageFlags) {
3714 error_str << " (" << string_VkShaderStageFlags(binding_ci->stageFlags)
3715 << " != " << string_VkShaderStageFlags(other_binding_ci->stageFlags) << ")";
3716 } else if (!hash_util::similar_for_nullity(binding_ci->pImmutableSamplers, other_binding_ci->pImmutableSamplers)) {
3717 error_str << " (pImmutableSamplers don't match)";
3718 } else if (orig_binding.GetDescriptorBindingFlags() != current_binding.GetDescriptorBindingFlags()) {
3719 error_str << " (" << string_VkDescriptorBindingFlags(orig_binding.GetDescriptorBindingFlags())
3720 << " != " << string_VkDescriptorBindingFlags(current_binding.GetDescriptorBindingFlags()) << ")";
3721 }
3722
3723 error_str << " so this update is invalid";
locke-lunarge46b7782019-09-10 01:44:20 -06003724 *error_msg = error_str.str();
3725 }
3726 return pass;
John Zulauf4a015c92019-06-04 09:50:05 -06003727}
John Zulauf4956fff2019-06-04 16:54:38 -06003728
3729// Validate the state for a given write update but don't actually perform the update
3730// 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 -06003731bool CoreChecks::ValidateWriteUpdate(const DescriptorSet *dest_set, const VkWriteDescriptorSet *update, const char *func_name,
ziga-lunarg6c46b242021-09-13 18:33:37 +02003732 std::string *error_code, std::string *error_msg, bool push) const {
Jeremy Gebben9d0dda32022-01-28 10:16:56 -07003733 const auto *dest_layout = dest_set->GetLayout().get();
John Zulauf4956fff2019-06-04 16:54:38 -06003734
3735 // Verify dst layout still valid
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003736 if (dest_layout->Destroyed()) {
John Zulauf4956fff2019-06-04 16:54:38 -06003737 *error_code = "VUID-VkWriteDescriptorSet-dstSet-00320";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06003738 std::ostringstream str;
3739 str << "Cannot call " << func_name << " to perform write update on " << dest_set->StringifySetAndLayout()
3740 << " which has been destroyed";
3741 *error_msg = str.str();
John Zulauf4956fff2019-06-04 16:54:38 -06003742 return false;
3743 }
3744 // Verify dst binding exists
3745 if (!dest_layout->HasBinding(update->dstBinding)) {
3746 *error_code = "VUID-VkWriteDescriptorSet-dstBinding-00315";
3747 std::stringstream error_str;
3748 error_str << dest_set->StringifySetAndLayout() << " does not have binding " << update->dstBinding;
3749 *error_msg = error_str.str();
3750 return false;
3751 }
3752
Jeff Bolz6aad1742019-10-16 11:10:09 -05003753 DescriptorSetLayout::ConstBindingIterator dest(dest_layout, update->dstBinding);
John Zulauf4956fff2019-06-04 16:54:38 -06003754 // Make sure binding isn't empty
3755 if (0 == dest.GetDescriptorCount()) {
3756 *error_code = "VUID-VkWriteDescriptorSet-dstBinding-00316";
3757 std::stringstream error_str;
3758 error_str << dest_set->StringifySetAndLayout() << " cannot updated binding " << update->dstBinding
3759 << " that has 0 descriptors";
3760 *error_msg = error_str.str();
3761 return false;
3762 }
3763
3764 // Verify idle ds
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06003765 if (dest_set->InUse() && !(dest.GetDescriptorBindingFlags() & (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT |
Mike Schuchardt2df08912020-12-15 16:28:09 -08003766 VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
aitor-lunarg9f859002022-01-27 19:33:35 +01003767 *error_code = "VUID-vkUpdateDescriptorSets-None-03047";
John Zulauf4956fff2019-06-04 16:54:38 -06003768 std::stringstream error_str;
3769 error_str << "Cannot call " << func_name << " to perform write update on " << dest_set->StringifySetAndLayout()
3770 << " that is in use by a command buffer";
3771 *error_msg = error_str.str();
3772 return false;
3773 }
3774 // We know that binding is valid, verify update and do update on each descriptor
3775 auto start_idx = dest.GetGlobalIndexRange().start + update->dstArrayElement;
3776 auto type = dest.GetType();
Tony-LunarGf563b362021-03-18 16:13:18 -06003777 if ((type != VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) && (type != update->descriptorType)) {
John Zulauf4956fff2019-06-04 16:54:38 -06003778 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00319";
3779 std::stringstream error_str;
3780 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3781 << " with type " << string_VkDescriptorType(type) << " but update type is "
3782 << string_VkDescriptorType(update->descriptorType);
3783 *error_msg = error_str.str();
3784 return false;
3785 }
John Zulauf4956fff2019-06-04 16:54:38 -06003786 if (type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
3787 if ((update->dstArrayElement % 4) != 0) {
3788 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02219";
3789 std::stringstream error_str;
3790 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3791 << " with "
3792 << "dstArrayElement " << update->dstArrayElement << " not a multiple of 4";
3793 *error_msg = error_str.str();
3794 return false;
3795 }
3796 if ((update->descriptorCount % 4) != 0) {
3797 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02220";
3798 std::stringstream error_str;
3799 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3800 << " with "
3801 << "descriptorCount " << update->descriptorCount << " not a multiple of 4";
3802 *error_msg = error_str.str();
3803 return false;
3804 }
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003805 const auto *write_inline_info = LvlFindInChain<VkWriteDescriptorSetInlineUniformBlockEXT>(update->pNext);
John Zulauf4956fff2019-06-04 16:54:38 -06003806 if (!write_inline_info || write_inline_info->dataSize != update->descriptorCount) {
3807 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02221";
3808 std::stringstream error_str;
3809 if (!write_inline_info) {
3810 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #"
3811 << update->dstBinding << " with "
Tony-LunarG836ea5b2021-12-07 10:07:17 -07003812 << "VkWriteDescriptorSetInlineUniformBlock missing";
John Zulauf4956fff2019-06-04 16:54:38 -06003813 } else {
3814 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #"
3815 << update->dstBinding << " with "
Tony-LunarG836ea5b2021-12-07 10:07:17 -07003816 << "VkWriteDescriptorSetInlineUniformBlock dataSize " << write_inline_info->dataSize
John Zulauf4956fff2019-06-04 16:54:38 -06003817 << " not equal to "
3818 << "VkWriteDescriptorSet descriptorCount " << update->descriptorCount;
3819 }
3820 *error_msg = error_str.str();
3821 return false;
3822 }
3823 // This error is probably unreachable due to the previous two errors
3824 if (write_inline_info && (write_inline_info->dataSize % 4) != 0) {
Tony-LunarG836ea5b2021-12-07 10:07:17 -07003825 *error_code = "VUID-VkWriteDescriptorSetInlineUniformBlock-dataSize-02222";
John Zulauf4956fff2019-06-04 16:54:38 -06003826 std::stringstream error_str;
3827 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3828 << " with "
Tony-LunarG836ea5b2021-12-07 10:07:17 -07003829 << "VkWriteDescriptorSetInlineUniformBlock dataSize " << write_inline_info->dataSize
John Zulauf4956fff2019-06-04 16:54:38 -06003830 << " not a multiple of 4";
3831 *error_msg = error_str.str();
3832 return false;
3833 }
3834 }
sfricke-samsung941d48b2020-02-10 00:20:01 -08003835 // Verify all bindings update share identical properties across all items
3836 if (update->descriptorCount > 0) {
3837 // Save first binding information and error if something different is found
3838 DescriptorSetLayout::ConstBindingIterator current_binding(dest_layout, update->dstBinding);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003839 VkShaderStageFlags stage_flags = current_binding.GetStageFlags();
3840 VkDescriptorType descriptor_type = current_binding.GetType();
3841 bool immutable_samplers = (current_binding.GetImmutableSamplerPtr() == nullptr);
3842 uint32_t dst_array_element = update->dstArrayElement;
sfricke-samsung941d48b2020-02-10 00:20:01 -08003843
Jeff Bolz9198e882020-03-18 13:03:30 -05003844 for (uint32_t i = 0; i < update->descriptorCount;) {
sfricke-samsung941d48b2020-02-10 00:20:01 -08003845 if (current_binding.AtEnd() == true) {
3846 break; // prevents setting error here if bindings don't exist
3847 }
3848
Quentin Huot-Marchand98d84dd2021-06-24 09:54:58 +02003849 // All consecutive bindings updated, except those with a descriptorCount of zero, must have identical descType and stageFlags
3850 if(current_binding.GetDescriptorCount() > 0) {
3851 // Check for consistent stageFlags and descriptorType
3852 if ((current_binding.GetStageFlags() != stage_flags) || (current_binding.GetType() != descriptor_type)) {
3853 *error_code = "VUID-VkWriteDescriptorSet-descriptorCount-00317";
3854 std::stringstream error_str;
3855 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3856 << current_binding.GetIndex() << " (" << i << " from dstBinding offset)"
3857 << " with a different stageFlag and/or descriptorType from previous bindings."
3858 << " All bindings must have consecutive stageFlag and/or descriptorType across a VkWriteDescriptorSet";
3859 *error_msg = error_str.str();
3860 return false;
3861 }
3862 // Check if all immutableSamplers or not
3863 if ((current_binding.GetImmutableSamplerPtr() == nullptr) != immutable_samplers) {
3864 *error_code = "VUID-VkWriteDescriptorSet-descriptorCount-00318";
3865 std::stringstream error_str;
3866 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3867 << current_binding.GetIndex() << " (" << i << " from dstBinding offset)"
3868 << " with a different usage of immutable samplers from previous bindings."
3869 << " All bindings must have all or none usage of immutable samplers across a VkWriteDescriptorSet";
3870 *error_msg = error_str.str();
3871 return false;
3872 }
sfricke-samsung941d48b2020-02-10 00:20:01 -08003873 }
Jeff Bolz9198e882020-03-18 13:03:30 -05003874
3875 // Skip the remaining descriptors for this binding, and move to the next binding
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003876 i += (current_binding.GetDescriptorCount() - dst_array_element);
3877 dst_array_element = 0;
sfricke-samsung941d48b2020-02-10 00:20:01 -08003878 ++current_binding;
3879 }
3880 }
3881
John Zulauf4956fff2019-06-04 16:54:38 -06003882 // Verify consecutive bindings match (if needed)
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003883 if (!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(dest_layout, update->dstBinding),
John Zulauf4956fff2019-06-04 16:54:38 -06003884 update->dstArrayElement, update->descriptorCount, "write update to", dest_set->GetSet(),
3885 error_msg)) {
John Zulauf4956fff2019-06-04 16:54:38 -06003886 *error_code = "VUID-VkWriteDescriptorSet-dstArrayElement-00321";
3887 return false;
3888 }
Tony-LunarG1f79c952020-10-27 15:55:51 -06003889 // Verify write to variable descriptor
3890 if (dest_set->IsVariableDescriptorCount(update->dstBinding)) {
3891 if ((update->dstArrayElement + update->descriptorCount) > dest_set->GetVariableDescriptorCount()) {
3892 std::stringstream error_str;
3893 *error_code = "VUID-VkWriteDescriptorSet-dstArrayElement-00321";
3894 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3895 << update->dstBinding << " array element " << update->dstArrayElement << " with " << update->descriptorCount
3896 << " writes but variable descriptor size is " << dest_set->GetVariableDescriptorCount();
3897 *error_msg = error_str.str();
3898 return false;
3899 }
3900 }
John Zulauf4956fff2019-06-04 16:54:38 -06003901 // Update is within bounds and consistent so last step is to validate update contents
ziga-lunarg6c46b242021-09-13 18:33:37 +02003902 if (!VerifyWriteUpdateContents(dest_set, update, start_idx, func_name, error_code, error_msg, push)) {
John Zulauf4956fff2019-06-04 16:54:38 -06003903 std::stringstream error_str;
3904 error_str << "Write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3905 << " failed with error message: " << error_msg->c_str();
3906 *error_msg = error_str.str();
3907 return false;
3908 }
ziga-lunargd67b5f52021-10-16 23:52:59 +02003909 const auto orig_binding = DescriptorSetLayout::ConstBindingIterator(dest_set->GetLayout().get(), update->dstBinding);
3910 if (!orig_binding.AtEnd() && orig_binding.GetType() == VK_DESCRIPTOR_TYPE_MUTABLE_VALVE) {
3911 // Check if the new descriptor descriptor type is in the list of allowed mutable types for this binding
3912 if (!orig_binding.Layout()->IsTypeMutable(update->descriptorType, update->dstBinding)) {
3913 *error_code = "VUID-VkWriteDescriptorSet-dstSet-04611";
3914 std::stringstream error_str;
3915 error_str << "Write update type is " << string_VkDescriptorType(update->descriptorType)
3916 << ", but descriptor set layout binding was created with type VK_DESCRIPTOR_TYPE_MUTABLE_VALVE and used type "
3917 "is not in VkMutableDescriptorTypeListVALVE::pDescriptorTypes for this binding.";
3918 *error_msg = error_str.str();
3919 return false;
3920 }
3921 }
John Zulauf4956fff2019-06-04 16:54:38 -06003922 // All checks passed, update is clean
3923 return true;
3924}
John Zulaufadb3f542019-06-04 17:01:00 -06003925
3926// Verify that the contents of the update are ok, but don't perform actual update
John Zulaufc93c4252019-06-25 09:19:49 -06003927bool CoreChecks::VerifyWriteUpdateContents(const DescriptorSet *dest_set, const VkWriteDescriptorSet *update, const uint32_t index,
ziga-lunarg6c46b242021-09-13 18:33:37 +02003928 const char *func_name, std::string *error_code, std::string *error_msg,
3929 bool push) const {
John Zulaufc93c4252019-06-25 09:19:49 -06003930 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
Nathaniel Cesarioff521512020-12-11 16:00:26 -07003931 using Descriptor = cvdescriptorset::Descriptor;
John Zulaufc93c4252019-06-25 09:19:49 -06003932
John Zulaufadb3f542019-06-04 17:01:00 -06003933 switch (update->descriptorType) {
3934 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
3935 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3936 // Validate image
3937 auto image_view = update->pImageInfo[di].imageView;
3938 auto image_layout = update->pImageInfo[di].imageLayout;
Mark Lobodzinski3ca937b2020-02-14 14:56:06 -07003939 auto sampler = update->pImageInfo[di].sampler;
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003940 auto iv_state = Get<IMAGE_VIEW_STATE>(image_view);
Nathaniel Cesarioff521512020-12-11 16:00:26 -07003941 const ImageSamplerDescriptor *desc =
3942 (const ImageSamplerDescriptor *)dest_set->GetDescriptorFromGlobalIndex(index + di);
Jeff Bolz165818a2020-05-08 11:19:03 -05003943 if (image_view) {
Jeremy Gebben9d0dda32022-01-28 10:16:56 -07003944 const auto *image_state = iv_state->image_state.get();
Jeff Bolz165818a2020-05-08 11:19:03 -05003945 if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, func_name, error_code, error_msg)) {
3946 std::stringstream error_str;
3947 error_str << "Attempted write update to combined image sampler descriptor failed due to: "
3948 << error_msg->c_str();
3949 *error_msg = error_str.str();
3950 return false;
3951 }
sfricke-samsung45996a42021-09-16 13:45:27 -07003952 if (IsExtEnabled(device_extensions.vk_khr_sampler_ycbcr_conversion)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003953 if (desc->IsImmutableSampler()) {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06003954 auto sampler_state = Get<SAMPLER_STATE>(desc->GetSampler());
Jeff Bolz165818a2020-05-08 11:19:03 -05003955 if (iv_state && sampler_state) {
3956 if (iv_state->samplerConversion != sampler_state->samplerConversion) {
3957 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-01948";
3958 std::stringstream error_str;
3959 error_str
3960 << "Attempted write update to combined image sampler and image view and sampler ycbcr "
3961 "conversions are not identical, sampler: "
3962 << report_data->FormatHandle(desc->GetSampler())
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003963 << " image view: " << report_data->FormatHandle(iv_state->image_view()) << ".";
Jeff Bolz165818a2020-05-08 11:19:03 -05003964 *error_msg = error_str.str();
3965 return false;
3966 }
3967 }
3968 } else {
3969 if (iv_state && (iv_state->samplerConversion != VK_NULL_HANDLE)) {
3970 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02738";
John Zulaufadb3f542019-06-04 17:01:00 -06003971 std::stringstream error_str;
Jeff Bolz165818a2020-05-08 11:19:03 -05003972 error_str << "Because dstSet (" << report_data->FormatHandle(update->dstSet)
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003973 << ") is bound to image view (" << report_data->FormatHandle(iv_state->image_view())
Jeff Bolz165818a2020-05-08 11:19:03 -05003974 << ") that includes a YCBCR conversion, it must have been allocated with a layout that "
3975 "includes an immutable sampler.";
John Zulaufadb3f542019-06-04 17:01:00 -06003976 *error_msg = error_str.str();
3977 return false;
3978 }
3979 }
Jeff Bolz165818a2020-05-08 11:19:03 -05003980 }
John Baumanda8abff2020-10-19 21:25:21 +00003981 // If there is an immutable sampler then |sampler| isn't used, so the following VU does not apply.
3982 if (sampler && !desc->IsImmutableSampler() && FormatIsMultiplane(image_state->createInfo.format)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003983 // multiplane formats must be created with mutable format bit
3984 if (0 == (image_state->createInfo.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) {
3985 *error_code = "VUID-VkDescriptorImageInfo-sampler-01564";
John Zulaufadb3f542019-06-04 17:01:00 -06003986 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06003987 error_str << "image " << report_data->FormatHandle(image_state->image())
Jeff Bolz165818a2020-05-08 11:19:03 -05003988 << " combined image sampler is a multi-planar "
3989 << "format and was not was not created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT";
John Zulaufadb3f542019-06-04 17:01:00 -06003990 *error_msg = error_str.str();
3991 return false;
3992 }
Jeff Bolz165818a2020-05-08 11:19:03 -05003993 // image view need aspect mask for only the planes supported of format
3994 VkImageAspectFlags legal_aspect_flags = (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT);
3995 legal_aspect_flags |=
3996 (FormatPlaneCount(image_state->createInfo.format) == 3) ? VK_IMAGE_ASPECT_PLANE_2_BIT : 0;
3997 if (0 != (iv_state->create_info.subresourceRange.aspectMask & (~legal_aspect_flags))) {
3998 *error_code = "VUID-VkDescriptorImageInfo-sampler-01564";
3999 std::stringstream error_str;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06004000 error_str << "image " << report_data->FormatHandle(image_state->image())
Jeff Bolz165818a2020-05-08 11:19:03 -05004001 << " combined image sampler is a multi-planar "
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06004002 << "format and " << report_data->FormatHandle(iv_state->image_view())
Jeff Bolz165818a2020-05-08 11:19:03 -05004003 << " aspectMask must only include " << string_VkImageAspectFlags(legal_aspect_flags);
4004 *error_msg = error_str.str();
4005 return false;
4006 }
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08004007 }
Nathaniel Cesario23afadd2020-11-17 12:51:45 -07004008
4009 // Verify portability
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06004010 auto sampler_state = Get<SAMPLER_STATE>(sampler);
Nathaniel Cesario23afadd2020-11-17 12:51:45 -07004011 if (sampler_state) {
sfricke-samsung45996a42021-09-16 13:45:27 -07004012 if (IsExtEnabled(device_extensions.vk_khr_portability_subset)) {
Nathaniel Cesario23afadd2020-11-17 12:51:45 -07004013 if ((VK_FALSE == enabled_features.portability_subset_features.mutableComparisonSamplers) &&
4014 (VK_FALSE != sampler_state->createInfo.compareEnable)) {
4015 LogError(device, "VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450",
4016 "%s (portability error): sampler comparison not available.", func_name);
4017 }
4018 }
4019 }
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08004020 }
John Zulaufadb3f542019-06-04 17:01:00 -06004021 }
4022 }
Mark Lobodzinskiac727772020-01-08 10:47:30 -07004023 // Fall through
John Zulaufadb3f542019-06-04 17:01:00 -06004024 case VK_DESCRIPTOR_TYPE_SAMPLER: {
4025 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07004026 const auto *desc = static_cast<const Descriptor *>(dest_set->GetDescriptorFromGlobalIndex(index + di));
John Zulaufadb3f542019-06-04 17:01:00 -06004027 if (!desc->IsImmutableSampler()) {
John Zulaufc93c4252019-06-25 09:19:49 -06004028 if (!ValidateSampler(update->pImageInfo[di].sampler)) {
John Zulaufadb3f542019-06-04 17:01:00 -06004029 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
4030 std::stringstream error_str;
4031 error_str << "Attempted write update to sampler descriptor with invalid sampler: "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06004032 << report_data->FormatHandle(update->pImageInfo[di].sampler) << ".";
John Zulaufadb3f542019-06-04 17:01:00 -06004033 *error_msg = error_str.str();
4034 return false;
4035 }
ziga-lunarg6c46b242021-09-13 18:33:37 +02004036 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER && !push) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07004037 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02752";
4038 std::stringstream error_str;
4039 error_str << "Attempted write update to an immutable sampler descriptor.";
4040 *error_msg = error_str.str();
4041 return false;
John Zulaufadb3f542019-06-04 17:01:00 -06004042 }
4043 }
4044 break;
4045 }
4046 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4047 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4048 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
4049 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
4050 auto image_view = update->pImageInfo[di].imageView;
4051 auto image_layout = update->pImageInfo[di].imageLayout;
Jeff Bolz165818a2020-05-08 11:19:03 -05004052 if (image_view) {
4053 if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, func_name, error_code, error_msg)) {
4054 std::stringstream error_str;
4055 error_str << "Attempted write update to image descriptor failed due to: " << error_msg->c_str();
4056 *error_msg = error_str.str();
4057 return false;
4058 }
John Zulaufadb3f542019-06-04 17:01:00 -06004059 }
4060 }
4061 break;
4062 }
4063 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4064 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
4065 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
4066 auto buffer_view = update->pTexelBufferView[di];
Jeff Bolz165818a2020-05-08 11:19:03 -05004067 if (buffer_view) {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06004068 auto bv_state = Get<BUFFER_VIEW_STATE>(buffer_view);
Jeff Bolz165818a2020-05-08 11:19:03 -05004069 if (!bv_state) {
4070 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
4071 std::stringstream error_str;
4072 error_str << "Attempted write update to texel buffer descriptor with invalid buffer view: "
4073 << report_data->FormatHandle(buffer_view);
4074 *error_msg = error_str.str();
4075 return false;
4076 }
4077 auto buffer = bv_state->create_info.buffer;
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06004078 auto buffer_state = Get<BUFFER_STATE>(buffer);
Jeff Bolz165818a2020-05-08 11:19:03 -05004079 // Verify that buffer underlying the view hasn't been destroyed prematurely
4080 if (!buffer_state) {
4081 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
4082 std::stringstream error_str;
4083 error_str << "Attempted write update to texel buffer descriptor failed because underlying buffer ("
4084 << report_data->FormatHandle(buffer) << ") has been destroyed: " << error_msg->c_str();
4085 *error_msg = error_str.str();
4086 return false;
Jeremy Gebben9f537102021-10-05 16:37:12 -06004087 } else if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_state.get(), update->descriptorType,
4088 error_code, error_msg)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05004089 std::stringstream error_str;
4090 error_str << "Attempted write update to texel buffer descriptor failed due to: " << error_msg->c_str();
4091 *error_msg = error_str.str();
4092 return false;
4093 }
John Zulaufadb3f542019-06-04 17:01:00 -06004094 }
4095 }
4096 break;
4097 }
4098 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4099 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
4100 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4101 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
4102 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Jeff Bolz165818a2020-05-08 11:19:03 -05004103 if (update->pBufferInfo[di].buffer) {
4104 if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, func_name, error_code, error_msg)) {
4105 std::stringstream error_str;
4106 error_str << "Attempted write update to buffer descriptor failed due to: " << error_msg->c_str();
4107 *error_msg = error_str.str();
4108 return false;
4109 }
John Zulaufadb3f542019-06-04 17:01:00 -06004110 }
4111 }
4112 break;
4113 }
4114 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
4115 break;
Jeff Bolz95176d02020-04-01 00:36:16 -05004116 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07004117 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(update->pNext);
Jeff Bolz95176d02020-04-01 00:36:16 -05004118 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Jeremy Gebben9f537102021-10-05 16:37:12 -06004119 auto as_state = Get<ACCELERATION_STRUCTURE_STATE>(acc_info->pAccelerationStructures[di]);
4120 if (!ValidateAccelerationStructureUpdate(as_state.get(), func_name, error_code, error_msg)) {
Jeff Bolz95176d02020-04-01 00:36:16 -05004121 std::stringstream error_str;
4122 error_str << "Attempted write update to acceleration structure descriptor failed due to: "
4123 << error_msg->c_str();
4124 *error_msg = error_str.str();
4125 return false;
4126 }
4127 }
4128
4129 } break;
sourav parmarcd5fb182020-07-17 12:58:44 -07004130 // KHR acceleration structures don't require memory to be bound manually to them.
4131 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
4132 break;
John Zulaufadb3f542019-06-04 17:01:00 -06004133 default:
4134 assert(0); // We've already verified update type so should never get here
4135 break;
4136 }
4137 // All checks passed so update contents are good
4138 return true;
4139}