1 /* 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. 5 * 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 24 #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 34 static const char DECORATE_UNUSED *kVUID_PVError_RequiredParameter = "UNASSIGNED-GeneralParameterError-RequiredParameter"; 35 static const char DECORATE_UNUSED *kVUID_PVError_UnrecognizedValue = "UNASSIGNED-GeneralParameterError-UnrecognizedValue"; 36 static const char DECORATE_UNUSED *kVUID_PVError_ExtensionNotEnabled = "UNASSIGNED-GeneralParameterError-ExtensionNotEnabled"; 37 static const char DECORATE_UNUSED *kVUID_PVError_ApiVersionViolation = "UNASSIGNED-API-Version-Violation"; 38 // static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructPNext = "UNASSIGNED-GeneralParameterError-InvalidStructPNext"; 39 // static const char DECORATE_UNUSED *kVUID_PVError_NONE = "UNASSIGNED-GeneralParameterError-Info"; 40 // static const char DECORATE_UNUSED *kVUID_PVError_InvalidUsage = "UNASSIGNED-GeneralParameterError-InvalidUsage"; 41 // static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructSType = "UNASSIGNED-GeneralParameterError-InvalidStructSType"; 42 // static const char DECORATE_UNUSED *kVUID_PVError_ReservedParameter = "UNASSIGNED-GeneralParameterError-ReservedParameter"; 43 // static const char DECORATE_UNUSED *kVUID_PVError_DeviceLimit = "UNASSIGNED-GeneralParameterError-DeviceLimit"; 44 // static const char DECORATE_UNUSED *kVUID_PVError_FailureCode = "UNASSIGNED-GeneralParameterError-FailureCode"; 45 // static const char DECORATE_UNUSED *kVUID_PVError_DeviceFeature = "UNASSIGNED-GeneralParameterError-DeviceFeature"; 46 47 extern const uint32_t GeneratedVulkanHeaderVersion; 48 49 extern const VkQueryPipelineStatisticFlags AllVkQueryPipelineStatisticFlagBits; 50 extern const VkColorComponentFlags AllVkColorComponentFlagBits; 51 extern const VkShaderStageFlags AllVkShaderStageFlagBits; 52 extern const VkQueryControlFlags AllVkQueryControlFlagBits; 53 extern const VkImageUsageFlags AllVkImageUsageFlagBits; 54 extern const VkSampleCountFlags AllVkSampleCountFlagBits; 55 extern const VkBuildAccelerationStructureFlagsNV AllVkBuildAccelerationStructureFlagBitsNV; 56 extern const VkGeometryFlagsKHR AllVkGeometryFlagBitsKHR; 57 58 extern const std::vector<VkGeometryTypeKHR> AllVkGeometryTypeKHREnums; 59 extern const std::vector<VkCompareOp> AllVkCompareOpEnums; 60 extern const std::vector<VkStencilOp> AllVkStencilOpEnums; 61 extern const std::vector<VkBlendFactor> AllVkBlendFactorEnums; 62 extern const std::vector<VkBlendOp> AllVkBlendOpEnums; 63 extern const std::vector<VkLogicOp> AllVkLogicOpEnums; 64 extern const std::vector<VkBorderColor> AllVkBorderColorEnums; 65 extern const std::vector<VkImageLayout> AllVkImageLayoutEnums; 66 extern const std::vector<VkFormat> AllVkFormatEnums; 67 extern const std::vector<VkVertexInputRate> AllVkVertexInputRateEnums; 68 extern const std::vector<VkPrimitiveTopology> AllVkPrimitiveTopologyEnums; 69 extern const std::vector<VkIndexType> AllVkIndexTypeEnums; 70 71 extern std::vector<std::pair<uint32_t, uint32_t>> custom_stype_info; 72 73 // String returned by string_VkStructureType for an unrecognized type. 74 const std::string UnsupportedStructureTypeString = "Unhandled VkStructureType"; 75 76 // String returned by string_VkResult for an unrecognized type. 77 const std::string UnsupportedResultString = "Unhandled VkResult"; 78 79 // The base value used when computing the offset for an enumeration token value that is added by an extension. 80 // When validating enumeration tokens, any value >= to this value is considered to be provided by an extension. 81 // See Appendix C.10 "Assigning Extension Token Values" from the Vulkan specification 82 const uint32_t ExtEnumBaseValue = 1000000000; 83 84 // The value of all VK_xxx_MAX_ENUM tokens 85 const uint32_t MaxEnumValue = 0x7FFFFFFF; 86 87 class StatelessValidation : public ValidationObject { 88 public: 89 VkPhysicalDeviceLimits device_limits = {}; 90 safe_VkPhysicalDeviceFeatures2 physical_device_features2; 91 void *device_createinfo_pnext; 92 const VkPhysicalDeviceFeatures &physical_device_features = physical_device_features2.features; 93 std::unordered_map<VkPhysicalDevice, VkPhysicalDeviceProperties *> physical_device_properties_map; 94 std::unordered_map<VkPhysicalDevice, std::unordered_set<std::string>> device_extensions_enumerated{}; 95 96 // Override chassis read/write locks for this validation object 97 // This override takes a deferred lock. i.e. it is not acquired. read_lock()98 virtual read_lock_guard_t read_lock() { return read_lock_guard_t(validation_object_mutex, std::defer_lock); } write_lock()99 virtual write_lock_guard_t write_lock() { return write_lock_guard_t(validation_object_mutex, std::defer_lock); } 100 101 // Device extension properties -- storing properties gathered from VkPhysicalDeviceProperties2KHR::pNext chain 102 struct DeviceExtensionProperties { 103 VkPhysicalDeviceShadingRateImagePropertiesNV shading_rate_image_props; 104 VkPhysicalDeviceMeshShaderPropertiesNV mesh_shader_props; 105 VkPhysicalDeviceRayTracingPropertiesNV ray_tracing_propsNV; 106 VkPhysicalDeviceRayTracingPropertiesKHR ray_tracing_propsKHR; 107 VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_props; 108 }; 109 DeviceExtensionProperties phys_dev_ext_props = {}; 110 111 struct SubpassesUsageStates { 112 std::unordered_set<uint32_t> subpasses_using_color_attachment; 113 std::unordered_set<uint32_t> subpasses_using_depthstencil_attachment; 114 }; 115 116 // Though this validation object is predominantly statless, the Framebuffer checks are greatly simplified by creating and 117 // updating a map of the renderpass usage states, and these accesses need thread protection. Use a mutex separate from the 118 // parent object's to maintain that functionality. 119 mutable std::mutex renderpass_map_mutex; 120 std::unordered_map<VkRenderPass, SubpassesUsageStates> renderpasses_states; 121 122 // Constructor for stateles validation tracking StatelessValidation()123 StatelessValidation() : device_createinfo_pnext(nullptr) { container_type = LayerObjectTypeParameterValidation; } ~StatelessValidation()124 ~StatelessValidation() { 125 if (device_createinfo_pnext) { 126 FreePnextChain(device_createinfo_pnext); 127 } 128 } 129 130 /** 131 * Validate a minimum value. 132 * 133 * Verify that the specified value is greater than the specified lower bound. 134 * 135 * @param api_name Name of API call being validated. 136 * @param parameter_name Name of parameter being validated. 137 * @param value Value to validate. 138 * @param lower_bound Lower bound value to use for validation. 139 * @return Boolean value indicating that the call should be skipped. 140 */ 141 template <typename T> ValidateGreaterThan(const T value,const T lower_bound,const ParameterName & parameter_name,const std::string & vuid,const char * api_name)142 bool ValidateGreaterThan(const T value, const T lower_bound, const ParameterName ¶meter_name, const std::string &vuid, 143 const char *api_name) const { 144 bool skip_call = false; 145 146 if (value <= lower_bound) { 147 std::ostringstream ss; 148 ss << api_name << ": parameter " << parameter_name.get_name() << " (= " << value << ") is not greater than " 149 << lower_bound; 150 skip_call |= LogError(device, vuid, "%s", ss.str().c_str()); 151 } 152 153 return skip_call; 154 } 155 156 template <typename T> ValidateGreaterThanZero(const T value,const ParameterName & parameter_name,const std::string & vuid,const char * api_name)157 bool ValidateGreaterThanZero(const T value, const ParameterName ¶meter_name, const std::string &vuid, 158 const char *api_name) const { 159 return ValidateGreaterThan(value, T{0}, parameter_name, vuid, api_name); 160 } 161 /** 162 * Validate a required pointer. 163 * 164 * Verify that a required pointer is not NULL. 165 * 166 * @param apiName Name of API call being validated. 167 * @param parameterName Name of parameter being validated. 168 * @param value Pointer to validate. 169 * @return Boolean value indicating that the call should be skipped. 170 */ validate_required_pointer(const char * apiName,const ParameterName & parameterName,const void * value,const std::string & vuid)171 bool validate_required_pointer(const char *apiName, const ParameterName ¶meterName, const void *value, 172 const std::string &vuid) const { 173 bool skip_call = false; 174 175 if (value == NULL) { 176 skip_call |= 177 LogError(device, vuid, "%s: required parameter %s specified as NULL.", apiName, parameterName.get_name().c_str()); 178 } 179 180 return skip_call; 181 } 182 183 /** 184 * Validate array count and pointer to array. 185 * 186 * Verify that required count and array parameters are not 0 or NULL. If the 187 * count parameter is not optional, verify that it is not 0. If the array 188 * parameter is NULL, and it is not optional, verify that count is 0. 189 * 190 * @param apiName Name of API call being validated. 191 * @param countName Name of count parameter. 192 * @param arrayName Name of array parameter. 193 * @param count Number of elements in the array. 194 * @param array Array to validate. 195 * @param countRequired The 'count' parameter may not be 0 when true. 196 * @param arrayRequired The 'array' parameter may not be NULL when true. 197 * @return Boolean value indicating that the call should be skipped. 198 */ 199 template <typename T1, typename T2> validate_array(const char * apiName,const ParameterName & countName,const ParameterName & arrayName,T1 count,const T2 * array,bool countRequired,bool arrayRequired,const char * count_required_vuid,const char * array_required_vuid)200 bool validate_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, T1 count, 201 const T2 *array, bool countRequired, bool arrayRequired, const char *count_required_vuid, 202 const char *array_required_vuid) const { 203 bool skip_call = false; 204 205 // Count parameters not tagged as optional cannot be 0 206 if (countRequired && (count == 0)) { 207 skip_call |= LogError(device, count_required_vuid, "%s: parameter %s must be greater than 0.", apiName, 208 countName.get_name().c_str()); 209 } 210 211 // Array parameters not tagged as optional cannot be NULL, unless the count is 0 212 if (arrayRequired && (count != 0) && (*array == NULL)) { 213 skip_call |= LogError(device, array_required_vuid, "%s: required parameter %s specified as NULL.", apiName, 214 arrayName.get_name().c_str()); 215 } 216 217 return skip_call; 218 } 219 220 /** 221 * Validate pointer to array count and pointer to array. 222 * 223 * Verify that required count and array parameters are not NULL. If count 224 * is not NULL and its value is not optional, verify that it is not 0. If the 225 * array parameter is NULL, and it is not optional, verify that count is 0. 226 * The array parameter will typically be optional for this case (where count is 227 * a pointer), allowing the caller to retrieve the available count. 228 * 229 * @param apiName Name of API call being validated. 230 * @param countName Name of count parameter. 231 * @param arrayName Name of array parameter. 232 * @param count Pointer to the number of elements in the array. 233 * @param array Array to validate. 234 * @param countPtrRequired The 'count' parameter may not be NULL when true. 235 * @param countValueRequired The '*count' value may not be 0 when true. 236 * @param arrayRequired The 'array' parameter may not be NULL when true. 237 * @return Boolean value indicating that the call should be skipped. 238 */ 239 template <typename T1, typename T2> validate_array(const char * apiName,const ParameterName & countName,const ParameterName & arrayName,const T1 * count,const T2 * array,bool countPtrRequired,bool countValueRequired,bool arrayRequired,const char * count_required_vuid,const char * array_required_vuid)240 bool validate_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, const T1 *count, 241 const T2 *array, bool countPtrRequired, bool countValueRequired, bool arrayRequired, 242 const char *count_required_vuid, const char *array_required_vuid) const { 243 bool skip_call = false; 244 245 if (count == NULL) { 246 if (countPtrRequired) { 247 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL", 248 apiName, countName.get_name().c_str()); 249 } 250 } else { 251 skip_call |= validate_array(apiName, countName, arrayName, *array ? (*count) : 0, &array, countValueRequired, 252 arrayRequired, count_required_vuid, array_required_vuid); 253 } 254 255 return skip_call; 256 } 257 258 /** 259 * Validate a pointer to a Vulkan structure. 260 * 261 * Verify that a required pointer to a structure is not NULL. If the pointer is 262 * not NULL, verify that each structure's sType field is set to the correct 263 * VkStructureType value. 264 * 265 * @param apiName Name of API call being validated. 266 * @param parameterName Name of struct parameter being validated. 267 * @param sTypeName Name of expected VkStructureType value. 268 * @param value Pointer to the struct to validate. 269 * @param sType VkStructureType for structure validation. 270 * @param required The parameter may not be NULL when true. 271 * @return Boolean value indicating that the call should be skipped. 272 */ 273 template <typename T> validate_struct_type(const char * apiName,const ParameterName & parameterName,const char * sTypeName,const T * value,VkStructureType sType,bool required,const char * struct_vuid,const char * stype_vuid)274 bool validate_struct_type(const char *apiName, const ParameterName ¶meterName, const char *sTypeName, const T *value, 275 VkStructureType sType, bool required, const char *struct_vuid, const char *stype_vuid) const { 276 bool skip_call = false; 277 278 if (value == NULL) { 279 if (required) { 280 skip_call |= LogError(device, struct_vuid, "%s: required parameter %s specified as NULL", apiName, 281 parameterName.get_name().c_str()); 282 } 283 } else if (value->sType != sType) { 284 skip_call |= LogError(device, stype_vuid, "%s: parameter %s->sType must be %s.", apiName, 285 parameterName.get_name().c_str(), sTypeName); 286 } 287 288 return skip_call; 289 } 290 291 /** 292 * Validate an array of Vulkan structures 293 * 294 * Verify that required count and array parameters are not 0 or NULL. If 295 * the array contains 1 or more structures, verify that each structure's 296 * sType field is set to the correct VkStructureType value. 297 * 298 * @param apiName Name of API call being validated. 299 * @param countName Name of count parameter. 300 * @param arrayName Name of array parameter. 301 * @param sTypeName Name of expected VkStructureType value. 302 * @param count Number of elements in the array. 303 * @param array Array to validate. 304 * @param sType VkStructureType for structure validation. 305 * @param countRequired The 'count' parameter may not be 0 when true. 306 * @param arrayRequired The 'array' parameter may not be NULL when true. 307 * @return Boolean value indicating that the call should be skipped. 308 */ 309 template <typename T> validate_struct_type_array(const char * apiName,const ParameterName & countName,const ParameterName & arrayName,const char * sTypeName,uint32_t count,const T * array,VkStructureType sType,bool countRequired,bool arrayRequired,const char * stype_vuid,const char * param_vuid,const char * count_required_vuid)310 bool validate_struct_type_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, 311 const char *sTypeName, uint32_t count, const T *array, VkStructureType sType, 312 bool countRequired, bool arrayRequired, const char *stype_vuid, const char *param_vuid, 313 const char *count_required_vuid) const { 314 bool skip_call = false; 315 316 if ((count == 0) || (array == NULL)) { 317 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired, 318 count_required_vuid, param_vuid); 319 } else { 320 // Verify that all structs in the array have the correct type 321 for (uint32_t i = 0; i < count; ++i) { 322 if (array[i].sType != sType) { 323 skip_call |= LogError(device, stype_vuid, "%s: parameter %s[%d].sType must be %s", apiName, 324 arrayName.get_name().c_str(), i, sTypeName); 325 } 326 } 327 } 328 329 return skip_call; 330 } 331 332 /** 333 * Validate an array of Vulkan structures. 334 * 335 * Verify that required count and array parameters are not NULL. If count 336 * is not NULL and its value is not optional, verify that it is not 0. 337 * If the array contains 1 or more structures, verify that each structure's 338 * sType field is set to the correct VkStructureType value. 339 * 340 * @param apiName Name of API call being validated. 341 * @param countName Name of count parameter. 342 * @param arrayName Name of array parameter. 343 * @param sTypeName Name of expected VkStructureType value. 344 * @param count Pointer to the number of elements in the array. 345 * @param array Array to validate. 346 * @param sType VkStructureType for structure validation. 347 * @param countPtrRequired The 'count' parameter may not be NULL when true. 348 * @param countValueRequired The '*count' value may not be 0 when true. 349 * @param arrayRequired The 'array' parameter may not be NULL when true. 350 * @return Boolean value indicating that the call should be skipped. 351 */ 352 template <typename T> validate_struct_type_array(const char * apiName,const ParameterName & countName,const ParameterName & arrayName,const char * sTypeName,uint32_t * count,const T * array,VkStructureType sType,bool countPtrRequired,bool countValueRequired,bool arrayRequired,const char * stype_vuid,const char * param_vuid,const char * count_required_vuid)353 bool validate_struct_type_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, 354 const char *sTypeName, uint32_t *count, const T *array, VkStructureType sType, 355 bool countPtrRequired, bool countValueRequired, bool arrayRequired, const char *stype_vuid, 356 const char *param_vuid, const char *count_required_vuid) const { 357 bool skip_call = false; 358 359 if (count == NULL) { 360 if (countPtrRequired) { 361 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL", 362 apiName, countName.get_name().c_str()); 363 } 364 } else { 365 skip_call |= validate_struct_type_array(apiName, countName, arrayName, sTypeName, (*count), array, sType, 366 countValueRequired && (array != nullptr), arrayRequired, stype_vuid, param_vuid, 367 count_required_vuid); 368 } 369 370 return skip_call; 371 } 372 373 /** 374 * Validate a Vulkan handle. 375 * 376 * Verify that the specified handle is not VK_NULL_HANDLE. 377 * 378 * @param api_name Name of API call being validated. 379 * @param parameter_name Name of struct parameter being validated. 380 * @param value Handle to validate. 381 * @return Boolean value indicating that the call should be skipped. 382 */ 383 template <typename T> validate_required_handle(const char * api_name,const ParameterName & parameter_name,T value)384 bool validate_required_handle(const char *api_name, const ParameterName ¶meter_name, T value) const { 385 bool skip_call = false; 386 387 if (value == VK_NULL_HANDLE) { 388 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as VK_NULL_HANDLE", 389 api_name, parameter_name.get_name().c_str()); 390 } 391 392 return skip_call; 393 } 394 395 /** 396 * Validate an array of Vulkan handles. 397 * 398 * Verify that required count and array parameters are not NULL. If count 399 * is not NULL and its value is not optional, verify that it is not 0. 400 * If the array contains 1 or more handles, verify that no handle is set to 401 * VK_NULL_HANDLE. 402 * 403 * @note This function is only intended to validate arrays of handles when none 404 * of the handles are allowed to be VK_NULL_HANDLE. For arrays of handles 405 * that are allowed to contain VK_NULL_HANDLE, use validate_array() instead. 406 * 407 * @param api_name Name of API call being validated. 408 * @param count_name Name of count parameter. 409 * @param array_name Name of array parameter. 410 * @param count Number of elements in the array. 411 * @param array Array to validate. 412 * @param count_required The 'count' parameter may not be 0 when true. 413 * @param array_required The 'array' parameter may not be NULL when true. 414 * @return Boolean value indicating that the call should be skipped. 415 */ 416 template <typename T> validate_handle_array(const char * api_name,const ParameterName & count_name,const ParameterName & array_name,uint32_t count,const T * array,bool count_required,bool array_required)417 bool validate_handle_array(const char *api_name, const ParameterName &count_name, const ParameterName &array_name, 418 uint32_t count, const T *array, bool count_required, bool array_required) const { 419 bool skip_call = false; 420 421 if ((count == 0) || (array == NULL)) { 422 skip_call |= validate_array(api_name, count_name, array_name, count, &array, count_required, array_required, 423 kVUIDUndefined, kVUIDUndefined); 424 } else { 425 // Verify that no handles in the array are VK_NULL_HANDLE 426 for (uint32_t i = 0; i < count; ++i) { 427 if (array[i] == VK_NULL_HANDLE) { 428 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, 429 "%s: required parameter %s[%d] specified as VK_NULL_HANDLE", api_name, 430 array_name.get_name().c_str(), i); 431 } 432 } 433 } 434 435 return skip_call; 436 } 437 438 /** 439 * Validate string array count and content. 440 * 441 * Verify that required count and array parameters are not 0 or NULL. If the 442 * count parameter is not optional, verify that it is not 0. If the array 443 * parameter is NULL, and it is not optional, verify that count is 0. If the 444 * array parameter is not NULL, verify that none of the strings are NULL. 445 * 446 * @param apiName Name of API call being validated. 447 * @param countName Name of count parameter. 448 * @param arrayName Name of array parameter. 449 * @param count Number of strings in the array. 450 * @param array Array of strings to validate. 451 * @param countRequired The 'count' parameter may not be 0 when true. 452 * @param arrayRequired The 'array' parameter may not be NULL when true. 453 * @return Boolean value indicating that the call should be skipped. 454 */ validate_string_array(const char * apiName,const ParameterName & countName,const ParameterName & arrayName,uint32_t count,const char * const * array,bool countRequired,bool arrayRequired,const char * count_required_vuid,const char * array_required_vuid)455 bool validate_string_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, uint32_t count, 456 const char *const *array, bool countRequired, bool arrayRequired, const char *count_required_vuid, 457 const char *array_required_vuid) const { 458 bool skip_call = false; 459 460 if ((count == 0) || (array == NULL)) { 461 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired, 462 count_required_vuid, array_required_vuid); 463 } else { 464 // Verify that strings in the array are not NULL 465 for (uint32_t i = 0; i < count; ++i) { 466 if (array[i] == NULL) { 467 skip_call |= LogError(device, array_required_vuid, "%s: required parameter %s[%d] specified as NULL", apiName, 468 arrayName.get_name().c_str(), i); 469 } 470 } 471 } 472 473 return skip_call; 474 } 475 476 // Forward declarations 477 bool CheckPromotedApiAgainstVulkanVersion(VkInstance instance, const char *api_name, const uint32_t promoted_version) const; 478 bool CheckPromotedApiAgainstVulkanVersion(VkPhysicalDevice pdev, const char *api_name, const uint32_t promoted_version) const; 479 bool SupportedByPdev(const VkPhysicalDevice physical_device, const std::string ext_name) const; 480 481 bool ValidatePnextStructContents(const char *api_name, const ParameterName ¶meter_name, const VkBaseOutStructure *header, 482 const char *pnext_vuid) const; 483 484 /** 485 * Validate a structure's pNext member. 486 * 487 * Verify that the specified pNext value points to the head of a list of 488 * allowed extension structures. If no extension structures are allowed, 489 * verify that pNext is null. 490 * 491 * @param api_name Name of API call being validated. 492 * @param parameter_name Name of parameter being validated. 493 * @param allowed_struct_names Names of allowed structs. 494 * @param next Pointer to validate. 495 * @param allowed_type_count Total number of allowed structure types. 496 * @param allowed_types Array of structure types allowed for pNext. 497 * @param header_version Version of header defining the pNext validation rules. 498 * @return Boolean value indicating that the call should be skipped. 499 */ validate_struct_pnext(const char * api_name,const ParameterName & parameter_name,const char * allowed_struct_names,const void * next,size_t allowed_type_count,const VkStructureType * allowed_types,uint32_t header_version,const char * pnext_vuid,const char * stype_vuid)500 bool validate_struct_pnext(const char *api_name, const ParameterName ¶meter_name, const char *allowed_struct_names, 501 const void *next, size_t allowed_type_count, const VkStructureType *allowed_types, 502 uint32_t header_version, const char *pnext_vuid, const char *stype_vuid) const { 503 bool skip_call = false; 504 505 if (next != NULL) { 506 std::unordered_set<const void *> cycle_check; 507 std::unordered_set<VkStructureType, std::hash<int>> unique_stype_check; 508 509 const char *disclaimer = 510 "This error is based on the Valid Usage documentation for version %d of the Vulkan header. It is possible that " 511 "you are using a struct from a private extension or an extension that was added to a later version of the Vulkan " 512 "header, in which case the use of %s is undefined and may not work correctly with validation enabled"; 513 514 if ((allowed_type_count == 0) && (custom_stype_info.size() == 0)) { 515 std::string message = "%s: value of %s must be NULL. "; 516 message += disclaimer; 517 skip_call |= LogError(device, pnext_vuid, message.c_str(), api_name, parameter_name.get_name().c_str(), 518 header_version, parameter_name.get_name().c_str()); 519 } else { 520 const VkStructureType *start = allowed_types; 521 const VkStructureType *end = allowed_types + allowed_type_count; 522 const VkBaseOutStructure *current = reinterpret_cast<const VkBaseOutStructure *>(next); 523 524 while (current != NULL) { 525 if (((strncmp(api_name, "vkCreateInstance", strlen(api_name)) != 0) || 526 (current->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)) && 527 ((strncmp(api_name, "vkCreateDevice", strlen(api_name)) != 0) || 528 (current->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO))) { 529 std::string type_name = string_VkStructureType(current->sType); 530 if (unique_stype_check.find(current->sType) != unique_stype_check.end()) { 531 // stype_vuid will only be null if there are no listed pNext and will hit disclaimer check 532 std::string message = "%s: %s chain contains duplicate structure types: %s appears multiple times."; 533 skip_call |= LogError(device, stype_vuid, message.c_str(), api_name, parameter_name.get_name().c_str(), 534 type_name.c_str()); 535 } else { 536 unique_stype_check.insert(current->sType); 537 } 538 539 // Search custom stype list -- if sType found, skip this entirely 540 bool custom = false; 541 for (auto item : custom_stype_info) { 542 if (item.first == current->sType) { 543 custom = true; 544 break; 545 } 546 } 547 if (!custom) { 548 if (std::find(start, end, current->sType) == end) { 549 if (type_name.compare(UnsupportedStructureTypeString) == 0) { 550 std::string message = 551 "%s: %s chain includes a structure with unknown VkStructureType (%d); Allowed structures " 552 "are [%s]. "; 553 message += disclaimer; 554 skip_call |= LogError(device, pnext_vuid, message.c_str(), api_name, 555 parameter_name.get_name().c_str(), current->sType, allowed_struct_names, 556 header_version, parameter_name.get_name().c_str()); 557 } else { 558 std::string message = 559 "%s: %s chain includes a structure with unexpected VkStructureType %s; Allowed structures " 560 "are [%s]. "; 561 message += disclaimer; 562 skip_call |= LogError(device, pnext_vuid, message.c_str(), api_name, 563 parameter_name.get_name().c_str(), type_name.c_str(), 564 allowed_struct_names, header_version, parameter_name.get_name().c_str()); 565 } 566 } 567 skip_call |= ValidatePnextStructContents(api_name, parameter_name, current, pnext_vuid); 568 } 569 } 570 current = reinterpret_cast<const VkBaseOutStructure *>(current->pNext); 571 } 572 } 573 } 574 575 return skip_call; 576 } 577 578 /** 579 * Validate a VkBool32 value. 580 * 581 * Generate an error if a VkBool32 value is neither VK_TRUE nor VK_FALSE. 582 * 583 * @param apiName Name of API call being validated. 584 * @param parameterName Name of parameter being validated. 585 * @param value Boolean value to validate. 586 * @return Boolean value indicating that the call should be skipped. 587 */ validate_bool32(const char * apiName,const ParameterName & parameterName,VkBool32 value)588 bool validate_bool32(const char *apiName, const ParameterName ¶meterName, VkBool32 value) const { 589 bool skip_call = false; 590 if ((value != VK_TRUE) && (value != VK_FALSE)) { 591 skip_call |= LogError(device, kVUID_PVError_UnrecognizedValue, 592 "%s: value of %s (%d) is neither VK_TRUE nor VK_FALSE. Applications MUST not pass any other " 593 "values than VK_TRUE or VK_FALSE into a Vulkan implementation where a VkBool32 is expected.", 594 apiName, parameterName.get_name().c_str(), value); 595 } 596 return skip_call; 597 } 598 599 /** 600 * Validate a Vulkan enumeration value. 601 * 602 * Generate a warning if an enumeration token value does not fall within the core enumeration 603 * begin and end token values, and was not added to the enumeration by an extension. Extension 604 * provided enumerations use the equation specified in Appendix C.10 of the Vulkan specification, 605 * with 1,000,000,000 as the base token value. 606 * 607 * @note This function does not expect to process enumerations defining bitmask flag bits. 608 * 609 * @param apiName Name of API call being validated. 610 * @param parameterName Name of parameter being validated. 611 * @param enumName Name of the enumeration being validated. 612 * @param valid_values The list of valid values for the enumeration. 613 * @param value Enumeration value to validate. 614 * @return Boolean value indicating that the call should be skipped. 615 */ 616 template <typename T> validate_ranged_enum(const char * apiName,const ParameterName & parameterName,const char * enumName,const std::vector<T> & valid_values,T value,const char * vuid)617 bool validate_ranged_enum(const char *apiName, const ParameterName ¶meterName, const char *enumName, 618 const std::vector<T> &valid_values, T value, const char *vuid) const { 619 bool skip = false; 620 621 if (std::find(valid_values.begin(), valid_values.end(), value) == valid_values.end()) { 622 skip |= 623 LogError(device, vuid, 624 "%s: value of %s (%d) does not fall within the begin..end range of the core %s enumeration tokens and is " 625 "not an extension added token.", 626 apiName, parameterName.get_name().c_str(), value, enumName); 627 } 628 629 return skip; 630 } 631 632 /** 633 * Validate an array of Vulkan enumeration value. 634 * 635 * Process all enumeration token values in the specified array and generate a warning if a value 636 * does not fall within the core enumeration begin and end token values, and was not added to 637 * the enumeration by an extension. Extension provided enumerations use the equation specified 638 * in Appendix C.10 of the Vulkan specification, with 1,000,000,000 as the base token value. 639 * 640 * @note This function does not expect to process enumerations defining bitmask flag bits. 641 * 642 * @param apiName Name of API call being validated. 643 * @param countName Name of count parameter. 644 * @param arrayName Name of array parameter. 645 * @param enumName Name of the enumeration being validated. 646 * @param valid_values The list of valid values for the enumeration. 647 * @param count Number of enumeration values in the array. 648 * @param array Array of enumeration values to validate. 649 * @param countRequired The 'count' parameter may not be 0 when true. 650 * @param arrayRequired The 'array' parameter may not be NULL when true. 651 * @return Boolean value indicating that the call should be skipped. 652 */ 653 template <typename T> validate_ranged_enum_array(const char * apiName,const ParameterName & countName,const ParameterName & arrayName,const char * enumName,const std::vector<T> & valid_values,uint32_t count,const T * array,bool countRequired,bool arrayRequired)654 bool validate_ranged_enum_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, 655 const char *enumName, const std::vector<T> &valid_values, uint32_t count, const T *array, 656 bool countRequired, bool arrayRequired) const { 657 bool skip_call = false; 658 659 if ((count == 0) || (array == NULL)) { 660 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired, kVUIDUndefined, 661 kVUIDUndefined); 662 } else { 663 for (uint32_t i = 0; i < count; ++i) { 664 if (std::find(valid_values.begin(), valid_values.end(), array[i]) == valid_values.end()) { 665 skip_call |= LogError(device, kVUID_PVError_UnrecognizedValue, 666 "%s: value of %s[%d] (%d) does not fall within the begin..end range of the core %s " 667 "enumeration tokens and is not an extension added token", 668 apiName, arrayName.get_name().c_str(), i, array[i], enumName); 669 } 670 } 671 } 672 673 return skip_call; 674 } 675 676 /** 677 * Verify that a reserved VkFlags value is zero. 678 * 679 * Verify that the specified value is zero, to check VkFlags values that are reserved for 680 * future use. 681 * 682 * @param api_name Name of API call being validated. 683 * @param parameter_name Name of parameter being validated. 684 * @param value Value to validate. 685 * @return Boolean value indicating that the call should be skipped. 686 */ validate_reserved_flags(const char * api_name,const ParameterName & parameter_name,VkFlags value,const char * vuid)687 bool validate_reserved_flags(const char *api_name, const ParameterName ¶meter_name, VkFlags value, const char *vuid) const { 688 bool skip_call = false; 689 690 if (value != 0) { 691 skip_call |= LogError(device, vuid, "%s: parameter %s must be 0.", api_name, parameter_name.get_name().c_str()); 692 } 693 694 return skip_call; 695 } 696 697 enum FlagType { kRequiredFlags, kOptionalFlags, kRequiredSingleBit, kOptionalSingleBit }; 698 699 /** 700 * Validate a Vulkan bitmask value. 701 * 702 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits 703 * for that type. 704 * 705 * @param api_name Name of API call being validated. 706 * @param parameter_name Name of parameter being validated. 707 * @param flag_bits_name Name of the VkFlags type being validated. 708 * @param all_flags A bit mask combining all valid flag bits for the VkFlags type being validated. 709 * @param value VkFlags value to validate. 710 * @param flag_type The type of flag, like optional, or single bit. 711 * @param vuid VUID used for flag that is outside defined bits (or has more than one bit for Bits type). 712 * @param flags_zero_vuid VUID used for non-optional Flags that are zero. 713 * @return Boolean value indicating that the call should be skipped. 714 */ 715 bool validate_flags(const char *api_name, const ParameterName ¶meter_name, const char *flag_bits_name, VkFlags all_flags, 716 VkFlags value, const FlagType flag_type, const char *vuid, const char *flags_zero_vuid = nullptr) const { 717 bool skip_call = false; 718 719 if ((value & ~all_flags) != 0) { 720 skip_call |= LogError(device, vuid, "%s: value of %s contains flag bits that are not recognized members of %s", 721 api_name, parameter_name.get_name().c_str(), flag_bits_name); 722 } 723 724 const bool required = flag_type == kRequiredFlags || flag_type == kRequiredSingleBit; 725 const char *zero_vuid = flag_type == kRequiredFlags ? flags_zero_vuid : vuid; 726 if (required && value == 0) { 727 skip_call |= LogError(device, zero_vuid, "%s: value of %s must not be 0.", api_name, parameter_name.get_name().c_str()); 728 } 729 730 const auto HasMaxOneBitSet = [](const VkFlags f) { 731 // Decrement flips bits from right upto first 1. 732 // Rest stays same, and if there was any other 1s &ded together they would be non-zero. QED 733 return f == 0 || !(f & (f - 1)); 734 }; 735 736 const bool is_bits_type = flag_type == kRequiredSingleBit || flag_type == kOptionalSingleBit; 737 if (is_bits_type && !HasMaxOneBitSet(value)) { 738 skip_call |= 739 LogError(device, vuid, "%s: value of %s contains multiple members of %s when only a single value is allowed", 740 api_name, parameter_name.get_name().c_str(), flag_bits_name); 741 } 742 743 return skip_call; 744 } 745 746 /** 747 * Validate an array of Vulkan bitmask values. 748 * 749 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits 750 * for that type. 751 * 752 * @param api_name Name of API call being validated. 753 * @param count_name Name of parameter being validated. 754 * @param array_name Name of parameter being validated. 755 * @param flag_bits_name Name of the VkFlags type being validated. 756 * @param all_flags A bitmask combining all valid flag bits for the VkFlags type being validated. 757 * @param count Number of VkFlags values in the array. 758 * @param array Array of VkFlags value to validate. 759 * @param count_required The 'count' parameter may not be 0 when true. 760 * @param array_required The 'array' parameter may not be NULL when true. 761 * @return Boolean value indicating that the call should be skipped. 762 */ validate_flags_array(const char * api_name,const ParameterName & count_name,const ParameterName & array_name,const char * flag_bits_name,VkFlags all_flags,uint32_t count,const VkFlags * array,bool count_required,bool array_required)763 bool validate_flags_array(const char *api_name, const ParameterName &count_name, const ParameterName &array_name, 764 const char *flag_bits_name, VkFlags all_flags, uint32_t count, const VkFlags *array, 765 bool count_required, bool array_required) const { 766 bool skip_call = false; 767 768 if ((count == 0) || (array == NULL)) { 769 skip_call |= validate_array(api_name, count_name, array_name, count, &array, count_required, array_required, 770 kVUIDUndefined, kVUIDUndefined); 771 } else { 772 // Verify that all VkFlags values in the array 773 for (uint32_t i = 0; i < count; ++i) { 774 if (array[i] == 0) { 775 // Current XML registry logic for validity generation uses the array parameter's optional tag to determine if 776 // elements in the array are allowed be 0 777 if (array_required) { 778 skip_call |= LogError(device, kVUID_PVError_RequiredParameter, "%s: value of %s[%d] must not be 0", 779 api_name, array_name.get_name().c_str(), i); 780 } 781 } else if ((array[i] & (~all_flags)) != 0) { 782 skip_call |= LogError(device, kVUID_PVError_UnrecognizedValue, 783 "%s: value of %s[%d] contains flag bits that are not recognized members of %s", api_name, 784 array_name.get_name().c_str(), i, flag_bits_name); 785 } 786 } 787 } 788 789 return skip_call; 790 } 791 792 template <typename ExtensionState> validate_extension_reqs(const ExtensionState & extensions,const char * vuid,const char * extension_type,const char * extension_name)793 bool validate_extension_reqs(const ExtensionState &extensions, const char *vuid, const char *extension_type, 794 const char *extension_name) const { 795 bool skip = false; 796 if (!extension_name) { 797 return skip; // Robust to invalid char * 798 } 799 auto info = ExtensionState::get_info(extension_name); 800 801 if (!info.state) { 802 return skip; // Unknown extensions cannot be checked so report OK 803 } 804 805 // Check against the required list in the info 806 std::vector<const char *> missing; 807 for (const auto &req : info.requirements) { 808 if (!(extensions.*(req.enabled))) { 809 missing.push_back(req.name); 810 } 811 } 812 813 // Report any missing requirements 814 if (missing.size()) { 815 std::string missing_joined_list = string_join(", ", missing); 816 skip |= LogError(instance, vuid, "Missing extension%s required by the %s extension %s: %s.", 817 ((missing.size() > 1) ? "s" : ""), extension_type, extension_name, missing_joined_list.c_str()); 818 } 819 return skip; 820 } 821 822 enum RenderPassCreateVersion { RENDER_PASS_VERSION_1 = 0, RENDER_PASS_VERSION_2 = 1 }; 823 824 template <typename RenderPassCreateInfoGeneric> ValidateSubpassGraphicsFlags(const debug_report_data * report_data,const RenderPassCreateInfoGeneric * pCreateInfo,uint32_t dependency_index,uint32_t subpass,VkPipelineStageFlags stages,const char * vuid,const char * target,const char * func_name)825 bool ValidateSubpassGraphicsFlags(const debug_report_data *report_data, const RenderPassCreateInfoGeneric *pCreateInfo, 826 uint32_t dependency_index, uint32_t subpass, VkPipelineStageFlags stages, const char *vuid, 827 const char *target, const char *func_name) const { 828 const VkPipelineStageFlags kCommonStages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 829 const VkPipelineStageFlags kFramebufferStages = 830 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | 831 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 832 const VkPipelineStageFlags kPrimitiveShadingPipelineStages = 833 kCommonStages | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | 834 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 835 VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 836 VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT | VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV | kFramebufferStages; 837 const VkPipelineStageFlags kMeshShadingPipelineStages = 838 kCommonStages | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV | 839 VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV | kFramebufferStages; 840 const VkPipelineStageFlags kFragmentDensityStages = VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT; 841 const VkPipelineStageFlags kConditionalRenderingStages = VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT; 842 const VkPipelineStageFlags kCommandProcessingPipelineStages = kCommonStages | VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV; 843 844 const VkPipelineStageFlags kGraphicsStages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | kPrimitiveShadingPipelineStages | 845 kMeshShadingPipelineStages | kFragmentDensityStages | 846 kConditionalRenderingStages | kCommandProcessingPipelineStages; 847 848 bool skip = false; 849 850 const auto IsPipeline = [pCreateInfo](uint32_t subpass, const VkPipelineBindPoint stage) { 851 if (subpass == VK_SUBPASS_EXTERNAL) 852 return false; 853 else 854 return pCreateInfo->pSubpasses[subpass].pipelineBindPoint == stage; 855 }; 856 857 const bool is_all_graphics_stages = (stages & ~kGraphicsStages) == 0; 858 if (IsPipeline(subpass, VK_PIPELINE_BIND_POINT_GRAPHICS) && !is_all_graphics_stages) { 859 skip |= LogError(VkRenderPass(0), vuid, 860 "%s: Dependency pDependencies[%" PRIu32 861 "] specifies a %sStageMask that contains stages (%s) that are not part " 862 "of the Graphics pipeline, as specified by the %sSubpass (= %" PRIu32 ") in pipelineBindPoint.", 863 func_name, dependency_index, target, string_VkPipelineStageFlags(stages & ~kGraphicsStages).c_str(), 864 target, subpass); 865 } 866 867 return skip; 868 }; 869 870 template <typename RenderPassCreateInfoGeneric> CreateRenderPassGeneric(VkDevice device,const RenderPassCreateInfoGeneric * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass,RenderPassCreateVersion rp_version)871 bool CreateRenderPassGeneric(VkDevice device, const RenderPassCreateInfoGeneric *pCreateInfo, 872 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, 873 RenderPassCreateVersion rp_version) const { 874 bool skip = false; 875 uint32_t max_color_attachments = device_limits.maxColorAttachments; 876 bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); 877 const char *func_name = (use_rp2) ? "vkCreateRenderPass2" : "vkCreateRenderPass"; 878 const char *vuid; 879 VkBool32 separate_depth_stencil_layouts = false; 880 const auto *vulkan_12_features = lvl_find_in_chain<VkPhysicalDeviceVulkan12Features>(device_createinfo_pnext); 881 if (vulkan_12_features) { 882 separate_depth_stencil_layouts = vulkan_12_features->separateDepthStencilLayouts; 883 } else { 884 const auto *separate_depth_stencil_layouts_features = 885 lvl_find_in_chain<VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR>(device_createinfo_pnext); 886 if (separate_depth_stencil_layouts_features) 887 separate_depth_stencil_layouts = separate_depth_stencil_layouts_features->separateDepthStencilLayouts; 888 } 889 890 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 891 const auto *attachment_description_stencil_layout = 892 (use_rp2) ? lvl_find_in_chain<VkAttachmentDescriptionStencilLayoutKHR>( 893 reinterpret_cast<VkAttachmentDescription2KHR const *>(&pCreateInfo->pAttachments[i])->pNext) 894 : 0; 895 896 const VkFormat attachment_format = pCreateInfo->pAttachments[i].format; 897 const VkImageLayout initial_layout = pCreateInfo->pAttachments[i].initialLayout; 898 const VkImageLayout final_layout = pCreateInfo->pAttachments[i].finalLayout; 899 if (attachment_format == VK_FORMAT_UNDEFINED) { 900 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-parameter" : "VUID-VkAttachmentDescription-format-parameter"; 901 skip |= LogWarning(device, vuid, "%s: pCreateInfo->pAttachments[%u].format is VK_FORMAT_UNDEFINED.", func_name, i); 902 } 903 if (final_layout == VK_IMAGE_LAYOUT_UNDEFINED || final_layout == VK_IMAGE_LAYOUT_PREINITIALIZED) { 904 vuid = 905 use_rp2 ? "VUID-VkAttachmentDescription2-finalLayout-03061" : "VUID-VkAttachmentDescription-finalLayout-00843"; 906 skip |= LogError(device, vuid, 907 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or " 908 "VK_IMAGE_LAYOUT_PREINITIALIZED.", 909 func_name, i); 910 } 911 if (!separate_depth_stencil_layouts) { 912 if (pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 913 pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 914 pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 915 pCreateInfo->pAttachments[i].initialLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 916 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03298" 917 : "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03284"; 918 skip |= LogError( 919 device, vuid, 920 "%s: pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, " 921 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or " 922 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR", 923 func_name, i); 924 } 925 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 926 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 927 final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 928 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 929 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-separateDepthStencilLayouts-03299" 930 : "VUID-VkAttachmentDescription-separateDepthStencilLayouts-03285"; 931 skip |= LogError( 932 device, vuid, 933 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, " 934 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or " 935 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR", 936 func_name, i); 937 } 938 } 939 if (!FormatIsDepthOrStencil(attachment_format)) { 940 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 941 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 942 initial_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 943 initial_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 944 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03300" : "VUID-VkAttachmentDescription-format-03286"; 945 skip |= LogError( 946 device, vuid, 947 "%s: pCreateInfo->pAttachments[%d].initialLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, " 948 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or " 949 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMA_KHRL", 950 func_name, i); 951 } 952 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 953 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 954 final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 955 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 956 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03301" : "VUID-VkAttachmentDescription-format-03287"; 957 skip |= LogError( 958 device, vuid, 959 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, " 960 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or " 961 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR", 962 func_name, i); 963 } 964 } else if (FormatIsDepthAndStencil(attachment_format)) { 965 if (use_rp2) { 966 if (!attachment_description_stencil_layout) { 967 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 968 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) { 969 skip |= LogError( 970 device, "VUID-VkAttachmentDescription2-format-03302", 971 "%s: pCreateInfo->pNext must include an instance of VkAttachmentDescriptionStencilLayoutKHR", 972 func_name); 973 } 974 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 975 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) { 976 skip |= LogError( 977 device, "VUID-VkAttachmentDescription2-format-03303", 978 "%s: pCreateInfo->pNext must include an instance of VkAttachmentDescriptionStencilLayoutKHR", 979 func_name); 980 } 981 } 982 } else { 983 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 984 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 985 initial_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 986 initial_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 987 skip |= LogError( 988 device, "VUID-VkAttachmentDescription-format-03288", 989 "%s: pCreateInfo->pAttachments[%d].initialLayout must not be " 990 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, " 991 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or " 992 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR", 993 func_name, i); 994 } 995 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 996 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 997 final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 998 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 999 skip |= LogError( 1000 device, "VUID-VkAttachmentDescription-format-03289", 1001 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be " 1002 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, " 1003 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or " 1004 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR", 1005 func_name, i); 1006 } 1007 } 1008 } else if (FormatIsDepthOnly(attachment_format)) { 1009 if (initial_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 1010 initial_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 1011 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03304" : "VUID-VkAttachmentDescription-format-03290"; 1012 skip |= LogError(device, vuid, 1013 "%s: pCreateInfo->pAttachments[%d].initialLayout must not be " 1014 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, or" 1015 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR", 1016 func_name, i); 1017 } 1018 if (final_layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR || 1019 final_layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR) { 1020 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03305" : "VUID-VkAttachmentDescription-format-03291"; 1021 skip |= LogError(device, vuid, 1022 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be " 1023 "VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR, or " 1024 "VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR", 1025 func_name, i); 1026 } 1027 } else if (FormatIsStencilOnly(attachment_format)) { 1028 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 1029 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) { 1030 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03306" : "VUID-VkAttachmentDescription-format-03292"; 1031 skip |= LogError(device, vuid, 1032 "%s: pCreateInfo->pAttachments[%d].initialLayout must not be " 1033 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, or" 1034 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR", 1035 func_name, i); 1036 } 1037 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 1038 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR) { 1039 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03307" : "VUID-VkAttachmentDescription-format-03293"; 1040 skip |= LogError(device, vuid, 1041 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be " 1042 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, or " 1043 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMA_KHRL", 1044 func_name, i); 1045 } 1046 } 1047 if (use_rp2 && attachment_description_stencil_layout) { 1048 if (attachment_description_stencil_layout->stencilInitialLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || 1049 attachment_description_stencil_layout->stencilInitialLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 1050 attachment_description_stencil_layout->stencilInitialLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 1051 attachment_description_stencil_layout->stencilInitialLayout == 1052 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || 1053 attachment_description_stencil_layout->stencilInitialLayout == 1054 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL || 1055 attachment_description_stencil_layout->stencilInitialLayout == 1056 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL || 1057 attachment_description_stencil_layout->stencilInitialLayout == 1058 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) { 1059 skip |= LogError(device, "VUID-VkAttachmentDescriptionStencilLayout-stencilInitialLayout-03308", 1060 "%s: VkAttachmentDescriptionStencilLayoutKHR.stencilInitialLayout must not be " 1061 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, " 1062 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, " 1063 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " 1064 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, " 1065 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or " 1066 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL.", 1067 func_name); 1068 } 1069 if (attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL || 1070 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR || 1071 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR || 1072 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || 1073 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL || 1074 attachment_description_stencil_layout->stencilFinalLayout == 1075 VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL || 1076 attachment_description_stencil_layout->stencilFinalLayout == 1077 VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) { 1078 skip |= LogError(device, "VUID-VkAttachmentDescriptionStencilLayout-stencilFinalLayout-03309", 1079 "%s: VkAttachmentDescriptionStencilLayoutKHR.stencilFinalLayout must not be " 1080 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, " 1081 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR, " 1082 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " 1083 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, " 1084 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or " 1085 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL.", 1086 func_name); 1087 } 1088 if (attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_UNDEFINED || 1089 attachment_description_stencil_layout->stencilFinalLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) { 1090 skip |= LogError( 1091 device, "VUID-VkAttachmentDescriptionStencilLayout-stencilFinalLayout-03310", 1092 "%s: VkAttachmentDescriptionStencilLayoutKHR.stencilFinalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED, or " 1093 "VK_IMAGE_LAYOUT_PREINITIALIZED.", 1094 func_name); 1095 } 1096 } 1097 1098 if (FormatIsDepthOrStencil(attachment_format)) { 1099 if (initial_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { 1100 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03295" : "VUID-VkAttachmentDescription-format-03281"; 1101 skip |= LogError(device, vuid, 1102 "%s: pCreateInfo->pAttachments[%d].initialLayout must not be " 1103 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when using a Depth or Stencil format", 1104 func_name, i); 1105 } 1106 if (final_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { 1107 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03297" : "VUID-VkAttachmentDescription-format-03283"; 1108 skip |= LogError(device, vuid, 1109 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be " 1110 "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL when using a Depth or Stencil format", 1111 func_name, i); 1112 } 1113 } 1114 if (FormatIsColor(attachment_format)) { 1115 if (initial_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || 1116 initial_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL || 1117 initial_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL || 1118 initial_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) { 1119 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03294" : "VUID-VkAttachmentDescription-format-03280"; 1120 skip |= LogError(device, vuid, 1121 "%s: pCreateInfo->pAttachments[%d].initialLayout must not be " 1122 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " 1123 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, " 1124 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or " 1125 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL when using a Color format", 1126 func_name, i); 1127 } 1128 if (final_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || 1129 final_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL || 1130 final_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL || 1131 final_layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL) { 1132 vuid = use_rp2 ? "VUID-VkAttachmentDescription2-format-03296" : "VUID-VkAttachmentDescription-format-03282"; 1133 skip |= LogError(device, vuid, 1134 "%s: pCreateInfo->pAttachments[%d].finalLayout must not be " 1135 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, " 1136 "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, " 1137 "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, or " 1138 "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL when using a Color format", 1139 func_name, i); 1140 } 1141 } 1142 } 1143 1144 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 1145 if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) { 1146 vuid = use_rp2 ? "VUID-VkSubpassDescription2-colorAttachmentCount-03063" 1147 : "VUID-VkSubpassDescription-colorAttachmentCount-00845"; 1148 skip |= 1149 LogError(device, vuid, 1150 "%s: Cannot create a render pass with %d color attachments in pCreateInfo->pSubpasses[%u]. Max is %d.", 1151 func_name, pCreateInfo->pSubpasses[i].colorAttachmentCount, i, max_color_attachments); 1152 } 1153 } 1154 1155 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { 1156 const auto &dependency = pCreateInfo->pDependencies[i]; 1157 1158 // Need to check first so layer doesn't segfault from out of bound array access 1159 // src subpass bound check 1160 if ((dependency.srcSubpass != VK_SUBPASS_EXTERNAL) && (dependency.srcSubpass >= pCreateInfo->subpassCount)) { 1161 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-srcSubpass-02526" : "VUID-VkRenderPassCreateInfo-srcSubpass-02517"; 1162 skip |= LogError(device, vuid, 1163 "%s: pCreateInfo->pDependencies[%u].srcSubpass index (%u) has to be less than subpassCount (%u)", 1164 func_name, i, dependency.srcSubpass, pCreateInfo->subpassCount); 1165 } 1166 1167 // dst subpass bound check 1168 if ((dependency.dstSubpass != VK_SUBPASS_EXTERNAL) && (dependency.dstSubpass >= pCreateInfo->subpassCount)) { 1169 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-dstSubpass-02527" : "VUID-VkRenderPassCreateInfo-dstSubpass-02518"; 1170 skip |= LogError(device, vuid, 1171 "%s: pCreateInfo->pDependencies[%u].dstSubpass index (%u) has to be less than subpassCount (%u)", 1172 func_name, i, dependency.dstSubpass, pCreateInfo->subpassCount); 1173 } 1174 1175 // Spec currently only supports Graphics pipeline in render pass -- so only that pipeline is currently checked 1176 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-pDependencies-03054" : "VUID-VkRenderPassCreateInfo-pDependencies-00837"; 1177 skip |= ValidateSubpassGraphicsFlags(report_data, pCreateInfo, i, dependency.srcSubpass, dependency.srcStageMask, vuid, 1178 "src", func_name); 1179 1180 vuid = use_rp2 ? "VUID-VkRenderPassCreateInfo2-pDependencies-03055" : "VUID-VkRenderPassCreateInfo-pDependencies-00838"; 1181 skip |= ValidateSubpassGraphicsFlags(report_data, pCreateInfo, i, dependency.dstSubpass, dependency.dstStageMask, vuid, 1182 "dst", func_name); 1183 } 1184 1185 return skip; 1186 } 1187 1188 template <typename T> RecordRenderPass(VkRenderPass renderPass,const T * pCreateInfo)1189 void RecordRenderPass(VkRenderPass renderPass, const T *pCreateInfo) { 1190 std::unique_lock<std::mutex> lock(renderpass_map_mutex); 1191 auto &renderpass_state = renderpasses_states[renderPass]; 1192 lock.unlock(); 1193 1194 for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) { 1195 bool uses_color = false; 1196 for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i) 1197 if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true; 1198 1199 bool uses_depthstencil = false; 1200 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment) 1201 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) 1202 uses_depthstencil = true; 1203 1204 if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass); 1205 if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass); 1206 } 1207 } 1208 1209 bool require_device_extension(bool flag, char const *function_name, char const *extension_name) const; 1210 1211 bool validate_instance_extensions(const VkInstanceCreateInfo *pCreateInfo) const; 1212 1213 bool validate_validation_features(const VkInstanceCreateInfo *pCreateInfo, 1214 const VkValidationFeaturesEXT *validation_features) const; 1215 1216 bool validate_api_version(uint32_t api_version, uint32_t effective_api_version) const; 1217 1218 bool validate_string(const char *apiName, const ParameterName &stringName, const std::string &vuid, 1219 const char *validateString) const; 1220 1221 bool ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV *order) const; 1222 1223 bool ValidateQueueFamilies(uint32_t queue_family_count, const uint32_t *queue_families, const char *cmd_name, 1224 const char *array_parameter_name, const std::string &unique_error_code, 1225 const std::string &valid_error_code, bool optional); 1226 1227 bool ValidateDeviceQueueFamily(uint32_t queue_family, const char *cmd_name, const char *parameter_name, 1228 const std::string &error_code, bool optional); 1229 1230 bool ValidateGeometryTrianglesNV(const VkGeometryTrianglesNV &triangles, VkAccelerationStructureNV object_handle, 1231 const char *func_name) const; 1232 bool ValidateGeometryAABBNV(const VkGeometryAABBNV &geometry, VkAccelerationStructureNV object_handle, 1233 const char *func_name) const; 1234 bool ValidateGeometryNV(const VkGeometryNV &geometry, VkAccelerationStructureNV object_handle, const char *func_name) const; 1235 bool ValidateAccelerationStructureInfoNV(const VkAccelerationStructureInfoNV &info, VkAccelerationStructureNV object_handle, 1236 const char *func_nam, bool is_cmd) const; 1237 bool ValidateCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 1238 const VkAllocationCallbacks *pAllocator, VkSamplerYcbcrConversion *pYcbcrConversion, 1239 const char *apiName) const; 1240 bool ValidateCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkDeviceSize offset, VkDeviceSize countBufferOffset, 1241 bool khr) const; 1242 bool ValidateCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkDeviceSize offset, VkDeviceSize countBufferOffset, 1243 bool khr) const; 1244 1245 bool OutputExtensionError(const std::string &api_name, const std::string &extension_name) const; 1246 1247 void PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 1248 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, VkResult result); 1249 void PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, 1250 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, VkResult result); 1251 void PostCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator); 1252 void PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 1253 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result); 1254 1255 void PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 1256 VkInstance *pInstance, VkResult result); 1257 1258 void PreCallRecordDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator); 1259 1260 bool manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, 1261 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) const; 1262 1263 bool manual_PreCallValidateCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 1264 VkInstance *pInstance) const; 1265 1266 bool manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 1267 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) const; 1268 1269 bool manual_PreCallValidateCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, 1270 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) const; 1271 1272 bool manual_PreCallValidateCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, 1273 const VkAllocationCallbacks *pAllocator, VkImage *pImage) const; 1274 1275 bool manual_PreCallValidateCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, 1276 const VkAllocationCallbacks *pAllocator, VkImageView *pView) const; 1277 1278 bool manual_PreCallValidateViewport(const VkViewport &viewport, const char *fn_name, const ParameterName ¶meter_name, 1279 VkCommandBuffer object) const; 1280 1281 bool manual_PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, 1282 const VkGraphicsPipelineCreateInfo *pCreateInfos, 1283 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const; 1284 bool manual_PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, 1285 const VkComputePipelineCreateInfo *pCreateInfos, 1286 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const; 1287 1288 bool manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, 1289 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) const; 1290 bool manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 1291 const VkAllocationCallbacks *pAllocator, 1292 VkDescriptorSetLayout *pSetLayout) const; 1293 1294 bool validate_WriteDescriptorSet(const char *vkCallingFunction, const uint32_t descriptorWriteCount, 1295 const VkWriteDescriptorSet *pDescriptorWrites, const bool validateDstSet = true) const; 1296 bool manual_PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, 1297 const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 1298 const VkCopyDescriptorSet *pDescriptorCopies) const; 1299 1300 bool manual_PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, 1301 const VkDescriptorSet *pDescriptorSets) const; 1302 1303 bool manual_PreCallValidateCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 1304 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const; 1305 1306 bool manual_PreCallValidateCreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo, 1307 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const; 1308 1309 bool manual_PreCallValidateCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, 1310 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) const; 1311 1312 bool manual_PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, 1313 const VkCommandBuffer *pCommandBuffers) const; 1314 1315 bool manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) const; 1316 1317 bool manual_PreCallValidateCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, 1318 const VkViewport *pViewports) const; 1319 1320 bool manual_PreCallValidateCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, 1321 const VkRect2D *pScissors) const; 1322 bool manual_PreCallValidateCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) const; 1323 1324 bool manual_PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, 1325 uint32_t stride) const; 1326 1327 bool manual_PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1328 uint32_t count, uint32_t stride) const; 1329 1330 bool manual_PreCallValidateCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1331 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, 1332 uint32_t stride) const; 1333 1334 bool manual_PreCallValidateCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1335 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, 1336 uint32_t stride) const; 1337 1338 bool manual_PreCallValidateCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1339 VkBuffer countBuffer, VkDeviceSize countBufferOffset, 1340 uint32_t maxDrawCount, uint32_t stride) const; 1341 1342 bool manual_PreCallValidateCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1343 VkBuffer countBuffer, VkDeviceSize countBufferOffset, 1344 uint32_t maxDrawCount, uint32_t stride) const; 1345 1346 bool manual_PreCallValidateCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, 1347 const VkClearAttachment *pAttachments, uint32_t rectCount, 1348 const VkClearRect *pRects) const; 1349 1350 bool ValidateGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, 1351 const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 1352 VkImageFormatProperties2 *pImageFormatProperties, 1353 const char *apiName) const; 1354 bool manual_PreCallValidateGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, 1355 const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 1356 VkImageFormatProperties2 *pImageFormatProperties) const; 1357 bool manual_PreCallValidateGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, 1358 const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 1359 VkImageFormatProperties2 *pImageFormatProperties) const; 1360 1361 bool manual_PreCallValidateCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, 1362 uint32_t regionCount, const VkBufferCopy *pRegions) const; 1363 1364 bool manual_PreCallValidateCmdCopyBuffer2KHR(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR *pCopyBufferInfo) const; 1365 1366 bool manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 1367 VkDeviceSize dataSize, const void *pData) const; 1368 1369 bool manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 1370 VkDeviceSize size, uint32_t data) const; 1371 1372 bool manual_PreCallValidateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, 1373 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) const; 1374 bool manual_PreCallValidateQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) const; 1375 1376 #ifdef VK_USE_PLATFORM_WIN32_KHR 1377 bool manual_PreCallValidateCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 1378 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) const; 1379 #endif // VK_USE_PLATFORM_WIN32_KHR 1380 1381 bool manual_PreCallValidateCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, 1382 const VkAllocationCallbacks *pAllocator, 1383 VkDescriptorPool *pDescriptorPool) const; 1384 bool manual_PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, 1385 uint32_t groupCountZ) const; 1386 1387 bool manual_PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) const; 1388 1389 bool manual_PreCallValidateCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, 1390 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, 1391 uint32_t groupCountZ) const; 1392 bool manual_PreCallValidateCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 1393 VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, 1394 const VkWriteDescriptorSet *pDescriptorWrites) const; 1395 bool manual_PreCallValidateCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, 1396 uint32_t exclusiveScissorCount, const VkRect2D *pExclusiveScissors) const; 1397 bool manual_PreCallValidateCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, 1398 uint32_t viewportCount, 1399 const VkShadingRatePaletteNV *pShadingRatePalettes) const; 1400 1401 bool manual_PreCallValidateCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, 1402 uint32_t customSampleOrderCount, 1403 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) const; 1404 1405 bool manual_PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) const; 1406 bool manual_PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1407 uint32_t drawCount, uint32_t stride) const; 1408 1409 bool manual_PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1410 VkBuffer countBuffer, VkDeviceSize countBufferOffset, 1411 uint32_t maxDrawCount, uint32_t stride) const; 1412 1413 bool manual_PreCallValidateEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, 1414 uint32_t *pPropertyCount, 1415 VkExtensionProperties *pProperties) const; 1416 bool manual_PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, 1417 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) const; 1418 1419 bool manual_PreCallValidateCreateAccelerationStructureNV(VkDevice device, 1420 const VkAccelerationStructureCreateInfoNV *pCreateInfo, 1421 const VkAllocationCallbacks *pAllocator, 1422 VkAccelerationStructureNV *pAccelerationStructure) const; 1423 bool manual_PreCallValidateCreateAccelerationStructureKHR(VkDevice device, 1424 const VkAccelerationStructureCreateInfoKHR *pCreateInfo, 1425 const VkAllocationCallbacks *pAllocator, 1426 VkAccelerationStructureKHR *pAccelerationStructure) const; 1427 bool manual_PreCallValidateCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer, 1428 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData, 1429 VkDeviceSize instanceOffset, VkBool32 update, 1430 VkAccelerationStructureNV dst, VkAccelerationStructureNV src, 1431 VkBuffer scratch, VkDeviceSize scratchOffset) const; 1432 bool manual_PreCallValidateGetAccelerationStructureHandleNV(VkDevice device, VkAccelerationStructureNV accelerationStructure, 1433 size_t dataSize, void *pData) const; 1434 bool manual_PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, 1435 const VkRayTracingPipelineCreateInfoNV *pCreateInfos, 1436 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const; 1437 bool manual_PreCallValidateCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache, 1438 uint32_t createInfoCount, 1439 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos, 1440 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) const; 1441 bool manual_PreCallValidateCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, 1442 uint32_t viewportCount, 1443 const VkViewportWScalingNV *pViewportWScalings) const; 1444 1445 #ifdef VK_USE_PLATFORM_WIN32_KHR 1446 bool PreCallValidateGetDeviceGroupSurfacePresentModes2EXT(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 1447 VkDeviceGroupPresentModeFlagsKHR *pModes) const; 1448 #endif // VK_USE_PLATFORM_WIN32_KHR 1449 1450 bool manual_PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo, 1451 const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) const; 1452 1453 bool manual_PreCallValidateCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, 1454 uint16_t lineStipplePattern) const; 1455 1456 bool manual_PreCallValidateCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1457 VkIndexType indexType) const; 1458 bool manual_PreCallValidateCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, 1459 const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) const; 1460 1461 bool manual_PreCallValidateSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) const; 1462 1463 bool manual_PreCallValidateSetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) const; 1464 1465 bool manual_PreCallValidateAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 1466 VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) const; 1467 1468 bool manual_PreCallValidateAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR *pAcquireInfo, 1469 uint32_t *pImageIndex) const; 1470 1471 bool manual_PreCallValidateCmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer, uint32_t firstBinding, 1472 uint32_t bindingCount, const VkBuffer *pBuffers, 1473 const VkDeviceSize *pOffsets, const VkDeviceSize *pSizes) const; 1474 1475 bool manual_PreCallValidateCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, 1476 uint32_t counterBufferCount, const VkBuffer *pCounterBuffers, 1477 const VkDeviceSize *pCounterBufferOffsets) const; 1478 1479 bool manual_PreCallValidateCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, 1480 uint32_t counterBufferCount, const VkBuffer *pCounterBuffers, 1481 const VkDeviceSize *pCounterBufferOffsets) const; 1482 1483 bool manual_PreCallValidateCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount, 1484 uint32_t firstInstance, VkBuffer counterBuffer, 1485 VkDeviceSize counterBufferOffset, uint32_t counterOffset, 1486 uint32_t vertexStride) const; 1487 1488 bool manual_PreCallValidateCreateSamplerYcbcrConversion(VkDevice device, const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 1489 const VkAllocationCallbacks *pAllocator, 1490 VkSamplerYcbcrConversion *pYcbcrConversion) const; 1491 bool manual_PreCallValidateCreateSamplerYcbcrConversionKHR(VkDevice device, 1492 const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 1493 const VkAllocationCallbacks *pAllocator, 1494 VkSamplerYcbcrConversion *pYcbcrConversion) const; 1495 bool manual_PreCallValidateImportSemaphoreFdKHR(VkDevice device, 1496 const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) const; 1497 1498 bool manual_PreCallValidateCopyAccelerationStructureToMemoryKHR(VkDevice device, 1499 const VkCopyAccelerationStructureToMemoryInfoKHR *pInfo) const; 1500 1501 bool manual_PreCallValidateCmdCopyAccelerationStructureToMemoryKHR( 1502 VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureToMemoryInfoKHR *pInfo) const; 1503 1504 bool manual_PreCallValidateCopyAccelerationStructureKHR(VkDevice device, const VkCopyAccelerationStructureInfoKHR *pInfo) const; 1505 1506 bool manual_PreCallValidateCmdCopyAccelerationStructureKHR(VkCommandBuffer commandBuffer, 1507 const VkCopyAccelerationStructureInfoKHR *pInfo) const; 1508 bool ValidateCopyAccelerationStructureInfoKHR(const VkCopyAccelerationStructureInfoKHR *pInfo, const char *api_name) const; 1509 bool ValidateCopyMemoryToAccelerationStructureInfoKHR(const VkCopyMemoryToAccelerationStructureInfoKHR *pInfo, 1510 const char *api_name, bool is_cmd = false) const; 1511 1512 bool manual_PreCallValidateCopyMemoryToAccelerationStructureKHR(VkDevice device, 1513 const VkCopyMemoryToAccelerationStructureInfoKHR *pInfo) const; 1514 bool manual_PreCallValidateCmdCopyMemoryToAccelerationStructureKHR( 1515 VkCommandBuffer commandBuffer, const VkCopyMemoryToAccelerationStructureInfoKHR *pInfo) const; 1516 1517 bool manual_PreCallValidateCmdWriteAccelerationStructuresPropertiesKHR( 1518 VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, 1519 const VkAccelerationStructureKHR *pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, 1520 uint32_t firstQuery) const; 1521 bool manual_PreCallValidateWriteAccelerationStructuresPropertiesKHR(VkDevice device, uint32_t accelerationStructureCount, 1522 const VkAccelerationStructureKHR *pAccelerationStructures, 1523 VkQueryType queryType, size_t dataSize, void *pData, 1524 size_t stride) const; 1525 bool manual_PreCallValidateGetRayTracingCaptureReplayShaderGroupHandlesKHR(VkDevice device, VkPipeline pipeline, 1526 uint32_t firstGroup, uint32_t groupCount, 1527 size_t dataSize, void *pData) const; 1528 1529 bool manual_PreCallValidateCmdTraceRaysKHR(VkCommandBuffer commandBuffer, 1530 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable, 1531 const VkStridedBufferRegionKHR *pMissShaderBindingTable, 1532 const VkStridedBufferRegionKHR *pHitShaderBindingTable, 1533 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width, 1534 uint32_t height, uint32_t depth) const; 1535 1536 bool manual_PreCallValidateCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer, 1537 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable, 1538 const VkStridedBufferRegionKHR *pMissShaderBindingTable, 1539 const VkStridedBufferRegionKHR *pHitShaderBindingTable, 1540 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, VkBuffer buffer, 1541 VkDeviceSize offset) const; 1542 1543 bool manual_PreCallValidateCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, 1544 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, 1545 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, 1546 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, 1547 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, 1548 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, 1549 uint32_t width, uint32_t height, uint32_t depth) const; 1550 1551 bool manual_PreCallValidateCmdBuildAccelerationStructureIndirectKHR(VkCommandBuffer commandBuffer, 1552 const VkAccelerationStructureBuildGeometryInfoKHR *pInfo, 1553 VkBuffer indirectBuffer, VkDeviceSize indirectOffset, 1554 uint32_t indirectStride) const; 1555 1556 bool manual_PreCallValidateGetDeviceAccelerationStructureCompatibilityKHR( 1557 VkDevice device, const VkAccelerationStructureVersionKHR *version) const; 1558 1559 bool manual_PreCallValidateBuildAccelerationStructureKHR( 1560 VkDevice device, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos, 1561 const VkAccelerationStructureBuildOffsetInfoKHR *const *ppOffsetInfos) const; 1562 1563 bool manual_PreCallValidateCmdBuildAccelerationStructureKHR( 1564 VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR *pInfos, 1565 const VkAccelerationStructureBuildOffsetInfoKHR *const *ppOffsetInfos) const; 1566 1567 bool manual_PreCallValidateCmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer, uint32_t viewportCount, 1568 const VkViewport *pViewports) const; 1569 bool manual_PreCallValidateCmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer, uint32_t scissorCount, 1570 const VkRect2D *pScissors) const; 1571 bool manual_PreCallValidateCmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, 1572 const VkBuffer *pBuffers, const VkDeviceSize *pOffsets, 1573 const VkDeviceSize *pSizes, const VkDeviceSize *pStrides) const; 1574 1575 #include "parameter_validation.h" 1576 }; // Class StatelessValidation 1577