blob: 7904b27c58e5ee850e6efa83538aeb1cffe8ddfe [file] [log] [blame]
sfricke-samsung11ea8ed2020-01-07 22:24:56 -08001/* Copyright (c) 2015-2020 The Khronos Group Inc.
2 * Copyright (c) 2015-2020 Valve Corporation
3 * Copyright (c) 2015-2020 LunarG, Inc.
4 * Copyright (C) 2015-2020 Google Inc.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07005 *
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: Dustin Graves <dustin@lunarg.com>
19 * Author: Mark Lobodzinski <mark@lunarg.com>
20 */
21
22#pragma once
23
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070024#include "parameter_name.h"
25#include "vk_typemap_helper.h"
26
27// Suppress unused warning on Linux
28#if defined(__GNUC__)
29#define DECORATE_UNUSED __attribute__((unused))
30#else
31#define DECORATE_UNUSED
32#endif
33
34static const char DECORATE_UNUSED *kVUID_PVError_NONE = "UNASSIGNED-GeneralParameterError-Info";
35static const char DECORATE_UNUSED *kVUID_PVError_InvalidUsage = "UNASSIGNED-GeneralParameterError-InvalidUsage";
36static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructSType = "UNASSIGNED-GeneralParameterError-InvalidStructSType";
37static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructPNext = "UNASSIGNED-GeneralParameterError-InvalidStructPNext";
38static const char DECORATE_UNUSED *kVUID_PVError_RequiredParameter = "UNASSIGNED-GeneralParameterError-RequiredParameter";
39static const char DECORATE_UNUSED *kVUID_PVError_ReservedParameter = "UNASSIGNED-GeneralParameterError-ReservedParameter";
40static const char DECORATE_UNUSED *kVUID_PVError_UnrecognizedValue = "UNASSIGNED-GeneralParameterError-UnrecognizedValue";
41static const char DECORATE_UNUSED *kVUID_PVError_DeviceLimit = "UNASSIGNED-GeneralParameterError-DeviceLimit";
42static const char DECORATE_UNUSED *kVUID_PVError_DeviceFeature = "UNASSIGNED-GeneralParameterError-DeviceFeature";
43static const char DECORATE_UNUSED *kVUID_PVError_FailureCode = "UNASSIGNED-GeneralParameterError-FailureCode";
44static const char DECORATE_UNUSED *kVUID_PVError_ExtensionNotEnabled = "UNASSIGNED-GeneralParameterError-ExtensionNotEnabled";
45
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070046extern const uint32_t GeneratedVulkanHeaderVersion;
47
48extern const VkQueryPipelineStatisticFlags AllVkQueryPipelineStatisticFlagBits;
49extern const VkColorComponentFlags AllVkColorComponentFlagBits;
50extern const VkShaderStageFlags AllVkShaderStageFlagBits;
51extern const VkQueryControlFlags AllVkQueryControlFlagBits;
52extern const VkImageUsageFlags AllVkImageUsageFlagBits;
Mark Lobodzinski876d5b52019-08-06 16:32:27 -060053extern const VkSampleCountFlags AllVkSampleCountFlagBits;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070054
55extern const std::vector<VkCompareOp> AllVkCompareOpEnums;
56extern const std::vector<VkStencilOp> AllVkStencilOpEnums;
57extern const std::vector<VkBlendFactor> AllVkBlendFactorEnums;
58extern const std::vector<VkBlendOp> AllVkBlendOpEnums;
59extern const std::vector<VkLogicOp> AllVkLogicOpEnums;
60extern const std::vector<VkBorderColor> AllVkBorderColorEnums;
61extern const std::vector<VkImageLayout> AllVkImageLayoutEnums;
Mark Lobodzinski876d5b52019-08-06 16:32:27 -060062extern const std::vector<VkFormat> AllVkFormatEnums;
63extern const std::vector<VkVertexInputRate> AllVkVertexInputRateEnums;
64extern const std::vector<VkPrimitiveTopology> AllVkPrimitiveTopologyEnums;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070065
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070066// String returned by string_VkStructureType for an unrecognized type.
67const std::string UnsupportedStructureTypeString = "Unhandled VkStructureType";
68
69// String returned by string_VkResult for an unrecognized type.
70const std::string UnsupportedResultString = "Unhandled VkResult";
71
72// The base value used when computing the offset for an enumeration token value that is added by an extension.
73// When validating enumeration tokens, any value >= to this value is considered to be provided by an extension.
74// See Appendix C.10 "Assigning Extension Token Values" from the Vulkan specification
75const uint32_t ExtEnumBaseValue = 1000000000;
76
77// The value of all VK_xxx_MAX_ENUM tokens
78const uint32_t MaxEnumValue = 0x7FFFFFFF;
79
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070080class StatelessValidation : public ValidationObject {
Petr Kraus4ed81e32019-09-02 23:41:19 +020081 public:
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070082 VkPhysicalDeviceLimits device_limits = {};
Petr Kraus715bcc72019-08-15 17:17:33 +020083 safe_VkPhysicalDeviceFeatures2 physical_device_features2;
Tony-LunarG6c3c5452019-12-13 10:37:38 -070084 void *device_createinfo_pnext;
Petr Kraus715bcc72019-08-15 17:17:33 +020085 const VkPhysicalDeviceFeatures &physical_device_features = physical_device_features2.features;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070086
Mark Lobodzinskif27a6bc2019-02-04 13:00:49 -070087 // Override chassis read/write locks for this validation object
88 // This override takes a deferred lock. i.e. it is not acquired.
Jeff Bolzcaeccc72019-10-15 15:35:26 -050089 virtual read_lock_guard_t read_lock() { return read_lock_guard_t(validation_object_mutex, std::defer_lock); }
90 virtual write_lock_guard_t write_lock() { return write_lock_guard_t(validation_object_mutex, std::defer_lock); }
Mark Lobodzinskif27a6bc2019-02-04 13:00:49 -070091
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070092 // Device extension properties -- storing properties gathered from VkPhysicalDeviceProperties2KHR::pNext chain
93 struct DeviceExtensionProperties {
94 VkPhysicalDeviceShadingRateImagePropertiesNV shading_rate_image_props;
95 VkPhysicalDeviceMeshShaderPropertiesNV mesh_shader_props;
Jeff Bolz443c2ca2020-03-19 12:11:51 -050096 VkPhysicalDeviceRayTracingPropertiesNV ray_tracing_propsNV;
97 VkPhysicalDeviceRayTracingPropertiesKHR ray_tracing_propsKHR;
Mark Lobodzinski953b7bc2019-12-19 13:50:10 -070098 VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_props;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -070099 };
100 DeviceExtensionProperties phys_dev_ext_props = {};
101
102 struct SubpassesUsageStates {
103 std::unordered_set<uint32_t> subpasses_using_color_attachment;
104 std::unordered_set<uint32_t> subpasses_using_depthstencil_attachment;
105 };
106
Mark Lobodzinskif27a6bc2019-02-04 13:00:49 -0700107 // Though this validation object is predominantly statless, the Framebuffer checks are greatly simplified by creating and
108 // updating a map of the renderpass usage states, and these accesses need thread protection. Use a mutex separate from the
109 // parent object's to maintain that functionality.
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500110 mutable std::mutex renderpass_map_mutex;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700111 std::unordered_map<VkRenderPass, SubpassesUsageStates> renderpasses_states;
112
113 // Constructor for stateles validation tracking
Mark Lobodzinski0dcb87d2020-03-30 16:09:24 -0600114 StatelessValidation() { container_type = LayerObjectTypeParameterValidation; }
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700115 /**
116 * Validate a minimum value.
117 *
118 * Verify that the specified value is greater than the specified lower bound.
119 *
120 * @param api_name Name of API call being validated.
121 * @param parameter_name Name of parameter being validated.
122 * @param value Value to validate.
123 * @param lower_bound Lower bound value to use for validation.
124 * @return Boolean value indicating that the call should be skipped.
125 */
126 template <typename T>
127 bool ValidateGreaterThan(const T value, const T lower_bound, const ParameterName &parameter_name, const std::string &vuid,
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700128 const char *api_name) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700129 bool skip_call = false;
130
131 if (value <= lower_bound) {
132 std::ostringstream ss;
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700133 ss << api_name << ": parameter " << parameter_name.get_name() << " (= " << value << ") is greater than " << lower_bound;
134 skip_call |= LogError(device, vuid, "%s", ss.str().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700135 }
136
137 return skip_call;
138 }
139
140 template <typename T>
141 bool ValidateGreaterThanZero(const T value, const ParameterName &parameter_name, const std::string &vuid,
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700142 const char *api_name) const {
143 return ValidateGreaterThan(value, T{0}, parameter_name, vuid, api_name);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700144 }
145 /**
146 * Validate a required pointer.
147 *
148 * Verify that a required pointer is not NULL.
149 *
150 * @param apiName Name of API call being validated.
151 * @param parameterName Name of parameter being validated.
152 * @param value Pointer to validate.
153 * @return Boolean value indicating that the call should be skipped.
154 */
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700155 bool validate_required_pointer(const char *apiName, const ParameterName &parameterName, const void *value,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500156 const std::string &vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700157 bool skip_call = false;
158
159 if (value == NULL) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700160 skip_call |=
161 LogError(device, vuid, "%s: required parameter %s specified as NULL.", apiName, parameterName.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700162 }
163
164 return skip_call;
165 }
166
167 /**
168 * Validate array count and pointer to array.
169 *
170 * Verify that required count and array parameters are not 0 or NULL. If the
171 * count parameter is not optional, verify that it is not 0. If the array
172 * parameter is NULL, and it is not optional, verify that count is 0.
173 *
174 * @param apiName Name of API call being validated.
175 * @param countName Name of count parameter.
176 * @param arrayName Name of array parameter.
177 * @param count Number of elements in the array.
178 * @param array Array to validate.
179 * @param countRequired The 'count' parameter may not be 0 when true.
180 * @param arrayRequired The 'array' parameter may not be NULL when true.
181 * @return Boolean value indicating that the call should be skipped.
182 */
183 template <typename T1, typename T2>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700184 bool validate_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, T1 count,
Jeff Bolzfdd0d852019-02-03 21:55:12 -0600185 const T2 *array, bool countRequired, bool arrayRequired, const char *count_required_vuid,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500186 const char *array_required_vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700187 bool skip_call = false;
188
189 // Count parameters not tagged as optional cannot be 0
190 if (countRequired && (count == 0)) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700191 skip_call |= LogError(device, count_required_vuid, "%s: parameter %s must be greater than 0.", apiName,
192 countName.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700193 }
194
195 // Array parameters not tagged as optional cannot be NULL, unless the count is 0
196 if (arrayRequired && (count != 0) && (*array == NULL)) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700197 skip_call |= LogError(device, array_required_vuid, "%s: required parameter %s specified as NULL.", apiName,
198 arrayName.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700199 }
200
201 return skip_call;
202 }
203
204 /**
205 * Validate pointer to array count and pointer to array.
206 *
207 * Verify that required count and array parameters are not NULL. If count
208 * is not NULL and its value is not optional, verify that it is not 0. If the
209 * array parameter is NULL, and it is not optional, verify that count is 0.
210 * The array parameter will typically be optional for this case (where count is
211 * a pointer), allowing the caller to retrieve the available count.
212 *
213 * @param apiName Name of API call being validated.
214 * @param countName Name of count parameter.
215 * @param arrayName Name of array parameter.
216 * @param count Pointer to the number of elements in the array.
217 * @param array Array to validate.
218 * @param countPtrRequired The 'count' parameter may not be NULL when true.
219 * @param countValueRequired The '*count' value may not be 0 when true.
220 * @param arrayRequired The 'array' parameter may not be NULL when true.
221 * @return Boolean value indicating that the call should be skipped.
222 */
223 template <typename T1, typename T2>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700224 bool validate_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, const T1 *count,
225 const T2 *array, bool countPtrRequired, bool countValueRequired, bool arrayRequired,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500226 const char *count_required_vuid, const char *array_required_vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700227 bool skip_call = false;
228
229 if (count == NULL) {
230 if (countPtrRequired) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700231 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL",
232 apiName, countName.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700233 }
234 } else {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700235 skip_call |= validate_array(apiName, countName, arrayName, *array ? (*count) : 0, &array, countValueRequired,
236 arrayRequired, count_required_vuid, array_required_vuid);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700237 }
238
239 return skip_call;
240 }
241
242 /**
243 * Validate a pointer to a Vulkan structure.
244 *
245 * Verify that a required pointer to a structure is not NULL. If the pointer is
246 * not NULL, verify that each structure's sType field is set to the correct
247 * VkStructureType value.
248 *
249 * @param apiName Name of API call being validated.
250 * @param parameterName Name of struct parameter being validated.
251 * @param sTypeName Name of expected VkStructureType value.
252 * @param value Pointer to the struct to validate.
253 * @param sType VkStructureType for structure validation.
254 * @param required The parameter may not be NULL when true.
255 * @return Boolean value indicating that the call should be skipped.
256 */
257 template <typename T>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700258 bool validate_struct_type(const char *apiName, const ParameterName &parameterName, const char *sTypeName, const T *value,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500259 VkStructureType sType, bool required, const char *struct_vuid, const char *stype_vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700260 bool skip_call = false;
261
262 if (value == NULL) {
263 if (required) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700264 skip_call |= LogError(device, struct_vuid, "%s: required parameter %s specified as NULL", apiName,
265 parameterName.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700266 }
267 } else if (value->sType != sType) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700268 skip_call |= LogError(device, stype_vuid, "%s: parameter %s->sType must be %s.", apiName,
269 parameterName.get_name().c_str(), sTypeName);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700270 }
271
272 return skip_call;
273 }
274
275 /**
276 * Validate an array of Vulkan structures
277 *
278 * Verify that required count and array parameters are not 0 or NULL. If
279 * the array contains 1 or more structures, verify that each structure's
280 * sType field is set to the correct VkStructureType value.
281 *
282 * @param apiName Name of API call being validated.
283 * @param countName Name of count parameter.
284 * @param arrayName Name of array parameter.
285 * @param sTypeName Name of expected VkStructureType value.
286 * @param count Number of elements in the array.
287 * @param array Array to validate.
288 * @param sType VkStructureType for structure validation.
289 * @param countRequired The 'count' parameter may not be 0 when true.
290 * @param arrayRequired The 'array' parameter may not be NULL when true.
291 * @return Boolean value indicating that the call should be skipped.
292 */
293 template <typename T>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700294 bool validate_struct_type_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName,
295 const char *sTypeName, uint32_t count, const T *array, VkStructureType sType,
Jasper St. Pierre6c98f8c2019-01-22 15:18:03 -0800296 bool countRequired, bool arrayRequired, const char *stype_vuid, const char *param_vuid,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500297 const char *count_required_vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700298 bool skip_call = false;
299
300 if ((count == 0) || (array == NULL)) {
Jasper St. Pierre6c98f8c2019-01-22 15:18:03 -0800301 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
302 count_required_vuid, param_vuid);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700303 } else {
304 // Verify that all structs in the array have the correct type
305 for (uint32_t i = 0; i < count; ++i) {
306 if (array[i].sType != sType) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700307 skip_call |= LogError(device, stype_vuid, "%s: parameter %s[%d].sType must be %s", apiName,
308 arrayName.get_name().c_str(), i, sTypeName);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700309 }
310 }
311 }
312
313 return skip_call;
314 }
315
316 /**
317 * Validate an array of Vulkan structures.
318 *
319 * Verify that required count and array parameters are not NULL. If count
320 * is not NULL and its value is not optional, verify that it is not 0.
321 * If the array contains 1 or more structures, verify that each structure's
322 * sType field is set to the correct VkStructureType value.
323 *
324 * @param apiName Name of API call being validated.
325 * @param countName Name of count parameter.
326 * @param arrayName Name of array parameter.
327 * @param sTypeName Name of expected VkStructureType value.
328 * @param count Pointer to the number of elements in the array.
329 * @param array Array to validate.
330 * @param sType VkStructureType for structure validation.
331 * @param countPtrRequired The 'count' parameter may not be NULL when true.
332 * @param countValueRequired The '*count' value may not be 0 when true.
333 * @param arrayRequired The 'array' parameter may not be NULL when true.
334 * @return Boolean value indicating that the call should be skipped.
335 */
336 template <typename T>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700337 bool validate_struct_type_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName,
338 const char *sTypeName, uint32_t *count, const T *array, VkStructureType sType,
Jeff Bolzfdd0d852019-02-03 21:55:12 -0600339 bool countPtrRequired, bool countValueRequired, bool arrayRequired, const char *stype_vuid,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500340 const char *param_vuid, const char *count_required_vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700341 bool skip_call = false;
342
343 if (count == NULL) {
344 if (countPtrRequired) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700345 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL",
346 apiName, countName.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700347 }
348 } else {
349 skip_call |= validate_struct_type_array(apiName, countName, arrayName, sTypeName, (*count), array, sType,
Mark Lobodzinski75a38812019-12-10 15:22:52 -0700350 countValueRequired && (array != nullptr), arrayRequired, stype_vuid, param_vuid,
351 count_required_vuid);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700352 }
353
354 return skip_call;
355 }
356
357 /**
358 * Validate a Vulkan handle.
359 *
360 * Verify that the specified handle is not VK_NULL_HANDLE.
361 *
362 * @param api_name Name of API call being validated.
363 * @param parameter_name Name of struct parameter being validated.
364 * @param value Handle to validate.
365 * @return Boolean value indicating that the call should be skipped.
366 */
367 template <typename T>
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500368 bool validate_required_handle(const char *api_name, const ParameterName &parameter_name, T value) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700369 bool skip_call = false;
370
371 if (value == VK_NULL_HANDLE) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700372 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as VK_NULL_HANDLE",
373 api_name, parameter_name.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700374 }
375
376 return skip_call;
377 }
378
379 /**
380 * Validate an array of Vulkan handles.
381 *
382 * Verify that required count and array parameters are not NULL. If count
383 * is not NULL and its value is not optional, verify that it is not 0.
384 * If the array contains 1 or more handles, verify that no handle is set to
385 * VK_NULL_HANDLE.
386 *
387 * @note This function is only intended to validate arrays of handles when none
388 * of the handles are allowed to be VK_NULL_HANDLE. For arrays of handles
389 * that are allowed to contain VK_NULL_HANDLE, use validate_array() instead.
390 *
391 * @param api_name Name of API call being validated.
392 * @param count_name Name of count parameter.
393 * @param array_name Name of array parameter.
394 * @param count Number of elements in the array.
395 * @param array Array to validate.
396 * @param count_required The 'count' parameter may not be 0 when true.
397 * @param array_required The 'array' parameter may not be NULL when true.
398 * @return Boolean value indicating that the call should be skipped.
399 */
400 template <typename T>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700401 bool validate_handle_array(const char *api_name, const ParameterName &count_name, const ParameterName &array_name,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500402 uint32_t count, const T *array, bool count_required, bool array_required) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700403 bool skip_call = false;
404
405 if ((count == 0) || (array == NULL)) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700406 skip_call |= validate_array(api_name, count_name, array_name, count, &array, count_required, array_required,
407 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700408 } else {
409 // Verify that no handles in the array are VK_NULL_HANDLE
410 for (uint32_t i = 0; i < count; ++i) {
411 if (array[i] == VK_NULL_HANDLE) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700412 skip_call |= LogError(device, kVUID_PVError_RequiredParameter,
413 "%s: required parameter %s[%d] specified as VK_NULL_HANDLE", api_name,
414 array_name.get_name().c_str(), i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700415 }
416 }
417 }
418
419 return skip_call;
420 }
421
422 /**
423 * Validate string array count and content.
424 *
425 * Verify that required count and array parameters are not 0 or NULL. If the
426 * count parameter is not optional, verify that it is not 0. If the array
427 * parameter is NULL, and it is not optional, verify that count is 0. If the
428 * array parameter is not NULL, verify that none of the strings are NULL.
429 *
430 * @param apiName Name of API call being validated.
431 * @param countName Name of count parameter.
432 * @param arrayName Name of array parameter.
433 * @param count Number of strings in the array.
434 * @param array Array of strings to validate.
435 * @param countRequired The 'count' parameter may not be 0 when true.
436 * @param arrayRequired The 'array' parameter may not be NULL when true.
437 * @return Boolean value indicating that the call should be skipped.
438 */
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700439 bool validate_string_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, uint32_t count,
Jeff Bolzfdd0d852019-02-03 21:55:12 -0600440 const char *const *array, bool countRequired, bool arrayRequired, const char *count_required_vuid,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500441 const char *array_required_vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700442 bool skip_call = false;
443
444 if ((count == 0) || (array == NULL)) {
445 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
446 count_required_vuid, array_required_vuid);
447 } else {
448 // Verify that strings in the array are not NULL
449 for (uint32_t i = 0; i < count; ++i) {
450 if (array[i] == NULL) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700451 skip_call |=
452 LogError(device, kVUID_PVError_RequiredParameter, "%s: required parameter %s[%d] specified as NULL",
453 apiName, arrayName.get_name().c_str(), i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700454 }
455 }
456 }
457
458 return skip_call;
459 }
460
461 // Forward declaration for pNext validation
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500462 bool ValidatePnextStructContents(const char *api_name, const ParameterName &parameter_name,
463 const VkBaseOutStructure *header) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700464
465 /**
466 * Validate a structure's pNext member.
467 *
468 * Verify that the specified pNext value points to the head of a list of
469 * allowed extension structures. If no extension structures are allowed,
470 * verify that pNext is null.
471 *
472 * @param api_name Name of API call being validated.
473 * @param parameter_name Name of parameter being validated.
474 * @param allowed_struct_names Names of allowed structs.
475 * @param next Pointer to validate.
476 * @param allowed_type_count Total number of allowed structure types.
477 * @param allowed_types Array of structure types allowed for pNext.
478 * @param header_version Version of header defining the pNext validation rules.
479 * @return Boolean value indicating that the call should be skipped.
480 */
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700481 bool validate_struct_pnext(const char *api_name, const ParameterName &parameter_name, const char *allowed_struct_names,
482 const void *next, size_t allowed_type_count, const VkStructureType *allowed_types,
sfricke-samsung32a27362020-02-28 09:06:42 -0800483 uint32_t header_version, const char *pnext_vuid, const char *stype_vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700484 bool skip_call = false;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700485
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700486 // TODO: The valid pNext structure types are not recursive. Each structure has its own list of valid sTypes for pNext.
487 // Codegen a map of vectors containing the allowable pNext types for each struct and use that here -- also simplifies parms.
488 if (next != NULL) {
Jeff Bolzfdd0d852019-02-03 21:55:12 -0600489 std::unordered_set<const void *> cycle_check;
490 std::unordered_set<VkStructureType, std::hash<int>> unique_stype_check;
491
Jeff Bolz6d3beaa2019-02-09 21:00:05 -0600492 const char *disclaimer =
493 "This warning is based on the Valid Usage documentation for version %d of the Vulkan header. It is possible that "
494 "you "
495 "are "
496 "using a struct from a private extension or an extension that was added to a later version of the Vulkan header, "
497 "in "
498 "which "
499 "case your use of %s is perfectly valid but is not guaranteed to work correctly with validation enabled";
500
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700501 if (allowed_type_count == 0) {
502 std::string message = "%s: value of %s must be NULL. ";
503 message += disclaimer;
sfricke-samsung32a27362020-02-28 09:06:42 -0800504 skip_call |= LogWarning(device, pnext_vuid, message.c_str(), api_name, parameter_name.get_name().c_str(),
505 header_version, parameter_name.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700506 } else {
507 const VkStructureType *start = allowed_types;
508 const VkStructureType *end = allowed_types + allowed_type_count;
Lockefbdd1af2019-04-16 15:07:23 -0600509 const VkBaseOutStructure *current = reinterpret_cast<const VkBaseOutStructure *>(next);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700510
511 cycle_check.insert(next);
512
513 while (current != NULL) {
514 if (((strncmp(api_name, "vkCreateInstance", strlen(api_name)) != 0) ||
515 (current->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)) &&
516 ((strncmp(api_name, "vkCreateDevice", strlen(api_name)) != 0) ||
517 (current->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO))) {
518 if (cycle_check.find(current->pNext) != cycle_check.end()) {
519 std::string message = "%s: %s chain contains a cycle -- pNext pointer " PRIx64 " is repeated.";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700520 skip_call |= LogError(device, kVUID_PVError_InvalidStructPNext, message.c_str(), api_name,
521 parameter_name.get_name().c_str(), reinterpret_cast<uint64_t>(next));
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700522 break;
523 } else {
524 cycle_check.insert(current->pNext);
525 }
526
527 std::string type_name = string_VkStructureType(current->sType);
528 if (unique_stype_check.find(current->sType) != unique_stype_check.end()) {
sfricke-samsung32a27362020-02-28 09:06:42 -0800529 // stype_vuid will only be null if there are no listed pNext and will hit disclaimer check
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700530 std::string message = "%s: %s chain contains duplicate structure types: %s appears multiple times.";
sfricke-samsung32a27362020-02-28 09:06:42 -0800531 skip_call |= LogError(device, stype_vuid, message.c_str(), api_name, parameter_name.get_name().c_str(),
532 type_name.c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700533 } else {
534 unique_stype_check.insert(current->sType);
535 }
536
537 if (std::find(start, end, current->sType) == end) {
538 if (type_name == UnsupportedStructureTypeString) {
539 std::string message =
540 "%s: %s chain includes a structure with unknown VkStructureType (%d); Allowed structures are "
541 "[%s]. ";
542 message += disclaimer;
sfricke-samsung32a27362020-02-28 09:06:42 -0800543 skip_call |= LogWarning(device, pnext_vuid, message.c_str(), api_name,
544 parameter_name.get_name().c_str(), current->sType, allowed_struct_names,
545 header_version, parameter_name.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700546 } else {
547 std::string message =
548 "%s: %s chain includes a structure with unexpected VkStructureType %s; Allowed structures are "
549 "[%s]. ";
550 message += disclaimer;
sfricke-samsung32a27362020-02-28 09:06:42 -0800551 skip_call |= LogWarning(device, pnext_vuid, message.c_str(), api_name,
552 parameter_name.get_name().c_str(), type_name.c_str(), allowed_struct_names,
553 header_version, parameter_name.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700554 }
555 }
556 skip_call |= ValidatePnextStructContents(api_name, parameter_name, current);
557 }
Lockefbdd1af2019-04-16 15:07:23 -0600558 current = reinterpret_cast<const VkBaseOutStructure *>(current->pNext);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700559 }
560 }
561 }
562
563 return skip_call;
564 }
565
566 /**
567 * Validate a VkBool32 value.
568 *
569 * Generate a warning if a VkBool32 value is neither VK_TRUE nor VK_FALSE.
570 *
571 * @param apiName Name of API call being validated.
572 * @param parameterName Name of parameter being validated.
573 * @param value Boolean value to validate.
574 * @return Boolean value indicating that the call should be skipped.
575 */
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500576 bool validate_bool32(const char *apiName, const ParameterName &parameterName, VkBool32 value) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700577 bool skip_call = false;
578
579 if ((value != VK_TRUE) && (value != VK_FALSE)) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700580 skip_call |= LogWarning(device, kVUID_PVError_UnrecognizedValue, "%s: value of %s (%d) is neither VK_TRUE nor VK_FALSE",
581 apiName, parameterName.get_name().c_str(), value);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700582 }
583
584 return skip_call;
585 }
586
587 /**
588 * Validate a Vulkan enumeration value.
589 *
590 * Generate a warning if an enumeration token value does not fall within the core enumeration
591 * begin and end token values, and was not added to the enumeration by an extension. Extension
592 * provided enumerations use the equation specified in Appendix C.10 of the Vulkan specification,
593 * with 1,000,000,000 as the base token value.
594 *
595 * @note This function does not expect to process enumerations defining bitmask flag bits.
596 *
597 * @param apiName Name of API call being validated.
598 * @param parameterName Name of parameter being validated.
599 * @param enumName Name of the enumeration being validated.
600 * @param valid_values The list of valid values for the enumeration.
601 * @param value Enumeration value to validate.
602 * @return Boolean value indicating that the call should be skipped.
603 */
604 template <typename T>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700605 bool validate_ranged_enum(const char *apiName, const ParameterName &parameterName, const char *enumName,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500606 const std::vector<T> &valid_values, T value, const char *vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700607 bool skip = false;
608
609 if (std::find(valid_values.begin(), valid_values.end(), value) == valid_values.end()) {
610 skip |=
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700611 LogError(device, vuid,
612 "%s: value of %s (%d) does not fall within the begin..end range of the core %s enumeration tokens and is "
613 "not an extension added token.",
614 apiName, parameterName.get_name().c_str(), value, enumName);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700615 }
616
617 return skip;
618 }
619
620 /**
621 * Validate an array of Vulkan enumeration value.
622 *
623 * Process all enumeration token values in the specified array and generate a warning if a value
624 * does not fall within the core enumeration begin and end token values, and was not added to
625 * the enumeration by an extension. Extension provided enumerations use the equation specified
626 * in Appendix C.10 of the Vulkan specification, with 1,000,000,000 as the base token value.
627 *
628 * @note This function does not expect to process enumerations defining bitmask flag bits.
629 *
630 * @param apiName Name of API call being validated.
631 * @param countName Name of count parameter.
632 * @param arrayName Name of array parameter.
633 * @param enumName Name of the enumeration being validated.
634 * @param valid_values The list of valid values for the enumeration.
635 * @param count Number of enumeration values in the array.
636 * @param array Array of enumeration values to validate.
637 * @param countRequired The 'count' parameter may not be 0 when true.
638 * @param arrayRequired The 'array' parameter may not be NULL when true.
639 * @return Boolean value indicating that the call should be skipped.
640 */
641 template <typename T>
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700642 bool validate_ranged_enum_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName,
643 const char *enumName, const std::vector<T> &valid_values, uint32_t count, const T *array,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500644 bool countRequired, bool arrayRequired) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700645 bool skip_call = false;
646
647 if ((count == 0) || (array == NULL)) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700648 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired, kVUIDUndefined,
649 kVUIDUndefined);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700650 } else {
651 for (uint32_t i = 0; i < count; ++i) {
652 if (std::find(valid_values.begin(), valid_values.end(), array[i]) == valid_values.end()) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700653 skip_call |= LogError(device, kVUID_PVError_UnrecognizedValue,
654 "%s: value of %s[%d] (%d) does not fall within the begin..end range of the core %s "
655 "enumeration tokens and is not an extension added token",
656 apiName, arrayName.get_name().c_str(), i, array[i], enumName);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700657 }
658 }
659 }
660
661 return skip_call;
662 }
663
664 /**
665 * Verify that a reserved VkFlags value is zero.
666 *
667 * Verify that the specified value is zero, to check VkFlags values that are reserved for
668 * future use.
669 *
670 * @param api_name Name of API call being validated.
671 * @param parameter_name Name of parameter being validated.
672 * @param value Value to validate.
673 * @return Boolean value indicating that the call should be skipped.
674 */
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500675 bool validate_reserved_flags(const char *api_name, const ParameterName &parameter_name, VkFlags value, const char *vuid) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700676 bool skip_call = false;
677
678 if (value != 0) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700679 skip_call |= LogError(device, vuid, "%s: parameter %s must be 0.", api_name, parameter_name.get_name().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700680 }
681
682 return skip_call;
683 }
684
Petr Kraus52758be2019-08-12 00:53:58 +0200685 enum FlagType { kRequiredFlags, kOptionalFlags, kRequiredSingleBit, kOptionalSingleBit };
686
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700687 /**
688 * Validate a Vulkan bitmask value.
689 *
690 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits
691 * for that type.
692 *
693 * @param api_name Name of API call being validated.
694 * @param parameter_name Name of parameter being validated.
695 * @param flag_bits_name Name of the VkFlags type being validated.
696 * @param all_flags A bit mask combining all valid flag bits for the VkFlags type being validated.
697 * @param value VkFlags value to validate.
Petr Kraus52758be2019-08-12 00:53:58 +0200698 * @param flag_type The type of flag, like optional, or single bit.
699 * @param vuid VUID used for flag that is outside defined bits (or has more than one bit for Bits type).
700 * @param flags_zero_vuid VUID used for non-optional Flags that are zero.
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700701 * @return Boolean value indicating that the call should be skipped.
702 */
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700703 bool validate_flags(const char *api_name, const ParameterName &parameter_name, const char *flag_bits_name, VkFlags all_flags,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500704 VkFlags value, const FlagType flag_type, const char *vuid, const char *flags_zero_vuid = nullptr) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700705 bool skip_call = false;
706
Petr Kraus52758be2019-08-12 00:53:58 +0200707 if ((value & ~all_flags) != 0) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700708 skip_call |= LogError(device, vuid, "%s: value of %s contains flag bits that are not recognized members of %s",
709 api_name, parameter_name.get_name().c_str(), flag_bits_name);
Petr Kraus52758be2019-08-12 00:53:58 +0200710 }
711
712 const bool required = flag_type == kRequiredFlags || flag_type == kRequiredSingleBit;
713 const char *zero_vuid = flag_type == kRequiredFlags ? flags_zero_vuid : vuid;
714 if (required && value == 0) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700715 skip_call |= LogError(device, zero_vuid, "%s: value of %s must not be 0.", api_name, parameter_name.get_name().c_str());
Petr Kraus52758be2019-08-12 00:53:58 +0200716 }
717
718 const auto HasMaxOneBitSet = [](const VkFlags f) {
719 // Decrement flips bits from right upto first 1.
720 // Rest stays same, and if there was any other 1s &ded together they would be non-zero. QED
721 return f == 0 || !(f & (f - 1));
722 };
723
724 const bool is_bits_type = flag_type == kRequiredSingleBit || flag_type == kOptionalSingleBit;
725 if (is_bits_type && !HasMaxOneBitSet(value)) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700726 skip_call |=
727 LogError(device, vuid, "%s: value of %s contains multiple members of %s when only a single value is allowed",
728 api_name, parameter_name.get_name().c_str(), flag_bits_name);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700729 }
730
731 return skip_call;
732 }
733
734 /**
735 * Validate an array of Vulkan bitmask values.
736 *
737 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits
738 * for that type.
739 *
740 * @param api_name Name of API call being validated.
741 * @param count_name Name of parameter being validated.
742 * @param array_name Name of parameter being validated.
743 * @param flag_bits_name Name of the VkFlags type being validated.
744 * @param all_flags A bitmask combining all valid flag bits for the VkFlags type being validated.
745 * @param count Number of VkFlags values in the array.
746 * @param array Array of VkFlags value to validate.
747 * @param count_required The 'count' parameter may not be 0 when true.
748 * @param array_required The 'array' parameter may not be NULL when true.
749 * @return Boolean value indicating that the call should be skipped.
750 */
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700751 bool validate_flags_array(const char *api_name, const ParameterName &count_name, const ParameterName &array_name,
752 const char *flag_bits_name, VkFlags all_flags, uint32_t count, const VkFlags *array,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500753 bool count_required, bool array_required) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700754 bool skip_call = false;
755
756 if ((count == 0) || (array == NULL)) {
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700757 skip_call |= validate_array(api_name, count_name, array_name, count, &array, count_required, array_required,
758 kVUIDUndefined, kVUIDUndefined);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700759 } else {
760 // Verify that all VkFlags values in the array
761 for (uint32_t i = 0; i < count; ++i) {
762 if (array[i] == 0) {
763 // Current XML registry logic for validity generation uses the array parameter's optional tag to determine if
764 // elements in the array are allowed be 0
765 if (array_required) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700766 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: value of %s[%d] must not be 0",
767 api_name, array_name.get_name().c_str(), i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700768 }
769 } else if ((array[i] & (~all_flags)) != 0) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700770 skip_call |= LogError(device, kVUID_PVError_UnrecognizedValue,
771 "%s: value of %s[%d] contains flag bits that are not recognized members of %s", api_name,
772 array_name.get_name().c_str(), i, flag_bits_name);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700773 }
774 }
775 }
776
777 return skip_call;
778 }
779
780 template <typename ExtensionState>
Jeff Bolzfdd0d852019-02-03 21:55:12 -0600781 bool validate_extension_reqs(const ExtensionState &extensions, const char *vuid, const char *extension_type,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500782 const char *extension_name) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700783 bool skip = false;
784 if (!extension_name) {
785 return skip; // Robust to invalid char *
786 }
787 auto info = ExtensionState::get_info(extension_name);
788
789 if (!info.state) {
790 return skip; // Unknown extensions cannot be checked so report OK
791 }
792
793 // Check against the required list in the info
794 std::vector<const char *> missing;
Petr Krausbce952d2020-04-02 18:40:40 +0200795 for (const auto &req : info.requirements) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700796 if (!(extensions.*(req.enabled))) {
797 missing.push_back(req.name);
798 }
799 }
800
801 // Report any missing requirements
802 if (missing.size()) {
803 std::string missing_joined_list = string_join(", ", missing);
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700804 skip |= LogError(instance, vuid, "Missing extension%s required by the %s extension %s: %s.",
805 ((missing.size() > 1) ? "s" : ""), extension_type, extension_name, missing_joined_list.c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700806 }
807 return skip;
808 }
809
810 enum RenderPassCreateVersion { RENDER_PASS_VERSION_1 = 0, RENDER_PASS_VERSION_2 = 1 };
811
812 template <typename RenderPassCreateInfoGeneric>
Petr Kraus3e52eba2019-07-10 01:24:10 +0200813 bool ValidateSubpassGraphicsFlags(const debug_report_data *report_data, const RenderPassCreateInfoGeneric *pCreateInfo,
814 uint32_t dependency_index, uint32_t subpass, VkPipelineStageFlags stages, const char *vuid,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500815 const char *target) const {
Petr Krausdfd26442019-08-13 03:25:19 +0200816 const VkPipelineStageFlags kCommonStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
817 const VkPipelineStageFlags kFramebufferStages =
818 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
819 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
820 const VkPipelineStageFlags kPrimitiveShadingPipelineStages =
821 kCommonStages | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
Petr Kraus3e52eba2019-07-10 01:24:10 +0200822 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
823 VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
Petr Krausdfd26442019-08-13 03:25:19 +0200824 VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT | VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV | kFramebufferStages;
825 const VkPipelineStageFlags kMeshShadingPipelineStages =
826 kCommonStages | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV |
827 VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV | kFramebufferStages;
828 const VkPipelineStageFlags kFragmentDensityStages = VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT;
829 const VkPipelineStageFlags kConditionalRenderingStages = VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT;
Mike Schuchardtf4c0cb52020-03-17 00:40:13 -0700830 const VkPipelineStageFlags kCommandProcessingPipelineStages = kCommonStages | VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV;
Petr Krausdfd26442019-08-13 03:25:19 +0200831
832 const VkPipelineStageFlags kGraphicsStages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | kPrimitiveShadingPipelineStages |
833 kMeshShadingPipelineStages | kFragmentDensityStages |
834 kConditionalRenderingStages | kCommandProcessingPipelineStages;
835
Petr Kraus3e52eba2019-07-10 01:24:10 +0200836 bool skip = false;
Petr Krausdfd26442019-08-13 03:25:19 +0200837
838 const auto IsPipeline = [pCreateInfo](uint32_t subpass, const VkPipelineBindPoint stage) {
Petr Kraus3e52eba2019-07-10 01:24:10 +0200839 if (subpass == VK_SUBPASS_EXTERNAL)
840 return false;
841 else
Petr Krausdfd26442019-08-13 03:25:19 +0200842 return pCreateInfo->pSubpasses[subpass].pipelineBindPoint == stage;
Petr Kraus3e52eba2019-07-10 01:24:10 +0200843 };
844
Petr Krausdfd26442019-08-13 03:25:19 +0200845 const bool is_all_graphics_stages = (stages & ~kGraphicsStages) == 0;
846 if (IsPipeline(subpass, VK_PIPELINE_BIND_POINT_GRAPHICS) && !is_all_graphics_stages) {
Petr Kraus3e52eba2019-07-10 01:24:10 +0200847 skip |=
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700848 LogError(VkRenderPass(0), vuid,
849 "Dependency pDependencies[%" PRIu32
850 "] specifies a %sStageMask that contains stages (%s) that are not part "
851 "of the Graphics pipeline, as specified by the %sSubpass (= %" PRIu32 ") in pipelineBindPoint.",
852 dependency_index, target, string_VkPipelineStageFlags(stages & ~kGraphicsStages).c_str(), target, subpass);
Petr Kraus3e52eba2019-07-10 01:24:10 +0200853 }
854
855 return skip;
856 };
857
858 template <typename RenderPassCreateInfoGeneric>
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700859 bool CreateRenderPassGeneric(VkDevice device, const RenderPassCreateInfoGeneric *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700860 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
Jeff Bolz46c0ea02019-10-09 13:06:29 -0500861 RenderPassCreateVersion rp_version) const {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700862 bool skip = false;
863 uint32_t max_color_attachments = device_limits.maxColorAttachments;
864 bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2);
865 const char *vuid;
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700866 VkBool32 separate_depth_stencil_layouts = false;
867 const auto *vulkan_12_features = lvl_find_in_chain<VkPhysicalDeviceVulkan12Features>(device_createinfo_pnext);
868 if (vulkan_12_features) {
869 separate_depth_stencil_layouts = vulkan_12_features->separateDepthStencilLayouts;
870 } else {
871 const auto *separate_depth_stencil_layouts_features =
872 lvl_find_in_chain<VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR>(device_createinfo_pnext);
873 if (separate_depth_stencil_layouts_features)
874 separate_depth_stencil_layouts = separate_depth_stencil_layouts_features->separateDepthStencilLayouts;
875 }
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700876
877 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Piers Daniell4fde9b72019-11-27 16:19:46 -0700878 const auto *attachment_description_stencil_layout =
879 (use_rp2) ? lvl_find_in_chain<VkAttachmentDescriptionStencilLayoutKHR>(
880 reinterpret_cast<VkAttachmentDescription2KHR const *>(&pCreateInfo->pAttachments[i])->pNext)
881 : 0;
882
sfricke-samsungcac6a262020-04-28 07:50:49 -0700883 const VkFormat attachment_format = pCreateInfo->pAttachments[i].format;
884 const VkImageLayout initial_layout = pCreateInfo->pAttachments[i].initialLayout;
885 const VkImageLayout final_layout = pCreateInfo->pAttachments[i].finalLayout;
886 if (attachment_format == VK_FORMAT_UNDEFINED) {
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700887 std::stringstream ss;
888 ss << (use_rp2 ? "vkCreateRenderPass2KHR" : "vkCreateRenderPass") << ": pCreateInfo->pAttachments[" << i
Mark Lobodzinskibf599b92018-12-31 12:15:55 -0700889 << "].format is VK_FORMAT_UNDEFINED. ";
Mike Schuchardt65847d92019-12-20 13:50:47 -0800890 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-parameter" : "VUID-VkAttachmentDescription-format-parameter";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700891 skip |= LogWarning(device, vuid, "%s", ss.str().c_str());
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700892 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700893 if (final_layout == VK_IMAGE_LAYOUT_UNDEFINED || final_layout == VK_IMAGE_LAYOUT_PREINITIALIZED) {
Mike Schuchardt65847d92019-12-20 13:50:47 -0800894 vuid =
895 use_rp2 ? "VUID-VkAttachmentDescription2-finalLayout-03061" : "VUID-VkAttachmentDescription-finalLayout-00843";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700896 skip |= LogError(device, vuid,
897 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or "
898 "VK_IMAGE_LAYOUT_PREINITIALIZED.",
899 i);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -0700900 }
Tony-LunarGb036c2f2019-12-05 14:38:25 -0700901 if (!separate_depth_stencil_layouts) {
Piers Daniell9af77cd2019-10-16 13:54:12 -0600902 if (pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
903 pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
904 pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
905 pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -0800906 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03298"
Piers Daniell9af77cd2019-10-16 13:54:12 -0600907 : "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03284";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700908 skip |= LogError(
909 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -0600910 "pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, "
911 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or "
912 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR",
913 i);
914 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700915 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
916 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
917 final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
918 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -0800919 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03299"
Piers Daniell9af77cd2019-10-16 13:54:12 -0600920 : "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03285";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700921 skip |= LogError(
922 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -0600923 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, "
924 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or "
925 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR",
926 i);
927 }
928 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700929 if (!FormatIsDepthOrStencil(attachment_format)) {
930 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
931 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
932 initial_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
933 initial_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -0800934 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03300" : "VUID-VkAttachmentDescription-format-03286";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700935 skip |= LogError(
936 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -0600937 "pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, "
938 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or "
939 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMA_KHRL",
940 i);
941 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700942 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
943 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
944 final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
945 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -0800946 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03301" : "VUID-VkAttachmentDescription-format-03287";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700947 skip |= LogError(
948 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -0600949 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, "
950 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or "
951 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR",
952 i);
953 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700954 } else if (FormatIsDepthAndStencil(attachment_format)) {
Piers Daniell9af77cd2019-10-16 13:54:12 -0600955 if (use_rp2) {
956 if (!attachment_description_stencil_layout) {
sfricke-samsungcac6a262020-04-28 07:50:49 -0700957 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
958 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) {
Piers Daniell9af77cd2019-10-16 13:54:12 -0600959 skip |=
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700960 LogError(device, "VUID-VkAttachmentDescription2-format-03302",
961 "pCreateInfo->pNext must include an instance of VkAttachmentDescriptionStencilLayoutKHR");
Piers Daniell9af77cd2019-10-16 13:54:12 -0600962 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700963 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
964 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) {
Piers Daniell9af77cd2019-10-16 13:54:12 -0600965 skip |=
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700966 LogError(device, "VUID-VkAttachmentDescription2-format-03303",
967 "pCreateInfo->pNext must include an instance of VkAttachmentDescriptionStencilLayoutKHR");
Piers Daniell9af77cd2019-10-16 13:54:12 -0600968 }
969 }
970 } else {
sfricke-samsungcac6a262020-04-28 07:50:49 -0700971 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
972 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
973 initial_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
974 initial_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700975 skip |= LogError(
976 device, "VUID-VkAttachmentDescription-format-03288",
Piers Daniell9af77cd2019-10-16 13:54:12 -0600977 "pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, "
978 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or "
979 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR",
980 i);
981 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700982 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
983 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
984 final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
985 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700986 skip |= LogError(
987 device, "VUID-VkAttachmentDescription-format-03289",
Piers Daniell9af77cd2019-10-16 13:54:12 -0600988 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, "
989 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or "
990 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR",
991 i);
992 }
993 }
sfricke-samsungcac6a262020-04-28 07:50:49 -0700994 } else if (FormatIsDepthOnly(attachment_format)) {
995 if (initial_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
996 initial_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -0800997 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03304" : "VUID-VkAttachmentDescription-format-03290";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -0700998 skip |= LogError(
999 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -06001000 "pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, or"
1001 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR",
1002 i);
1003 }
sfricke-samsungcac6a262020-04-28 07:50:49 -07001004 if (final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
1005 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -08001006 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03305" : "VUID-VkAttachmentDescription-format-03291";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001007 skip |= LogError(
1008 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -06001009 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or "
1010 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR",
1011 i);
1012 }
sfricke-samsungcac6a262020-04-28 07:50:49 -07001013 } else if (FormatIsStencilOnly(attachment_format)) {
1014 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
1015 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -08001016 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03306" : "VUID-VkAttachmentDescription-format-03292";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001017 skip |= LogError(
1018 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -06001019 "pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, or"
1020 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR",
1021 i);
1022 }
sfricke-samsungcac6a262020-04-28 07:50:49 -07001023 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
1024 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) {
Mike Schuchardt65847d92019-12-20 13:50:47 -08001025 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03307" : "VUID-VkAttachmentDescription-format-03293";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001026 skip |= LogError(
1027 device, vuid,
Piers Daniell9af77cd2019-10-16 13:54:12 -06001028 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, or "
1029 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMA_KHRL",
1030 i);
1031 }
1032 }
1033 if (use_rp2 && attachment_description_stencil_layout) {
1034 if (attachment_description_stencil_layout->stencilInitialLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ||
1035 attachment_description_stencil_layout->stencilInitialLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
1036 attachment_description_stencil_layout->stencilInitialLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
1037 attachment_description_stencil_layout->stencilInitialLayout ==
1038 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
1039 attachment_description_stencil_layout->stencilInitialLayout ==
1040 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1041 attachment_description_stencil_layout->stencilInitialLayout ==
1042 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
1043 attachment_description_stencil_layout->stencilInitialLayout ==
1044 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001045 skip |= LogError(device, "VUID-VkAttachmentDescriptionStencilLayout-stencilInitialLayout-03308",
1046 "VkAttachmentDescriptionStencilLayoutKHR.stencilInitialLayout must not be "
1047 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
1048 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, "
1049 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "
1050 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "
1051 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or "
1052 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL.");
Piers Daniell9af77cd2019-10-16 13:54:12 -06001053 }
1054 if (attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ||
1055 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
1056 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR ||
1057 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
1058 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1059 attachment_description_stencil_layout->stencilFinalLayout ==
1060 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
1061 attachment_description_stencil_layout->stencilFinalLayout ==
1062 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001063 skip |= LogError(device, "VUID-VkAttachmentDescriptionStencilLayout-stencilFinalLayout-03309",
1064 "VkAttachmentDescriptionStencilLayoutKHR.stencilFinalLayout must not be "
1065 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
1066 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, "
1067 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "
1068 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "
1069 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or "
1070 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL.");
Piers Daniell9af77cd2019-10-16 13:54:12 -06001071 }
1072 if (attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_UNDEFINED ||
1073 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) {
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001074 skip |= LogError(
1075 device, "VUID-VkAttachmentDescriptionStencilLayout-stencilFinalLayout-03310",
Piers Daniell9af77cd2019-10-16 13:54:12 -06001076 "VkAttachmentDescriptionStencilLayoutKHR.stencilFinalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED, or "
1077 "VK_IMAGE_LAYOUT_PREINITIALIZED.");
1078 }
1079 }
sfricke-samsungcac6a262020-04-28 07:50:49 -07001080
1081 if (FormatIsDepthOrStencil(attachment_format)) {
1082 if (initial_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
1083 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03295" : "VUID-VkAttachmentDescription-format-03281";
1084 skip |= LogError(device, vuid,
1085 "pCreateInfo->pAttachments[%d].initialLayout must not be "
1086 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when using a Depth or Stencil format",
1087 i);
1088 }
1089 if (final_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
1090 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03297" : "VUID-VkAttachmentDescription-format-03283";
1091 skip |= LogError(device, vuid,
1092 "pCreateInfo->pAttachments[%d].finalLayout must not be "
1093 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when using a Depth or Stencil format",
1094 i);
1095 }
1096 }
1097 if (FormatIsColor(attachment_format)) {
1098 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
1099 initial_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1100 initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
1101 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) {
1102 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03294" : "VUID-VkAttachmentDescription-format-03280";
1103 skip |= LogError(
1104 device, vuid,
1105 "pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "
1106 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "
1107 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or "
1108 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL when using a Color format",
1109 i);
1110 }
1111 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
1112 final_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
1113 final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
1114 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) {
1115 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03296" : "VUID-VkAttachmentDescription-format-03282";
1116 skip |= LogError(
1117 device, vuid,
1118 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "
1119 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "
1120 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or "
1121 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL when using a Color format",
1122 i);
1123 }
1124 }
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001125 }
1126
1127 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
1128 if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) {
Mike Schuchardt65847d92019-12-20 13:50:47 -08001129 vuid = use_rp2 ? "VUID-VkSubpassDescription2-colorAttachmentCount-03063"
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001130 : "VUID-VkSubpassDescription-colorAttachmentCount-00845";
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001131 skip |= LogError(device, vuid, "Cannot create a render pass with %d color attachments. Max is %d.",
1132 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001133 }
1134 }
Petr Kraus3e52eba2019-07-10 01:24:10 +02001135
1136 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) {
1137 const auto &dependency = pCreateInfo->pDependencies[i];
1138
sfricke-samsung55f01952020-03-24 08:16:41 -07001139 // Need to check first so layer doesn't segfault from out of bound array access
1140 // src subpass bound check
Mark Lobodzinskif5a10b62020-03-09 13:16:13 -06001141 if ((dependency.srcSubpass != VK_SUBPASS_EXTERNAL) && (dependency.srcSubpass >= pCreateInfo->subpassCount)) {
sfricke-samsung55f01952020-03-24 08:16:41 -07001142 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-srcSubpass-02526" : "VUID-VkRenderPassCreateInfo-srcSubpass-02517";
1143 skip |= LogError(device, vuid, "Dependency %u srcSubpass index (%u) has to be less than subpassCount (%u)", i,
1144 dependency.srcSubpass, pCreateInfo->subpassCount);
Mark Lobodzinskif5a10b62020-03-09 13:16:13 -06001145 }
1146
sfricke-samsung55f01952020-03-24 08:16:41 -07001147 // dst subpass bound check
Mark Lobodzinskif5a10b62020-03-09 13:16:13 -06001148 if ((dependency.dstSubpass != VK_SUBPASS_EXTERNAL) && (dependency.dstSubpass >= pCreateInfo->subpassCount)) {
sfricke-samsung55f01952020-03-24 08:16:41 -07001149 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-dstSubpass-02527" : "VUID-VkRenderPassCreateInfo-dstSubpass-02518";
1150 skip |= LogError(device, vuid, "Dependency %u dstSubpass index (%u) has to be less than subpassCount (%u)", i,
1151 dependency.dstSubpass, pCreateInfo->subpassCount);
Mark Lobodzinskif5a10b62020-03-09 13:16:13 -06001152 }
1153
Petr Kraus3e52eba2019-07-10 01:24:10 +02001154 // Spec currently only supports Graphics pipeline in render pass -- so only that pipeline is currently checked
Mike Schuchardt65847d92019-12-20 13:50:47 -08001155 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-pDependencies-03054" : "VUID-VkRenderPassCreateInfo-pDependencies-00837";
Petr Kraus3e52eba2019-07-10 01:24:10 +02001156 skip |= ValidateSubpassGraphicsFlags(report_data, pCreateInfo, i, dependency.srcSubpass, dependency.srcStageMask, vuid,
1157 "src");
1158
Tony-LunarGb036c2f2019-12-05 14:38:25 -07001159 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-pDependencies-03055" : "VUID-VkRenderPassCreateInfo-pDependencies-00838";
Petr Kraus3e52eba2019-07-10 01:24:10 +02001160 skip |= ValidateSubpassGraphicsFlags(report_data, pCreateInfo, i, dependency.dstSubpass, dependency.dstStageMask, vuid,
1161 "dst");
1162 }
1163
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001164 return skip;
1165 }
1166
1167 template <typename T>
1168 void RecordRenderPass(VkRenderPass renderPass, const T *pCreateInfo) {
Mark Lobodzinskif27a6bc2019-02-04 13:00:49 -07001169 std::unique_lock<std::mutex> lock(renderpass_map_mutex);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001170 auto &renderpass_state = renderpasses_states[renderPass];
Mark Lobodzinskif27a6bc2019-02-04 13:00:49 -07001171 lock.unlock();
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001172
1173 for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) {
1174 bool uses_color = false;
1175 for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i)
1176 if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true;
1177
1178 bool uses_depthstencil = false;
1179 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment)
1180 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
1181 uses_depthstencil = true;
1182
1183 if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass);
1184 if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass);
1185 }
1186 }
1187
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001188 bool require_device_extension(bool flag, char const *function_name, char const *extension_name) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001189
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001190 bool validate_instance_extensions(const VkInstanceCreateInfo *pCreateInfo) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001191
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001192 bool validate_api_version(uint32_t api_version, uint32_t effective_api_version) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001193
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001194 bool validate_string(const char *apiName, const ParameterName &stringName, const std::string &vuid,
1195 const char *validateString) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001196
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001197 bool ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV *order) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001198
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001199 bool ValidateQueueFamilies(uint32_t queue_family_count, const uint32_t *queue_families, const char *cmd_name,
1200 const char *array_parameter_name, const std::string &unique_error_code,
1201 const std::string &valid_error_code, bool optional);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001202
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001203 bool ValidateDeviceQueueFamily(uint32_t queue_family, const char *cmd_name, const char *parameter_name,
1204 const std::string &error_code, bool optional);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001205
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001206 bool ValidateGeometryTrianglesNV(const VkGeometryTrianglesNV &triangles, VkAccelerationStructureNV object_handle,
1207 const char *func_name) const;
1208 bool ValidateGeometryAABBNV(const VkGeometryAABBNV &geometry, VkAccelerationStructureNV object_handle,
Jason Macnak192fa0e2019-07-26 15:07:16 -07001209 const char *func_name) const;
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001210 bool ValidateGeometryNV(const VkGeometryNV &geometry, VkAccelerationStructureNV object_handle, const char *func_name) const;
1211 bool ValidateAccelerationStructureInfoNV(const VkAccelerationStructureInfoNV &info, VkAccelerationStructureNV object_handle,
1212 const char *func_nam) const;
sfricke-samsung11ea8ed2020-01-07 22:24:56 -08001213 bool ValidateCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
1214 const VkAllocationCallbacks *pAllocator, VkSamplerYcbcrConversion *pYcbcrConversion,
1215 const char *apiName) const;
Jason Macnak5c954952019-07-09 15:46:12 -07001216
Jeff Bolz46c0ea02019-10-09 13:06:29 -05001217 bool OutputExtensionError(const std::string &api_name, const std::string &extension_name) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001218
1219 void PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07001220 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, VkResult result);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001221 void PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07001222 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, VkResult result);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001223 void PostCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator);
1224 void PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07001225 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001226
1227 void PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskicd05c1e2019-01-17 15:33:46 -07001228 VkInstance *pInstance, VkResult result);
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001229
1230 bool manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001231 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001232
1233 bool manual_PreCallValidateCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001234 VkInstance *pInstance) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001235
1236 bool manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001237 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001238
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001239 bool manual_PreCallValidateCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001240 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001241
1242 bool manual_PreCallValidateCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001243 const VkAllocationCallbacks *pAllocator, VkImage *pImage) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001244
Jeff Bolz99e3f632020-03-24 22:59:22 -05001245 bool manual_PreCallValidateCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
1246 const VkAllocationCallbacks *pAllocator, VkImageView *pView) const;
1247
Jeff Bolz6d3beaa2019-02-09 21:00:05 -06001248 bool manual_PreCallValidateViewport(const VkViewport &viewport, const char *fn_name, const ParameterName &parameter_name,
Mark Lobodzinski5d8244a2020-01-23 13:00:43 -07001249 VkCommandBuffer object) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001250
1251 bool manual_PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
1252 const VkGraphicsPipelineCreateInfo *pCreateInfos,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001253 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001254 bool manual_PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
1255 const VkComputePipelineCreateInfo *pCreateInfos,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001256 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001257
1258 bool manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001259 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001260 bool manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001261 const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001262 VkDescriptorSetLayout *pSetLayout) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001263
Jeremy Hayes390ff6f2020-02-10 13:48:57 -07001264 bool validate_WriteDescriptorSet(const char *vkCallingFunction, const uint32_t descriptorWriteCount,
1265 const VkWriteDescriptorSet *pDescriptorWrites, const bool validateDstSet = true) const;
Mark Lobodzinskibf599b92018-12-31 12:15:55 -07001266 bool manual_PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
1267 const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001268 const VkCopyDescriptorSet *pDescriptorCopies) const;
Jason Macnak5c954952019-07-09 15:46:12 -07001269
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001270 bool manual_PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001271 const VkDescriptorSet *pDescriptorSets) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001272
1273 bool manual_PreCallValidateCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001274 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001275
1276 bool manual_PreCallValidateCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001277 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001278
1279 bool manual_PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001280 const VkCommandBuffer *pCommandBuffers) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001281
Jeff Bolz5c801d12019-10-09 10:38:45 -05001282 bool manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001283
1284 bool manual_PreCallValidateCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001285 const VkViewport *pViewports) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001286
1287 bool manual_PreCallValidateCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001288 const VkRect2D *pScissors) const;
1289 bool manual_PreCallValidateCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001290
1291 bool manual_PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001292 uint32_t firstVertex, uint32_t firstInstance) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001293
1294 bool manual_PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001295 uint32_t stride) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001296
1297 bool manual_PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001298 uint32_t count, uint32_t stride) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001299
Mark Lobodzinskif77a4ac2019-06-27 15:30:51 -06001300 bool manual_PreCallValidateCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
1301 const VkClearAttachment *pAttachments, uint32_t rectCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001302 const VkClearRect *pRects) const;
Mark Lobodzinskif77a4ac2019-06-27 15:30:51 -06001303
Andrew Fobel3abeb992020-01-20 16:33:22 -05001304 bool ValidateGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,
1305 const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
1306 VkImageFormatProperties2 *pImageFormatProperties,
1307 const char *apiName) const;
1308 bool manual_PreCallValidateGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,
1309 const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
1310 VkImageFormatProperties2 *pImageFormatProperties) const;
1311 bool manual_PreCallValidateGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice,
1312 const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
1313 VkImageFormatProperties2 *pImageFormatProperties) const;
1314
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001315 bool manual_PreCallValidateCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1316 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001317 const VkImageCopy *pRegions) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001318
1319 bool manual_PreCallValidateCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
1320 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001321 const VkImageBlit *pRegions, VkFilter filter) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001322
sfricke-samsung3999ef62020-02-09 17:05:59 -08001323 bool manual_PreCallValidateCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
1324 uint32_t regionCount, const VkBufferCopy *pRegions) const;
1325
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001326 bool manual_PreCallValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
1327 VkImageLayout dstImageLayout, uint32_t regionCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001328 const VkBufferImageCopy *pRegions) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001329
1330 bool manual_PreCallValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001331 VkBuffer dstBuffer, uint32_t regionCount,
1332 const VkBufferImageCopy *pRegions) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001333
1334 bool manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001335 VkDeviceSize dataSize, const void *pData) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001336
1337 bool manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001338 VkDeviceSize size, uint32_t data) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001339
1340 bool manual_PreCallValidateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001341 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) const;
1342 bool manual_PreCallValidateQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001343
1344#ifdef VK_USE_PLATFORM_WIN32_KHR
1345 bool manual_PreCallValidateCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001346 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001347#endif // VK_USE_PLATFORM_WIN32_KHR
1348
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001349 bool manual_PreCallValidateCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001350 const VkAllocationCallbacks *pAllocator,
1351 VkDescriptorPool *pDescriptorPool) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001352 bool manual_PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001353 uint32_t groupCountZ) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001354
Jeff Bolz5c801d12019-10-09 10:38:45 -05001355 bool manual_PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001356
1357 bool manual_PreCallValidateCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1358 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001359 uint32_t groupCountZ) const;
Jeremy Hayes390ff6f2020-02-10 13:48:57 -07001360 bool manual_PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
1361 VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount,
1362 const VkWriteDescriptorSet *pDescriptorWrites) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001363 bool manual_PreCallValidateCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001364 uint32_t exclusiveScissorCount, const VkRect2D *pExclusiveScissors) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001365 bool manual_PreCallValidateCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
1366 uint32_t viewportCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001367 const VkShadingRatePaletteNV *pShadingRatePalettes) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001368
1369 bool manual_PreCallValidateCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType,
1370 uint32_t customSampleOrderCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001371 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001372
Jeff Bolz5c801d12019-10-09 10:38:45 -05001373 bool manual_PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001374 bool manual_PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001375 uint32_t drawCount, uint32_t stride) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001376
1377 bool manual_PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1378 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001379 uint32_t maxDrawCount, uint32_t stride) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001380
1381 bool manual_PreCallValidateEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001382 uint32_t *pPropertyCount,
1383 VkExtensionProperties *pProperties) const;
Jeff Bolz7e7e6e02019-01-11 22:53:41 -06001384 bool manual_PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001385 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) const;
Ricardo Garciaa4935972019-02-21 17:43:18 +01001386
1387 bool manual_PreCallValidateCreateAccelerationStructureNV(VkDevice device,
1388 const VkAccelerationStructureCreateInfoNV *pCreateInfo,
1389 const VkAllocationCallbacks *pAllocator,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001390 VkAccelerationStructureNV *pAccelerationStructure) const;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001391 bool manual_PreCallValidateCreateAccelerationStructureKHR(VkDevice device,
1392 const VkAccelerationStructureCreateInfoKHR *pCreateInfo,
1393 const VkAllocationCallbacks *pAllocator,
1394 VkAccelerationStructureKHR *pAccelerationStructure) const;
Jason Macnak5c954952019-07-09 15:46:12 -07001395 bool manual_PreCallValidateCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
1396 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
1397 VkDeviceSize instanceOffset, VkBool32 update,
1398 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001399 VkBuffer scratch, VkDeviceSize scratchOffset) const;
Jason Macnak5c954952019-07-09 15:46:12 -07001400 bool manual_PreCallValidateGetAccelerationStructureHandleNV(VkDevice device, VkAccelerationStructureNV accelerationStructure,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001401 size_t dataSize, void *pData) const;
Peter Chen85366392019-05-14 15:20:11 -04001402 bool manual_PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
1403 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001404 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001405 bool manual_PreCallValidateCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache,
1406 uint32_t createInfoCount,
1407 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1408 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const;
Chris Mayer9ded5eb2019-09-19 16:33:26 +02001409 bool manual_PreCallValidateCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001410 uint32_t viewportCount,
1411 const VkViewportWScalingNV *pViewportWScalings) const;
Mike Schuchardt21638df2019-03-16 10:52:02 -07001412
1413#ifdef VK_USE_PLATFORM_WIN32_KHR
1414 bool PreCallValidateGetDeviceGroupSurfacePresentModes2EXT(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001415 VkDeviceGroupPresentModeFlagsKHR *pModes) const;
Mike Schuchardt21638df2019-03-16 10:52:02 -07001416#endif // VK_USE_PLATFORM_WIN32_KHR
Tobias Hectorebb855f2019-07-23 12:17:33 +01001417
1418 bool manual_PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001419 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) const;
Tobias Hectorebb855f2019-07-23 12:17:33 +01001420
Jeff Bolz8125a8b2019-08-16 16:29:45 -05001421 bool manual_PreCallValidateCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001422 uint16_t lineStipplePattern) const;
Piers Daniell8fd03f52019-08-21 12:07:53 -06001423
1424 bool manual_PreCallValidateCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001425 VkIndexType indexType) const;
sfricke-samsung4ada8d42020-02-09 17:43:11 -08001426 bool manual_PreCallValidateCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount,
1427 const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) const;
Piers Daniell8fd03f52019-08-21 12:07:53 -06001428
Jeff Bolz5c801d12019-10-09 10:38:45 -05001429 bool manual_PreCallValidateSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) const;
Mark Lobodzinski84988402019-09-11 15:27:30 -06001430
Jeff Bolz5c801d12019-10-09 10:38:45 -05001431 bool manual_PreCallValidateSetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) const;
Mark Lobodzinski84988402019-09-11 15:27:30 -06001432
Petr Kraus3d720392019-11-13 02:52:39 +01001433 bool manual_PreCallValidateAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
1434 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) const;
1435
1436 bool manual_PreCallValidateAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo,
1437 uint32_t *pImageIndex) const;
1438
Mark Lobodzinski953b7bc2019-12-19 13:50:10 -07001439 bool manual_PreCallValidateCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1440 uint32_t firstInstance, VkBuffer counterBuffer,
1441 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1442 uint32_t vertexStride) const;
sfricke-samsung11ea8ed2020-01-07 22:24:56 -08001443 bool manual_PreCallValidateCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
1444 const VkAllocationCallbacks *pAllocator,
1445 VkSamplerYcbcrConversion *pYcbcrConversion) const;
1446 bool manual_PreCallValidateCreateSamplerYcbcrConversionKHR(VkDevice device,
1447 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
1448 const VkAllocationCallbacks *pAllocator,
1449 VkSamplerYcbcrConversion *pYcbcrConversion) const;
sfricke-samsung1708a8c2020-02-10 00:35:06 -08001450 bool manual_PreCallValidateImportSemaphoreFdKHR(VkDevice device,
1451 const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) const;
Mark Lobodzinskiaf7c0382018-12-18 11:55:55 -07001452#include "parameter_validation.h"
1453}; // Class StatelessValidation