blob: 4bedceca399f3dc51641cc6c43f89ab0398383cb [file] [log] [blame]
sfricke-samsung691299b2021-01-01 20:48:48 -08001/* Copyright (c) 2015-2021 The Khronos Group Inc.
2 * Copyright (c) 2015-2021 Valve Corporation
3 * Copyright (c) 2015-2021 LunarG, Inc.
4 * Copyright (C) 2015-2021 Google Inc.
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06005 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Tobin Ehlis <tobine@google.com>
John Zulaufc483f442017-12-15 14:02:06 -070019 * John Zulauf <jzulauf@lunarg.com>
Jeremy Kniagere6827432020-04-01 09:05:56 -060020 * Jeremy Kniager <jeremyk@lunarg.com>
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060021 */
22
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -070023#include "chassis.h"
Mark Lobodzinski76d76662019-02-14 14:38:21 -070024#include "core_validation_error_enums.h"
25#include "core_validation.h"
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060026#include "descriptor_sets.h"
John Zulaufd47d0612018-02-16 13:00:34 -070027#include "hash_vk_types.h"
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060028#include "vk_enum_string_helper.h"
29#include "vk_safe_struct.h"
Jeff Bolzfdf96072018-04-10 14:32:18 -050030#include "vk_typemap_helper.h"
Tobin Ehlisc8266452017-04-07 12:20:30 -060031#include "buffer_validation.h"
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060032#include <sstream>
Mark Lobodzinski2eee5d82016-12-02 15:33:18 -070033#include <algorithm>
John Zulauff4c07882019-01-24 14:03:36 -070034#include <array>
John Zulauf1f8174b2018-02-16 12:58:37 -070035#include <memory>
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060036
Jeff Bolzfdf96072018-04-10 14:32:18 -050037// ExtendedBinding collects a VkDescriptorSetLayoutBinding and any extended
38// state that comes from a different array/structure so they can stay together
39// while being sorted by binding number.
40struct ExtendedBinding {
Mike Schuchardt2df08912020-12-15 16:28:09 -080041 ExtendedBinding(const VkDescriptorSetLayoutBinding *l, VkDescriptorBindingFlags f) : layout_binding(l), binding_flags(f) {}
Jeff Bolzfdf96072018-04-10 14:32:18 -050042
43 const VkDescriptorSetLayoutBinding *layout_binding;
Mike Schuchardt2df08912020-12-15 16:28:09 -080044 VkDescriptorBindingFlags binding_flags;
Jeff Bolzfdf96072018-04-10 14:32:18 -050045};
46
John Zulauf508d13a2018-01-05 15:10:34 -070047struct BindingNumCmp {
Jeff Bolzfdf96072018-04-10 14:32:18 -050048 bool operator()(const ExtendedBinding &a, const ExtendedBinding &b) const {
49 return a.layout_binding->binding < b.layout_binding->binding;
John Zulauf508d13a2018-01-05 15:10:34 -070050 }
51};
52
John Zulauf613fd982019-06-04 15:14:41 -060053using DescriptorSet = cvdescriptorset::DescriptorSet;
John Zulauf4a015c92019-06-04 09:50:05 -060054using DescriptorSetLayout = cvdescriptorset::DescriptorSetLayout;
John Zulaufd47d0612018-02-16 13:00:34 -070055using DescriptorSetLayoutDef = cvdescriptorset::DescriptorSetLayoutDef;
56using DescriptorSetLayoutId = cvdescriptorset::DescriptorSetLayoutId;
57
John Zulauf34ebf272018-02-16 13:08:47 -070058// Canonical dictionary of DescriptorSetLayoutDef (without any handle/device specific information)
59cvdescriptorset::DescriptorSetLayoutDict descriptor_set_layout_dict;
John Zulaufd47d0612018-02-16 13:00:34 -070060
Shannon McPhersonc06c33d2018-06-28 17:21:12 -060061DescriptorSetLayoutId GetCanonicalId(const VkDescriptorSetLayoutCreateInfo *p_create_info) {
John Zulauf34ebf272018-02-16 13:08:47 -070062 return descriptor_set_layout_dict.look_up(DescriptorSetLayoutDef(p_create_info));
John Zulaufd47d0612018-02-16 13:00:34 -070063}
John Zulauf34ebf272018-02-16 13:08:47 -070064
Tobin Ehlis0a43bde2016-05-03 08:31:08 -060065// Construct DescriptorSetLayout instance from given create info
John Zulauf48a6a702017-12-22 17:14:54 -070066// Proactively reserve and resize as possible, as the reallocation was visible in profiling
John Zulauf1f8174b2018-02-16 12:58:37 -070067cvdescriptorset::DescriptorSetLayoutDef::DescriptorSetLayoutDef(const VkDescriptorSetLayoutCreateInfo *p_create_info)
68 : flags_(p_create_info->flags), binding_count_(0), descriptor_count_(0), dynamic_descriptor_count_(0) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -070069 const auto *flags_create_info = LvlFindInChain<VkDescriptorSetLayoutBindingFlagsCreateInfo>(p_create_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -050070
sfricke-samsung0d00aed2021-03-08 23:31:17 -080071 binding_type_stats_ = {0, 0};
Jeff Bolzfdf96072018-04-10 14:32:18 -050072 std::set<ExtendedBinding, BindingNumCmp> sorted_bindings;
John Zulauf508d13a2018-01-05 15:10:34 -070073 const uint32_t input_bindings_count = p_create_info->bindingCount;
74 // Sort the input bindings in binding number order, eliminating duplicates
75 for (uint32_t i = 0; i < input_bindings_count; i++) {
Mike Schuchardt2df08912020-12-15 16:28:09 -080076 VkDescriptorBindingFlags flags = 0;
Jeff Bolzfdf96072018-04-10 14:32:18 -050077 if (flags_create_info && flags_create_info->bindingCount == p_create_info->bindingCount) {
78 flags = flags_create_info->pBindingFlags[i];
79 }
Jeremy Gebbenfc6f8152021-03-18 16:58:55 -060080 sorted_bindings.emplace(p_create_info->pBindings + i, flags);
John Zulaufb6d71202017-12-22 16:47:09 -070081 }
82
83 // Store the create info in the sorted order from above
John Zulauf508d13a2018-01-05 15:10:34 -070084 uint32_t index = 0;
85 binding_count_ = static_cast<uint32_t>(sorted_bindings.size());
86 bindings_.reserve(binding_count_);
Jeff Bolzfdf96072018-04-10 14:32:18 -050087 binding_flags_.reserve(binding_count_);
John Zulauf508d13a2018-01-05 15:10:34 -070088 binding_to_index_map_.reserve(binding_count_);
John Zulauf79f06582021-02-27 18:38:39 -070089 for (const auto &input_binding : sorted_bindings) {
John Zulauf508d13a2018-01-05 15:10:34 -070090 // Add to binding and map, s.t. it is robust to invalid duplication of binding_num
Jeff Bolzfdf96072018-04-10 14:32:18 -050091 const auto binding_num = input_binding.layout_binding->binding;
John Zulauf508d13a2018-01-05 15:10:34 -070092 binding_to_index_map_[binding_num] = index++;
Jeff Bolzfdf96072018-04-10 14:32:18 -050093 bindings_.emplace_back(input_binding.layout_binding);
John Zulauf508d13a2018-01-05 15:10:34 -070094 auto &binding_info = bindings_.back();
Jeff Bolzfdf96072018-04-10 14:32:18 -050095 binding_flags_.emplace_back(input_binding.binding_flags);
John Zulauf508d13a2018-01-05 15:10:34 -070096
John Zulaufb6d71202017-12-22 16:47:09 -070097 descriptor_count_ += binding_info.descriptorCount;
98 if (binding_info.descriptorCount > 0) {
99 non_empty_bindings_.insert(binding_num);
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700100 }
John Zulaufb6d71202017-12-22 16:47:09 -0700101
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800102 if (IsDynamicDescriptor(binding_info.descriptorType)) {
sfricke-samsung0d00aed2021-03-08 23:31:17 -0800103 dynamic_descriptor_count_ += binding_info.descriptorCount;
104 }
105
106 // Get stats depending on descriptor type for caching later
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800107 if (IsBufferDescriptor(binding_info.descriptorType)) {
108 if (IsDynamicDescriptor(binding_info.descriptorType)) {
109 binding_type_stats_.dynamic_buffer_count++;
110 } else {
111 binding_type_stats_.non_dynamic_buffer_count++;
112 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600113 }
114 }
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700115 assert(bindings_.size() == binding_count_);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500116 assert(binding_flags_.size() == binding_count_);
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700117 uint32_t global_index = 0;
John Zulauf7705bfc2019-06-10 09:52:04 -0600118 global_index_range_.reserve(binding_count_);
119 // Vector order is finalized so build vectors of descriptors and dynamic offsets by binding index
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700120 for (uint32_t i = 0; i < binding_count_; ++i) {
John Zulaufc483f442017-12-15 14:02:06 -0700121 auto final_index = global_index + bindings_[i].descriptorCount;
John Zulauf7705bfc2019-06-10 09:52:04 -0600122 global_index_range_.emplace_back(global_index, final_index);
John Zulaufc483f442017-12-15 14:02:06 -0700123 global_index = final_index;
Tobin Ehlis9637fb22016-12-12 15:59:34 -0700124 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600125}
Tobin Ehlis154c2692016-10-25 09:36:53 -0600126
John Zulaufd47d0612018-02-16 13:00:34 -0700127size_t cvdescriptorset::DescriptorSetLayoutDef::hash() const {
128 hash_util::HashCombiner hc;
129 hc << flags_;
130 hc.Combine(bindings_);
John Zulauf223b69d2018-11-09 16:00:59 -0700131 hc.Combine(binding_flags_);
John Zulaufd47d0612018-02-16 13:00:34 -0700132 return hc.Value();
133}
134//
135
John Zulauf1f8174b2018-02-16 12:58:37 -0700136// Return valid index or "end" i.e. binding_count_;
137// The asserts in "Get" are reduced to the set where no valid answer(like null or 0) could be given
138// Common code for all binding lookups.
139uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetIndexFromBinding(uint32_t binding) const {
140 const auto &bi_itr = binding_to_index_map_.find(binding);
141 if (bi_itr != binding_to_index_map_.cend()) return bi_itr->second;
142 return GetBindingCount();
143}
144VkDescriptorSetLayoutBinding const *cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorSetLayoutBindingPtrFromIndex(
145 const uint32_t index) const {
146 if (index >= bindings_.size()) return nullptr;
147 return bindings_[index].ptr();
148}
149// Return descriptorCount for given index, 0 if index is unavailable
150uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorCountFromIndex(const uint32_t index) const {
151 if (index >= bindings_.size()) return 0;
152 return bindings_[index].descriptorCount;
153}
154// For the given index, return descriptorType
155VkDescriptorType cvdescriptorset::DescriptorSetLayoutDef::GetTypeFromIndex(const uint32_t index) const {
156 assert(index < bindings_.size());
157 if (index < bindings_.size()) return bindings_[index].descriptorType;
158 return VK_DESCRIPTOR_TYPE_MAX_ENUM;
159}
160// For the given index, return stageFlags
161VkShaderStageFlags cvdescriptorset::DescriptorSetLayoutDef::GetStageFlagsFromIndex(const uint32_t index) const {
162 assert(index < bindings_.size());
163 if (index < bindings_.size()) return bindings_[index].stageFlags;
164 return VkShaderStageFlags(0);
165}
Jeff Bolzfdf96072018-04-10 14:32:18 -0500166// Return binding flags for given index, 0 if index is unavailable
Mike Schuchardt2df08912020-12-15 16:28:09 -0800167VkDescriptorBindingFlags cvdescriptorset::DescriptorSetLayoutDef::GetDescriptorBindingFlagsFromIndex(const uint32_t index) const {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500168 if (index >= binding_flags_.size()) return 0;
169 return binding_flags_[index];
170}
John Zulauf1f8174b2018-02-16 12:58:37 -0700171
John Zulauf7705bfc2019-06-10 09:52:04 -0600172const cvdescriptorset::IndexRange &cvdescriptorset::DescriptorSetLayoutDef::GetGlobalIndexRangeFromIndex(uint32_t index) const {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700173 const static IndexRange k_invalid_range = {0xFFFFFFFF, 0xFFFFFFFF};
174 if (index >= binding_flags_.size()) return k_invalid_range;
John Zulauf7705bfc2019-06-10 09:52:04 -0600175 return global_index_range_[index];
John Zulauf1f8174b2018-02-16 12:58:37 -0700176}
177
John Zulauf7705bfc2019-06-10 09:52:04 -0600178// For the given binding, return the global index range (half open)
179// As start and end are often needed in pairs, get both with a single lookup.
John Zulauf1f8174b2018-02-16 12:58:37 -0700180const cvdescriptorset::IndexRange &cvdescriptorset::DescriptorSetLayoutDef::GetGlobalIndexRangeFromBinding(
181 const uint32_t binding) const {
John Zulauf7705bfc2019-06-10 09:52:04 -0600182 uint32_t index = GetIndexFromBinding(binding);
183 return GetGlobalIndexRangeFromIndex(index);
John Zulauf1f8174b2018-02-16 12:58:37 -0700184}
185
186// For given binding, return ptr to ImmutableSampler array
187VkSampler const *cvdescriptorset::DescriptorSetLayoutDef::GetImmutableSamplerPtrFromBinding(const uint32_t binding) const {
188 const auto &bi_itr = binding_to_index_map_.find(binding);
189 if (bi_itr != binding_to_index_map_.end()) {
190 return bindings_[bi_itr->second].pImmutableSamplers;
191 }
192 return nullptr;
193}
194// Move to next valid binding having a non-zero binding count
195uint32_t cvdescriptorset::DescriptorSetLayoutDef::GetNextValidBinding(const uint32_t binding) const {
196 auto it = non_empty_bindings_.upper_bound(binding);
197 assert(it != non_empty_bindings_.cend());
198 if (it != non_empty_bindings_.cend()) return *it;
199 return GetMaxBinding() + 1;
200}
201// For given index, return ptr to ImmutableSampler array
202VkSampler const *cvdescriptorset::DescriptorSetLayoutDef::GetImmutableSamplerPtrFromIndex(const uint32_t index) const {
203 if (index < bindings_.size()) {
204 return bindings_[index].pImmutableSamplers;
205 }
206 return nullptr;
207}
John Zulauf9ce3b252019-06-06 15:20:22 -0600208
209// If our layout is compatible with rh_ds_layout, return true.
210bool cvdescriptorset::DescriptorSetLayout::IsCompatible(DescriptorSetLayout const *rh_ds_layout) const {
211 bool compatible = (this == rh_ds_layout) || (GetLayoutDef() == rh_ds_layout->GetLayoutDef());
212 return compatible;
213}
John Zulauf1f8174b2018-02-16 12:58:37 -0700214
John Zulauff43695f2019-09-13 17:56:26 -0600215// TODO: Find a way to add smarts to the autogenerated version of this
216static std::string smart_string_VkShaderStageFlags(VkShaderStageFlags stage_flags) {
217 if (stage_flags == VK_SHADER_STAGE_ALL) {
218 return string_VkShaderStageFlagBits(VK_SHADER_STAGE_ALL);
219 }
220
221 return string_VkShaderStageFlags(stage_flags);
222}
223
224// If our layout is compatible with bound_dsl, return true,
225// else return false and fill in error_msg will description of what causes incompatibility
226bool cvdescriptorset::VerifySetLayoutCompatibility(const debug_report_data *report_data, DescriptorSetLayout const *layout_dsl,
227 DescriptorSetLayout const *bound_dsl, std::string *error_msg) {
228 // Short circuit the detailed check.
229 if (layout_dsl->IsCompatible(bound_dsl)) return true;
230
231 // 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 -0600232 // Should only be run if trivial accept has failed, and in that context should return false.
John Zulauff43695f2019-09-13 17:56:26 -0600233 VkDescriptorSetLayout layout_dsl_handle = layout_dsl->GetDescriptorSetLayout();
234 VkDescriptorSetLayout bound_dsl_handle = bound_dsl->GetDescriptorSetLayout();
235 DescriptorSetLayoutDef const *layout_ds_layout_def = layout_dsl->GetLayoutDef();
236 DescriptorSetLayoutDef const *bound_ds_layout_def = bound_dsl->GetLayoutDef();
John Zulauf9ce3b252019-06-06 15:20:22 -0600237
238 // Check descriptor counts
John Zulauff43695f2019-09-13 17:56:26 -0600239 const auto bound_total_count = bound_ds_layout_def->GetTotalDescriptorCount();
240 if (layout_ds_layout_def->GetTotalDescriptorCount() != bound_ds_layout_def->GetTotalDescriptorCount()) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700241 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600242 error_str << report_data->FormatHandle(layout_dsl_handle) << " from pipeline layout has "
243 << layout_ds_layout_def->GetTotalDescriptorCount() << " total descriptors, but "
244 << report_data->FormatHandle(bound_dsl_handle) << ", which is bound, has " << bound_total_count
245 << " total descriptors.";
John Zulauf1f8174b2018-02-16 12:58:37 -0700246 *error_msg = error_str.str();
247 return false; // trivial fail case
248 }
John Zulaufd47d0612018-02-16 13:00:34 -0700249
John Zulauf1f8174b2018-02-16 12:58:37 -0700250 // Descriptor counts match so need to go through bindings one-by-one
251 // and verify that type and stageFlags match
John Zulauff43695f2019-09-13 17:56:26 -0600252 for (const auto &layout_binding : layout_ds_layout_def->GetBindings()) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700253 // TODO : Do we also need to check immutable samplers?
John Zulauff43695f2019-09-13 17:56:26 -0600254 const auto bound_binding = bound_ds_layout_def->GetBindingInfoFromBinding(layout_binding.binding);
255 if (layout_binding.descriptorCount != bound_binding->descriptorCount) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700256 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600257 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
258 << " from pipeline layout has a descriptorCount of " << layout_binding.descriptorCount << " but binding "
259 << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
260 << ", which is bound, has a descriptorCount of " << bound_binding->descriptorCount;
John Zulauf1f8174b2018-02-16 12:58:37 -0700261 *error_msg = error_str.str();
262 return false;
John Zulauff43695f2019-09-13 17:56:26 -0600263 } else if (layout_binding.descriptorType != bound_binding->descriptorType) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700264 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600265 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
266 << " from pipeline layout is type '" << string_VkDescriptorType(layout_binding.descriptorType)
267 << "' but binding " << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
268 << ", which is bound, is type '" << string_VkDescriptorType(bound_binding->descriptorType) << "'";
John Zulauf1f8174b2018-02-16 12:58:37 -0700269 *error_msg = error_str.str();
270 return false;
John Zulauff43695f2019-09-13 17:56:26 -0600271 } else if (layout_binding.stageFlags != bound_binding->stageFlags) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700272 std::stringstream error_str;
John Zulauff43695f2019-09-13 17:56:26 -0600273 error_str << "Binding " << layout_binding.binding << " for " << report_data->FormatHandle(layout_dsl_handle)
274 << " from pipeline layout has stageFlags " << smart_string_VkShaderStageFlags(layout_binding.stageFlags)
275 << " but binding " << layout_binding.binding << " for " << report_data->FormatHandle(bound_dsl_handle)
276 << ", which is bound, has stageFlags " << smart_string_VkShaderStageFlags(bound_binding->stageFlags);
John Zulauf1f8174b2018-02-16 12:58:37 -0700277 *error_msg = error_str.str();
278 return false;
279 }
280 }
Tony-LunarG692b8b42019-09-30 16:07:26 -0600281
282 const auto &ds_layout_flags = layout_ds_layout_def->GetBindingFlags();
283 const auto &bound_layout_flags = bound_ds_layout_def->GetBindingFlags();
284 if (bound_layout_flags != ds_layout_flags) {
285 std::stringstream error_str;
286 assert(ds_layout_flags.size() == bound_layout_flags.size());
287 size_t i;
288 for (i = 0; i < ds_layout_flags.size(); i++) {
289 if (ds_layout_flags[i] != bound_layout_flags[i]) break;
290 }
291 error_str << report_data->FormatHandle(layout_dsl_handle)
292 << " from pipeline layout does not have the same binding flags at binding " << i << " ( "
293 << string_VkDescriptorBindingFlagsEXT(ds_layout_flags[i]) << " ) as "
294 << report_data->FormatHandle(bound_dsl_handle) << " ( "
295 << string_VkDescriptorBindingFlagsEXT(bound_layout_flags[i]) << " ), which is bound";
296 *error_msg = error_str.str();
297 return false;
298 }
299
John Zulauf9ce3b252019-06-06 15:20:22 -0600300 // No detailed check should succeed if the trivial check failed -- or the dictionary has failed somehow.
301 bool compatible = true;
302 assert(!compatible);
303 return compatible;
John Zulauf1f8174b2018-02-16 12:58:37 -0700304}
305
306bool cvdescriptorset::DescriptorSetLayoutDef::IsNextBindingConsistent(const uint32_t binding) const {
307 if (!binding_to_index_map_.count(binding + 1)) return false;
308 auto const &bi_itr = binding_to_index_map_.find(binding);
309 if (bi_itr != binding_to_index_map_.end()) {
310 const auto &next_bi_itr = binding_to_index_map_.find(binding + 1);
311 if (next_bi_itr != binding_to_index_map_.end()) {
312 auto type = bindings_[bi_itr->second].descriptorType;
313 auto stage_flags = bindings_[bi_itr->second].stageFlags;
314 auto immut_samp = bindings_[bi_itr->second].pImmutableSamplers ? true : false;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500315 auto flags = binding_flags_[bi_itr->second];
John Zulauf1f8174b2018-02-16 12:58:37 -0700316 if ((type != bindings_[next_bi_itr->second].descriptorType) ||
317 (stage_flags != bindings_[next_bi_itr->second].stageFlags) ||
Jeff Bolzfdf96072018-04-10 14:32:18 -0500318 (immut_samp != (bindings_[next_bi_itr->second].pImmutableSamplers ? true : false)) ||
319 (flags != binding_flags_[next_bi_itr->second])) {
John Zulauf1f8174b2018-02-16 12:58:37 -0700320 return false;
321 }
322 return true;
323 }
324 }
325 return false;
326}
John Zulauf1f8174b2018-02-16 12:58:37 -0700327
328// The DescriptorSetLayout stores the per handle data for a descriptor set layout, and references the common defintion for the
329// handle invariant portion
330cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *p_create_info,
331 const VkDescriptorSetLayout layout)
Jeff Bolz6ae39612019-10-11 20:57:36 -0500332 : layout_(layout), layout_id_(GetCanonicalId(p_create_info)) {}
John Zulauf1f8174b2018-02-16 12:58:37 -0700333
Tobin Ehlis154c2692016-10-25 09:36:53 -0600334// Validate descriptor set layout create info
John Zulaufd9435c32019-06-05 15:55:36 -0600335bool cvdescriptorset::ValidateDescriptorSetLayoutCreateInfo(
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700336 const ValidationObject *val_obj, const VkDescriptorSetLayoutCreateInfo *create_info, const bool push_descriptor_ext,
Jeff Bolzfdf96072018-04-10 14:32:18 -0500337 const uint32_t max_push_descriptors, const bool descriptor_indexing_ext,
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700338 const VkPhysicalDeviceVulkan12Features *core12_features,
Jeff Bolze54ae892018-09-08 12:16:29 -0500339 const VkPhysicalDeviceInlineUniformBlockFeaturesEXT *inline_uniform_block_features,
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600340 const VkPhysicalDeviceInlineUniformBlockPropertiesEXT *inline_uniform_block_props, const DeviceExtensions *device_extensions) {
Tobin Ehlis154c2692016-10-25 09:36:53 -0600341 bool skip = false;
Jeremy Gebbencbf22862021-03-03 12:01:22 -0700342 layer_data::unordered_set<uint32_t> bindings;
John Zulauf0fdeab32018-01-23 11:27:35 -0700343 uint64_t total_descriptors = 0;
344
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700345 const auto *flags_create_info = LvlFindInChain<VkDescriptorSetLayoutBindingFlagsCreateInfo>(create_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500346
347 const bool push_descriptor_set = !!(create_info->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
John Zulauf0fdeab32018-01-23 11:27:35 -0700348 if (push_descriptor_set && !push_descriptor_ext) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800349 skip |= val_obj->LogError(
350 val_obj->device, kVUID_Core_DrawState_ExtensionNotEnabled,
351 "vkCreateDescriptorSetLayout(): Attempted to use %s in %s but its required extension %s has not been enabled.\n",
352 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR", "VkDescriptorSetLayoutCreateInfo::flags",
353 VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
John Zulauf0fdeab32018-01-23 11:27:35 -0700354 }
355
Mike Schuchardt2df08912020-12-15 16:28:09 -0800356 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 -0500357 if (update_after_bind_set && !descriptor_indexing_ext) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800358 skip |= val_obj->LogError(
359 val_obj->device, kVUID_Core_DrawState_ExtensionNotEnabled,
360 "vkCreateDescriptorSetLayout(): Attemped to use %s in %s but its required extension %s has not been enabled.\n",
361 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT", "VkDescriptorSetLayoutCreateInfo::flags",
362 VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500363 }
364
John Zulauf0fdeab32018-01-23 11:27:35 -0700365 auto valid_type = [push_descriptor_set](const VkDescriptorType type) {
366 return !push_descriptor_set ||
Dave Houlton142c4cb2018-10-17 15:04:41 -0600367 ((type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) && (type != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) &&
Jeff Bolze54ae892018-09-08 12:16:29 -0500368 (type != VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT));
John Zulauf0fdeab32018-01-23 11:27:35 -0700369 };
370
Jeff Bolzfdf96072018-04-10 14:32:18 -0500371 uint32_t max_binding = 0;
372
Tobin Ehlis154c2692016-10-25 09:36:53 -0600373 for (uint32_t i = 0; i < create_info->bindingCount; ++i) {
John Zulauf0fdeab32018-01-23 11:27:35 -0700374 const auto &binding_info = create_info->pBindings[i];
Jeff Bolzfdf96072018-04-10 14:32:18 -0500375 max_binding = std::max(max_binding, binding_info.binding);
376
John Zulauf0fdeab32018-01-23 11:27:35 -0700377 if (!bindings.insert(binding_info.binding).second) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700378 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-binding-00279",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800379 "vkCreateDescriptorSetLayout(): pBindings[%u] has duplicated binding number (%u).", i,
380 binding_info.binding);
Tobin Ehlis154c2692016-10-25 09:36:53 -0600381 }
John Zulauf0fdeab32018-01-23 11:27:35 -0700382 if (!valid_type(binding_info.descriptorType)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700383 skip |= val_obj->LogError(val_obj->device,
384 (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
385 ? "VUID-VkDescriptorSetLayoutCreateInfo-flags-02208"
386 : "VUID-VkDescriptorSetLayoutCreateInfo-flags-00280",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800387 "vkCreateDescriptorSetLayout(): pBindings[%u] has invalid type %s , for push descriptors.", i,
388 string_VkDescriptorType(binding_info.descriptorType));
John Zulauf0fdeab32018-01-23 11:27:35 -0700389 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500390
391 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
sfricke-samsungc1e27c32021-01-16 09:32:49 -0800392 if (!inline_uniform_block_features->inlineUniformBlock) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800393 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-04604",
394 "vkCreateDescriptorSetLayout(): pBindings[%u] is creating VkDescriptorSetLayout with "
395 "descriptor type VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT "
396 "but inlineUniformBlock is not enabled",
397 i, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600398 } else {
399 if ((binding_info.descriptorCount % 4) != 0) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800400 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02209",
401 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorCount =(%" PRIu32
402 ") but must be a multiple of 4",
403 i, binding_info.descriptorCount);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600404 }
405 if (binding_info.descriptorCount > inline_uniform_block_props->maxInlineUniformBlockSize) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700406 skip |=
407 val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBinding-descriptorType-02210",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800408 "vkCreateDescriptorSetLayout(): pBindings[%u] has descriptorCount =(%" PRIu32
409 ") but must be less than or equal to maxInlineUniformBlockSize (%u)",
410 i, binding_info.descriptorCount, inline_uniform_block_props->maxInlineUniformBlockSize);
Tony-LunarGd6744bc2019-08-23 09:57:10 -0600411 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500412 }
413 }
414
Tony-LunarG7337b312020-04-15 16:40:25 -0600415 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
416 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
417 binding_info.pImmutableSamplers && device_extensions->vk_ext_custom_border_color) {
418 const CoreChecks *core_checks = reinterpret_cast<const CoreChecks *>(val_obj);
419 for (uint32_t j = 0; j < binding_info.descriptorCount; j++) {
420 const SAMPLER_STATE *sampler_state = core_checks->GetSamplerState(binding_info.pImmutableSamplers[j]);
421 if (sampler_state && (sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
422 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800423 skip |= val_obj->LogError(
424 val_obj->device, "VUID-VkDescriptorSetLayoutBinding-pImmutableSamplers-04009",
425 "vkCreateDescriptorSetLayout(): pBindings[%u].pImmutableSamplers[%u] has VkSampler %" PRIu64
426 " presented as immutable has a custom border color",
427 i, j, binding_info.pImmutableSamplers[j]);
Tony-LunarG7337b312020-04-15 16:40:25 -0600428 }
429 }
430 }
431
John Zulauf0fdeab32018-01-23 11:27:35 -0700432 total_descriptors += binding_info.descriptorCount;
Tobin Ehlis154c2692016-10-25 09:36:53 -0600433 }
John Zulauf0fdeab32018-01-23 11:27:35 -0700434
Jeff Bolzfdf96072018-04-10 14:32:18 -0500435 if (flags_create_info) {
436 if (flags_create_info->bindingCount != 0 && flags_create_info->bindingCount != create_info->bindingCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700437 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-bindingCount-03002",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800438 "vkCreateDescriptorSetLayout(): VkDescriptorSetLayoutCreateInfo::bindingCount (%d) != "
Mike Schuchardt2df08912020-12-15 16:28:09 -0800439 "VkDescriptorSetLayoutBindingFlagsCreateInfo::bindingCount (%d)",
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700440 create_info->bindingCount, flags_create_info->bindingCount);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500441 }
442
443 if (flags_create_info->bindingCount == create_info->bindingCount) {
444 for (uint32_t i = 0; i < create_info->bindingCount; ++i) {
445 const auto &binding_info = create_info->pBindings[i];
446
Mike Schuchardt2df08912020-12-15 16:28:09 -0800447 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT) {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500448 if (!update_after_bind_set) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700449 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-flags-03000",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800450 "vkCreateDescriptorSetLayout(): pBindings[%u] does not have "
451 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT.",
452 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500453 }
454
455 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700456 !core12_features->descriptorBindingUniformBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800457 skip |= val_obj->LogError(
458 val_obj->device,
459 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
460 "descriptorBindingUniformBufferUpdateAfterBind-03005",
461 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
462 "for %s since descriptorBindingUniformBufferUpdateAfterBind is not enabled.",
463 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500464 }
465 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
466 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
467 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700468 !core12_features->descriptorBindingSampledImageUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800469 skip |= val_obj->LogError(
470 val_obj->device,
471 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
472 "descriptorBindingSampledImageUpdateAfterBind-03006",
473 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
474 "for %s since descriptorBindingSampledImageUpdateAfterBind is not enabled.",
475 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500476 }
477 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700478 !core12_features->descriptorBindingStorageImageUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800479 skip |= val_obj->LogError(
480 val_obj->device,
481 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
482 "descriptorBindingStorageImageUpdateAfterBind-03007",
483 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
484 "for %s since descriptorBindingStorageImageUpdateAfterBind is not enabled.",
485 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500486 }
487 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700488 !core12_features->descriptorBindingStorageBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800489 skip |= val_obj->LogError(
490 val_obj->device,
491 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
492 "descriptorBindingStorageBufferUpdateAfterBind-03008",
493 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
494 "for %s since descriptorBindingStorageBufferUpdateAfterBind is not enabled.",
495 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500496 }
497 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700498 !core12_features->descriptorBindingUniformTexelBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800499 skip |= val_obj->LogError(
500 val_obj->device,
501 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
502 "descriptorBindingUniformTexelBufferUpdateAfterBind-03009",
503 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
504 "for %s since descriptorBindingUniformTexelBufferUpdateAfterBind is not enabled.",
505 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500506 }
507 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER &&
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700508 !core12_features->descriptorBindingStorageTexelBufferUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800509 skip |= val_obj->LogError(
510 val_obj->device,
511 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
512 "descriptorBindingStorageTexelBufferUpdateAfterBind-03010",
513 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
514 "for %s since descriptorBindingStorageTexelBufferUpdateAfterBind is not enabled.",
515 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500516 }
517 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
518 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
519 binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700520 skip |= val_obj->LogError(val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-None-03011",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800521 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
522 "VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT for %s.",
523 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500524 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500525
526 if (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
527 !inline_uniform_block_features->descriptorBindingInlineUniformBlockUpdateAfterBind) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800528 skip |= val_obj->LogError(
529 val_obj->device,
530 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-"
531 "descriptorBindingInlineUniformBlockUpdateAfterBind-02211",
532 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT "
533 "for %s since descriptorBindingInlineUniformBlockUpdateAfterBind is not enabled.",
534 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolze54ae892018-09-08 12:16:29 -0500535 }
Jeff Bolzfdf96072018-04-10 14:32:18 -0500536 }
537
Mike Schuchardt2df08912020-12-15 16:28:09 -0800538 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700539 if (!core12_features->descriptorBindingUpdateUnusedWhilePending) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700540 skip |= val_obj->LogError(
541 val_obj->device,
Mike Schuchardt65847d92019-12-20 13:50:47 -0800542 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingUpdateUnusedWhilePending-03012",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800543 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
544 "VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT for %s since "
545 "descriptorBindingUpdateUnusedWhilePending is not enabled.",
546 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500547 }
548 }
549
Mike Schuchardt2df08912020-12-15 16:28:09 -0800550 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT) {
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700551 if (!core12_features->descriptorBindingPartiallyBound) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700552 skip |= val_obj->LogError(
553 val_obj->device,
554 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingPartiallyBound-03013",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800555 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT for "
556 "%s since descriptorBindingPartiallyBound is not enabled.",
557 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500558 }
559 }
560
Mike Schuchardt2df08912020-12-15 16:28:09 -0800561 if (flags_create_info->pBindingFlags[i] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT) {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500562 if (binding_info.binding != max_binding) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800563 skip |= val_obj->LogError(
564 val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004",
565 "vkCreateDescriptorSetLayout(): pBindings[%u] has VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT "
566 "but %u is the largest value of all the bindings.",
567 i, binding_info.binding);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500568 }
569
Piers Daniell41b8c5d2020-01-10 15:42:00 -0700570 if (!core12_features->descriptorBindingVariableDescriptorCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700571 skip |= val_obj->LogError(
572 val_obj->device,
Mike Schuchardt65847d92019-12-20 13:50:47 -0800573 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingVariableDescriptorCount-03014",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800574 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
575 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for %s since "
576 "descriptorBindingVariableDescriptorCount is not enabled.",
577 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500578 }
sfricke-samsung4ba7d6e2021-03-06 20:56:35 -0800579 if ((binding_info.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
580 (binding_info.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700581 skip |= val_obj->LogError(val_obj->device,
582 "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03015",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800583 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have "
584 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for %s.",
585 i, string_VkDescriptorType(binding_info.descriptorType));
Jeff Bolzfdf96072018-04-10 14:32:18 -0500586 }
587 }
588
589 if (push_descriptor_set &&
590 (flags_create_info->pBindingFlags[i] &
Mike Schuchardt2df08912020-12-15 16:28:09 -0800591 (VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT |
592 VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT))) {
sfricke-samsungbda4a852021-03-06 20:58:01 -0800593 skip |= val_obj->LogError(
594 val_obj->device, "VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-flags-03003",
595 "vkCreateDescriptorSetLayout(): pBindings[%u] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, "
596 "VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, or "
597 "VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT for with "
598 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR.",
599 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -0500600 }
601 }
602 }
603 }
604
John Zulauf0fdeab32018-01-23 11:27:35 -0700605 if ((push_descriptor_set) && (total_descriptors > max_push_descriptors)) {
606 const char *undefined = push_descriptor_ext ? "" : " -- undefined";
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700607 skip |= val_obj->LogError(
608 val_obj->device, "VUID-VkDescriptorSetLayoutCreateInfo-flags-00281",
sfricke-samsungbda4a852021-03-06 20:58:01 -0800609 "vkCreateDescriptorSetLayout(): for push descriptor, total descriptor count in layout (%" PRIu64
Mark Lobodzinskid18de902020-01-15 12:20:37 -0700610 ") must not be greater than VkPhysicalDevicePushDescriptorPropertiesKHR::maxPushDescriptors (%" PRIu32 "%s).",
611 total_descriptors, max_push_descriptors, undefined);
John Zulauf0fdeab32018-01-23 11:27:35 -0700612 }
613
Tobin Ehlis154c2692016-10-25 09:36:53 -0600614 return skip;
615}
616
Mark Lobodzinskie12b6e32020-06-29 11:44:15 -0600617void cvdescriptorset::AllocateDescriptorSetsData::Init(uint32_t count) {
618 layout_nodes.resize(count);
Mark Lobodzinskie12b6e32020-06-29 11:44:15 -0600619}
Tobin Ehlis68d0adf2016-06-01 11:33:50 -0600620
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500621cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, DESCRIPTOR_POOL_STATE *pool_state,
Jeff Bolzfdf96072018-04-10 14:32:18 -0500622 const std::shared_ptr<DescriptorSetLayout const> &layout, uint32_t variable_count,
John Zulaufd2c3dae2019-12-12 11:02:17 -0700623 const cvdescriptorset::DescriptorSet::StateTracker *state_data)
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -0700624 : some_update_(false),
625 set_(set),
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500626 pool_state_(pool_state),
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700627 layout_(layout),
John Zulaufd2c3dae2019-12-12 11:02:17 -0700628 state_data_(state_data),
Jeff Bolzdd4cfa12019-08-11 20:57:51 -0500629 variable_count_(variable_count),
630 change_count_(0) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600631 // Foreach binding, create default descriptors of given type
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700632 descriptors_.reserve(layout_->GetTotalDescriptorCount());
633 descriptor_store_.resize(layout_->GetTotalDescriptorCount());
John Zulaufe4850d42019-12-30 16:10:55 -0700634 auto free_descriptor = descriptor_store_.data();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700635 for (uint32_t i = 0; i < layout_->GetBindingCount(); ++i) {
636 auto type = layout_->GetTypeFromIndex(i);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600637 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700638 case VK_DESCRIPTOR_TYPE_SAMPLER: {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700639 auto immut_sampler = layout_->GetImmutableSamplerPtrFromIndex(i);
640 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
Tobin Ehlis082c7512017-05-08 11:24:57 -0600641 if (immut_sampler) {
John Zulaufe4850d42019-12-30 16:10:55 -0700642 descriptors_.emplace_back(new ((free_descriptor++)->Sampler())
643 SamplerDescriptor(state_data, immut_sampler + di));
Tobin Ehlis082c7512017-05-08 11:24:57 -0600644 some_update_ = true; // Immutable samplers are updated at creation
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700645 } else {
John Zulaufe4850d42019-12-30 16:10:55 -0700646 descriptors_.emplace_back(new ((free_descriptor++)->Sampler()) SamplerDescriptor(state_data, nullptr));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700647 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700648 }
649 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600650 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700651 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700652 auto immut = layout_->GetImmutableSamplerPtrFromIndex(i);
653 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
Tobin Ehlis082c7512017-05-08 11:24:57 -0600654 if (immut) {
John Zulaufe4850d42019-12-30 16:10:55 -0700655 descriptors_.emplace_back(new ((free_descriptor++)->ImageSampler())
656 ImageSamplerDescriptor(state_data, immut + di));
Tobin Ehlis082c7512017-05-08 11:24:57 -0600657 some_update_ = true; // Immutable samplers are updated at creation
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700658 } else {
John Zulaufe4850d42019-12-30 16:10:55 -0700659 descriptors_.emplace_back(new ((free_descriptor++)->ImageSampler())
660 ImageSamplerDescriptor(state_data, nullptr));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700661 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700662 }
663 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600664 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700665 // ImageDescriptors
666 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
667 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
668 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700669 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700670 descriptors_.emplace_back(new ((free_descriptor++)->Image()) ImageDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700671 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700672 break;
673 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
674 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700675 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700676 descriptors_.emplace_back(new ((free_descriptor++)->Texel()) TexelDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700677 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700678 break;
sfricke-samsung4ca35652021-03-05 02:22:10 -0800679 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
680 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
681 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700682 descriptors_.emplace_back(new ((free_descriptor++)->Buffer()) BufferDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700683 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700684 break;
Jeff Bolze54ae892018-09-08 12:16:29 -0500685 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700686 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700687 descriptors_.emplace_back(new ((free_descriptor++)->InlineUniform()) InlineUniformDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700688 }
Jeff Bolze54ae892018-09-08 12:16:29 -0500689 break;
Eric Werness30127fd2018-10-31 21:01:03 -0700690 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
sourav parmarcd5fb182020-07-17 12:58:44 -0700691 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700692 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
John Zulaufe4850d42019-12-30 16:10:55 -0700693 descriptors_.emplace_back(new ((free_descriptor++)->AccelerationStructure())
694 AccelerationStructureDescriptor(type));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700695 }
Jeff Bolzfbe51582018-09-13 10:01:35 -0500696 break;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700697 default:
sfricke-samsung60f29ec2021-03-10 20:37:25 -0800698 if (IsDynamicDescriptor(type) && IsBufferDescriptor(type)) {
699 for (uint32_t di = 0; di < layout_->GetDescriptorCountFromIndex(i); ++di) {
700 dynamic_offset_idx_to_descriptor_list_.push_back(descriptors_.size());
701 descriptors_.emplace_back(new ((free_descriptor++)->Buffer()) BufferDescriptor(type));
702 }
703 } else {
704 assert(0); // Bad descriptor type specified
705 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700706 break;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -0600707 }
708 }
709}
Tobin Ehlis56a30942016-05-19 08:00:00 -0600710
Jeff Bolz41a1ced2019-10-11 11:40:49 -0500711cvdescriptorset::DescriptorSet::~DescriptorSet() {}
Chris Forbes57989132016-07-26 17:06:10 +1200712
Shannon McPhersonc06c33d2018-06-28 17:21:12 -0600713static std::string StringDescriptorReqViewType(descriptor_req req) {
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700714 std::string result("");
Mark Lobodzinski29f451a2020-02-10 16:15:30 -0700715 for (unsigned i = 0; i <= VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; i++) {
Chris Forbes57989132016-07-26 17:06:10 +1200716 if (req & (1 << i)) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700717 if (result.size()) result += ", ";
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700718 result += string_VkImageViewType(VkImageViewType(i));
Chris Forbes57989132016-07-26 17:06:10 +1200719 }
720 }
721
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700722 if (!result.size()) result = "(none)";
Chris Forbes6e58ebd2016-08-31 12:58:14 -0700723
724 return result;
Chris Forbes57989132016-07-26 17:06:10 +1200725}
726
Chris Forbesda01e8d2018-08-27 15:36:57 -0700727static char const *StringDescriptorReqComponentType(descriptor_req req) {
728 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_SINT) return "SINT";
729 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_UINT) return "UINT";
730 if (req & DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT) return "FLOAT";
731 return "(none)";
732}
733
Jeff Bolz6cede832019-08-09 23:30:39 -0500734unsigned DescriptorRequirementsBitsFromFormat(VkFormat fmt) {
Chris Forbesda01e8d2018-08-27 15:36:57 -0700735 if (FormatIsSInt(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_SINT;
736 if (FormatIsUInt(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_UINT;
737 if (FormatIsDepthAndStencil(fmt)) return DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT | DESCRIPTOR_REQ_COMPONENT_TYPE_UINT;
738 if (fmt == VK_FORMAT_UNDEFINED) return 0;
739 // everything else -- UNORM/SNORM/FLOAT/USCALED/SSCALED is all float in the shader.
740 return DESCRIPTOR_REQ_COMPONENT_TYPE_FLOAT;
741}
742
Tobin Ehlis3066db62016-08-22 08:12:23 -0600743// 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 -0600744// This includes validating that all descriptors in the given bindings are updated,
745// that any update buffers are valid, and that any dynamic offsets are within the bounds of their buffers.
746// Return true if state is acceptable, or false and write an error message into error string
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600747bool CoreChecks::ValidateDrawState(const DescriptorSet *descriptor_set, const BindingReqMap &bindings,
748 const std::vector<uint32_t> &dynamic_offsets, const CMD_BUFFER_STATE *cb_node,
locke-lunargfc78e932020-11-19 17:06:24 -0700749 const std::vector<IMAGE_VIEW_STATE *> *attachments, const std::vector<SUBPASS_INFO> &subpasses,
750 const char *caller, const DrawDispatchVuid &vuids) const {
Tony-LunarGace473a2020-05-06 12:48:04 -0600751 bool result = false;
locke-lunarg540b2252020-08-03 13:23:36 -0600752 VkFramebuffer framebuffer = cb_node->activeFramebuffer ? cb_node->activeFramebuffer->framebuffer : VK_NULL_HANDLE;
John Zulauf79f06582021-02-27 18:38:39 -0700753 for (const auto &binding_pair : bindings) {
754 const auto binding = binding_pair.first;
John Zulauf382e1912019-06-10 15:27:44 -0600755 DescriptorSetLayout::ConstBindingIterator binding_it(descriptor_set->GetLayout().get(), binding);
756 if (binding_it.AtEnd()) { // End at construction is the condition for an invalid binding.
Tony-LunarGace473a2020-05-06 12:48:04 -0600757 auto set = descriptor_set->GetSet();
locke-lunarg1328e8e2020-08-20 12:40:08 -0600758 result |= LogError(set, vuids.descriptor_valid,
Tony-LunarGace473a2020-05-06 12:48:04 -0600759 "%s encountered the following validation error at %s time: Attempting to "
760 "validate DrawState for binding #%u which is an invalid binding for this descriptor set.",
761 report_data->FormatHandle(set).c_str(), caller, binding);
762 return result;
Tobin Ehlis58c59582016-06-21 12:34:33 -0600763 }
Jeff Bolz6cede832019-08-09 23:30:39 -0500764
765 if (binding_it.GetDescriptorBindingFlags() &
Mike Schuchardt2df08912020-12-15 16:28:09 -0800766 (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT)) {
Jeff Bolz6cede832019-08-09 23:30:39 -0500767 // Can't validate the descriptor because it may not have been updated,
768 // or the view could have been destroyed
769 continue;
770 }
John Zulauf81dd1f12021-01-26 16:49:16 -0700771 // // This is a record time only path
772 const bool record_time_validate = true;
locke-lunargfc78e932020-11-19 17:06:24 -0700773 result |= ValidateDescriptorSetBindingData(cb_node, descriptor_set, dynamic_offsets, binding_pair, framebuffer, attachments,
John Zulauf81dd1f12021-01-26 16:49:16 -0700774 subpasses, record_time_validate, caller, vuids);
unknown3087a642019-09-26 17:21:05 -0600775 }
Tony-LunarGace473a2020-05-06 12:48:04 -0600776 return result;
unknown3087a642019-09-26 17:21:05 -0600777}
Jeff Bolz6cede832019-08-09 23:30:39 -0500778
locke-lunargb8be8222020-10-20 00:34:37 -0600779bool CoreChecks::ValidateDescriptorSetBindingData(const CMD_BUFFER_STATE *cb_node, const DescriptorSet *descriptor_set,
780 const std::vector<uint32_t> &dynamic_offsets,
John Zulauf79f06582021-02-27 18:38:39 -0700781 const std::pair<const uint32_t, DescriptorRequirement> &binding_info,
Mark Lobodzinski85ebd402020-12-03 12:56:07 -0700782 VkFramebuffer framebuffer, const std::vector<IMAGE_VIEW_STATE *> *attachments,
John Zulauf81dd1f12021-01-26 16:49:16 -0700783 const std::vector<SUBPASS_INFO> &subpasses, bool record_time_validate,
784 const char *caller, const DrawDispatchVuid &vuids) const {
unknown3087a642019-09-26 17:21:05 -0600785 using DescriptorClass = cvdescriptorset::DescriptorClass;
786 using BufferDescriptor = cvdescriptorset::BufferDescriptor;
787 using ImageDescriptor = cvdescriptorset::ImageDescriptor;
788 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
789 using SamplerDescriptor = cvdescriptorset::SamplerDescriptor;
790 using TexelDescriptor = cvdescriptorset::TexelDescriptor;
Jeff Bolz95176d02020-04-01 00:36:16 -0500791 using AccelerationStructureDescriptor = cvdescriptorset::AccelerationStructureDescriptor;
locke-lunarg36045992020-08-20 16:54:37 -0600792 const auto reqs = binding_info.second.reqs;
793 const auto binding = binding_info.first;
unknown3087a642019-09-26 17:21:05 -0600794 DescriptorSetLayout::ConstBindingIterator binding_it(descriptor_set->GetLayout().get(), binding);
795 {
John Zulauf382e1912019-06-10 15:27:44 -0600796 // Copy the range, the end range is subject to update based on variable length descriptor arrays.
797 cvdescriptorset::IndexRange index_range = binding_it.GetGlobalIndexRange();
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700798 auto array_idx = 0; // Track array idx if we're dealing with array descriptors
Jeff Bolzfdf96072018-04-10 14:32:18 -0500799
John Zulauf382e1912019-06-10 15:27:44 -0600800 if (binding_it.IsVariableDescriptorCount()) {
Jeff Bolzfdf96072018-04-10 14:32:18 -0500801 // Only validate the first N descriptors if it uses variable_count
John Zulauf382e1912019-06-10 15:27:44 -0600802 index_range.end = index_range.start + descriptor_set->GetVariableDescriptorCount();
Jeff Bolzfdf96072018-04-10 14:32:18 -0500803 }
804
John Zulaufc483f442017-12-15 14:02:06 -0700805 for (uint32_t i = index_range.start; i < index_range.end; ++i, ++array_idx) {
Lockeb994adf2019-03-29 23:52:31 -0600806 uint32_t index = i - index_range.start;
John Zulauf382e1912019-06-10 15:27:44 -0600807 const auto *descriptor = descriptor_set->GetDescriptorFromGlobalIndex(i);
Jeremy Gebben550ebbd2021-03-11 05:04:52 -0700808 const auto descriptor_class = descriptor->GetClass();
Lockeb994adf2019-03-29 23:52:31 -0600809
Jeremy Gebben550ebbd2021-03-11 05:04:52 -0700810 if (descriptor_class == DescriptorClass::InlineUniform) {
Jeff Bolz6cede832019-08-09 23:30:39 -0500811 // Can't validate the descriptor because it may not have been updated.
Jeff Bolzfdf96072018-04-10 14:32:18 -0500812 continue;
John Zulauf382e1912019-06-10 15:27:44 -0600813 } else if (!descriptor->updated) {
Tony-LunarGace473a2020-05-06 12:48:04 -0600814 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -0800815 return LogError(
816 set, vuids.descriptor_valid,
817 "Descriptor set %s encountered the following validation error at %s time: Descriptor in binding #%" PRIu32
818 " index %" PRIu32
819 " is being used in draw but has never been updated via vkUpdateDescriptorSets() or a similar call.",
820 report_data->FormatHandle(set).c_str(), caller, binding, index);
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700821 } else {
John Zulaufc93c4252019-06-25 09:19:49 -0600822 if (descriptor_class == DescriptorClass::GeneralBuffer) {
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700823 // Verify that buffers are valid
John Zulauf382e1912019-06-10 15:27:44 -0600824 auto buffer = static_cast<const BufferDescriptor *>(descriptor)->GetBuffer();
Jeff Bolzfaffeb32019-10-04 12:47:16 -0500825 auto buffer_node = static_cast<const BufferDescriptor *>(descriptor)->GetBufferState();
Karl Schultz76d16a42020-11-11 05:05:33 -0700826 if ((!buffer_node && !enabled_features.robustness2_features.nullDescriptor) ||
827 (buffer_node && buffer_node->destroyed)) {
828 auto set = descriptor_set->GetSet();
829 return LogError(set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -0800830 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
Karl Schultz76d16a42020-11-11 05:05:33 -0700831 "binding #%" PRIu32 " index %" PRIu32
832 " is using buffer %s that is invalid or has been destroyed.",
833 report_data->FormatHandle(set).c_str(), caller, binding, index,
834 report_data->FormatHandle(buffer).c_str());
835 }
Jeff Bolz165818a2020-05-08 11:19:03 -0500836 if (buffer) {
Karl Schultz76d16a42020-11-11 05:05:33 -0700837 if (!buffer_node->sparse) {
John Zulauf79f06582021-02-27 18:38:39 -0700838 for (const auto *mem_binding : buffer_node->GetBoundMemory()) {
Jeff Bolz165818a2020-05-08 11:19:03 -0500839 if (mem_binding->destroyed) {
840 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -0800841 return LogError(
842 set, vuids.descriptor_valid,
843 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
844 "binding #%" PRIu32 " index %" PRIu32
845 " is uses buffer %s that references invalid memory %s.",
846 report_data->FormatHandle(set).c_str(), caller, binding, index,
847 report_data->FormatHandle(buffer).c_str(),
848 report_data->FormatHandle(mem_binding->mem).c_str());
Jeff Bolz165818a2020-05-08 11:19:03 -0500849 }
Tobin Ehlisc8266452017-04-07 12:20:30 -0600850 }
851 }
locke-lunarg351c9d82020-10-23 14:43:21 -0600852 if (enabled_features.core11.protectedMemory == VK_TRUE) {
853 if (ValidateProtectedBuffer(cb_node, buffer_node, caller, vuids.unprotected_command_buffer,
854 "Buffer is in a descriptorSet")) {
855 return true;
856 }
857 if (binding_info.second.is_writable &&
858 ValidateUnprotectedBuffer(cb_node, buffer_node, caller, vuids.protected_command_buffer,
859 "Buffer is in a descriptorSet")) {
860 return true;
861 }
862 }
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700863 }
John Zulaufc93c4252019-06-25 09:19:49 -0600864 } else if (descriptor_class == DescriptorClass::ImageSampler || descriptor_class == DescriptorClass::Image) {
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700865 VkImageView image_view;
866 VkImageLayout image_layout;
Jeff Bolzfaffeb32019-10-04 12:47:16 -0500867 const IMAGE_VIEW_STATE *image_view_state;
locke-lunarg4e1e4632020-10-26 01:52:19 -0600868 std::vector<const SAMPLER_STATE *> sampler_states;
locke-lunarg36045992020-08-20 16:54:37 -0600869
John Zulaufc93c4252019-06-25 09:19:49 -0600870 if (descriptor_class == DescriptorClass::ImageSampler) {
locke-lunarg36045992020-08-20 16:54:37 -0600871 const ImageSamplerDescriptor *image_descriptor = static_cast<const ImageSamplerDescriptor *>(descriptor);
872 image_view = image_descriptor->GetImageView();
873 image_view_state = image_descriptor->GetImageViewState();
874 image_layout = image_descriptor->GetImageLayout();
locke-lunarg4e1e4632020-10-26 01:52:19 -0600875 sampler_states.emplace_back(image_descriptor->GetSamplerState());
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700876 } else {
locke-lunarg36045992020-08-20 16:54:37 -0600877 const ImageDescriptor *image_descriptor = static_cast<const ImageDescriptor *>(descriptor);
878 image_view = image_descriptor->GetImageView();
879 image_view_state = image_descriptor->GetImageViewState();
880 image_layout = image_descriptor->GetImageLayout();
locke-lunarg4e1e4632020-10-26 01:52:19 -0600881
882 if (binding_info.second.samplers_used_by_image.size() > index) {
883 for (auto &sampler : binding_info.second.samplers_used_by_image[index]) {
Nathaniel Cesarioaa8dd222021-02-17 23:45:11 -0700884 // NOTE: This check _shouldn't_ be necessary due to the checks made in IsSpecificDescriptorType in
885 // shader_validation.cpp. However, without this check some traces still crash.
886 if (sampler.second &&
887 (sampler.second->GetClass() == cvdescriptorset::DescriptorClass::PlainSampler)) {
locke-lunarg4e1e4632020-10-26 01:52:19 -0600888 const auto *sampler_state =
889 static_cast<const cvdescriptorset::SamplerDescriptor *>(sampler.second)->GetSamplerState();
890 if (sampler_state) sampler_states.emplace_back(sampler_state);
891 }
892 }
893 }
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700894 }
Chris Forbes1f7f3ca2017-05-08 13:54:50 -0700895
Karl Schultz76d16a42020-11-11 05:05:33 -0700896 if ((!image_view_state && !enabled_features.robustness2_features.nullDescriptor) ||
897 (image_view_state && image_view_state->destroyed)) {
898 // Image view must have been destroyed since initial update. Could potentially flag the descriptor
899 // as "invalid" (updated = false) at DestroyImageView() time and detect this error at bind time
900
901 auto set = descriptor_set->GetSet();
902 return LogError(set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -0800903 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
Karl Schultz76d16a42020-11-11 05:05:33 -0700904 "binding #%" PRIu32 " index %" PRIu32
905 " is using imageView %s that is invalid or has been destroyed.",
906 report_data->FormatHandle(set).c_str(), caller, binding, index,
907 report_data->FormatHandle(image_view).c_str());
908 }
Jeff Bolz165818a2020-05-08 11:19:03 -0500909 if (image_view) {
Jeff Bolz165818a2020-05-08 11:19:03 -0500910 const auto &image_view_ci = image_view_state->create_info;
locke-lunarg4e1e4632020-10-26 01:52:19 -0600911 const auto *image_state = image_view_state->image_state.get();
912
Jeff Bolz165818a2020-05-08 11:19:03 -0500913 if (reqs & DESCRIPTOR_REQ_ALL_VIEW_TYPE_BITS) {
914 if (~reqs & (1 << image_view_ci.viewType)) {
915 auto set = descriptor_set->GetSet();
916 return LogError(
locke-lunarg1328e8e2020-08-20 12:40:08 -0600917 set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -0800918 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
Jeff Bolz165818a2020-05-08 11:19:03 -0500919 "in binding #%" PRIu32 " index %" PRIu32 " requires an image view of type %s but got %s.",
920 report_data->FormatHandle(set).c_str(), caller, binding, index,
921 StringDescriptorReqViewType(reqs).c_str(), string_VkImageViewType(image_view_ci.viewType));
922 }
923
924 if (!(reqs & image_view_state->descriptor_format_bits)) {
925 // bad component type
926 auto set = descriptor_set->GetSet();
locke-lunarg1328e8e2020-08-20 12:40:08 -0600927 return LogError(set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -0800928 "Descriptor set %s encountered the following validation error at %s time: "
929 "Descriptor in binding "
Jeff Bolz165818a2020-05-08 11:19:03 -0500930 "#%" PRIu32 " index %" PRIu32
931 " requires %s component type, but bound descriptor format is %s.",
932 report_data->FormatHandle(set).c_str(), caller, binding, index,
933 StringDescriptorReqComponentType(reqs), string_VkFormat(image_view_ci.format));
934 }
935 }
936
John Zulauf81dd1f12021-01-26 16:49:16 -0700937 // NOTE: Submit time validation of UPDATE_AFTER_BIND image layout is not possible with the
938 // image layout tracking as currently implemented, so only record_time_validation is done
939 if (!disabled[image_layout_validation] && record_time_validate) {
Jeff Bolz165818a2020-05-08 11:19:03 -0500940 auto image_node = image_view_state->image_state.get();
941 assert(image_node);
942 // Verify Image Layout
943 // No "invalid layout" VUID required for this call, since the optimal_layout parameter is UNDEFINED.
944 bool hit_error = false;
945 VerifyImageLayout(cb_node, image_node, image_view_state->normalized_subresource_range,
946 image_view_ci.subresourceRange.aspectMask, image_layout, VK_IMAGE_LAYOUT_UNDEFINED,
947 caller, kVUIDUndefined, "VUID-VkDescriptorImageInfo-imageLayout-00344", &hit_error);
948 if (hit_error) {
949 auto set = descriptor_set->GetSet();
950 return LogError(
locke-lunarg1328e8e2020-08-20 12:40:08 -0600951 set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -0800952 "Descriptor set %s encountered the following validation error at %s time: Image layout "
953 "specified "
Jeff Bolz165818a2020-05-08 11:19:03 -0500954 "at vkUpdateDescriptorSet* or vkCmdPushDescriptorSet* time "
955 "doesn't match actual image layout at time descriptor is used. See previous error callback for "
956 "specific details.",
957 report_data->FormatHandle(set).c_str(), caller);
958 }
959 }
960
961 // Verify Sample counts
962 if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) && image_view_state->samples != VK_SAMPLE_COUNT_1_BIT) {
963 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -0800964 return LogError(
965 set, vuids.descriptor_valid,
966 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
967 "binding #%" PRIu32 " index %" PRIu32
968 " requires bound image to have VK_SAMPLE_COUNT_1_BIT but got %s.",
969 report_data->FormatHandle(set).c_str(), caller, binding, index,
970 string_VkSampleCountFlagBits(image_view_state->samples));
Jeff Bolz165818a2020-05-08 11:19:03 -0500971 }
972 if ((reqs & DESCRIPTOR_REQ_MULTI_SAMPLE) && image_view_state->samples == VK_SAMPLE_COUNT_1_BIT) {
Tony-LunarGace473a2020-05-06 12:48:04 -0600973 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -0800974 return LogError(set, vuids.descriptor_valid,
975 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
976 "in binding #%" PRIu32 " index %" PRIu32
977 " requires bound image to have multiple samples, but got VK_SAMPLE_COUNT_1_BIT.",
978 report_data->FormatHandle(set).c_str(), caller, binding, index);
Jeff Bolz6cede832019-08-09 23:30:39 -0500979 }
locke-lunarg25b6c352020-08-06 17:44:18 -0600980
John Zulauf79f06582021-02-27 18:38:39 -0700981 const VkDescriptorType descriptor_type = binding_it.GetType();
locke-lunarg540b2252020-08-03 13:23:36 -0600982
locke-lunarg25b6c352020-08-06 17:44:18 -0600983 // Verify VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
984 if ((reqs & DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION) &&
locke-lunarg540b2252020-08-03 13:23:36 -0600985 (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) &&
locke-lunarg25b6c352020-08-06 17:44:18 -0600986 !(image_view_state->format_features & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) {
987 auto set = descriptor_set->GetSet();
988 LogObjectList objlist(set);
989 objlist.add(image_view);
sfricke-samsungbda4a852021-03-06 20:58:01 -0800990 return LogError(objlist, vuids.imageview_atomic,
991 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
992 "in binding #%" PRIu32 " index %" PRIu32
993 ", %s, format %s, doesn't "
994 "contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT.",
995 report_data->FormatHandle(set).c_str(), caller, binding, index,
996 report_data->FormatHandle(image_view).c_str(), string_VkFormat(image_view_ci.format));
locke-lunarg25b6c352020-08-06 17:44:18 -0600997 }
locke-lunarg540b2252020-08-03 13:23:36 -0600998
999 // Verify if attachments are used in DescriptorSet
locke-lunargfc78e932020-11-19 17:06:24 -07001000 if (attachments && attachments->size() > 0 && (descriptor_type != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
locke-lunarg5e1bdde2020-11-16 17:08:44 -07001001 bool ds_aspect = (image_view_state->create_info.subresourceRange.aspectMask &
1002 (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1003 ? true
1004 : false;
locke-lunargfc78e932020-11-19 17:06:24 -07001005 uint32_t att_index = 0;
1006 for (const auto &view_state : *attachments) {
1007 if (!subpasses[att_index].used || !view_state || view_state->destroyed) {
locke-lunarg1ae57d62020-11-18 10:49:19 -07001008 continue;
1009 }
locke-lunargfc78e932020-11-19 17:06:24 -07001010 if (ds_aspect && subpasses[att_index].usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
locke-lunarg5e1bdde2020-11-16 17:08:44 -07001011 if ((image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1012 image_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
1013 image_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL) &&
locke-lunargfc78e932020-11-19 17:06:24 -07001014 (subpasses[att_index].layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1015 subpasses[att_index].layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
1016 subpasses[att_index].layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL)) {
locke-lunarg5e1bdde2020-11-16 17:08:44 -07001017 continue;
1018 }
1019 if ((image_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL &&
locke-lunargfc78e932020-11-19 17:06:24 -07001020 subpasses[att_index].layout ==
1021 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL) ||
1022 (subpasses[att_index].layout ==
1023 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL &&
locke-lunarg5e1bdde2020-11-16 17:08:44 -07001024 image_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)) {
1025 continue;
1026 }
1027 }
locke-lunargfc78e932020-11-19 17:06:24 -07001028 if (view_state->image_view == image_view) {
locke-lunarg540b2252020-08-03 13:23:36 -06001029 auto set = descriptor_set->GetSet();
1030 LogObjectList objlist(set);
1031 objlist.add(image_view);
1032 objlist.add(framebuffer);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001033 return LogError(
1034 objlist, vuids.image_subresources,
1035 "Descriptor set %s encountered the following validation error at %s time: %s is used in "
1036 "Descriptor in binding #%" PRIu32 " index %" PRIu32 " and %s attachment # %" PRIu32 ".",
1037 report_data->FormatHandle(set).c_str(), caller,
1038 report_data->FormatHandle(image_view).c_str(), binding, index,
1039 report_data->FormatHandle(framebuffer).c_str(), att_index);
locke-lunargfc78e932020-11-19 17:06:24 -07001040 } else {
1041 if (image_view_state->OverlapSubresource(*view_state)) {
locke-lunarg540b2252020-08-03 13:23:36 -06001042 auto set = descriptor_set->GetSet();
1043 LogObjectList objlist(set);
1044 objlist.add(image_view);
1045 objlist.add(framebuffer);
locke-lunargfc78e932020-11-19 17:06:24 -07001046 objlist.add(view_state->image_view);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001047 return LogError(objlist, vuids.image_subresources,
1048 "Descriptor set %s encountered the following validation error at %s time: "
1049 "Image subresources of %s in "
1050 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1051 " and %s in %s attachment # %" PRIu32 " overlap.",
1052 report_data->FormatHandle(set).c_str(), caller,
1053 report_data->FormatHandle(image_view).c_str(), binding, index,
1054 report_data->FormatHandle(view_state->image_view).c_str(),
1055 report_data->FormatHandle(framebuffer).c_str(), att_index);
locke-lunarg540b2252020-08-03 13:23:36 -06001056 }
1057 }
locke-lunargfc78e932020-11-19 17:06:24 -07001058 ++att_index;
locke-lunarg540b2252020-08-03 13:23:36 -06001059 }
locke-lunarg351c9d82020-10-23 14:43:21 -06001060 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1061 if (ValidateProtectedImage(cb_node, image_view_state->image_state.get(), caller,
1062 vuids.unprotected_command_buffer, "Image is in a descriptorSet")) {
1063 return true;
1064 }
1065 if (binding_info.second.is_writable &&
1066 ValidateUnprotectedImage(cb_node, image_view_state->image_state.get(), caller,
1067 vuids.protected_command_buffer, "Image is in a descriptorSet")) {
1068 return true;
1069 }
1070 }
locke-lunarg540b2252020-08-03 13:23:36 -06001071 }
locke-lunarg36045992020-08-20 16:54:37 -06001072
locke-lunarg4e1e4632020-10-26 01:52:19 -06001073 for (const auto *sampler_state : sampler_states) {
1074 if (!sampler_state || sampler_state->destroyed) {
1075 continue;
1076 }
locke-lunarg654a9052020-10-13 16:28:42 -06001077
locke-lunarg4e1e4632020-10-26 01:52:19 -06001078 // TODO: Validate 04015 for DescriptorClass::PlainSampler
1079 if ((sampler_state->createInfo.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT ||
1080 sampler_state->createInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) &&
1081 (sampler_state->customCreateInfo.format == VK_FORMAT_UNDEFINED)) {
1082 if (image_view_state->create_info.format == VK_FORMAT_B4G4R4A4_UNORM_PACK16 ||
1083 image_view_state->create_info.format == VK_FORMAT_B5G6R5_UNORM_PACK16 ||
1084 image_view_state->create_info.format == VK_FORMAT_B5G5R5A1_UNORM_PACK16) {
1085 auto set = descriptor_set->GetSet();
1086 LogObjectList objlist(set);
1087 objlist.add(sampler_state->sampler);
1088 objlist.add(image_view_state->image_view);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001089 return LogError(
1090 objlist, "VUID-VkSamplerCustomBorderColorCreateInfoEXT-format-04015",
1091 "Descriptor set %s encountered the following validation error at %s time: Sampler %s in "
1092 "binding #%" PRIu32 " index %" PRIu32
1093 " has a custom border color with format = VK_FORMAT_UNDEFINED and is used to "
1094 "sample an image view %s with format %s",
1095 report_data->FormatHandle(set).c_str(), caller,
1096 report_data->FormatHandle(sampler_state->sampler).c_str(), binding, index,
1097 report_data->FormatHandle(image_view_state->image_view).c_str(),
1098 string_VkFormat(image_view_state->create_info.format));
locke-lunarg4e1e4632020-10-26 01:52:19 -06001099 }
1100 }
1101 VkFilter sampler_mag_filter = sampler_state->createInfo.magFilter;
1102 VkFilter sampler_min_filter = sampler_state->createInfo.minFilter;
1103 VkBool32 sampler_compare_enable = sampler_state->createInfo.compareEnable;
1104 if ((sampler_mag_filter == VK_FILTER_LINEAR || sampler_min_filter == VK_FILTER_LINEAR) &&
1105 (sampler_compare_enable == VK_FALSE) &&
1106 !(image_view_state->format_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) {
locke-lunarg36045992020-08-20 16:54:37 -06001107 auto set = descriptor_set->GetSet();
1108 LogObjectList objlist(set);
locke-lunarg36045992020-08-20 16:54:37 -06001109 objlist.add(sampler_state->sampler);
locke-lunarg4e1e4632020-10-26 01:52:19 -06001110 objlist.add(image_view_state->image_view);
1111 return LogError(objlist, vuids.linear_sampler,
sfricke-samsungbda4a852021-03-06 20:58:01 -08001112 "Descriptor set %s encountered the following validation error at %s time: Sampler "
1113 "(%s) is set to use VK_FILTER_LINEAR with "
sfricke-samsung691299b2021-01-01 20:48:48 -08001114 "compareEnable is set to VK_TRUE, but image view's (%s) format (%s) does not "
locke-lunarg4e1e4632020-10-26 01:52:19 -06001115 "contain VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT in its format features.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08001116 report_data->FormatHandle(set).c_str(), caller,
locke-lunarg4e1e4632020-10-26 01:52:19 -06001117 report_data->FormatHandle(sampler_state->sampler).c_str(),
locke-lunarg4e1e4632020-10-26 01:52:19 -06001118 report_data->FormatHandle(image_view_state->image_view).c_str(),
1119 string_VkFormat(image_view_state->create_info.format));
locke-lunarg36045992020-08-20 16:54:37 -06001120 }
locke-lunarg9939d4b2020-10-26 20:11:08 -06001121 if (sampler_mag_filter == VK_FILTER_CUBIC_EXT || sampler_min_filter == VK_FILTER_CUBIC_EXT) {
1122 if (!(image_view_state->format_features & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT)) {
1123 auto set = descriptor_set->GetSet();
1124 LogObjectList objlist(set);
1125 objlist.add(sampler_state->sampler);
1126 objlist.add(image_view_state->image_view);
1127 return LogError(objlist, vuids.cubic_sampler,
sfricke-samsungbda4a852021-03-06 20:58:01 -08001128 "Descriptor set %s encountered the following validation error at %s time: "
1129 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT, then "
Mark Lobodzinski45034452020-11-30 16:56:48 -07001130 "image view's (%s) format (%s) MUST contain "
1131 "VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT in its format features.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08001132 report_data->FormatHandle(set).c_str(), caller,
locke-lunarg9939d4b2020-10-26 20:11:08 -06001133 report_data->FormatHandle(sampler_state->sampler).c_str(),
locke-lunarg9939d4b2020-10-26 20:11:08 -06001134 report_data->FormatHandle(image_view_state->image_view).c_str(),
1135 string_VkFormat(image_view_state->create_info.format));
1136 }
1137
Mark Lobodzinski45034452020-11-30 16:56:48 -07001138 if (IsExtEnabled(device_extensions.vk_ext_filter_cubic)) {
1139 const auto reduction_mode_info =
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001140 LvlFindInChain<VkSamplerReductionModeCreateInfo>(sampler_state->createInfo.pNext);
Mark Lobodzinski45034452020-11-30 16:56:48 -07001141 if (reduction_mode_info &&
1142 (reduction_mode_info->reductionMode == VK_SAMPLER_REDUCTION_MODE_MIN ||
1143 reduction_mode_info->reductionMode == VK_SAMPLER_REDUCTION_MODE_MAX) &&
1144 !image_view_state->filter_cubic_props.filterCubicMinmax) {
1145 auto set = descriptor_set->GetSet();
1146 LogObjectList objlist(set);
1147 objlist.add(sampler_state->sampler);
1148 objlist.add(image_view_state->image_view);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001149 return LogError(objlist, vuids.filter_cubic_min_max,
1150 "Descriptor set %s encountered the following validation error at %s time: "
1151 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT & %s, "
1152 "but image view (%s) doesn't support filterCubicMinmax.",
1153 report_data->FormatHandle(set).c_str(), caller,
1154 report_data->FormatHandle(sampler_state->sampler).c_str(),
1155 string_VkSamplerReductionMode(reduction_mode_info->reductionMode),
1156 report_data->FormatHandle(image_view_state->image_view).c_str());
Mark Lobodzinski45034452020-11-30 16:56:48 -07001157 }
1158
1159 if (!image_view_state->filter_cubic_props.filterCubic) {
1160 auto set = descriptor_set->GetSet();
1161 LogObjectList objlist(set);
1162 objlist.add(sampler_state->sampler);
1163 objlist.add(image_view_state->image_view);
1164 return LogError(objlist, vuids.filter_cubic,
sfricke-samsungbda4a852021-03-06 20:58:01 -08001165 "Descriptor set %s encountered the following validation error at %s time: "
1166 "Sampler (%s) is set to use VK_FILTER_CUBIC_EXT, "
Mark Lobodzinski45034452020-11-30 16:56:48 -07001167 "but image view (%s) doesn't support filterCubic.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08001168 report_data->FormatHandle(set).c_str(), caller,
Mark Lobodzinski45034452020-11-30 16:56:48 -07001169 report_data->FormatHandle(sampler_state->sampler).c_str(),
Mark Lobodzinski45034452020-11-30 16:56:48 -07001170 report_data->FormatHandle(image_view_state->image_view).c_str());
1171 }
locke-lunarg9939d4b2020-10-26 20:11:08 -06001172 }
1173
Mark Lobodzinski45034452020-11-30 16:56:48 -07001174 if (IsExtEnabled(device_extensions.vk_img_filter_cubic)) {
1175 if (image_view_state->create_info.viewType &
1176 (VK_IMAGE_VIEW_TYPE_3D | VK_IMAGE_VIEW_TYPE_CUBE | VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)) {
1177 auto set = descriptor_set->GetSet();
1178 LogObjectList objlist(set);
1179 objlist.add(sampler_state->sampler);
1180 objlist.add(image_view_state->image_view);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001181 return LogError(
1182 objlist, vuids.img_filter_cubic,
1183 "Descriptor set %s encountered the following validation error at %s time: Sampler "
1184 "(%s)is set to use VK_FILTER_CUBIC_EXT while the VK_IMG_filter_cubic extension "
1185 "is enabled, but image view (%s) has an invalid imageViewType (%s).",
1186 report_data->FormatHandle(set).c_str(), caller,
1187 report_data->FormatHandle(sampler_state->sampler).c_str(),
1188 report_data->FormatHandle(image_view_state->image_view).c_str(),
1189 string_VkImageViewType(image_view_state->create_info.viewType));
Mark Lobodzinski45034452020-11-30 16:56:48 -07001190 }
locke-lunarg9939d4b2020-10-26 20:11:08 -06001191 }
locke-lunarg654a9052020-10-13 16:28:42 -06001192 }
1193
locke-lunarg4e1e4632020-10-26 01:52:19 -06001194 if ((image_state->createInfo.flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) &&
1195 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE ||
1196 sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE ||
1197 sampler_state->createInfo.addressModeW != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)) {
1198 std::string address_mode_letter =
locke-lunarg9939d4b2020-10-26 20:11:08 -06001199 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1200 ? "U"
1201 : (sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) ? "V"
1202 : "W";
locke-lunarg4e1e4632020-10-26 01:52:19 -06001203 VkSamplerAddressMode address_mode =
1204 (sampler_state->createInfo.addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1205 ? sampler_state->createInfo.addressModeU
locke-lunarg9939d4b2020-10-26 20:11:08 -06001206 : (sampler_state->createInfo.addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
1207 ? sampler_state->createInfo.addressModeV
1208 : sampler_state->createInfo.addressModeW;
locke-lunargae2a43c2020-09-22 17:21:57 -06001209 auto set = descriptor_set->GetSet();
1210 LogObjectList objlist(set);
locke-lunargae2a43c2020-09-22 17:21:57 -06001211 objlist.add(sampler_state->sampler);
locke-lunarg4e1e4632020-10-26 01:52:19 -06001212 objlist.add(image_state->image);
1213 objlist.add(image_view_state->image_view);
1214 return LogError(objlist, vuids.corner_sampled_address_mode,
sfricke-samsungbda4a852021-03-06 20:58:01 -08001215 "Descriptor set %s encountered the following validation error at %s time: Image "
1216 "(%s) in image view (%s) is created with flag "
locke-lunarg4e1e4632020-10-26 01:52:19 -06001217 "VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and can only be sampled using "
1218 "VK_SAMPLER_ADDRESS_MODE_CLAMP_EDGE, but sampler (%s) has "
1219 "createInfo.addressMode%s set to %s.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08001220 report_data->FormatHandle(set).c_str(), caller,
locke-lunarg4e1e4632020-10-26 01:52:19 -06001221 report_data->FormatHandle(image_state->image).c_str(),
1222 report_data->FormatHandle(image_view_state->image_view).c_str(),
locke-lunarg4e1e4632020-10-26 01:52:19 -06001223 report_data->FormatHandle(sampler_state->sampler).c_str(),
1224 address_mode_letter.c_str(), string_VkSamplerAddressMode(address_mode));
1225 }
1226
1227 // UnnormalizedCoordinates sampler validations
1228 if (sampler_state->createInfo.unnormalizedCoordinates) {
1229 // If ImageView is used by a unnormalizedCoordinates sampler, it needs to check ImageView type
1230 if (image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_3D ||
1231 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1232 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY ||
1233 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY ||
1234 image_view_ci.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
1235 auto set = descriptor_set->GetSet();
1236 LogObjectList objlist(set);
1237 objlist.add(image_view);
1238 objlist.add(sampler_state->sampler);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001239 return LogError(
1240 objlist, vuids.sampler_imageview_type,
1241 "Descriptor set %s encountered the following validation error at %s time: %s, type: %s in "
1242 "Descriptor in binding #%" PRIu32 " index %" PRIu32 "is used by %s.",
1243 report_data->FormatHandle(set).c_str(), caller,
1244 report_data->FormatHandle(image_view).c_str(),
1245 string_VkImageViewType(image_view_ci.viewType), binding, index,
1246 report_data->FormatHandle(sampler_state->sampler).c_str());
locke-lunarg4e1e4632020-10-26 01:52:19 -06001247 }
1248
1249 // sampler must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample*
1250 // instructions with ImplicitLod, Dref or Proj in their name
1251 if (reqs & DESCRIPTOR_REQ_SAMPLER_IMPLICITLOD_DREF_PROJ) {
1252 auto set = descriptor_set->GetSet();
1253 LogObjectList objlist(set);
1254 objlist.add(image_view);
1255 objlist.add(sampler_state->sampler);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001256 return LogError(
1257 objlist, vuids.sampler_implicitLod_dref_proj,
1258 "Descriptor set %s encountered the following validation error at %s time: %s in "
1259 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1260 " is used by %s that uses invalid operator.",
1261 report_data->FormatHandle(set).c_str(), caller,
1262 report_data->FormatHandle(image_view).c_str(), binding, index,
1263 report_data->FormatHandle(sampler_state->sampler).c_str());
locke-lunarg4e1e4632020-10-26 01:52:19 -06001264 }
1265
1266 // sampler must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample*
1267 // instructions that includes a LOD bias or any offset values
1268 if (reqs & DESCRIPTOR_REQ_SAMPLER_BIAS_OFFSET) {
1269 auto set = descriptor_set->GetSet();
1270 LogObjectList objlist(set);
1271 objlist.add(image_view);
1272 objlist.add(sampler_state->sampler);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001273 return LogError(
1274 objlist, vuids.sampler_bias_offset,
1275 "Descriptor set %s encountered the following validation error at %s time: %s in "
1276 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1277 " is used by %s that uses invalid bias or offset operator.",
1278 report_data->FormatHandle(set).c_str(), caller,
1279 report_data->FormatHandle(image_view).c_str(), binding, index,
1280 report_data->FormatHandle(sampler_state->sampler).c_str());
locke-lunarg4e1e4632020-10-26 01:52:19 -06001281 }
locke-lunargae2a43c2020-09-22 17:21:57 -06001282 }
locke-lunarg36045992020-08-20 16:54:37 -06001283 }
Chris Forbes1f7f3ca2017-05-08 13:54:50 -07001284 }
John Zulaufc93c4252019-06-25 09:19:49 -06001285 } else if (descriptor_class == DescriptorClass::TexelBuffer) {
John Zulauf382e1912019-06-10 15:27:44 -06001286 auto texel_buffer = static_cast<const TexelDescriptor *>(descriptor);
Jeff Bolzfaffeb32019-10-04 12:47:16 -05001287 auto buffer_view = texel_buffer->GetBufferView();
1288 auto buffer_view_state = texel_buffer->GetBufferViewState();
Chris Forbese92dd1d2019-01-21 15:58:57 -08001289
Karl Schultz76d16a42020-11-11 05:05:33 -07001290 if ((!buffer_view_state && !enabled_features.robustness2_features.nullDescriptor) ||
1291 (buffer_view_state && buffer_view_state->destroyed)) {
1292 auto set = descriptor_set->GetSet();
1293 return LogError(set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -08001294 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
Karl Schultz76d16a42020-11-11 05:05:33 -07001295 "binding #%" PRIu32 " index %" PRIu32
1296 " is using bufferView %s that is invalid or has been destroyed.",
1297 report_data->FormatHandle(set).c_str(), caller, binding, index,
1298 report_data->FormatHandle(buffer_view).c_str());
1299 }
Jeff Bolz165818a2020-05-08 11:19:03 -05001300 if (buffer_view) {
Jeff Bolz165818a2020-05-08 11:19:03 -05001301 auto buffer = buffer_view_state->create_info.buffer;
1302 auto buffer_state = buffer_view_state->buffer_state.get();
1303 if (buffer_state->destroyed) {
1304 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001305 return LogError(
1306 set, vuids.descriptor_valid,
1307 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1308 "binding #%" PRIu32 " index %" PRIu32 " is using buffer %s that has been destroyed.",
1309 report_data->FormatHandle(set).c_str(), caller, binding, index,
1310 report_data->FormatHandle(buffer).c_str());
Jeff Bolz165818a2020-05-08 11:19:03 -05001311 }
1312 auto format_bits = DescriptorRequirementsBitsFromFormat(buffer_view_state->create_info.format);
Chris Forbese92dd1d2019-01-21 15:58:57 -08001313
Jeff Bolz165818a2020-05-08 11:19:03 -05001314 if (!(reqs & format_bits)) {
1315 // bad component type
1316 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001317 return LogError(
1318 set, vuids.descriptor_valid,
1319 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1320 "binding #%" PRIu32 " index %" PRIu32
1321 " requires %s component type, but bound descriptor format is %s.",
1322 report_data->FormatHandle(set).c_str(), caller, binding, index,
1323 StringDescriptorReqComponentType(reqs), string_VkFormat(buffer_view_state->create_info.format));
Jeff Bolz165818a2020-05-08 11:19:03 -05001324 }
locke-lunarg25b6c352020-08-06 17:44:18 -06001325
1326 // Verify VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
1327 if ((reqs & DESCRIPTOR_REQ_VIEW_ATOMIC_OPERATION) &&
locke-lunarge4bf18f2020-08-21 10:23:08 -06001328 (descriptor_set->GetTypeFromBinding(binding) == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) &&
locke-lunarg25b6c352020-08-06 17:44:18 -06001329 !(buffer_view_state->format_features & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)) {
1330 auto set = descriptor_set->GetSet();
1331 LogObjectList objlist(set);
1332 objlist.add(buffer_view);
sfricke-samsungbda4a852021-03-06 20:58:01 -08001333 return LogError(objlist, "UNASSIGNED-None-MismatchAtomicBufferFeature",
1334 "Descriptor set %s encountered the following validation error at %s time: Descriptor "
1335 "in binding #%" PRIu32 " index %" PRIu32
1336 ", %s, format %s, doesn't "
1337 "contain VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT.",
1338 report_data->FormatHandle(set).c_str(), caller, binding, index,
1339 report_data->FormatHandle(buffer_view).c_str(),
1340 string_VkFormat(buffer_view_state->create_info.format));
locke-lunarg25b6c352020-08-06 17:44:18 -06001341 }
locke-lunarg351c9d82020-10-23 14:43:21 -06001342 if (enabled_features.core11.protectedMemory == VK_TRUE) {
1343 if (ValidateProtectedBuffer(cb_node, buffer_view_state->buffer_state.get(), caller,
1344 vuids.unprotected_command_buffer, "Buffer is in a descriptorSet")) {
1345 return true;
1346 }
1347 if (binding_info.second.is_writable &&
1348 ValidateUnprotectedBuffer(cb_node, buffer_view_state->buffer_state.get(), caller,
1349 vuids.protected_command_buffer, "Buffer is in a descriptorSet")) {
1350 return true;
1351 }
1352 }
Chris Forbese92dd1d2019-01-21 15:58:57 -08001353 }
Jeff Bolz95176d02020-04-01 00:36:16 -05001354 } else if (descriptor_class == DescriptorClass::AccelerationStructure) {
1355 // Verify that acceleration structures are valid
sourav parmarcd51aa82020-11-17 12:04:52 -08001356 bool is_khr = (*((cvdescriptorset::AccelerationStructureDescriptor *)(descriptor))).is_khr();
1357 if (is_khr) {
1358 auto acc = static_cast<const AccelerationStructureDescriptor *>(descriptor)->GetAccelerationStructure();
1359 auto acc_node =
1360 static_cast<const AccelerationStructureDescriptor *>(descriptor)->GetAccelerationStructureStateKHR();
1361 if (!acc_node || acc_node->destroyed) {
1362 if (acc != VK_NULL_HANDLE || !enabled_features.robustness2_features.nullDescriptor) {
1363 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001364 return LogError(set, vuids.descriptor_valid,
1365 "Descriptor set %s encountered the following validation error at %s time: "
1366 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1367 " is using acceleration structure %s that is invalid or has been destroyed.",
1368 report_data->FormatHandle(set).c_str(), caller, binding, index,
1369 report_data->FormatHandle(acc).c_str());
sourav parmarcd51aa82020-11-17 12:04:52 -08001370 }
1371 } else {
John Zulauf79f06582021-02-27 18:38:39 -07001372 for (const auto *mem_binding : acc_node->GetBoundMemory()) {
sourav parmarcd51aa82020-11-17 12:04:52 -08001373 if (mem_binding->destroyed) {
1374 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001375 return LogError(
1376 set, vuids.descriptor_valid,
1377 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1378 "binding #%" PRIu32 " index %" PRIu32
1379 " is using acceleration structure %s that references invalid memory %s.",
1380 report_data->FormatHandle(set).c_str(), caller, binding, index,
1381 report_data->FormatHandle(acc).c_str(),
1382 report_data->FormatHandle(mem_binding->mem).c_str());
sourav parmarcd51aa82020-11-17 12:04:52 -08001383 }
1384 }
Ricardo Garcia3f145ae2020-10-28 16:53:35 +01001385 }
Jeff Bolz95176d02020-04-01 00:36:16 -05001386 } else {
sourav parmarcd51aa82020-11-17 12:04:52 -08001387 auto acc = static_cast<const AccelerationStructureDescriptor *>(descriptor)->GetAccelerationStructureNV();
1388 auto acc_node =
1389 static_cast<const AccelerationStructureDescriptor *>(descriptor)->GetAccelerationStructureStateNV();
1390 if (!acc_node || acc_node->destroyed) {
1391 if (acc != VK_NULL_HANDLE || !enabled_features.robustness2_features.nullDescriptor) {
Tony-LunarGace473a2020-05-06 12:48:04 -06001392 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001393 return LogError(set, vuids.descriptor_valid,
1394 "Descriptor set %s encountered the following validation error at %s time: "
1395 "Descriptor in binding #%" PRIu32 " index %" PRIu32
1396 " is using acceleration structure %s that is invalid or has been destroyed.",
1397 report_data->FormatHandle(set).c_str(), caller, binding, index,
1398 report_data->FormatHandle(acc).c_str());
sourav parmarcd51aa82020-11-17 12:04:52 -08001399 }
1400 } else {
John Zulauf79f06582021-02-27 18:38:39 -07001401 for (const auto *mem_binding : acc_node->GetBoundMemory()) {
sourav parmarcd51aa82020-11-17 12:04:52 -08001402 if (mem_binding->destroyed) {
1403 auto set = descriptor_set->GetSet();
sfricke-samsungbda4a852021-03-06 20:58:01 -08001404 return LogError(
1405 set, vuids.descriptor_valid,
1406 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
1407 "binding #%" PRIu32 " index %" PRIu32
1408 " is using acceleration structure %s that references invalid memory %s.",
1409 report_data->FormatHandle(set).c_str(), caller, binding, index,
1410 report_data->FormatHandle(acc).c_str(),
1411 report_data->FormatHandle(mem_binding->mem).c_str());
sourav parmarcd51aa82020-11-17 12:04:52 -08001412 }
Jeff Bolz95176d02020-04-01 00:36:16 -05001413 }
1414 }
1415 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001416 }
locke-lunarg4e1e4632020-10-26 01:52:19 -06001417
1418 // If the validation is related to both of image and sampler,
locke-lunarg9939d4b2020-10-26 20:11:08 -06001419 // please leave it in (descriptor_class == DescriptorClass::ImageSampler || descriptor_class ==
1420 // DescriptorClass::Image) Here is to validate for only sampler.
John Zulaufc93c4252019-06-25 09:19:49 -06001421 if (descriptor_class == DescriptorClass::ImageSampler || descriptor_class == DescriptorClass::PlainSampler) {
Tobin Ehlisb1a2e4b2018-03-16 07:54:24 -06001422 // Verify Sampler still valid
1423 VkSampler sampler;
Jeff Bolzfaffeb32019-10-04 12:47:16 -05001424 const SAMPLER_STATE *sampler_state;
John Zulaufc93c4252019-06-25 09:19:49 -06001425 if (descriptor_class == DescriptorClass::ImageSampler) {
John Zulauf382e1912019-06-10 15:27:44 -06001426 sampler = static_cast<const ImageSamplerDescriptor *>(descriptor)->GetSampler();
Jeff Bolzfaffeb32019-10-04 12:47:16 -05001427 sampler_state = static_cast<const ImageSamplerDescriptor *>(descriptor)->GetSamplerState();
Tobin Ehlisb1a2e4b2018-03-16 07:54:24 -06001428 } else {
John Zulauf382e1912019-06-10 15:27:44 -06001429 sampler = static_cast<const SamplerDescriptor *>(descriptor)->GetSampler();
Jeff Bolzfaffeb32019-10-04 12:47:16 -05001430 sampler_state = static_cast<const SamplerDescriptor *>(descriptor)->GetSamplerState();
Tobin Ehlisb1a2e4b2018-03-16 07:54:24 -06001431 }
Jeff Bolzfaffeb32019-10-04 12:47:16 -05001432 if (!sampler_state || sampler_state->destroyed) {
Tony-LunarGace473a2020-05-06 12:48:04 -06001433 auto set = descriptor_set->GetSet();
locke-lunarg1328e8e2020-08-20 12:40:08 -06001434 return LogError(set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -08001435 "Descriptor set %s encountered the following validation error at %s time: Descriptor in "
Tony-LunarGace473a2020-05-06 12:48:04 -06001436 "binding #%" PRIu32 " index %" PRIu32
1437 " is using sampler %s that is invalid or has been destroyed.",
1438 report_data->FormatHandle(set).c_str(), caller, binding, index,
1439 report_data->FormatHandle(sampler).c_str());
Lockea223c102019-04-05 00:38:24 -06001440 } else {
John Zulauf382e1912019-06-10 15:27:44 -06001441 if (sampler_state->samplerConversion && !descriptor->IsImmutableSampler()) {
Tony-LunarGace473a2020-05-06 12:48:04 -06001442 auto set = descriptor_set->GetSet();
locke-lunarg1328e8e2020-08-20 12:40:08 -06001443 return LogError(set, vuids.descriptor_valid,
sfricke-samsungbda4a852021-03-06 20:58:01 -08001444 "Descriptor set %s encountered the following validation error at %s time: sampler (%s) "
Zach Johnston0480f132021-03-21 23:58:57 -04001445 "in the descriptor set (%s) contains a YCBCR conversion (%s), then the sampler MUST "
Tony-LunarGace473a2020-05-06 12:48:04 -06001446 "also exist as an immutable sampler.",
1447 report_data->FormatHandle(set).c_str(), caller,
1448 report_data->FormatHandle(sampler).c_str(),
1449 report_data->FormatHandle(descriptor_set->GetSet()).c_str(),
1450 report_data->FormatHandle(sampler_state->samplerConversion).c_str());
Lockea223c102019-04-05 00:38:24 -06001451 }
Tobin Ehlisb1a2e4b2018-03-16 07:54:24 -06001452 }
1453 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001454 }
1455 }
1456 }
Tony-LunarGace473a2020-05-06 12:48:04 -06001457 return false;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001458}
Chris Forbes57989132016-07-26 17:06:10 +12001459
Tobin Ehlis9906d9d2016-05-17 14:23:46 -06001460// Set is being deleted or updates so invalidate all bound cmd buffers
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001461void cvdescriptorset::DescriptorSet::InvalidateBoundCmdBuffers(ValidationStateTracker *state_data) {
1462 state_data->InvalidateCommandBuffers(cb_bindings, VulkanTypedHandle(set_, kVulkanObjectTypeDescriptorSet), /*unlink*/ false);
Tobin Ehlis9906d9d2016-05-17 14:23:46 -06001463}
John Zulauf1d27e0a2018-11-05 10:12:48 -07001464
1465// Loop through the write updates to do for a push descriptor set, ignoring dstSet
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001466void cvdescriptorset::DescriptorSet::PerformPushDescriptorsUpdate(ValidationStateTracker *dev_data, uint32_t write_count,
1467 const VkWriteDescriptorSet *p_wds) {
John Zulauf1d27e0a2018-11-05 10:12:48 -07001468 assert(IsPushDescriptor());
1469 for (uint32_t i = 0; i < write_count; i++) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001470 PerformWriteUpdate(dev_data, &p_wds[i]);
John Zulauf1d27e0a2018-11-05 10:12:48 -07001471 }
Jason Macnak83cfd582019-07-31 10:14:24 -07001472
1473 push_descriptor_set_writes.clear();
1474 push_descriptor_set_writes.reserve(static_cast<std::size_t>(write_count));
1475 for (uint32_t i = 0; i < write_count; i++) {
1476 push_descriptor_set_writes.push_back(safe_VkWriteDescriptorSet(&p_wds[i]));
1477 }
John Zulauf1d27e0a2018-11-05 10:12:48 -07001478}
1479
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001480// Perform write update in given update struct
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001481void cvdescriptorset::DescriptorSet::PerformWriteUpdate(ValidationStateTracker *dev_data, const VkWriteDescriptorSet *update) {
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001482 // Perform update on a per-binding basis as consecutive updates roll over to next binding
1483 auto descriptors_remaining = update->descriptorCount;
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001484 auto offset = update->dstArrayElement;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001485 auto orig_binding = DescriptorSetLayout::ConstBindingIterator(layout_.get(), update->dstBinding);
locke-lunarge46b7782019-09-10 01:44:20 -06001486 auto current_binding = orig_binding;
1487
Tobin Ehlise16805c2017-08-09 09:10:37 -06001488 uint32_t update_index = 0;
locke-lunarge46b7782019-09-10 01:44:20 -06001489 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
1490 while (descriptors_remaining && orig_binding.IsConsistent(current_binding)) {
1491 const auto &index_range = current_binding.GetGlobalIndexRange();
1492 auto global_idx = index_range.start + offset;
1493 // global_idx is which descriptor is needed to update. If global_idx > index_range.end, it means the descriptor isn't in
1494 // this binding, maybe in next binding.
1495 if (global_idx >= index_range.end) {
1496 offset -= current_binding.GetDescriptorCount();
1497 ++current_binding;
1498 continue;
1499 }
1500
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001501 // Loop over the updates for a single binding at a time
locke-lunarge46b7782019-09-10 01:44:20 -06001502 uint32_t update_count = std::min(descriptors_remaining, current_binding.GetDescriptorCount() - offset);
Tobin Ehlise16805c2017-08-09 09:10:37 -06001503 for (uint32_t di = 0; di < update_count; ++di, ++update_index) {
John Zulaufd2c3dae2019-12-12 11:02:17 -07001504 descriptors_[global_idx + di]->WriteUpdate(state_data_, update, update_index);
Tobin Ehlisf922ef82016-11-30 10:19:14 -07001505 }
1506 // Roll over to next binding in case of consecutive update
1507 descriptors_remaining -= update_count;
locke-lunarge46b7782019-09-10 01:44:20 -06001508 if (descriptors_remaining) {
1509 // Starting offset is beyond the current binding. Check consistency, update counters and advance to the next binding,
1510 // looking for the start point. All bindings (even those skipped) must be consistent with the update and with the
1511 // original binding.
1512 offset = 0;
1513 ++current_binding;
1514 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001515 }
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05001516 if (update->descriptorCount) {
1517 some_update_ = true;
1518 change_count_++;
1519 }
Tobin Ehlis56a30942016-05-19 08:00:00 -06001520
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001521 if (!(layout_->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08001522 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001523 InvalidateBoundCmdBuffers(dev_data);
Jeff Bolzfdf96072018-04-10 14:32:18 -05001524 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001525}
Tobin Ehlis300888c2016-05-18 13:43:26 -06001526// Validate Copy update
John Zulaufc93c4252019-06-25 09:19:49 -06001527bool CoreChecks::ValidateCopyUpdate(const VkCopyDescriptorSet *update, const DescriptorSet *dst_set, const DescriptorSet *src_set,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001528 const char *func_name, std::string *error_code, std::string *error_msg) const {
Jeff Bolz6aad1742019-10-16 11:10:09 -05001529 auto dst_layout = dst_set->GetLayout().get();
1530 auto src_layout = src_set->GetLayout().get();
John Zulaufd9435c32019-06-05 15:55:36 -06001531
John Zulauf5dfd45c2018-01-17 11:06:34 -07001532 // Verify dst layout still valid
Jeff Bolz6ae39612019-10-11 20:57:36 -05001533 if (dst_layout->destroyed) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001534 *error_code = "VUID-VkCopyDescriptorSet-dstSet-parameter";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06001535 std::ostringstream str;
1536 str << "Cannot call " << func_name << " to perform copy update on dstSet " << report_data->FormatHandle(dst_set->GetSet())
1537 << " created with destroyed " << report_data->FormatHandle(dst_layout->GetDescriptorSetLayout()) << ".";
1538 *error_msg = str.str();
John Zulauf5dfd45c2018-01-17 11:06:34 -07001539 return false;
1540 }
1541
1542 // Verify src layout still valid
Jeff Bolz6ae39612019-10-11 20:57:36 -05001543 if (src_layout->destroyed) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001544 *error_code = "VUID-VkCopyDescriptorSet-srcSet-parameter";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06001545 std::ostringstream str;
1546 str << "Cannot call " << func_name << " to perform copy update on dstSet " << report_data->FormatHandle(dst_set->GetSet())
1547 << " from srcSet " << report_data->FormatHandle(src_set->GetSet()) << " created with destroyed "
1548 << report_data->FormatHandle(src_layout->GetDescriptorSetLayout()) << ".";
1549 *error_msg = str.str();
John Zulauf5dfd45c2018-01-17 11:06:34 -07001550 return false;
1551 }
1552
John Zulaufd9435c32019-06-05 15:55:36 -06001553 if (!dst_layout->HasBinding(update->dstBinding)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001554 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-00347";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001555 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001556 error_str << "DescriptorSet " << report_data->FormatHandle(dst_set->GetSet())
1557 << " does not have copy update dest binding of " << update->dstBinding;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001558 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001559 return false;
1560 }
1561 if (!src_set->HasBinding(update->srcBinding)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001562 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-00345";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001563 std::stringstream error_str;
sourav parmarf4a78252020-04-10 13:04:21 -07001564 error_str << "DescriptorSet " << report_data->FormatHandle(src_set->GetSet())
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001565 << " does not have copy update src binding of " << update->srcBinding;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001566 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001567 return false;
1568 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001569 // Verify idle ds
John Zulaufd9435c32019-06-05 15:55:36 -06001570 if (dst_set->in_use.load() &&
1571 !(dst_layout->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08001572 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeff Bolzfdf96072018-04-10 14:32:18 -05001573 // TODO : Re-using Free Idle error code, need copy update idle error code
Dave Houlton00c154e2018-05-24 13:20:50 -06001574 *error_code = "VUID-vkFreeDescriptorSets-pDescriptorSets-00309";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001575 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001576 error_str << "Cannot call " << func_name << " to perform copy update on descriptor set "
1577 << report_data->FormatHandle(dst_set->GetSet()) << " that is in use by a command buffer";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001578 *error_msg = error_str.str();
1579 return false;
1580 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001581 // src & dst set bindings are valid
1582 // Check bounds of src & dst
John Zulaufc483f442017-12-15 14:02:06 -07001583 auto src_start_idx = src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start + update->srcArrayElement;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001584 if ((src_start_idx + update->descriptorCount) > src_set->GetTotalDescriptorCount()) {
1585 // SRC update out of bounds
Dave Houlton00c154e2018-05-24 13:20:50 -06001586 *error_code = "VUID-VkCopyDescriptorSet-srcArrayElement-00346";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001587 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001588 error_str << "Attempting copy update from descriptorSet " << report_data->FormatHandle(update->srcSet) << " binding#"
1589 << update->srcBinding << " with offset index of "
1590 << src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start << " plus update array offset of "
1591 << update->srcArrayElement << " and update of " << update->descriptorCount
Tobin Ehlis1d81edd2016-11-21 09:50:49 -07001592 << " descriptors oversteps total number of descriptors in set: " << src_set->GetTotalDescriptorCount();
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001593 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001594 return false;
1595 }
John Zulaufd9435c32019-06-05 15:55:36 -06001596 auto dst_start_idx = dst_layout->GetGlobalIndexRangeFromBinding(update->dstBinding).start + update->dstArrayElement;
1597 if ((dst_start_idx + update->descriptorCount) > dst_layout->GetTotalDescriptorCount()) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001598 // DST update out of bounds
Dave Houlton00c154e2018-05-24 13:20:50 -06001599 *error_code = "VUID-VkCopyDescriptorSet-dstArrayElement-00348";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001600 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001601 error_str << "Attempting copy update to descriptorSet " << report_data->FormatHandle(dst_set->GetSet()) << " binding#"
1602 << update->dstBinding << " with offset index of "
1603 << dst_layout->GetGlobalIndexRangeFromBinding(update->dstBinding).start << " plus update array offset of "
1604 << update->dstArrayElement << " and update of " << update->descriptorCount
John Zulaufd9435c32019-06-05 15:55:36 -06001605 << " descriptors oversteps total number of descriptors in set: " << dst_layout->GetTotalDescriptorCount();
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001606 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001607 return false;
1608 }
1609 // Check that types match
Shannon McPhersonafe55122020-05-25 16:20:19 -06001610 // TODO : Base default error case going from here is "VUID-VkAcquireNextImageInfoKHR-semaphore-parameter" 2ba which covers all
Dave Houltond8ed0212018-05-16 17:18:24 -06001611 // consistency issues, need more fine-grained error codes
Dave Houlton00c154e2018-05-24 13:20:50 -06001612 *error_code = "VUID-VkCopyDescriptorSet-srcSet-00349";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001613 auto src_type = src_set->GetTypeFromBinding(update->srcBinding);
John Zulaufd9435c32019-06-05 15:55:36 -06001614 auto dst_type = dst_layout->GetTypeFromBinding(update->dstBinding);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001615 if (src_type != dst_type) {
sourav parmarf4a78252020-04-10 13:04:21 -07001616 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02632";
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001617 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001618 error_str << "Attempting copy update to descriptorSet " << report_data->FormatHandle(dst_set->GetSet()) << " binding #"
1619 << update->dstBinding << " with type " << string_VkDescriptorType(dst_type) << " from descriptorSet "
1620 << report_data->FormatHandle(src_set->GetSet()) << " binding #" << update->srcBinding << " with type "
1621 << string_VkDescriptorType(src_type) << ". Types do not match";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001622 *error_msg = error_str.str();
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001623 return false;
1624 }
1625 // Verify consistency of src & dst bindings if update crosses binding boundaries
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001626 if ((!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(src_layout, update->srcBinding),
John Zulauf4a015c92019-06-04 09:50:05 -06001627 update->srcArrayElement, update->descriptorCount, "copy update from", src_set->GetSet(),
1628 error_msg)) ||
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001629 (!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(dst_layout, update->dstBinding),
John Zulaufd9435c32019-06-05 15:55:36 -06001630 update->dstArrayElement, update->descriptorCount, "copy update to", dst_set->GetSet(),
1631 error_msg))) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001632 return false;
1633 }
Jeff Bolzfdf96072018-04-10 14:32:18 -05001634
Mike Schuchardt2df08912020-12-15 16:28:09 -08001635 if ((src_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) &&
1636 !(dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001637 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01918";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001638 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001639 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001640 << ") layout was created with the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001641 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001642 "set, then pname:dstSet's ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001643 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001644 << ") layout must: also have been created with the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001645 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001646 *error_msg = error_str.str();
1647 return false;
1648 }
1649
Mike Schuchardt2df08912020-12-15 16:28:09 -08001650 if (!(src_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT) &&
1651 (dst_layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001652 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01919";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001653 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001654 error_str << "If pname:srcSet's (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001655 << ") layout was created without the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001656 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001657 "set, then pname:dstSet's ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001658 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001659 << ") layout must: also have been created without the "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001660 "ename:VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001661 *error_msg = error_str.str();
1662 return false;
1663 }
1664
Mike Schuchardt2df08912020-12-15 16:28:09 -08001665 if ((src_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT) &&
1666 !(dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001667 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01920";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001668 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001669 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001670 << ") was allocated was created "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001671 "with the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001672 "set, then the descriptor pool from which pname:dstSet ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001673 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001674 << ") was allocated must: "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001675 "also have been created with the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001676 *error_msg = error_str.str();
1677 return false;
1678 }
1679
Mike Schuchardt2df08912020-12-15 16:28:09 -08001680 if (!(src_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT) &&
1681 (dst_set->GetPoolState()->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06001682 *error_code = "VUID-VkCopyDescriptorSet-srcSet-01921";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001683 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001684 error_str << "If the descriptor pool from which pname:srcSet (" << report_data->FormatHandle(update->srcSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001685 << ") was allocated was created "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001686 "without the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag "
Jeff Bolzfdf96072018-04-10 14:32:18 -05001687 "set, then the descriptor pool from which pname:dstSet ("
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06001688 << report_data->FormatHandle(update->dstSet)
Jeff Bolzfdf96072018-04-10 14:32:18 -05001689 << ") was allocated must: "
Mike Schuchardt2df08912020-12-15 16:28:09 -08001690 "also have been created without the ename:VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT flag set";
Jeff Bolzfdf96072018-04-10 14:32:18 -05001691 *error_msg = error_str.str();
1692 return false;
1693 }
1694
Jeff Bolze54ae892018-09-08 12:16:29 -05001695 if (src_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
1696 if ((update->srcArrayElement % 4) != 0) {
1697 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-02223";
1698 std::stringstream error_str;
1699 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
1700 << "srcArrayElement " << update->srcArrayElement << " not a multiple of 4";
1701 *error_msg = error_str.str();
1702 return false;
1703 }
1704 if ((update->dstArrayElement % 4) != 0) {
1705 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02224";
1706 std::stringstream error_str;
1707 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
1708 << "dstArrayElement " << update->dstArrayElement << " not a multiple of 4";
1709 *error_msg = error_str.str();
1710 return false;
1711 }
1712 if ((update->descriptorCount % 4) != 0) {
1713 *error_code = "VUID-VkCopyDescriptorSet-srcBinding-02225";
1714 std::stringstream error_str;
1715 error_str << "Attempting copy update to VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT binding with "
1716 << "descriptorCount " << update->descriptorCount << " not a multiple of 4";
1717 *error_msg = error_str.str();
1718 return false;
1719 }
1720 }
1721
Tobin Ehlisd41e7b62016-05-19 07:56:18 -06001722 // Update parameters all look good and descriptor updated so verify update contents
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07001723 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 -07001724 error_msg)) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07001725 return false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001726 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06001727
1728 // All checks passed so update is good
1729 return true;
1730}
1731// Perform Copy update
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001732void cvdescriptorset::DescriptorSet::PerformCopyUpdate(ValidationStateTracker *dev_data, const VkCopyDescriptorSet *update,
1733 const DescriptorSet *src_set) {
John Zulaufc483f442017-12-15 14:02:06 -07001734 auto src_start_idx = src_set->GetGlobalIndexRangeFromBinding(update->srcBinding).start + update->srcArrayElement;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001735 auto dst_start_idx = layout_->GetGlobalIndexRangeFromBinding(update->dstBinding).start + update->dstArrayElement;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001736 // Update parameters all look good so perform update
1737 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Józef Kucia5297e372017-10-13 22:31:34 +02001738 auto src = src_set->descriptors_[src_start_idx + di].get();
1739 auto dst = descriptors_[dst_start_idx + di].get();
1740 if (src->updated) {
John Zulaufd2c3dae2019-12-12 11:02:17 -07001741 dst->CopyUpdate(state_data_, src);
Józef Kucia5297e372017-10-13 22:31:34 +02001742 some_update_ = true;
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05001743 change_count_++;
Józef Kucia5297e372017-10-13 22:31:34 +02001744 } else {
1745 dst->updated = false;
1746 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001747 }
Tobin Ehlis56a30942016-05-19 08:00:00 -06001748
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001749 if (!(layout_->GetDescriptorBindingFlagsFromBinding(update->dstBinding) &
Mike Schuchardt2df08912020-12-15 16:28:09 -08001750 (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05001751 InvalidateBoundCmdBuffers(dev_data);
Jeff Bolzfdf96072018-04-10 14:32:18 -05001752 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001753}
Tobin Ehlis56a30942016-05-19 08:00:00 -06001754
John Zulauf6f3d2bd2018-10-29 17:08:42 -06001755// Update the drawing state for the affected descriptors.
1756// Set cb_node to this set and this set to cb_node.
1757// Add the bindings of the descriptor
1758// Set the layout based on the current descriptor layout (will mask subsequent layer mismatch errors)
1759// TODO: Modify the UpdateDrawState virtural functions to *only* set initial layout and not change layouts
Tobin Ehlisf9519102016-08-17 09:49:13 -06001760// Prereq: This should be called for a set that has been confirmed to be active for the given cb_node, meaning it's going
1761// to be used in a draw by the given cb_node
Jeremy Kniagere6827432020-04-01 09:05:56 -06001762void cvdescriptorset::DescriptorSet::UpdateDrawState(ValidationStateTracker *device_data, CMD_BUFFER_STATE *cb_node,
1763 CMD_TYPE cmd_type, const PIPELINE_STATE *pipe,
Karl Schultz7090a052020-11-10 08:54:21 -07001764 const BindingReqMap &binding_req_map, const char *function) {
Tony-LunarG77822802020-05-28 16:35:46 -06001765 if (!device_data->disabled[command_buffer_state] && !IsPushDescriptor()) {
Jeff Bolzafa429a2019-08-14 09:59:22 -05001766 // bind cb to this descriptor set
1767 // Add bindings for descriptor set, the set's pool, and individual objects in the set
Jeff Bolzadbfa852019-10-04 13:53:30 -05001768 if (device_data->AddCommandBufferBinding(cb_bindings, VulkanTypedHandle(set_, kVulkanObjectTypeDescriptorSet, this),
1769 cb_node)) {
1770 device_data->AddCommandBufferBinding(pool_state_->cb_bindings,
1771 VulkanTypedHandle(pool_state_->pool, kVulkanObjectTypeDescriptorPool, pool_state_),
1772 cb_node);
Jeff Bolzafa429a2019-08-14 09:59:22 -05001773 }
1774 }
Jeff Bolze18e7242019-08-12 20:55:22 -05001775
1776 // Descriptor UpdateDrawState functions do two things - associate resources to the command buffer,
1777 // and call image layout validation callbacks. If both are disabled, skip the entire loop.
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06001778 if (device_data->disabled[command_buffer_state] && device_data->disabled[image_layout_validation]) {
Jeff Bolze18e7242019-08-12 20:55:22 -05001779 return;
1780 }
1781
Tobin Ehlisf9519102016-08-17 09:49:13 -06001782 // For the active slots, use set# to look up descriptorSet from boundDescriptorSets, and bind all of that descriptor set's
1783 // resources
locke-lunarg540b2252020-08-03 13:23:36 -06001784 CMD_BUFFER_STATE::CmdDrawDispatchInfo cmd_info = {};
John Zulauf79f06582021-02-27 18:38:39 -07001785 for (const auto &binding_req_pair : binding_req_map) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001786 auto index = layout_->GetIndexFromBinding(binding_req_pair.first);
locke-gb3ce08f2019-09-30 12:30:56 -06001787
Tony-LunarG62c5dba2018-12-20 14:27:23 -07001788 // 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 -07001789 auto flags = layout_->GetDescriptorBindingFlagsFromIndex(index);
Mike Schuchardt2df08912020-12-15 16:28:09 -08001790 if (flags & (VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT)) {
1791 if (!(flags & VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT)) {
locke-lunarg36045992020-08-20 16:54:37 -06001792 cmd_info.binding_infos.emplace_back(binding_req_pair);
locke-gb3ce08f2019-09-30 12:30:56 -06001793 }
Tony-LunarG62c5dba2018-12-20 14:27:23 -07001794 continue;
1795 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001796 auto range = layout_->GetGlobalIndexRangeFromIndex(index);
John Zulaufc483f442017-12-15 14:02:06 -07001797 for (uint32_t i = range.start; i < range.end; ++i) {
Mark Lobodzinskifae179e2019-03-08 16:47:08 -07001798 descriptors_[i]->UpdateDrawState(device_data, cb_node);
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06001799 }
1800 }
locke-lunarg540b2252020-08-03 13:23:36 -06001801
1802 if (cmd_info.binding_infos.size() > 0) {
1803 cmd_info.cmd_type = cmd_type;
1804 cmd_info.function = function;
1805 if (cb_node->activeFramebuffer) {
1806 cmd_info.framebuffer = cb_node->activeFramebuffer->framebuffer;
locke-lunargfc78e932020-11-19 17:06:24 -07001807 cmd_info.attachments = cb_node->active_attachments;
1808 cmd_info.subpasses = cb_node->active_subpasses;
locke-lunarg540b2252020-08-03 13:23:36 -06001809 }
1810 cb_node->validate_descriptorsets_in_queuesubmit[set_].emplace_back(cmd_info);
1811 }
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06001812}
1813
John Zulauffbf3c202019-07-17 14:57:14 -06001814void cvdescriptorset::DescriptorSet::FilterOneBindingReq(const BindingReqMap::value_type &binding_req_pair, BindingReqMap *out_req,
1815 const TrackedBindings &bindings, uint32_t limit) {
1816 if (bindings.size() < limit) {
1817 const auto it = bindings.find(binding_req_pair.first);
1818 if (it == bindings.cend()) out_req->emplace(binding_req_pair);
John Zulauf48a6a702017-12-22 17:14:54 -07001819 }
1820}
Mark Lobodzinski2872f4a2018-09-03 17:00:53 -06001821
John Zulauffbf3c202019-07-17 14:57:14 -06001822void cvdescriptorset::DescriptorSet::FilterBindingReqs(const CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline,
1823 const BindingReqMap &in_req, BindingReqMap *out_req) const {
1824 // For const cleanliness we have to find in the maps...
1825 const auto validated_it = cached_validation_.find(&cb_state);
1826 if (validated_it == cached_validation_.cend()) {
1827 // We have nothing validated, copy in to out
1828 for (const auto &binding_req_pair : in_req) {
1829 out_req->emplace(binding_req_pair);
John Zulauf48a6a702017-12-22 17:14:54 -07001830 }
John Zulauffbf3c202019-07-17 14:57:14 -06001831 return;
John Zulauf48a6a702017-12-22 17:14:54 -07001832 }
John Zulauffbf3c202019-07-17 14:57:14 -06001833 const auto &validated = validated_it->second;
John Zulauf48a6a702017-12-22 17:14:54 -07001834
John Zulauffbf3c202019-07-17 14:57:14 -06001835 const auto image_sample_version_it = validated.image_samplers.find(&pipeline);
1836 const VersionedBindings *image_sample_version = nullptr;
1837 if (image_sample_version_it != validated.image_samplers.cend()) {
1838 image_sample_version = &(image_sample_version_it->second);
1839 }
1840 const auto &dynamic_buffers = validated.dynamic_buffers;
1841 const auto &non_dynamic_buffers = validated.non_dynamic_buffers;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001842 const auto &stats = layout_->GetBindingTypeStats();
John Zulauf48a6a702017-12-22 17:14:54 -07001843 for (const auto &binding_req_pair : in_req) {
1844 auto binding = binding_req_pair.first;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001845 VkDescriptorSetLayoutBinding const *layout_binding = layout_->GetDescriptorSetLayoutBindingPtrFromBinding(binding);
John Zulauf48a6a702017-12-22 17:14:54 -07001846 if (!layout_binding) {
1847 continue;
1848 }
1849 // Caching criteria differs per type.
1850 // If image_layout have changed , the image descriptors need to be validated against them.
sfricke-samsung60f29ec2021-03-10 20:37:25 -08001851 if (IsBufferDescriptor(layout_binding->descriptorType)) {
1852 if (IsDynamicDescriptor(layout_binding->descriptorType)) {
1853 FilterOneBindingReq(binding_req_pair, out_req, dynamic_buffers, stats.dynamic_buffer_count);
1854 } else {
1855 FilterOneBindingReq(binding_req_pair, out_req, non_dynamic_buffers, stats.non_dynamic_buffer_count);
1856 }
John Zulauf48a6a702017-12-22 17:14:54 -07001857 } else {
1858 // This is rather crude, as the changed layouts may not impact the bound descriptors,
1859 // but the simple "versioning" is a simple "dirt" test.
John Zulauffbf3c202019-07-17 14:57:14 -06001860 bool stale = true;
1861 if (image_sample_version) {
1862 const auto version_it = image_sample_version->find(binding);
1863 if (version_it != image_sample_version->cend() && (version_it->second == cb_state.image_layout_change_count)) {
1864 stale = false;
1865 }
1866 }
1867 if (stale) {
John Zulauf48a6a702017-12-22 17:14:54 -07001868 out_req->emplace(binding_req_pair);
1869 }
1870 }
1871 }
1872}
Tobin Ehlis9252c2b2016-07-21 14:40:22 -06001873
John Zulauffbf3c202019-07-17 14:57:14 -06001874void cvdescriptorset::DescriptorSet::UpdateValidationCache(const CMD_BUFFER_STATE &cb_state, const PIPELINE_STATE &pipeline,
1875 const BindingReqMap &updated_bindings) {
1876 // For const cleanliness we have to find in the maps...
1877 auto &validated = cached_validation_[&cb_state];
1878
1879 auto &image_sample_version = validated.image_samplers[&pipeline];
1880 auto &dynamic_buffers = validated.dynamic_buffers;
1881 auto &non_dynamic_buffers = validated.non_dynamic_buffers;
1882 for (const auto &binding_req_pair : updated_bindings) {
1883 auto binding = binding_req_pair.first;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001884 VkDescriptorSetLayoutBinding const *layout_binding = layout_->GetDescriptorSetLayoutBindingPtrFromBinding(binding);
John Zulauffbf3c202019-07-17 14:57:14 -06001885 if (!layout_binding) {
1886 continue;
1887 }
1888 // Caching criteria differs per type.
sfricke-samsung60f29ec2021-03-10 20:37:25 -08001889 if (IsBufferDescriptor(layout_binding->descriptorType)) {
1890 if (IsDynamicDescriptor(layout_binding->descriptorType)) {
1891 dynamic_buffers.emplace(binding);
1892 } else {
1893 non_dynamic_buffers.emplace(binding);
1894 }
John Zulauffbf3c202019-07-17 14:57:14 -06001895 } else {
1896 // Save the layout change version...
1897 image_sample_version[binding] = cb_state.image_layout_change_count;
1898 }
1899 }
1900}
1901
John Zulaufd2c3dae2019-12-12 11:02:17 -07001902cvdescriptorset::SamplerDescriptor::SamplerDescriptor(const ValidationStateTracker *dev_data, const VkSampler *immut)
Karl Schultz76d16a42020-11-11 05:05:33 -07001903 : immutable_(false) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001904 updated = false;
1905 descriptor_class = PlainSampler;
1906 if (immut) {
Karl Schultz76d16a42020-11-11 05:05:33 -07001907 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(*immut);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06001908 immutable_ = true;
1909 updated = true;
1910 }
1911}
Tobin Ehlise2f80292016-06-02 10:08:53 -06001912// Validate given sampler. Currently this only checks to make sure it exists in the samplerMap
John Zulaufc93c4252019-06-25 09:19:49 -06001913bool CoreChecks::ValidateSampler(const VkSampler sampler) const { return (GetSamplerState(sampler) != nullptr); }
Tobin Ehlis56a30942016-05-19 08:00:00 -06001914
John Zulaufc93c4252019-06-25 09:19:49 -06001915bool CoreChecks::ValidateImageUpdate(VkImageView image_view, VkImageLayout image_layout, VkDescriptorType type,
John Zulaufbd9b3412019-08-22 17:16:11 -06001916 const char *func_name, std::string *error_code, std::string *error_msg) const {
John Zulaufc93c4252019-06-25 09:19:49 -06001917 auto iv_state = GetImageViewState(image_view);
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06001918 assert(iv_state);
1919
Tobin Ehlis81280962016-07-20 14:04:20 -06001920 // 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 -06001921 // Validate that imageLayout is compatible with aspect_mask and image format
1922 // and validate that image usage bits are correct for given usage
Tobin Ehlis8b26a382016-09-14 08:02:49 -06001923 VkImageAspectFlags aspect_mask = iv_state->create_info.subresourceRange.aspectMask;
1924 VkImage image = iv_state->create_info.image;
Tobin Ehlis1809f912016-05-25 09:24:36 -06001925 VkFormat format = VK_FORMAT_MAX_ENUM;
1926 VkImageUsageFlags usage = 0;
John Zulaufc93c4252019-06-25 09:19:49 -06001927 auto image_node = GetImageState(image);
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06001928 assert(image_node);
Chris Forbes67757ff2017-07-21 13:59:01 -07001929
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06001930 format = image_node->createInfo.format;
1931 usage = image_node->createInfo.usage;
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07001932 const auto stencil_usage_info = LvlFindInChain<VkImageStencilUsageCreateInfo>(image_node->createInfo.pNext);
Ricardo Garcia3f5984c2020-04-09 10:56:34 +02001933 if (stencil_usage_info) {
1934 usage |= stencil_usage_info->stencilUsage;
1935 }
Mark Lobodzinski03d00062020-06-15 14:35:45 -06001936
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06001937 // Validate that memory is bound to image
Mark Lobodzinski03d00062020-06-15 14:35:45 -06001938 if (ValidateMemoryIsBoundToImage(image_node, func_name, "UNASSIGNED-CoreValidation-BoundResourceFreedMemoryAccess")) {
1939 *error_code = "UNASSIGNED-CoreValidation-BoundResourceFreedMemoryAccess";
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06001940 *error_msg = "No memory bound to image.";
Tobin Ehlis1809f912016-05-25 09:24:36 -06001941 return false;
1942 }
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06001943
1944 // KHR_maintenance1 allows rendering into 2D or 2DArray views which slice a 3D image,
1945 // but not binding them to descriptor sets.
1946 if (image_node->createInfo.imageType == VK_IMAGE_TYPE_3D && (iv_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_2D ||
1947 iv_state->create_info.viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY)) {
1948 *error_code = "VUID-VkDescriptorImageInfo-imageView-00343";
1949 *error_msg = "ImageView must not be a 2D or 2DArray view of a 3D image";
1950 return false;
1951 }
1952
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001953 // TODO : The various image aspect and format checks here are based on general spec language in 11.5 Image Views section under
1954 // vkCreateImageView(). What's the best way to create unique id for these cases?
Mark Lobodzinski3fc3d752019-06-24 14:22:46 -06001955 *error_code = "UNASSIGNED-CoreValidation-DrawState-InvalidImageView";
Dave Houlton1d2022c2017-03-29 11:43:58 -06001956 bool ds = FormatIsDepthOrStencil(format);
Tobin Ehlis1809f912016-05-25 09:24:36 -06001957 switch (image_layout) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001958 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
1959 // Only Color bit must be set
1960 if ((aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) != VK_IMAGE_ASPECT_COLOR_BIT) {
Tobin Ehlis1809f912016-05-25 09:24:36 -06001961 std::stringstream error_str;
Dave Houltona9df0ce2018-02-07 10:51:23 -07001962 error_str
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06001963 << "ImageView (" << report_data->FormatHandle(image_view)
Dave Houltona9df0ce2018-02-07 10:51:23 -07001964 << ") 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 -06001965 *error_msg = error_str.str();
Tobin Ehlis1809f912016-05-25 09:24:36 -06001966 return false;
1967 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001968 // format must NOT be DS
1969 if (ds) {
1970 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06001971 error_str << "ImageView (" << report_data->FormatHandle(image_view)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001972 << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but the image format is "
1973 << string_VkFormat(format) << " which is not a color format.";
1974 *error_msg = error_str.str();
1975 return false;
1976 }
1977 break;
1978 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
1979 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
1980 // Depth or stencil bit must be set, but both must NOT be set
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06001981 if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
1982 if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
1983 // both must NOT be set
1984 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06001985 error_str << "ImageView (" << report_data->FormatHandle(image_view)
Mark Lobodzinski6b042922019-06-21 14:46:42 -06001986 << ") has both STENCIL and DEPTH aspects set";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06001987 *error_msg = error_str.str();
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06001988 return false;
1989 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001990 } else if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
1991 // Neither were set
1992 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06001993 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06001994 << string_VkImageLayout(image_layout) << " but does not have STENCIL or DEPTH aspects set";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001995 *error_msg = error_str.str();
1996 return false;
Tobin Ehlisbbf3f912016-06-15 13:03:58 -06001997 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001998 // format must be DS
1999 if (!ds) {
2000 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002001 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002002 << string_VkImageLayout(image_layout) << " but the image format is " << string_VkFormat(format)
2003 << " which is not a depth/stencil format.";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002004 *error_msg = error_str.str();
2005 return false;
2006 }
2007 break;
2008 default:
2009 // For other layouts if the source is depth/stencil image, both aspect bits must not be set
2010 if (ds) {
2011 if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
2012 if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2013 // both must NOT be set
2014 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002015 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has layout "
Mark Lobodzinski6b042922019-06-21 14:46:42 -06002016 << string_VkImageLayout(image_layout) << " and is using depth/stencil image of format "
2017 << string_VkFormat(format)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002018 << " but it has both STENCIL and DEPTH aspects set, which is illegal. When using a depth/stencil "
2019 "image in a descriptor set, please only set either VK_IMAGE_ASPECT_DEPTH_BIT or "
2020 "VK_IMAGE_ASPECT_STENCIL_BIT depending on whether it will be used for depth reads or stencil "
2021 "reads respectively.";
Mark Lobodzinski4d05d7a2019-06-25 09:12:06 -06002022 *error_code = "VUID-VkDescriptorImageInfo-imageView-01976";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002023 *error_msg = error_str.str();
2024 return false;
2025 }
2026 }
2027 }
2028 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002029 }
2030 // Now validate that usage flags are correctly set for given type of update
Tobin Ehlisfb4cf712016-10-10 14:02:48 -06002031 // 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 -06002032 // TODO : The various image usage bit requirements are in general spec language for VkImageUsageFlags bit block in 11.3 Images
2033 // under vkCreateImage()
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002034 const char *error_usage_bit = nullptr;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002035 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002036 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
sfricke-samsung088f1242020-06-06 02:15:35 -07002037 if (iv_state->samplerConversion != VK_NULL_HANDLE) {
2038 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-01946";
2039 std::stringstream error_str;
2040 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ")"
2041 << "used as a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE can't be created with VkSamplerYcbcrConversion";
2042 *error_msg = error_str.str();
2043 return false;
2044 }
2045 // drop through
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002046 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
2047 if (!(usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
2048 error_usage_bit = "VK_IMAGE_USAGE_SAMPLED_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002049 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00337";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002050 }
2051 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002052 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002053 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
2054 if (!(usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
2055 error_usage_bit = "VK_IMAGE_USAGE_STORAGE_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002056 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00339";
sfricke-samsungada55a12020-08-15 03:39:41 -07002057 } else if ((VK_IMAGE_LAYOUT_GENERAL != image_layout) || ((VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR != image_layout) &&
2058 (device_extensions.vk_khr_shared_presentable_image))) {
sfricke-samsungf1058982020-09-10 22:36:49 -07002059 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04152";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002060 std::stringstream error_str;
sfricke-samsungada55a12020-08-15 03:39:41 -07002061 error_str << "Descriptor update with descriptorType VK_DESCRIPTOR_TYPE_STORAGE_IMAGE"
2062 << " is being updated with invalid imageLayout " << string_VkImageLayout(image_layout) << " for image "
2063 << report_data->FormatHandle(image) << " in imageView " << report_data->FormatHandle(image_view)
2064 << ". Allowed layouts are: VK_IMAGE_LAYOUT_GENERAL";
2065 if (device_extensions.vk_khr_shared_presentable_image) {
2066 error_str << " or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR";
Tobin Ehlisbb03e5f2017-05-11 08:52:51 -06002067 }
sfricke-samsungada55a12020-08-15 03:39:41 -07002068 *error_msg = error_str.str();
2069 return false;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002070 }
2071 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002072 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002073 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
2074 if (!(usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
2075 error_usage_bit = "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT";
sfricke-samsung7923f212020-02-29 21:17:35 -08002076 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00338";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002077 }
2078 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002079 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002080 default:
2081 break;
Tobin Ehlis1809f912016-05-25 09:24:36 -06002082 }
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002083 if (error_usage_bit) {
Tobin Ehlis1809f912016-05-25 09:24:36 -06002084 std::stringstream error_str;
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002085 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") with usage mask " << std::hex << std::showbase
2086 << usage << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
2087 << error_usage_bit << " set.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002088 *error_msg = error_str.str();
Tobin Ehlis1809f912016-05-25 09:24:36 -06002089 return false;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002090 }
John Zulauff4c07882019-01-24 14:03:36 -07002091
sfricke-samsungada55a12020-08-15 03:39:41 -07002092 // All the following types share the same image layouts
2093 // checkf or Storage Images above
2094 if ((type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
2095 (type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
John Zulauff4c07882019-01-24 14:03:36 -07002096 // Test that the layout is compatible with the descriptorType for the two sampled image types
2097 const static std::array<VkImageLayout, 3> valid_layouts = {
Jeremy Hayesd0549f62019-06-05 10:15:36 -06002098 {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 -07002099
2100 struct ExtensionLayout {
2101 VkImageLayout layout;
Tony-LunarG2ec96bb2019-11-26 13:43:02 -07002102 ExtEnabled DeviceExtensions::*extension;
John Zulauff4c07882019-01-24 14:03:36 -07002103 };
Jeremy Gebben579aaca2021-02-15 13:36:18 -07002104 const static std::array<ExtensionLayout, 5> extended_layouts{{
2105 // Note double brace req'd for aggregate initialization
2106 {VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, &DeviceExtensions::vk_khr_shared_presentable_image},
2107 {VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, &DeviceExtensions::vk_khr_maintenance2},
2108 {VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, &DeviceExtensions::vk_khr_maintenance2},
2109 {VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR, &DeviceExtensions::vk_khr_synchronization_2},
2110 {VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, &DeviceExtensions::vk_khr_synchronization_2},
2111 }};
John Zulaufc93c4252019-06-25 09:19:49 -06002112 auto is_layout = [image_layout, this](const ExtensionLayout &ext_layout) {
2113 return device_extensions.*(ext_layout.extension) && (ext_layout.layout == image_layout);
John Zulauff4c07882019-01-24 14:03:36 -07002114 };
2115
2116 bool valid_layout = (std::find(valid_layouts.cbegin(), valid_layouts.cend(), image_layout) != valid_layouts.cend()) ||
2117 std::any_of(extended_layouts.cbegin(), extended_layouts.cend(), is_layout);
2118
2119 if (!valid_layout) {
sfricke-samsungf1058982020-09-10 22:36:49 -07002120 // The following works as currently all 3 descriptor types share the same set of valid layouts
sfricke-samsungada55a12020-08-15 03:39:41 -07002121 switch (type) {
2122 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002123 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04149";
sfricke-samsungada55a12020-08-15 03:39:41 -07002124 break;
2125 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002126 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04150";
sfricke-samsungada55a12020-08-15 03:39:41 -07002127 break;
2128 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
sfricke-samsungf1058982020-09-10 22:36:49 -07002129 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-04151";
sfricke-samsungada55a12020-08-15 03:39:41 -07002130 break;
2131 default:
2132 break;
2133 }
John Zulauff4c07882019-01-24 14:03:36 -07002134 std::stringstream error_str;
2135 error_str << "Descriptor update with descriptorType " << string_VkDescriptorType(type)
Mark Lobodzinski74eddba2019-06-21 14:16:33 -06002136 << " is being updated with invalid imageLayout " << string_VkImageLayout(image_layout) << " for image "
Mark Lobodzinski298f0fd2020-04-09 11:50:19 -06002137 << report_data->FormatHandle(image) << " in imageView " << report_data->FormatHandle(image_view)
John Zulauff4c07882019-01-24 14:03:36 -07002138 << ". Allowed layouts are: VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "
2139 << "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL";
2140 for (auto &ext_layout : extended_layouts) {
John Zulaufc93c4252019-06-25 09:19:49 -06002141 if (device_extensions.*(ext_layout.extension)) {
John Zulauff4c07882019-01-24 14:03:36 -07002142 error_str << ", " << string_VkImageLayout(ext_layout.layout);
2143 }
2144 }
2145 *error_msg = error_str.str();
2146 return false;
2147 }
2148 }
2149
sfricke-samsungbd0e8052020-06-06 01:36:39 -07002150 if ((type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) || (type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
2151 const VkComponentMapping components = iv_state->create_info.components;
2152 if (IsIdentitySwizzle(components) == false) {
2153 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00336";
2154 std::stringstream error_str;
2155 error_str << "ImageView (" << report_data->FormatHandle(image_view) << ") has a non-identiy swizzle component, "
2156 << " r swizzle = " << string_VkComponentSwizzle(components.r) << ","
2157 << " g swizzle = " << string_VkComponentSwizzle(components.g) << ","
2158 << " b swizzle = " << string_VkComponentSwizzle(components.b) << ","
2159 << " a swizzle = " << string_VkComponentSwizzle(components.a) << ".";
2160 *error_msg = error_str.str();
2161 return false;
2162 }
2163 }
2164
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002165 return true;
2166}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002167
John Zulaufd2c3dae2019-12-12 11:02:17 -07002168void cvdescriptorset::SamplerDescriptor::WriteUpdate(const ValidationStateTracker *dev_data, const VkWriteDescriptorSet *update,
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002169 const uint32_t index) {
Chris Forbesfea2c542018-04-13 09:34:15 -07002170 if (!immutable_) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002171 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(update->pImageInfo[index].sampler);
Chris Forbesfea2c542018-04-13 09:34:15 -07002172 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002173 updated = true;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002174}
2175
John Zulaufd2c3dae2019-12-12 11:02:17 -07002176void cvdescriptorset::SamplerDescriptor::CopyUpdate(const ValidationStateTracker *dev_data, const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002177 if (!immutable_) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002178 sampler_state_ = static_cast<const SamplerDescriptor *>(src)->sampler_state_;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002179 }
2180 updated = true;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002181}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002182
John Zulauffbf3c202019-07-17 14:57:14 -06002183void cvdescriptorset::SamplerDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) {
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002184 if (!immutable_) {
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002185 auto sampler_state = GetSamplerState();
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -07002186 if (sampler_state) dev_data->AddCommandBufferBindingSampler(cb_node, sampler_state);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002187 }
2188}
2189
John Zulaufd2c3dae2019-12-12 11:02:17 -07002190cvdescriptorset::ImageSamplerDescriptor::ImageSamplerDescriptor(const ValidationStateTracker *dev_data, const VkSampler *immut)
Karl Schultz76d16a42020-11-11 05:05:33 -07002191 : immutable_(false), image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002192 updated = false;
2193 descriptor_class = ImageSampler;
2194 if (immut) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002195 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(*immut);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002196 immutable_ = true;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002197 }
2198}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002199
John Zulaufd2c3dae2019-12-12 11:02:17 -07002200void cvdescriptorset::ImageSamplerDescriptor::WriteUpdate(const ValidationStateTracker *dev_data,
2201 const VkWriteDescriptorSet *update, const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002202 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002203 const auto &image_info = update->pImageInfo[index];
Chris Forbesfea2c542018-04-13 09:34:15 -07002204 if (!immutable_) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002205 sampler_state_ = dev_data->GetConstCastShared<SAMPLER_STATE>(image_info.sampler);
Chris Forbesfea2c542018-04-13 09:34:15 -07002206 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002207 image_layout_ = image_info.imageLayout;
Karl Schultz76d16a42020-11-11 05:05:33 -07002208 image_view_state_ = dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002209}
2210
John Zulaufd2c3dae2019-12-12 11:02:17 -07002211void cvdescriptorset::ImageSamplerDescriptor::CopyUpdate(const ValidationStateTracker *dev_data, const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002212 if (!immutable_) {
Karl Schultz76d16a42020-11-11 05:05:33 -07002213 sampler_state_ = static_cast<const ImageSamplerDescriptor *>(src)->sampler_state_;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002214 }
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002215 updated = true;
Karl Schultz76d16a42020-11-11 05:05:33 -07002216 image_layout_ = static_cast<const ImageSamplerDescriptor *>(src)->image_layout_;
2217 image_view_state_ = static_cast<const ImageSamplerDescriptor *>(src)->image_view_state_;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002218}
2219
John Zulauffbf3c202019-07-17 14:57:14 -06002220void cvdescriptorset::ImageSamplerDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) {
Tobin Ehlis81e46372016-08-17 13:33:44 -06002221 // First add binding for any non-immutable sampler
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002222 if (!immutable_) {
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002223 auto sampler_state = GetSamplerState();
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -07002224 if (sampler_state) dev_data->AddCommandBufferBindingSampler(cb_node, sampler_state);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002225 }
Tobin Ehlis81e46372016-08-17 13:33:44 -06002226 // Add binding for image
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002227 auto iv_state = GetImageViewState();
Tobin Ehlis8b26a382016-09-14 08:02:49 -06002228 if (iv_state) {
Mark Lobodzinskifae179e2019-03-08 16:47:08 -07002229 dev_data->AddCommandBufferBindingImageView(cb_node, iv_state);
John Zulauffbf3c202019-07-17 14:57:14 -06002230 dev_data->CallSetImageViewInitialLayoutCallback(cb_node, *iv_state, image_layout_);
Jeff Bolz148d94e2018-12-13 21:25:56 -06002231 }
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002232}
2233
sfricke-samsung4ba7d6e2021-03-06 20:56:35 -08002234cvdescriptorset::ImageDescriptor::ImageDescriptor(const VkDescriptorType type) : image_layout_(VK_IMAGE_LAYOUT_UNDEFINED) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002235 updated = false;
2236 descriptor_class = Image;
Petr Kraus13c98a62017-12-09 00:22:39 +01002237}
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002238
John Zulaufd2c3dae2019-12-12 11:02:17 -07002239void cvdescriptorset::ImageDescriptor::WriteUpdate(const ValidationStateTracker *dev_data, const VkWriteDescriptorSet *update,
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002240 const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002241 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002242 const auto &image_info = update->pImageInfo[index];
Tobin Ehlis300888c2016-05-18 13:43:26 -06002243 image_layout_ = image_info.imageLayout;
Karl Schultz76d16a42020-11-11 05:05:33 -07002244 image_view_state_ = dev_data->GetConstCastShared<IMAGE_VIEW_STATE>(image_info.imageView);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002245}
2246
John Zulaufd2c3dae2019-12-12 11:02:17 -07002247void cvdescriptorset::ImageDescriptor::CopyUpdate(const ValidationStateTracker *dev_data, const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002248 updated = true;
Karl Schultz76d16a42020-11-11 05:05:33 -07002249 image_layout_ = static_cast<const ImageDescriptor *>(src)->image_layout_;
2250 image_view_state_ = static_cast<const ImageDescriptor *>(src)->image_view_state_;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002251}
2252
John Zulauffbf3c202019-07-17 14:57:14 -06002253void cvdescriptorset::ImageDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) {
Tobin Ehlis81e46372016-08-17 13:33:44 -06002254 // Add binding for image
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002255 auto iv_state = GetImageViewState();
Tobin Ehlis8b26a382016-09-14 08:02:49 -06002256 if (iv_state) {
Mark Lobodzinskifae179e2019-03-08 16:47:08 -07002257 dev_data->AddCommandBufferBindingImageView(cb_node, iv_state);
John Zulauffbf3c202019-07-17 14:57:14 -06002258 dev_data->CallSetImageViewInitialLayoutCallback(cb_node, *iv_state, image_layout_);
Jeff Bolz148d94e2018-12-13 21:25:56 -06002259 }
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002260}
2261
sfricke-samsung4ba7d6e2021-03-06 20:56:35 -08002262cvdescriptorset::BufferDescriptor::BufferDescriptor(const VkDescriptorType type) : offset_(0), range_(0) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002263 updated = false;
2264 descriptor_class = GeneralBuffer;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002265}
John Zulaufd2c3dae2019-12-12 11:02:17 -07002266void cvdescriptorset::BufferDescriptor::WriteUpdate(const ValidationStateTracker *dev_data, const VkWriteDescriptorSet *update,
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002267 const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002268 updated = true;
Tobin Ehlis56a30942016-05-19 08:00:00 -06002269 const auto &buffer_info = update->pBufferInfo[index];
Tobin Ehlis300888c2016-05-18 13:43:26 -06002270 offset_ = buffer_info.offset;
2271 range_ = buffer_info.range;
Karl Schultz76d16a42020-11-11 05:05:33 -07002272 buffer_state_ = dev_data->GetConstCastShared<BUFFER_STATE>(buffer_info.buffer);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002273}
2274
John Zulaufd2c3dae2019-12-12 11:02:17 -07002275void cvdescriptorset::BufferDescriptor::CopyUpdate(const ValidationStateTracker *dev_data, const Descriptor *src) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002276 updated = true;
Karl Schultz76d16a42020-11-11 05:05:33 -07002277 const auto buff_desc = static_cast<const BufferDescriptor *>(src);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002278 offset_ = buff_desc->offset_;
2279 range_ = buff_desc->range_;
Karl Schultz76d16a42020-11-11 05:05:33 -07002280 buffer_state_ = buff_desc->buffer_state_;
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002281}
2282
John Zulauffbf3c202019-07-17 14:57:14 -06002283void cvdescriptorset::BufferDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) {
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002284 auto buffer_node = GetBufferState();
Mark Lobodzinskifae179e2019-03-08 16:47:08 -07002285 if (buffer_node) dev_data->AddCommandBufferBindingBuffer(cb_node, buffer_node);
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002286}
2287
sfricke-samsung4ba7d6e2021-03-06 20:56:35 -08002288cvdescriptorset::TexelDescriptor::TexelDescriptor(const VkDescriptorType type) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002289 updated = false;
2290 descriptor_class = TexelBuffer;
Petr Kraus13c98a62017-12-09 00:22:39 +01002291}
Tobin Ehlis56a30942016-05-19 08:00:00 -06002292
John Zulaufd2c3dae2019-12-12 11:02:17 -07002293void cvdescriptorset::TexelDescriptor::WriteUpdate(const ValidationStateTracker *dev_data, const VkWriteDescriptorSet *update,
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002294 const uint32_t index) {
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002295 updated = true;
Karl Schultz76d16a42020-11-11 05:05:33 -07002296 buffer_view_state_ = dev_data->GetConstCastShared<BUFFER_VIEW_STATE>(update->pTexelBufferView[index]);
Tobin Ehlis0a43bde2016-05-03 08:31:08 -06002297}
2298
John Zulaufd2c3dae2019-12-12 11:02:17 -07002299void cvdescriptorset::TexelDescriptor::CopyUpdate(const ValidationStateTracker *dev_data, const Descriptor *src) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002300 updated = true;
Karl Schultz76d16a42020-11-11 05:05:33 -07002301 buffer_view_state_ = static_cast<const TexelDescriptor *>(src)->buffer_view_state_;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002302}
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002303
John Zulauffbf3c202019-07-17 14:57:14 -06002304void cvdescriptorset::TexelDescriptor::UpdateDrawState(ValidationStateTracker *dev_data, CMD_BUFFER_STATE *cb_node) {
Jeff Bolzfaffeb32019-10-04 12:47:16 -05002305 auto bv_state = GetBufferViewState();
Tobin Ehlis8b872462016-09-14 08:12:08 -06002306 if (bv_state) {
Mark Lobodzinskifae179e2019-03-08 16:47:08 -07002307 dev_data->AddCommandBufferBindingBufferView(cb_node, bv_state);
Tobin Ehlis81e46372016-08-17 13:33:44 -06002308 }
Tobin Ehlis8020eea2016-08-17 11:10:41 -06002309}
2310
Jeff Bolz95176d02020-04-01 00:36:16 -05002311cvdescriptorset::AccelerationStructureDescriptor::AccelerationStructureDescriptor(const VkDescriptorType type)
sourav parmarcd5fb182020-07-17 12:58:44 -07002312 : acc_(VK_NULL_HANDLE), acc_nv_(VK_NULL_HANDLE) {
Jeff Bolz95176d02020-04-01 00:36:16 -05002313 updated = false;
sourav parmarcd5fb182020-07-17 12:58:44 -07002314 is_khr_ = false;
Jeff Bolz95176d02020-04-01 00:36:16 -05002315 descriptor_class = AccelerationStructure;
2316}
2317void cvdescriptorset::AccelerationStructureDescriptor::WriteUpdate(const ValidationStateTracker *dev_data,
2318 const VkWriteDescriptorSet *update, const uint32_t index) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002319 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(update->pNext);
2320 const auto *acc_info_nv = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(update->pNext);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002321 assert(acc_info || acc_info_nv);
2322 is_khr_ = (acc_info != NULL);
Jeff Bolz95176d02020-04-01 00:36:16 -05002323 updated = true;
sourav parmarcd5fb182020-07-17 12:58:44 -07002324 if (is_khr_) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002325 acc_ = acc_info->pAccelerationStructures[index];
sourav parmarcd5fb182020-07-17 12:58:44 -07002326 acc_state_ = dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_);
2327 } else {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002328 acc_nv_ = acc_info_nv->pAccelerationStructures[index];
sourav parmarcd5fb182020-07-17 12:58:44 -07002329 acc_state_nv_ = dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_);
2330 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002331}
2332
2333void cvdescriptorset::AccelerationStructureDescriptor::CopyUpdate(const ValidationStateTracker *dev_data, const Descriptor *src) {
2334 auto acc_desc = static_cast<const AccelerationStructureDescriptor *>(src);
2335 updated = true;
sourav parmarcd5fb182020-07-17 12:58:44 -07002336 if (is_khr_) {
2337 acc_ = acc_desc->acc_;
2338 acc_state_ = dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE_KHR>(acc_);
2339 } else {
2340 acc_nv_ = acc_desc->acc_nv_;
2341 acc_state_nv_ = dev_data->GetConstCastShared<ACCELERATION_STRUCTURE_STATE>(acc_nv_);
2342 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002343}
2344
2345void cvdescriptorset::AccelerationStructureDescriptor::UpdateDrawState(ValidationStateTracker *dev_data,
2346 CMD_BUFFER_STATE *cb_node) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002347 if (is_khr_) {
2348 auto acc_node = GetAccelerationStructureStateKHR();
2349 if (acc_node) dev_data->AddCommandBufferBindingAccelerationStructure(cb_node, acc_node);
2350 } else {
2351 auto acc_node = GetAccelerationStructureStateNV();
2352 if (acc_node) dev_data->AddCommandBufferBindingAccelerationStructure(cb_node, acc_node);
2353 }
Jeff Bolz95176d02020-04-01 00:36:16 -05002354}
2355
Tobin Ehlis300888c2016-05-18 13:43:26 -06002356// This is a helper function that iterates over a set of Write and Copy updates, pulls the DescriptorSet* for updated
2357// sets, and then calls their respective Validate[Write|Copy]Update functions.
2358// If the update hits an issue for which the callback returns "true", meaning that the call down the chain should
2359// be skipped, then true is returned.
2360// If there is no issue with the update, then false is returned.
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002361bool CoreChecks::ValidateUpdateDescriptorSets(uint32_t write_count, const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002362 const VkCopyDescriptorSet *p_cds, const char *func_name) const {
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06002363 bool skip = false;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002364 // Validate Write updates
Tobin Ehlis56a30942016-05-19 08:00:00 -06002365 for (uint32_t i = 0; i < write_count; i++) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002366 auto dest_set = p_wds[i].dstSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002367 auto set_node = GetSetNode(dest_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06002368 if (!set_node) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08002369 skip |= LogError(dest_set, kVUID_Core_DrawState_InvalidDescriptorSet,
2370 "Cannot call %s on %s that has not been allocated in pDescriptorWrites[%u].", func_name,
2371 report_data->FormatHandle(dest_set).c_str(), i);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002372 } else {
Dave Houltond8ed0212018-05-16 17:18:24 -06002373 std::string error_code;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002374 std::string error_str;
John Zulaufc93c4252019-06-25 09:19:49 -06002375 if (!ValidateWriteUpdate(set_node, &p_wds[i], func_name, &error_code, &error_str)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08002376 skip |=
2377 LogError(dest_set, error_code, "%s pDescriptorWrites[%u] failed write update validation for %s with error: %s.",
2378 func_name, i, report_data->FormatHandle(dest_set).c_str(), error_str.c_str());
Tobin Ehlis300888c2016-05-18 13:43:26 -06002379 }
2380 }
sourav parmara24fb7b2020-05-26 10:50:04 -07002381 if (p_wds[i].pNext) {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002382 const auto *pnext_struct = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureKHR>(p_wds[i].pNext);
Mark Lobodzinski17dc4602020-05-29 07:48:40 -06002383 if (pnext_struct) {
2384 for (uint32_t j = 0; j < pnext_struct->accelerationStructureCount; ++j) {
sourav parmarcd5fb182020-07-17 12:58:44 -07002385 const ACCELERATION_STRUCTURE_STATE_KHR *as_state =
2386 GetAccelerationStructureStateKHR(pnext_struct->pAccelerationStructures[j]);
2387 if (as_state && (as_state->create_infoKHR.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR &&
sourav parmar766e2a72020-12-03 16:17:11 -08002388 (as_state->create_infoKHR.type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR &&
2389 as_state->create_infoKHR.type != VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR))) {
sourav parmara24fb7b2020-05-26 10:50:04 -07002390 skip |=
sourav parmarcd5fb182020-07-17 12:58:44 -07002391 LogError(dest_set, "VUID-VkWriteDescriptorSetAccelerationStructureKHR-pAccelerationStructures-03579",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002392 "%s: For pDescriptorWrites[%u] acceleration structure in pAccelerationStructures[%u] must "
2393 "have been created with "
sourav parmarbcee7512020-12-28 14:34:49 -08002394 "VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR or VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002395 func_name, i, j);
sourav parmara24fb7b2020-05-26 10:50:04 -07002396 }
2397 }
2398 }
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002399 const auto *pnext_struct_nv = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(p_wds[i].pNext);
sourav parmarcd5fb182020-07-17 12:58:44 -07002400 if (pnext_struct_nv) {
2401 for (uint32_t j = 0; j < pnext_struct_nv->accelerationStructureCount; ++j) {
2402 const ACCELERATION_STRUCTURE_STATE *as_state =
2403 GetAccelerationStructureStateNV(pnext_struct_nv->pAccelerationStructures[j]);
2404 if (as_state && (as_state->create_infoNV.sType == VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV &&
2405 as_state->create_infoNV.info.type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV)) {
2406 skip |= LogError(dest_set, "VUID-VkWriteDescriptorSetAccelerationStructureNV-pAccelerationStructures-03748",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002407 "%s: For pDescriptorWrites[%u] acceleration structure in pAccelerationStructures[%u] must "
2408 "have been created with"
sourav parmarcd5fb182020-07-17 12:58:44 -07002409 " VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV.",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002410 func_name, i, j);
sourav parmarcd5fb182020-07-17 12:58:44 -07002411 }
2412 }
2413 }
sourav parmara24fb7b2020-05-26 10:50:04 -07002414 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002415 }
2416 // Now validate copy updates
Tobin Ehlis56a30942016-05-19 08:00:00 -06002417 for (uint32_t i = 0; i < copy_count; ++i) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002418 auto dst_set = p_cds[i].dstSet;
2419 auto src_set = p_cds[i].srcSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002420 auto src_node = GetSetNode(src_set);
2421 auto dst_node = GetSetNode(dst_set);
Tobin Ehlisa1712752017-01-04 09:41:47 -07002422 // Object_tracker verifies that src & dest descriptor set are valid
2423 assert(src_node);
2424 assert(dst_node);
Dave Houltond8ed0212018-05-16 17:18:24 -06002425 std::string error_code;
Tobin Ehlisa1712752017-01-04 09:41:47 -07002426 std::string error_str;
John Zulaufc93c4252019-06-25 09:19:49 -06002427 if (!ValidateCopyUpdate(&p_cds[i], dst_node, src_node, func_name, &error_code, &error_str)) {
Mark Lobodzinski9d38ea22020-03-16 18:22:16 -06002428 LogObjectList objlist(dst_set);
2429 objlist.add(src_set);
sfricke-samsungbda4a852021-03-06 20:58:01 -08002430 skip |= LogError(objlist, error_code, "%s pDescriptorCopies[%u] failed copy update from %s to %s with error: %s.",
2431 func_name, i, report_data->FormatHandle(src_set).c_str(), report_data->FormatHandle(dst_set).c_str(),
2432 error_str.c_str());
Tobin Ehlis300888c2016-05-18 13:43:26 -06002433 }
2434 }
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06002435 return skip;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002436}
2437// This is a helper function that iterates over a set of Write and Copy updates, pulls the DescriptorSet* for updated
2438// sets, and then calls their respective Perform[Write|Copy]Update functions.
2439// Prerequisite : ValidateUpdateDescriptorSets() should be called and return "false" prior to calling PerformUpdateDescriptorSets()
2440// with the same set of updates.
2441// This is split from the validate code to allow validation prior to calling down the chain, and then update after
2442// calling down the chain.
John Zulaufe3b35f32019-06-25 14:21:21 -06002443void cvdescriptorset::PerformUpdateDescriptorSets(ValidationStateTracker *dev_data, uint32_t write_count,
2444 const VkWriteDescriptorSet *p_wds, uint32_t copy_count,
2445 const VkCopyDescriptorSet *p_cds) {
Tobin Ehlis300888c2016-05-18 13:43:26 -06002446 // Write updates first
2447 uint32_t i = 0;
2448 for (i = 0; i < write_count; ++i) {
2449 auto dest_set = p_wds[i].dstSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002450 auto set_node = dev_data->GetSetNode(dest_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06002451 if (set_node) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05002452 set_node->PerformWriteUpdate(dev_data, &p_wds[i]);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002453 }
2454 }
2455 // Now copy updates
2456 for (i = 0; i < copy_count; ++i) {
2457 auto dst_set = p_cds[i].dstSet;
2458 auto src_set = p_cds[i].srcSet;
Mark Lobodzinskifc2f0d32019-03-06 11:25:39 -07002459 auto src_node = dev_data->GetSetNode(src_set);
2460 auto dst_node = dev_data->GetSetNode(dst_set);
Tobin Ehlis6a72dc72016-06-01 16:41:17 -06002461 if (src_node && dst_node) {
Jeff Bolz41a1ced2019-10-11 11:40:49 -05002462 dst_node->PerformCopyUpdate(dev_data, &p_cds[i], src_node);
Tobin Ehlis300888c2016-05-18 13:43:26 -06002463 }
2464 }
2465}
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002466
John Zulaufe3b35f32019-06-25 14:21:21 -06002467cvdescriptorset::DecodedTemplateUpdate::DecodedTemplateUpdate(const ValidationStateTracker *device_data,
2468 VkDescriptorSet descriptorSet, const TEMPLATE_STATE *template_state,
2469 const void *pData, VkDescriptorSetLayout push_layout) {
John Zulaufb845eb22018-10-12 11:41:06 -06002470 auto const &create_info = template_state->create_info;
2471 inline_infos.resize(create_info.descriptorUpdateEntryCount); // Make sure we have one if we need it
sourav parmar480d2772021-01-24 22:24:54 -08002472 inline_infos_khr.resize(create_info.descriptorUpdateEntryCount);
2473 inline_infos_nv.resize(create_info.descriptorUpdateEntryCount);
John Zulaufb845eb22018-10-12 11:41:06 -06002474 desc_writes.reserve(create_info.descriptorUpdateEntryCount); // emplaced, so reserved without initialization
John Zulauf1d27e0a2018-11-05 10:12:48 -07002475 VkDescriptorSetLayout effective_dsl = create_info.templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET
2476 ? create_info.descriptorSetLayout
2477 : push_layout;
Jeff Bolz6ae39612019-10-11 20:57:36 -05002478 auto layout_obj = device_data->GetDescriptorSetLayoutShared(effective_dsl);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002479
2480 // Create a WriteDescriptorSet struct for each template update entry
2481 for (uint32_t i = 0; i < create_info.descriptorUpdateEntryCount; i++) {
2482 auto binding_count = layout_obj->GetDescriptorCountFromBinding(create_info.pDescriptorUpdateEntries[i].dstBinding);
2483 auto binding_being_updated = create_info.pDescriptorUpdateEntries[i].dstBinding;
2484 auto dst_array_element = create_info.pDescriptorUpdateEntries[i].dstArrayElement;
2485
John Zulaufb6d71202017-12-22 16:47:09 -07002486 desc_writes.reserve(desc_writes.size() + create_info.pDescriptorUpdateEntries[i].descriptorCount);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002487 for (uint32_t j = 0; j < create_info.pDescriptorUpdateEntries[i].descriptorCount; j++) {
2488 desc_writes.emplace_back();
2489 auto &write_entry = desc_writes.back();
2490
2491 size_t offset = create_info.pDescriptorUpdateEntries[i].offset + j * create_info.pDescriptorUpdateEntries[i].stride;
2492 char *update_entry = (char *)(pData) + offset;
2493
2494 if (dst_array_element >= binding_count) {
2495 dst_array_element = 0;
Mark Lobodzinski4aa479d2017-03-10 09:14:00 -07002496 binding_being_updated = layout_obj->GetNextValidBinding(binding_being_updated);
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002497 }
2498
2499 write_entry.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2500 write_entry.pNext = NULL;
2501 write_entry.dstSet = descriptorSet;
2502 write_entry.dstBinding = binding_being_updated;
2503 write_entry.dstArrayElement = dst_array_element;
2504 write_entry.descriptorCount = 1;
2505 write_entry.descriptorType = create_info.pDescriptorUpdateEntries[i].descriptorType;
2506
2507 switch (create_info.pDescriptorUpdateEntries[i].descriptorType) {
2508 case VK_DESCRIPTOR_TYPE_SAMPLER:
2509 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2510 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2511 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2512 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2513 write_entry.pImageInfo = reinterpret_cast<VkDescriptorImageInfo *>(update_entry);
2514 break;
2515
2516 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2517 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2518 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2519 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2520 write_entry.pBufferInfo = reinterpret_cast<VkDescriptorBufferInfo *>(update_entry);
2521 break;
2522
2523 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2524 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2525 write_entry.pTexelBufferView = reinterpret_cast<VkBufferView *>(update_entry);
2526 break;
Dave Houlton142c4cb2018-10-17 15:04:41 -06002527 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
2528 VkWriteDescriptorSetInlineUniformBlockEXT *inline_info = &inline_infos[i];
2529 inline_info->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
2530 inline_info->pNext = nullptr;
2531 inline_info->dataSize = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2532 inline_info->pData = update_entry;
2533 write_entry.pNext = inline_info;
Ricardo Garciafee15732019-05-28 11:13:31 +02002534 // descriptorCount must match the dataSize member of the VkWriteDescriptorSetInlineUniformBlockEXT structure
2535 write_entry.descriptorCount = inline_info->dataSize;
Dave Houlton142c4cb2018-10-17 15:04:41 -06002536 // skip the rest of the array, they just represent bytes in the update
2537 j = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2538 break;
2539 }
sourav parmar480d2772021-01-24 22:24:54 -08002540 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
2541 VkWriteDescriptorSetAccelerationStructureKHR *inline_info_khr = &inline_infos_khr[i];
2542 inline_info_khr->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
2543 inline_info_khr->pNext = nullptr;
2544 inline_info_khr->accelerationStructureCount = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2545 inline_info_khr->pAccelerationStructures = reinterpret_cast<VkAccelerationStructureKHR *>(update_entry);
2546 write_entry.pNext = inline_info_khr;
2547 break;
2548 }
2549 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: {
2550 VkWriteDescriptorSetAccelerationStructureNV *inline_info_nv = &inline_infos_nv[i];
2551 inline_info_nv->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV;
2552 inline_info_nv->pNext = nullptr;
2553 inline_info_nv->accelerationStructureCount = create_info.pDescriptorUpdateEntries[i].descriptorCount;
2554 inline_info_nv->pAccelerationStructures = reinterpret_cast<VkAccelerationStructureNV *>(update_entry);
2555 write_entry.pNext = inline_info_nv;
2556 break;
2557 }
Mark Lobodzinski3d63a042017-03-09 16:24:13 -07002558 default:
2559 assert(0);
2560 break;
2561 }
2562 dst_array_element++;
2563 }
2564 }
John Zulaufb845eb22018-10-12 11:41:06 -06002565}
John Zulaufb45fdc32018-10-12 15:14:17 -06002566// These helper functions carry out the validate and record descriptor updates peformed via update templates. They decode
2567// the templatized data and leverage the non-template UpdateDescriptor helper functions.
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002568bool CoreChecks::ValidateUpdateDescriptorSetsWithTemplateKHR(VkDescriptorSet descriptorSet, const TEMPLATE_STATE *template_state,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002569 const void *pData) const {
John Zulaufb45fdc32018-10-12 15:14:17 -06002570 // Translate the templated update into a normal update for validation...
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002571 cvdescriptorset::DecodedTemplateUpdate decoded_update(this, descriptorSet, template_state, pData);
2572 return ValidateUpdateDescriptorSets(static_cast<uint32_t>(decoded_update.desc_writes.size()), decoded_update.desc_writes.data(),
2573 0, NULL, "vkUpdateDescriptorSetWithTemplate()");
John Zulaufb45fdc32018-10-12 15:14:17 -06002574}
John Zulaufb845eb22018-10-12 11:41:06 -06002575
John Zulauf4e7bcb52018-11-02 10:46:30 -06002576std::string cvdescriptorset::DescriptorSet::StringifySetAndLayout() const {
2577 std::string out;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002578 auto layout_handle = layout_->GetDescriptorSetLayout();
John Zulauf4e7bcb52018-11-02 10:46:30 -06002579 if (IsPushDescriptor()) {
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002580 std::ostringstream str;
Tony-LunarG1d3ee2d2020-10-27 15:54:52 -06002581 str << "Push Descriptors defined with " << state_data_->report_data->FormatHandle(layout_handle);
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002582 out = str.str();
John Zulauf4e7bcb52018-11-02 10:46:30 -06002583 } else {
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002584 std::ostringstream str;
Tony-LunarG1d3ee2d2020-10-27 15:54:52 -06002585 str << state_data_->report_data->FormatHandle(set_) << " allocated with "
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06002586 << state_data_->report_data->FormatHandle(layout_handle);
2587 out = str.str();
John Zulauf4e7bcb52018-11-02 10:46:30 -06002588 }
2589 return out;
2590};
2591
John Zulauf1d27e0a2018-11-05 10:12:48 -07002592// Loop through the write updates to validate for a push descriptor set, ignoring dstSet
John Zulaufc93c4252019-06-25 09:19:49 -06002593bool CoreChecks::ValidatePushDescriptorsUpdate(const DescriptorSet *push_set, uint32_t write_count,
John Zulaufbd9b3412019-08-22 17:16:11 -06002594 const VkWriteDescriptorSet *p_wds, const char *func_name) const {
John Zulaufd9435c32019-06-05 15:55:36 -06002595 assert(push_set->IsPushDescriptor());
John Zulauf1d27e0a2018-11-05 10:12:48 -07002596 bool skip = false;
2597 for (uint32_t i = 0; i < write_count; i++) {
2598 std::string error_code;
2599 std::string error_str;
John Zulaufc93c4252019-06-25 09:19:49 -06002600 if (!ValidateWriteUpdate(push_set, &p_wds[i], func_name, &error_code, &error_str)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08002601 skip |= LogError(push_set->GetDescriptorSetLayout(), error_code,
2602 "%s VkWriteDescriptorSet[%u] failed update validation: %s.", func_name, i, error_str.c_str());
John Zulauf1d27e0a2018-11-05 10:12:48 -07002603 }
2604 }
2605 return skip;
2606}
2607
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002608// For the given buffer, verify that its creation parameters are appropriate for the given type
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002609// 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 -06002610bool cvdescriptorset::ValidateBufferUsage(debug_report_data *report_data, BUFFER_STATE const *buffer_node, VkDescriptorType type,
2611 std::string *error_code, std::string *error_msg) {
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002612 // Verify that usage bits set correctly for given type
Tobin Ehlis94bc5d22016-06-02 07:46:52 -06002613 auto usage = buffer_node->createInfo.usage;
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002614 const char *error_usage_bit = nullptr;
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002615 switch (type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002616 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2617 if (!(usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002618 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00334";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002619 error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT";
2620 }
2621 break;
2622 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2623 if (!(usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002624 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00335";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002625 error_usage_bit = "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT";
2626 }
2627 break;
2628 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2629 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2630 if (!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002631 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00330";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002632 error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT";
2633 }
2634 break;
2635 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2636 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2637 if (!(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002638 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00331";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002639 error_usage_bit = "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT";
2640 }
2641 break;
2642 default:
2643 break;
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002644 }
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06002645 if (error_usage_bit) {
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002646 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002647 error_str << "Buffer (" << report_data->FormatHandle(buffer_node->buffer) << ") with usage mask " << std::hex
2648 << std::showbase << usage << " being used for a descriptor update of type " << string_VkDescriptorType(type)
2649 << " does not have " << error_usage_bit << " set.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002650 *error_msg = error_str.str();
Tobin Ehlis6bd2b982016-05-24 12:33:42 -06002651 return false;
2652 }
2653 return true;
2654}
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002655// For buffer descriptor updates, verify the buffer usage and VkDescriptorBufferInfo struct which includes:
2656// 1. buffer is valid
2657// 2. buffer was created with correct usage flags
2658// 3. offset is less than buffer size
2659// 4. range is either VK_WHOLE_SIZE or falls in (0, (buffer size - offset)]
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002660// 5. range and offset are within the device's limits
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002661// 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 -06002662bool CoreChecks::ValidateBufferUpdate(VkDescriptorBufferInfo const *buffer_info, VkDescriptorType type, const char *func_name,
John Zulaufbd9b3412019-08-22 17:16:11 -06002663 std::string *error_code, std::string *error_msg) const {
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002664 // First make sure that buffer is valid
John Zulaufc93c4252019-06-25 09:19:49 -06002665 auto buffer_node = GetBufferState(buffer_info->buffer);
Tobin Ehlisfa8b6182016-12-22 13:40:45 -07002666 // Any invalid buffer should already be caught by object_tracker
2667 assert(buffer_node);
John Zulaufc93c4252019-06-25 09:19:49 -06002668 if (ValidateMemoryIsBoundToBuffer(buffer_node, func_name, "VUID-VkWriteDescriptorSet-descriptorType-00329")) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002669 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00329";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002670 *error_msg = "No memory bound to buffer.";
Tobin Ehlis81280962016-07-20 14:04:20 -06002671 return false;
Tobin Ehlisfed999f2016-09-21 15:09:45 -06002672 }
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002673 // Verify usage bits
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002674 if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_node, type, error_code, error_msg)) {
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002675 // error_msg will have been updated by ValidateBufferUsage()
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002676 return false;
2677 }
2678 // offset must be less than buffer size
Jeremy Hayesd1a6a822017-03-09 14:39:45 -07002679 if (buffer_info->offset >= buffer_node->createInfo.size) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002680 *error_code = "VUID-VkDescriptorBufferInfo-offset-00340";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002681 std::stringstream error_str;
Jeremy Hayesd1a6a822017-03-09 14:39:45 -07002682 error_str << "VkDescriptorBufferInfo offset of " << buffer_info->offset << " is greater than or equal to buffer "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002683 << report_data->FormatHandle(buffer_node->buffer) << " size of " << buffer_node->createInfo.size;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002684 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002685 return false;
2686 }
2687 if (buffer_info->range != VK_WHOLE_SIZE) {
2688 // Range must be VK_WHOLE_SIZE or > 0
2689 if (!buffer_info->range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002690 *error_code = "VUID-VkDescriptorBufferInfo-range-00341";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002691 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002692 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer)
2693 << " VkDescriptorBufferInfo range is not VK_WHOLE_SIZE and is zero, which is not allowed.";
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002694 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002695 return false;
2696 }
2697 // Range must be VK_WHOLE_SIZE or <= (buffer size - offset)
2698 if (buffer_info->range > (buffer_node->createInfo.size - buffer_info->offset)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002699 *error_code = "VUID-VkDescriptorBufferInfo-range-00342";
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002700 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002701 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer) << " VkDescriptorBufferInfo range is "
2702 << buffer_info->range << " which is greater than buffer size (" << buffer_node->createInfo.size
2703 << ") minus requested offset of " << buffer_info->offset;
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002704 *error_msg = error_str.str();
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002705 return false;
2706 }
2707 }
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002708 // Check buffer update sizes against device limits
John Zulaufc93c4252019-06-25 09:19:49 -06002709 const auto &limits = phys_dev_props.limits;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002710 if (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == type || VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC == type) {
John Zulaufd9435c32019-06-05 15:55:36 -06002711 auto max_ub_range = limits.maxUniformBufferRange;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002712 if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_ub_range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002713 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00332";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002714 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002715 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer) << " VkDescriptorBufferInfo range is "
2716 << buffer_info->range << " which is greater than this device's maxUniformBufferRange (" << max_ub_range
2717 << ")";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002718 *error_msg = error_str.str();
2719 return false;
Peter Kohaut2794a292018-07-13 11:13:47 +02002720 } else if (buffer_info->range == VK_WHOLE_SIZE && (buffer_node->createInfo.size - buffer_info->offset) > max_ub_range) {
2721 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00332";
2722 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002723 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer)
2724 << " VkDescriptorBufferInfo range is VK_WHOLE_SIZE but effective range "
Peter Kohaut18f413d2018-07-16 13:15:42 +02002725 << "(" << (buffer_node->createInfo.size - buffer_info->offset) << ") is greater than this device's "
Peter Kohaut2794a292018-07-13 11:13:47 +02002726 << "maxUniformBufferRange (" << max_ub_range << ")";
2727 *error_msg = error_str.str();
2728 return false;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002729 }
2730 } else if (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == type || VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC == type) {
John Zulaufd9435c32019-06-05 15:55:36 -06002731 auto max_sb_range = limits.maxStorageBufferRange;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002732 if (buffer_info->range != VK_WHOLE_SIZE && buffer_info->range > max_sb_range) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002733 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00333";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002734 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002735 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer) << " VkDescriptorBufferInfo range is "
2736 << buffer_info->range << " which is greater than this device's maxStorageBufferRange (" << max_sb_range
2737 << ")";
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002738 *error_msg = error_str.str();
2739 return false;
Peter Kohaut2794a292018-07-13 11:13:47 +02002740 } else if (buffer_info->range == VK_WHOLE_SIZE && (buffer_node->createInfo.size - buffer_info->offset) > max_sb_range) {
2741 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00333";
2742 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002743 error_str << "For buffer " << report_data->FormatHandle(buffer_node->buffer)
2744 << " VkDescriptorBufferInfo range is VK_WHOLE_SIZE but effective range "
Peter Kohaut18f413d2018-07-16 13:15:42 +02002745 << "(" << (buffer_node->createInfo.size - buffer_info->offset) << ") is greater than this device's "
Peter Kohaut2794a292018-07-13 11:13:47 +02002746 << "maxStorageBufferRange (" << max_sb_range << ")";
2747 *error_msg = error_str.str();
2748 return false;
Tobin Ehlisc3b6c4c2017-02-02 17:26:40 -07002749 }
2750 }
Tobin Ehlis3d38f082016-07-01 17:36:48 -06002751 return true;
2752}
sourav parmarcd5fb182020-07-17 12:58:44 -07002753template <typename T>
2754bool CoreChecks::ValidateAccelerationStructureUpdate(T acc_node, const char *func_name, std::string *error_code,
Jeff Bolz95176d02020-04-01 00:36:16 -05002755 std::string *error_msg) const {
Jeff Bolz95176d02020-04-01 00:36:16 -05002756 // Any invalid acc struct should already be caught by object_tracker
2757 assert(acc_node);
2758 if (ValidateMemoryIsBoundToAccelerationStructure(acc_node, func_name, kVUIDUndefined)) {
2759 *error_code = kVUIDUndefined;
2760 *error_msg = "No memory bound to acceleration structure.";
2761 return false;
2762 }
2763 return true;
2764}
2765
Tobin Ehlis300888c2016-05-18 13:43:26 -06002766// Verify that the contents of the update are ok, but don't perform actual update
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002767bool CoreChecks::VerifyCopyUpdateContents(const VkCopyDescriptorSet *update, const DescriptorSet *src_set,
2768 VkDescriptorType src_type, uint32_t src_index, const DescriptorSet *dst_set,
2769 VkDescriptorType dst_type, uint32_t dst_index, const char *func_name,
2770 std::string *error_code, std::string *error_msg) const {
Tobin Ehlis75f04ec2016-10-06 17:43:11 -06002771 // Note : Repurposing some Write update error codes here as specific details aren't called out for copy updates like they are
2772 // for write updates
John Zulaufc93c4252019-06-25 09:19:49 -06002773 using DescriptorClass = cvdescriptorset::DescriptorClass;
2774 using BufferDescriptor = cvdescriptorset::BufferDescriptor;
2775 using ImageDescriptor = cvdescriptorset::ImageDescriptor;
2776 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
2777 using SamplerDescriptor = cvdescriptorset::SamplerDescriptor;
2778 using TexelDescriptor = cvdescriptorset::TexelDescriptor;
2779
2780 auto device_data = this;
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002781
2782 if (dst_type == VK_DESCRIPTOR_TYPE_SAMPLER) {
2783 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
2784 const auto dst_desc = dst_set->GetDescriptorFromGlobalIndex(dst_index + di);
2785 if (!dst_desc->updated) continue;
2786 if (dst_desc->IsImmutableSampler()) {
2787 *error_code = "VUID-VkCopyDescriptorSet-dstBinding-02753";
2788 std::stringstream error_str;
2789 error_str << "Attempted copy update to an immutable sampler descriptor.";
2790 *error_msg = error_str.str();
2791 return false;
2792 }
2793 }
2794 }
2795
2796 switch (src_set->GetDescriptorFromGlobalIndex(src_index)->descriptor_class) {
John Zulaufc93c4252019-06-25 09:19:49 -06002797 case DescriptorClass::PlainSampler: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002798 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002799 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02002800 if (!src_desc->updated) continue;
2801 if (!src_desc->IsImmutableSampler()) {
John Zulaufd9435c32019-06-05 15:55:36 -06002802 auto update_sampler = static_cast<const SamplerDescriptor *>(src_desc)->GetSampler();
John Zulaufc93c4252019-06-25 09:19:49 -06002803 if (!ValidateSampler(update_sampler)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002804 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002805 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002806 error_str << "Attempted copy update to sampler descriptor with invalid sampler: "
2807 << report_data->FormatHandle(update_sampler) << ".";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002808 *error_msg = error_str.str();
2809 return false;
2810 }
2811 } else {
2812 // TODO : Warn here
2813 }
2814 }
2815 break;
2816 }
John Zulaufc93c4252019-06-25 09:19:49 -06002817 case DescriptorClass::ImageSampler: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002818 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002819 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02002820 if (!src_desc->updated) continue;
2821 auto img_samp_desc = static_cast<const ImageSamplerDescriptor *>(src_desc);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002822 // First validate sampler
2823 if (!img_samp_desc->IsImmutableSampler()) {
2824 auto update_sampler = img_samp_desc->GetSampler();
John Zulaufc93c4252019-06-25 09:19:49 -06002825 if (!ValidateSampler(update_sampler)) {
Dave Houlton00c154e2018-05-24 13:20:50 -06002826 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002827 std::stringstream error_str;
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06002828 error_str << "Attempted copy update to sampler descriptor with invalid sampler: "
2829 << report_data->FormatHandle(update_sampler) << ".";
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002830 *error_msg = error_str.str();
2831 return false;
2832 }
2833 } else {
2834 // TODO : Warn here
2835 }
2836 // Validate image
2837 auto image_view = img_samp_desc->GetImageView();
2838 auto image_layout = img_samp_desc->GetImageLayout();
Jeff Bolz165818a2020-05-08 11:19:03 -05002839 if (image_view) {
2840 if (!ValidateImageUpdate(image_view, image_layout, src_type, func_name, error_code, error_msg)) {
2841 std::stringstream error_str;
2842 error_str << "Attempted copy update to combined image sampler descriptor failed due to: "
2843 << error_msg->c_str();
2844 *error_msg = error_str.str();
2845 return false;
2846 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002847 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002848 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002849 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002850 }
John Zulaufc93c4252019-06-25 09:19:49 -06002851 case DescriptorClass::Image: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002852 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002853 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02002854 if (!src_desc->updated) continue;
2855 auto img_desc = static_cast<const ImageDescriptor *>(src_desc);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002856 auto image_view = img_desc->GetImageView();
2857 auto image_layout = img_desc->GetImageLayout();
Jeff Bolz165818a2020-05-08 11:19:03 -05002858 if (image_view) {
2859 if (!ValidateImageUpdate(image_view, image_layout, src_type, func_name, error_code, error_msg)) {
2860 std::stringstream error_str;
2861 error_str << "Attempted copy update to image descriptor failed due to: " << error_msg->c_str();
2862 *error_msg = error_str.str();
2863 return false;
2864 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002865 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002866 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002867 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002868 }
John Zulaufc93c4252019-06-25 09:19:49 -06002869 case DescriptorClass::TexelBuffer: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002870 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002871 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02002872 if (!src_desc->updated) continue;
John Zulaufd9435c32019-06-05 15:55:36 -06002873 auto buffer_view = static_cast<const TexelDescriptor *>(src_desc)->GetBufferView();
Jeff Bolz165818a2020-05-08 11:19:03 -05002874 if (buffer_view) {
2875 auto bv_state = device_data->GetBufferViewState(buffer_view);
2876 if (!bv_state) {
2877 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
2878 std::stringstream error_str;
2879 error_str << "Attempted copy update to texel buffer descriptor with invalid buffer view: "
2880 << report_data->FormatHandle(buffer_view);
2881 *error_msg = error_str.str();
2882 return false;
2883 }
2884 auto buffer = bv_state->create_info.buffer;
2885 if (!cvdescriptorset::ValidateBufferUsage(report_data, GetBufferState(buffer), src_type, error_code,
2886 error_msg)) {
2887 std::stringstream error_str;
2888 error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error_msg->c_str();
2889 *error_msg = error_str.str();
2890 return false;
2891 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002892 }
Tobin Ehlis300888c2016-05-18 13:43:26 -06002893 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002894 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002895 }
John Zulaufc93c4252019-06-25 09:19:49 -06002896 case DescriptorClass::GeneralBuffer: {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002897 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07002898 const auto src_desc = src_set->GetDescriptorFromGlobalIndex(src_index + di);
Józef Kucia5297e372017-10-13 22:31:34 +02002899 if (!src_desc->updated) continue;
John Zulaufd9435c32019-06-05 15:55:36 -06002900 auto buffer = static_cast<const BufferDescriptor *>(src_desc)->GetBuffer();
Jeff Bolz165818a2020-05-08 11:19:03 -05002901 if (buffer) {
2902 if (!cvdescriptorset::ValidateBufferUsage(report_data, GetBufferState(buffer), src_type, error_code,
2903 error_msg)) {
2904 std::stringstream error_str;
2905 error_str << "Attempted copy update to buffer descriptor failed due to: " << error_msg->c_str();
2906 *error_msg = error_str.str();
2907 return false;
2908 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002909 }
Tobin Ehliscbcf2342016-05-24 13:07:12 -06002910 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002911 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002912 }
John Zulaufc93c4252019-06-25 09:19:49 -06002913 case DescriptorClass::InlineUniform:
2914 case DescriptorClass::AccelerationStructure:
Jeff Bolze54ae892018-09-08 12:16:29 -05002915 break;
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07002916 default:
2917 assert(0); // We've already verified update type so should never get here
2918 break;
Tobin Ehlis300888c2016-05-18 13:43:26 -06002919 }
2920 // All checks passed so update contents are good
2921 return true;
Chris Forbesb4e0bdb2016-05-31 16:34:40 +12002922}
Tobin Ehlisee471462016-05-26 11:21:59 -06002923// Verify that the state at allocate time is correct, but don't actually allocate the sets yet
Mark Lobodzinski3840ca02019-03-08 18:36:11 -07002924bool CoreChecks::ValidateAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002925 const cvdescriptorset::AllocateDescriptorSetsData *ds_data) const {
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06002926 bool skip = false;
Mark Lobodzinski7804bd42019-03-06 11:28:48 -07002927 auto pool_state = GetDescriptorPoolState(p_alloc_info->descriptorPool);
Tobin Ehlisee471462016-05-26 11:21:59 -06002928
2929 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05002930 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
John Zulauf5562d062018-01-24 11:54:05 -07002931 if (layout) { // nullptr layout indicates no valid layout handle for this device, validated/logged in object_tracker
John Zulauf1d27e0a2018-11-05 10:12:48 -07002932 if (layout->IsPushDescriptor()) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002933 skip |= LogError(p_alloc_info->pSetLayouts[i], "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-00308",
2934 "%s specified at pSetLayouts[%" PRIu32
2935 "] in vkAllocateDescriptorSets() was created with invalid flag %s set.",
2936 report_data->FormatHandle(p_alloc_info->pSetLayouts[i]).c_str(), i,
2937 "VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR");
John Zulauf5562d062018-01-24 11:54:05 -07002938 }
Mike Schuchardt2df08912020-12-15 16:28:09 -08002939 if (layout->GetCreateFlags() & VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT &&
2940 !(pool_state->createInfo.flags & VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)) {
sfricke-samsungbda4a852021-03-06 20:58:01 -08002941 skip |= LogError(
2942 device, "VUID-VkDescriptorSetAllocateInfo-pSetLayouts-03044",
2943 "vkAllocateDescriptorSets(): Descriptor set layout create flags and pool create flags mismatch for index (%d)",
2944 i);
Jeff Bolzfdf96072018-04-10 14:32:18 -05002945 }
Tobin Ehlisee471462016-05-26 11:21:59 -06002946 }
2947 }
Mark Lobodzinskif45e45f2019-04-19 14:15:39 -06002948 if (!device_extensions.vk_khr_maintenance1) {
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06002949 // Track number of descriptorSets allowable in this pool
2950 if (pool_state->availableSets < p_alloc_info->descriptorSetCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002951 skip |= LogError(pool_state->pool, "VUID-VkDescriptorSetAllocateInfo-descriptorSetCount-00306",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002952 "vkAllocateDescriptorSets(): Unable to allocate %u descriptorSets from %s"
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002953 ". This pool only has %d descriptorSets remaining.",
2954 p_alloc_info->descriptorSetCount, report_data->FormatHandle(pool_state->pool).c_str(),
2955 pool_state->availableSets);
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06002956 }
2957 // Determine whether descriptor counts are satisfiable
Jeff Bolze54ae892018-09-08 12:16:29 -05002958 for (auto it = ds_data->required_descriptors_by_type.begin(); it != ds_data->required_descriptors_by_type.end(); ++it) {
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002959 auto count_iter = pool_state->availableDescriptorTypeCount.find(it->first);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002960 uint32_t available_count = (count_iter != pool_state->availableDescriptorTypeCount.end()) ? count_iter->second : 0;
Jeff Bolz46c0ea02019-10-09 13:06:29 -05002961
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002962 if (ds_data->required_descriptors_by_type.at(it->first) > available_count) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002963 skip |= LogError(pool_state->pool, "VUID-VkDescriptorSetAllocateInfo-descriptorPool-00307",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002964 "vkAllocateDescriptorSets(): Unable to allocate %u descriptors of type %s from %s"
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002965 ". This pool only has %d descriptors of this type remaining.",
2966 ds_data->required_descriptors_by_type.at(it->first),
2967 string_VkDescriptorType(VkDescriptorType(it->first)),
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002968 report_data->FormatHandle(pool_state->pool).c_str(), available_count);
Mike Schuchardt64b5bb72017-03-21 16:33:26 -06002969 }
Tobin Ehlisee471462016-05-26 11:21:59 -06002970 }
2971 }
Tobin Ehlis5d749ea2016-07-18 13:14:01 -06002972
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07002973 const auto *count_allocate_info = LvlFindInChain<VkDescriptorSetVariableDescriptorCountAllocateInfo>(p_alloc_info->pNext);
Jeff Bolzfdf96072018-04-10 14:32:18 -05002974
2975 if (count_allocate_info) {
2976 if (count_allocate_info->descriptorSetCount != 0 &&
2977 count_allocate_info->descriptorSetCount != p_alloc_info->descriptorSetCount) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002978 skip |= LogError(device, "VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-descriptorSetCount-03045",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002979 "vkAllocateDescriptorSets(): VkDescriptorSetAllocateInfo::descriptorSetCount (%d) != "
Mike Schuchardt2df08912020-12-15 16:28:09 -08002980 "VkDescriptorSetVariableDescriptorCountAllocateInfo::descriptorSetCount (%d)",
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002981 p_alloc_info->descriptorSetCount, count_allocate_info->descriptorSetCount);
Jeff Bolzfdf96072018-04-10 14:32:18 -05002982 }
2983 if (count_allocate_info->descriptorSetCount == p_alloc_info->descriptorSetCount) {
2984 for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
Jeff Bolz6ae39612019-10-11 20:57:36 -05002985 auto layout = GetDescriptorSetLayoutShared(p_alloc_info->pSetLayouts[i]);
Jeff Bolzfdf96072018-04-10 14:32:18 -05002986 if (count_allocate_info->pDescriptorCounts[i] > layout->GetDescriptorCountFromBinding(layout->GetMaxBinding())) {
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002987 skip |= LogError(device, "VUID-VkDescriptorSetVariableDescriptorCountAllocateInfo-pSetLayouts-03046",
sfricke-samsungbda4a852021-03-06 20:58:01 -08002988 "vkAllocateDescriptorSets(): pDescriptorCounts[%d] = (%d), binding's descriptorCount = (%d)",
2989 i, count_allocate_info->pDescriptorCounts[i],
Mark Lobodzinskid18de902020-01-15 12:20:37 -07002990 layout->GetDescriptorCountFromBinding(layout->GetMaxBinding()));
Jeff Bolzfdf96072018-04-10 14:32:18 -05002991 }
2992 }
2993 }
2994 }
2995
Mark Lobodzinskibdc3b022017-04-24 09:11:35 -06002996 return skip;
Tobin Ehlisee471462016-05-26 11:21:59 -06002997}
John Zulauf48a6a702017-12-22 17:14:54 -07002998
Jeff Bolzdd4cfa12019-08-11 20:57:51 -05002999const BindingReqMap &cvdescriptorset::PrefilterBindRequestMap::FilteredMap(const CMD_BUFFER_STATE &cb_state,
3000 const PIPELINE_STATE &pipeline) {
John Zulauffbf3c202019-07-17 14:57:14 -06003001 if (IsManyDescriptors()) {
Karl Schultz7090a052020-11-10 08:54:21 -07003002 filtered_map_.reset(new BindingReqMap);
John Zulauffbf3c202019-07-17 14:57:14 -06003003 descriptor_set_.FilterBindingReqs(cb_state, pipeline, orig_map_, filtered_map_.get());
3004 return *filtered_map_;
John Zulauf48a6a702017-12-22 17:14:54 -07003005 }
John Zulauffbf3c202019-07-17 14:57:14 -06003006 return orig_map_;
Artem Kharytoniuk2456f992018-01-12 14:17:41 +01003007}
John Zulauf4a015c92019-06-04 09:50:05 -06003008
3009// Starting at offset descriptor of given binding, parse over update_count
3010// descriptor updates and verify that for any binding boundaries that are crossed, the next binding(s) are all consistent
3011// Consistency means that their type, stage flags, and whether or not they use immutable samplers matches
3012// If so, return true. If not, fill in error_msg and return false
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003013bool cvdescriptorset::VerifyUpdateConsistency(debug_report_data *report_data,
3014 DescriptorSetLayout::ConstBindingIterator current_binding, uint32_t offset,
John Zulauf4a015c92019-06-04 09:50:05 -06003015 uint32_t update_count, const char *type, const VkDescriptorSet set,
3016 std::string *error_msg) {
locke-lunarge46b7782019-09-10 01:44:20 -06003017 bool pass = true;
John Zulauf4a015c92019-06-04 09:50:05 -06003018 // Verify consecutive bindings match (if needed)
3019 auto orig_binding = current_binding;
locke-lunarge46b7782019-09-10 01:44:20 -06003020
3021 while (pass && update_count) {
3022 // First, it's legal to offset beyond your own binding so handle that case
3023 if (offset > 0) {
3024 const auto &index_range = current_binding.GetGlobalIndexRange();
3025 // index_range.start + offset is which descriptor is needed to update. If it > index_range.end, it means the descriptor
3026 // isn't in this binding, maybe in next binding.
3027 if ((index_range.start + offset) >= index_range.end) {
3028 // Advance to next binding, decrement offset by binding size
3029 offset -= current_binding.GetDescriptorCount();
3030 ++current_binding;
3031 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
3032 if (!orig_binding.IsConsistent(current_binding)) {
3033 pass = false;
3034 }
3035 continue;
John Zulauf4a015c92019-06-04 09:50:05 -06003036 }
John Zulauf4a015c92019-06-04 09:50:05 -06003037 }
locke-lunarge46b7782019-09-10 01:44:20 -06003038
3039 update_count -= std::min(update_count, current_binding.GetDescriptorCount() - offset);
3040 if (update_count) {
3041 // Starting offset is beyond the current binding. Check consistency, update counters and advance to the next binding,
3042 // looking for the start point. All bindings (even those skipped) must be consistent with the update and with the
3043 // original binding.
3044 offset = 0;
3045 ++current_binding;
3046 // Verify next consecutive binding matches type, stage flags & immutable sampler use and if AtEnd
3047 if (!orig_binding.IsConsistent(current_binding)) {
3048 pass = false;
3049 }
3050 }
John Zulauf4a015c92019-06-04 09:50:05 -06003051 }
locke-lunarge46b7782019-09-10 01:44:20 -06003052
3053 if (!pass) {
3054 std::stringstream error_str;
3055 error_str << "Attempting " << type;
3056 if (current_binding.Layout()->IsPushDescriptor()) {
3057 error_str << " push descriptors";
3058 } else {
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003059 error_str << " descriptor set " << report_data->FormatHandle(set);
locke-lunarge46b7782019-09-10 01:44:20 -06003060 }
3061 error_str << " binding #" << orig_binding.Binding() << " with #" << update_count
3062 << " descriptors being updated but this update oversteps the bounds of this binding and the next binding is "
3063 "not consistent with current binding so this update is invalid.";
3064 *error_msg = error_str.str();
3065 }
3066 return pass;
John Zulauf4a015c92019-06-04 09:50:05 -06003067}
John Zulauf4956fff2019-06-04 16:54:38 -06003068
3069// Validate the state for a given write update but don't actually perform the update
3070// 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 -06003071bool CoreChecks::ValidateWriteUpdate(const DescriptorSet *dest_set, const VkWriteDescriptorSet *update, const char *func_name,
John Zulaufbd9b3412019-08-22 17:16:11 -06003072 std::string *error_code, std::string *error_msg) const {
Jeff Bolz6aad1742019-10-16 11:10:09 -05003073 const auto dest_layout = dest_set->GetLayout().get();
John Zulauf4956fff2019-06-04 16:54:38 -06003074
3075 // Verify dst layout still valid
Jeff Bolz6ae39612019-10-11 20:57:36 -05003076 if (dest_layout->destroyed) {
John Zulauf4956fff2019-06-04 16:54:38 -06003077 *error_code = "VUID-VkWriteDescriptorSet-dstSet-00320";
Mark Lobodzinski23e395e2020-04-09 10:17:31 -06003078 std::ostringstream str;
3079 str << "Cannot call " << func_name << " to perform write update on " << dest_set->StringifySetAndLayout()
3080 << " which has been destroyed";
3081 *error_msg = str.str();
John Zulauf4956fff2019-06-04 16:54:38 -06003082 return false;
3083 }
3084 // Verify dst binding exists
3085 if (!dest_layout->HasBinding(update->dstBinding)) {
3086 *error_code = "VUID-VkWriteDescriptorSet-dstBinding-00315";
3087 std::stringstream error_str;
3088 error_str << dest_set->StringifySetAndLayout() << " does not have binding " << update->dstBinding;
3089 *error_msg = error_str.str();
3090 return false;
3091 }
3092
Jeff Bolz6aad1742019-10-16 11:10:09 -05003093 DescriptorSetLayout::ConstBindingIterator dest(dest_layout, update->dstBinding);
John Zulauf4956fff2019-06-04 16:54:38 -06003094 // Make sure binding isn't empty
3095 if (0 == dest.GetDescriptorCount()) {
3096 *error_code = "VUID-VkWriteDescriptorSet-dstBinding-00316";
3097 std::stringstream error_str;
3098 error_str << dest_set->StringifySetAndLayout() << " cannot updated binding " << update->dstBinding
3099 << " that has 0 descriptors";
3100 *error_msg = error_str.str();
3101 return false;
3102 }
3103
3104 // Verify idle ds
Mike Schuchardt2df08912020-12-15 16:28:09 -08003105 if (dest_set->in_use.load() && !(dest.GetDescriptorBindingFlags() & (VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT |
3106 VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT))) {
John Zulauf4956fff2019-06-04 16:54:38 -06003107 // TODO : Re-using Free Idle error code, need write update idle error code
3108 *error_code = "VUID-vkFreeDescriptorSets-pDescriptorSets-00309";
3109 std::stringstream error_str;
3110 error_str << "Cannot call " << func_name << " to perform write update on " << dest_set->StringifySetAndLayout()
3111 << " that is in use by a command buffer";
3112 *error_msg = error_str.str();
3113 return false;
3114 }
3115 // We know that binding is valid, verify update and do update on each descriptor
3116 auto start_idx = dest.GetGlobalIndexRange().start + update->dstArrayElement;
3117 auto type = dest.GetType();
3118 if (type != update->descriptorType) {
3119 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00319";
3120 std::stringstream error_str;
3121 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3122 << " with type " << string_VkDescriptorType(type) << " but update type is "
3123 << string_VkDescriptorType(update->descriptorType);
3124 *error_msg = error_str.str();
3125 return false;
3126 }
John Zulauf4956fff2019-06-04 16:54:38 -06003127 if (type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
3128 if ((update->dstArrayElement % 4) != 0) {
3129 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02219";
3130 std::stringstream error_str;
3131 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3132 << " with "
3133 << "dstArrayElement " << update->dstArrayElement << " not a multiple of 4";
3134 *error_msg = error_str.str();
3135 return false;
3136 }
3137 if ((update->descriptorCount % 4) != 0) {
3138 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02220";
3139 std::stringstream error_str;
3140 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3141 << " with "
3142 << "descriptorCount " << update->descriptorCount << " not a multiple of 4";
3143 *error_msg = error_str.str();
3144 return false;
3145 }
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003146 const auto *write_inline_info = LvlFindInChain<VkWriteDescriptorSetInlineUniformBlockEXT>(update->pNext);
John Zulauf4956fff2019-06-04 16:54:38 -06003147 if (!write_inline_info || write_inline_info->dataSize != update->descriptorCount) {
3148 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02221";
3149 std::stringstream error_str;
3150 if (!write_inline_info) {
3151 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #"
3152 << update->dstBinding << " with "
3153 << "VkWriteDescriptorSetInlineUniformBlockEXT missing";
3154 } else {
3155 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #"
3156 << update->dstBinding << " with "
3157 << "VkWriteDescriptorSetInlineUniformBlockEXT dataSize " << write_inline_info->dataSize
3158 << " not equal to "
3159 << "VkWriteDescriptorSet descriptorCount " << update->descriptorCount;
3160 }
3161 *error_msg = error_str.str();
3162 return false;
3163 }
3164 // This error is probably unreachable due to the previous two errors
3165 if (write_inline_info && (write_inline_info->dataSize % 4) != 0) {
3166 *error_code = "VUID-VkWriteDescriptorSetInlineUniformBlockEXT-dataSize-02222";
3167 std::stringstream error_str;
3168 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3169 << " with "
3170 << "VkWriteDescriptorSetInlineUniformBlockEXT dataSize " << write_inline_info->dataSize
3171 << " not a multiple of 4";
3172 *error_msg = error_str.str();
3173 return false;
3174 }
3175 }
sfricke-samsung941d48b2020-02-10 00:20:01 -08003176 // Verify all bindings update share identical properties across all items
3177 if (update->descriptorCount > 0) {
3178 // Save first binding information and error if something different is found
3179 DescriptorSetLayout::ConstBindingIterator current_binding(dest_layout, update->dstBinding);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003180 VkShaderStageFlags stage_flags = current_binding.GetStageFlags();
3181 VkDescriptorType descriptor_type = current_binding.GetType();
3182 bool immutable_samplers = (current_binding.GetImmutableSamplerPtr() == nullptr);
3183 uint32_t dst_array_element = update->dstArrayElement;
sfricke-samsung941d48b2020-02-10 00:20:01 -08003184
Jeff Bolz9198e882020-03-18 13:03:30 -05003185 for (uint32_t i = 0; i < update->descriptorCount;) {
sfricke-samsung941d48b2020-02-10 00:20:01 -08003186 if (current_binding.AtEnd() == true) {
3187 break; // prevents setting error here if bindings don't exist
3188 }
3189
3190 // Check for consistent stageFlags and descriptorType
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003191 if ((current_binding.GetStageFlags() != stage_flags) || (current_binding.GetType() != descriptor_type)) {
sfricke-samsung941d48b2020-02-10 00:20:01 -08003192 *error_code = "VUID-VkWriteDescriptorSet-descriptorCount-00317";
3193 std::stringstream error_str;
3194 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3195 << current_binding.GetIndex() << " (" << i << " from dstBinding offset)"
3196 << " with a different stageFlag and/or descriptorType from previous bindings."
3197 << " All bindings must have consecutive stageFlag and/or descriptorType across a VkWriteDescriptorSet";
3198 *error_msg = error_str.str();
3199 return false;
3200 }
3201 // Check if all immutableSamplers or not
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003202 if ((current_binding.GetImmutableSamplerPtr() == nullptr) != immutable_samplers) {
sfricke-samsung941d48b2020-02-10 00:20:01 -08003203 *error_code = "VUID-VkWriteDescriptorSet-descriptorCount-00318";
3204 std::stringstream error_str;
3205 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3206 << current_binding.GetIndex() << " (" << i << " from dstBinding offset)"
3207 << " with a different usage of immutable samplers from previous bindings."
3208 << " All bindings must have all or none usage of immutable samplers across a VkWriteDescriptorSet";
3209 *error_msg = error_str.str();
3210 return false;
3211 }
Jeff Bolz9198e882020-03-18 13:03:30 -05003212
3213 // Skip the remaining descriptors for this binding, and move to the next binding
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003214 i += (current_binding.GetDescriptorCount() - dst_array_element);
3215 dst_array_element = 0;
sfricke-samsung941d48b2020-02-10 00:20:01 -08003216 ++current_binding;
3217 }
3218 }
3219
John Zulauf4956fff2019-06-04 16:54:38 -06003220 // Verify consecutive bindings match (if needed)
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003221 if (!VerifyUpdateConsistency(report_data, DescriptorSetLayout::ConstBindingIterator(dest_layout, update->dstBinding),
John Zulauf4956fff2019-06-04 16:54:38 -06003222 update->dstArrayElement, update->descriptorCount, "write update to", dest_set->GetSet(),
3223 error_msg)) {
3224 // TODO : Should break out "consecutive binding updates" language into valid usage statements
3225 *error_code = "VUID-VkWriteDescriptorSet-dstArrayElement-00321";
3226 return false;
3227 }
Tony-LunarG1f79c952020-10-27 15:55:51 -06003228 // Verify write to variable descriptor
3229 if (dest_set->IsVariableDescriptorCount(update->dstBinding)) {
3230 if ((update->dstArrayElement + update->descriptorCount) > dest_set->GetVariableDescriptorCount()) {
3231 std::stringstream error_str;
3232 *error_code = "VUID-VkWriteDescriptorSet-dstArrayElement-00321";
3233 error_str << "Attempting write update to " << dest_set->StringifySetAndLayout() << " binding index #"
3234 << update->dstBinding << " array element " << update->dstArrayElement << " with " << update->descriptorCount
3235 << " writes but variable descriptor size is " << dest_set->GetVariableDescriptorCount();
3236 *error_msg = error_str.str();
3237 return false;
3238 }
3239 }
John Zulauf4956fff2019-06-04 16:54:38 -06003240 // Update is within bounds and consistent so last step is to validate update contents
John Zulauf459939f2019-06-04 16:49:35 -06003241 if (!VerifyWriteUpdateContents(dest_set, update, start_idx, func_name, error_code, error_msg)) {
John Zulauf4956fff2019-06-04 16:54:38 -06003242 std::stringstream error_str;
3243 error_str << "Write update to " << dest_set->StringifySetAndLayout() << " binding #" << update->dstBinding
3244 << " failed with error message: " << error_msg->c_str();
3245 *error_msg = error_str.str();
3246 return false;
3247 }
3248 // All checks passed, update is clean
3249 return true;
3250}
John Zulaufadb3f542019-06-04 17:01:00 -06003251
3252// Verify that the contents of the update are ok, but don't perform actual update
John Zulaufc93c4252019-06-25 09:19:49 -06003253bool CoreChecks::VerifyWriteUpdateContents(const DescriptorSet *dest_set, const VkWriteDescriptorSet *update, const uint32_t index,
John Zulaufbd9b3412019-08-22 17:16:11 -06003254 const char *func_name, std::string *error_code, std::string *error_msg) const {
John Zulaufc93c4252019-06-25 09:19:49 -06003255 using ImageSamplerDescriptor = cvdescriptorset::ImageSamplerDescriptor;
Nathaniel Cesarioff521512020-12-11 16:00:26 -07003256 using Descriptor = cvdescriptorset::Descriptor;
John Zulaufc93c4252019-06-25 09:19:49 -06003257
John Zulaufadb3f542019-06-04 17:01:00 -06003258 switch (update->descriptorType) {
3259 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
3260 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3261 // Validate image
3262 auto image_view = update->pImageInfo[di].imageView;
3263 auto image_layout = update->pImageInfo[di].imageLayout;
Mark Lobodzinski3ca937b2020-02-14 14:56:06 -07003264 auto sampler = update->pImageInfo[di].sampler;
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08003265 auto iv_state = GetImageViewState(image_view);
Nathaniel Cesarioff521512020-12-11 16:00:26 -07003266 const ImageSamplerDescriptor *desc =
3267 (const ImageSamplerDescriptor *)dest_set->GetDescriptorFromGlobalIndex(index + di);
Jeff Bolz165818a2020-05-08 11:19:03 -05003268 if (image_view) {
3269 auto image_state = iv_state->image_state.get();
3270 if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, func_name, error_code, error_msg)) {
3271 std::stringstream error_str;
3272 error_str << "Attempted write update to combined image sampler descriptor failed due to: "
3273 << error_msg->c_str();
3274 *error_msg = error_str.str();
3275 return false;
3276 }
3277 if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
3278 if (desc->IsImmutableSampler()) {
3279 auto sampler_state = GetSamplerState(desc->GetSampler());
3280 if (iv_state && sampler_state) {
3281 if (iv_state->samplerConversion != sampler_state->samplerConversion) {
3282 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-01948";
3283 std::stringstream error_str;
3284 error_str
3285 << "Attempted write update to combined image sampler and image view and sampler ycbcr "
3286 "conversions are not identical, sampler: "
3287 << report_data->FormatHandle(desc->GetSampler())
3288 << " image view: " << report_data->FormatHandle(iv_state->image_view) << ".";
3289 *error_msg = error_str.str();
3290 return false;
3291 }
3292 }
3293 } else {
3294 if (iv_state && (iv_state->samplerConversion != VK_NULL_HANDLE)) {
3295 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02738";
John Zulaufadb3f542019-06-04 17:01:00 -06003296 std::stringstream error_str;
Jeff Bolz165818a2020-05-08 11:19:03 -05003297 error_str << "Because dstSet (" << report_data->FormatHandle(update->dstSet)
3298 << ") is bound to image view (" << report_data->FormatHandle(iv_state->image_view)
3299 << ") that includes a YCBCR conversion, it must have been allocated with a layout that "
3300 "includes an immutable sampler.";
John Zulaufadb3f542019-06-04 17:01:00 -06003301 *error_msg = error_str.str();
3302 return false;
3303 }
3304 }
Jeff Bolz165818a2020-05-08 11:19:03 -05003305 }
John Baumanda8abff2020-10-19 21:25:21 +00003306 // If there is an immutable sampler then |sampler| isn't used, so the following VU does not apply.
3307 if (sampler && !desc->IsImmutableSampler() && FormatIsMultiplane(image_state->createInfo.format)) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003308 // multiplane formats must be created with mutable format bit
3309 if (0 == (image_state->createInfo.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) {
3310 *error_code = "VUID-VkDescriptorImageInfo-sampler-01564";
John Zulaufadb3f542019-06-04 17:01:00 -06003311 std::stringstream error_str;
Jeff Bolz165818a2020-05-08 11:19:03 -05003312 error_str << "image " << report_data->FormatHandle(image_state->image)
3313 << " combined image sampler is a multi-planar "
3314 << "format and was not was not created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT";
John Zulaufadb3f542019-06-04 17:01:00 -06003315 *error_msg = error_str.str();
3316 return false;
3317 }
Jeff Bolz165818a2020-05-08 11:19:03 -05003318 // image view need aspect mask for only the planes supported of format
3319 VkImageAspectFlags legal_aspect_flags = (VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT);
3320 legal_aspect_flags |=
3321 (FormatPlaneCount(image_state->createInfo.format) == 3) ? VK_IMAGE_ASPECT_PLANE_2_BIT : 0;
3322 if (0 != (iv_state->create_info.subresourceRange.aspectMask & (~legal_aspect_flags))) {
3323 *error_code = "VUID-VkDescriptorImageInfo-sampler-01564";
3324 std::stringstream error_str;
3325 error_str << "image " << report_data->FormatHandle(image_state->image)
3326 << " combined image sampler is a multi-planar "
3327 << "format and " << report_data->FormatHandle(iv_state->image_view)
3328 << " aspectMask must only include " << string_VkImageAspectFlags(legal_aspect_flags);
3329 *error_msg = error_str.str();
3330 return false;
3331 }
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08003332 }
Nathaniel Cesario23afadd2020-11-17 12:51:45 -07003333
3334 // Verify portability
3335 auto sampler_state = GetSamplerState(sampler);
3336 if (sampler_state) {
3337 if (ExtEnabled::kNotEnabled != device_extensions.vk_khr_portability_subset) {
3338 if ((VK_FALSE == enabled_features.portability_subset_features.mutableComparisonSamplers) &&
3339 (VK_FALSE != sampler_state->createInfo.compareEnable)) {
3340 LogError(device, "VUID-VkDescriptorImageInfo-mutableComparisonSamplers-04450",
3341 "%s (portability error): sampler comparison not available.", func_name);
3342 }
3343 }
3344 }
sfricke-samsung27e5d5a2020-01-07 21:07:08 -08003345 }
John Zulaufadb3f542019-06-04 17:01:00 -06003346 }
3347 }
Mark Lobodzinskiac727772020-01-08 10:47:30 -07003348 // Fall through
John Zulaufadb3f542019-06-04 17:01:00 -06003349 case VK_DESCRIPTOR_TYPE_SAMPLER: {
3350 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003351 const auto *desc = static_cast<const Descriptor *>(dest_set->GetDescriptorFromGlobalIndex(index + di));
John Zulaufadb3f542019-06-04 17:01:00 -06003352 if (!desc->IsImmutableSampler()) {
John Zulaufc93c4252019-06-25 09:19:49 -06003353 if (!ValidateSampler(update->pImageInfo[di].sampler)) {
John Zulaufadb3f542019-06-04 17:01:00 -06003354 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-00325";
3355 std::stringstream error_str;
3356 error_str << "Attempted write update to sampler descriptor with invalid sampler: "
Mark Lobodzinskidb35b8b2020-04-09 08:46:59 -06003357 << report_data->FormatHandle(update->pImageInfo[di].sampler) << ".";
John Zulaufadb3f542019-06-04 17:01:00 -06003358 *error_msg = error_str.str();
3359 return false;
3360 }
Mark Lobodzinskiac727772020-01-08 10:47:30 -07003361 } else if (update->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) {
Mark Lobodzinskif4ed6c12020-01-03 11:21:58 -07003362 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02752";
3363 std::stringstream error_str;
3364 error_str << "Attempted write update to an immutable sampler descriptor.";
3365 *error_msg = error_str.str();
3366 return false;
John Zulaufadb3f542019-06-04 17:01:00 -06003367 }
3368 }
3369 break;
3370 }
3371 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3372 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
3373 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
3374 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3375 auto image_view = update->pImageInfo[di].imageView;
3376 auto image_layout = update->pImageInfo[di].imageLayout;
Jeff Bolz165818a2020-05-08 11:19:03 -05003377 if (image_view) {
3378 if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, func_name, error_code, error_msg)) {
3379 std::stringstream error_str;
3380 error_str << "Attempted write update to image descriptor failed due to: " << error_msg->c_str();
3381 *error_msg = error_str.str();
3382 return false;
3383 }
John Zulaufadb3f542019-06-04 17:01:00 -06003384 }
3385 }
3386 break;
3387 }
3388 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3389 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
3390 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
3391 auto buffer_view = update->pTexelBufferView[di];
Jeff Bolz165818a2020-05-08 11:19:03 -05003392 if (buffer_view) {
3393 auto bv_state = GetBufferViewState(buffer_view);
3394 if (!bv_state) {
3395 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
3396 std::stringstream error_str;
3397 error_str << "Attempted write update to texel buffer descriptor with invalid buffer view: "
3398 << report_data->FormatHandle(buffer_view);
3399 *error_msg = error_str.str();
3400 return false;
3401 }
3402 auto buffer = bv_state->create_info.buffer;
3403 auto buffer_state = GetBufferState(buffer);
3404 // Verify that buffer underlying the view hasn't been destroyed prematurely
3405 if (!buffer_state) {
3406 *error_code = "VUID-VkWriteDescriptorSet-descriptorType-02994";
3407 std::stringstream error_str;
3408 error_str << "Attempted write update to texel buffer descriptor failed because underlying buffer ("
3409 << report_data->FormatHandle(buffer) << ") has been destroyed: " << error_msg->c_str();
3410 *error_msg = error_str.str();
3411 return false;
3412 } else if (!cvdescriptorset::ValidateBufferUsage(report_data, buffer_state, update->descriptorType, error_code,
3413 error_msg)) {
3414 std::stringstream error_str;
3415 error_str << "Attempted write update to texel buffer descriptor failed due to: " << error_msg->c_str();
3416 *error_msg = error_str.str();
3417 return false;
3418 }
John Zulaufadb3f542019-06-04 17:01:00 -06003419 }
3420 }
3421 break;
3422 }
3423 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3424 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3425 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3426 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
3427 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Jeff Bolz165818a2020-05-08 11:19:03 -05003428 if (update->pBufferInfo[di].buffer) {
3429 if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, func_name, error_code, error_msg)) {
3430 std::stringstream error_str;
3431 error_str << "Attempted write update to buffer descriptor failed due to: " << error_msg->c_str();
3432 *error_msg = error_str.str();
3433 return false;
3434 }
John Zulaufadb3f542019-06-04 17:01:00 -06003435 }
3436 }
3437 break;
3438 }
3439 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
3440 break;
Jeff Bolz95176d02020-04-01 00:36:16 -05003441 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV: {
Mark Lobodzinski1f887d32020-12-30 15:31:33 -07003442 const auto *acc_info = LvlFindInChain<VkWriteDescriptorSetAccelerationStructureNV>(update->pNext);
Jeff Bolz95176d02020-04-01 00:36:16 -05003443 for (uint32_t di = 0; di < update->descriptorCount; ++di) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07003444 if (!ValidateAccelerationStructureUpdate(GetAccelerationStructureStateNV(acc_info->pAccelerationStructures[di]),
Mark Lobodzinski85ebd402020-12-03 12:56:07 -07003445 func_name, error_code, error_msg)) {
Jeff Bolz95176d02020-04-01 00:36:16 -05003446 std::stringstream error_str;
3447 error_str << "Attempted write update to acceleration structure descriptor failed due to: "
3448 << error_msg->c_str();
3449 *error_msg = error_str.str();
3450 return false;
3451 }
3452 }
3453
3454 } break;
sourav parmarcd5fb182020-07-17 12:58:44 -07003455 // KHR acceleration structures don't require memory to be bound manually to them.
3456 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
3457 break;
John Zulaufadb3f542019-06-04 17:01:00 -06003458 default:
3459 assert(0); // We've already verified update type so should never get here
3460 break;
3461 }
3462 // All checks passed so update contents are good
3463 return true;
3464}