1 /* Copyright (c) 2015-2019 The Khronos Group Inc. 2 * Copyright (c) 2015-2019 Valve Corporation 3 * Copyright (c) 2015-2019 LunarG, Inc. 4 * Copyright (C) 2015-2019 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 <bitset> 25 26 #include "parameter_name.h" 27 #include "vk_typemap_helper.h" 28 29 // Suppress unused warning on Linux 30 #if defined(__GNUC__) 31 #define DECORATE_UNUSED __attribute__((unused)) 32 #else 33 #define DECORATE_UNUSED 34 #endif 35 36 static const char DECORATE_UNUSED *kVUID_PVError_NONE = "UNASSIGNED-GeneralParameterError-Info"; 37 static const char DECORATE_UNUSED *kVUID_PVError_InvalidUsage = "UNASSIGNED-GeneralParameterError-InvalidUsage"; 38 static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructSType = "UNASSIGNED-GeneralParameterError-InvalidStructSType"; 39 static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructPNext = "UNASSIGNED-GeneralParameterError-InvalidStructPNext"; 40 static const char DECORATE_UNUSED *kVUID_PVError_RequiredParameter = "UNASSIGNED-GeneralParameterError-RequiredParameter"; 41 static const char DECORATE_UNUSED *kVUID_PVError_ReservedParameter = "UNASSIGNED-GeneralParameterError-ReservedParameter"; 42 static const char DECORATE_UNUSED *kVUID_PVError_UnrecognizedValue = "UNASSIGNED-GeneralParameterError-UnrecognizedValue"; 43 static const char DECORATE_UNUSED *kVUID_PVError_DeviceLimit = "UNASSIGNED-GeneralParameterError-DeviceLimit"; 44 static const char DECORATE_UNUSED *kVUID_PVError_DeviceFeature = "UNASSIGNED-GeneralParameterError-DeviceFeature"; 45 static const char DECORATE_UNUSED *kVUID_PVError_FailureCode = "UNASSIGNED-GeneralParameterError-FailureCode"; 46 static const char DECORATE_UNUSED *kVUID_PVError_ExtensionNotEnabled = "UNASSIGNED-GeneralParameterError-ExtensionNotEnabled"; 47 48 #undef DECORATE_UNUSED 49 50 extern const uint32_t GeneratedVulkanHeaderVersion; 51 52 extern const VkQueryPipelineStatisticFlags AllVkQueryPipelineStatisticFlagBits; 53 extern const VkColorComponentFlags AllVkColorComponentFlagBits; 54 extern const VkShaderStageFlags AllVkShaderStageFlagBits; 55 extern const VkQueryControlFlags AllVkQueryControlFlagBits; 56 extern const VkImageUsageFlags AllVkImageUsageFlagBits; 57 58 extern const std::vector<VkCompareOp> AllVkCompareOpEnums; 59 extern const std::vector<VkStencilOp> AllVkStencilOpEnums; 60 extern const std::vector<VkBlendFactor> AllVkBlendFactorEnums; 61 extern const std::vector<VkBlendOp> AllVkBlendOpEnums; 62 extern const std::vector<VkLogicOp> AllVkLogicOpEnums; 63 extern const std::vector<VkBorderColor> AllVkBorderColorEnums; 64 extern const std::vector<VkImageLayout> AllVkImageLayoutEnums; 65 66 struct GenericHeader { 67 VkStructureType sType; 68 const void *pNext; 69 }; 70 71 // String returned by string_VkStructureType for an unrecognized type. 72 const std::string UnsupportedStructureTypeString = "Unhandled VkStructureType"; 73 74 // String returned by string_VkResult for an unrecognized type. 75 const std::string UnsupportedResultString = "Unhandled VkResult"; 76 77 // The base value used when computing the offset for an enumeration token value that is added by an extension. 78 // When validating enumeration tokens, any value >= to this value is considered to be provided by an extension. 79 // See Appendix C.10 "Assigning Extension Token Values" from the Vulkan specification 80 const uint32_t ExtEnumBaseValue = 1000000000; 81 82 // The value of all VK_xxx_MAX_ENUM tokens 83 const uint32_t MaxEnumValue = 0x7FFFFFFF; 84 85 // Misc parameters of log_msg that are likely constant per command (or low frequency change) 86 struct LogMiscParams { 87 VkDebugReportObjectTypeEXT objectType; 88 uint64_t srcObject; 89 const char *api_name; 90 }; 91 92 class StatelessValidation : public ValidationObject { 93 public: 94 VkPhysicalDeviceLimits device_limits = {}; 95 VkPhysicalDeviceFeatures physical_device_features = {}; 96 VkDevice device = VK_NULL_HANDLE; 97 uint32_t api_version; 98 99 // Override chassis read/write locks for this validation object 100 // This override takes a deferred lock. i.e. it is not acquired. write_lock()101 std::unique_lock<std::mutex> write_lock() { return std::unique_lock<std::mutex>(validation_object_mutex, std::defer_lock); } 102 103 // Device extension properties -- storing properties gathered from VkPhysicalDeviceProperties2KHR::pNext chain 104 struct DeviceExtensionProperties { 105 VkPhysicalDeviceShadingRateImagePropertiesNV shading_rate_image_props; 106 VkPhysicalDeviceMeshShaderPropertiesNV mesh_shader_props; 107 }; 108 DeviceExtensionProperties phys_dev_ext_props = {}; 109 110 struct SubpassesUsageStates { 111 std::unordered_set<uint32_t> subpasses_using_color_attachment; 112 std::unordered_set<uint32_t> subpasses_using_depthstencil_attachment; 113 }; 114 115 // Though this validation object is predominantly statless, the Framebuffer checks are greatly simplified by creating and 116 // updating a map of the renderpass usage states, and these accesses need thread protection. Use a mutex separate from the 117 // parent object's to maintain that functionality. 118 std::mutex renderpass_map_mutex; 119 std::unordered_map<VkRenderPass, SubpassesUsageStates> renderpasses_states; 120 121 // Constructor for stateles validation tracking 122 // StatelessValidation() : {} 123 /** 124 * Validate a minimum value. 125 * 126 * Verify that the specified value is greater than the specified lower bound. 127 * 128 * @param api_name Name of API call being validated. 129 * @param parameter_name Name of parameter being validated. 130 * @param value Value to validate. 131 * @param lower_bound Lower bound value to use for validation. 132 * @return Boolean value indicating that the call should be skipped. 133 */ 134 template <typename T> ValidateGreaterThan(const T value,const T lower_bound,const ParameterName & parameter_name,const std::string & vuid,const LogMiscParams & misc)135 bool ValidateGreaterThan(const T value, const T lower_bound, const ParameterName ¶meter_name, const std::string &vuid, 136 const LogMiscParams &misc) { 137 bool skip_call = false; 138 139 if (value <= lower_bound) { 140 std::ostringstream ss; 141 ss << misc.api_name << ": parameter " << parameter_name.get_name() << " (= " << value << ") is greater than " 142 << lower_bound; 143 skip_call |= 144 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, misc.objectType, misc.srcObject, vuid, "%s", ss.str().c_str()); 145 } 146 147 return skip_call; 148 } 149 150 template <typename T> ValidateGreaterThanZero(const T value,const ParameterName & parameter_name,const std::string & vuid,const LogMiscParams & misc)151 bool ValidateGreaterThanZero(const T value, const ParameterName ¶meter_name, const std::string &vuid, 152 const LogMiscParams &misc) { 153 return ValidateGreaterThan(value, T{0}, parameter_name, vuid, misc); 154 } 155 /** 156 * Validate a required pointer. 157 * 158 * Verify that a required pointer is not NULL. 159 * 160 * @param apiName Name of API call being validated. 161 * @param parameterName Name of parameter being validated. 162 * @param value Pointer to validate. 163 * @return Boolean value indicating that the call should be skipped. 164 */ validate_required_pointer(const char * apiName,const ParameterName & parameterName,const void * value,const std::string & vuid)165 bool validate_required_pointer(const char *apiName, const ParameterName ¶meterName, const void *value, 166 const std::string &vuid) { 167 bool skip_call = false; 168 169 if (value == NULL) { 170 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 171 "%s: required parameter %s specified as NULL.", apiName, parameterName.get_name().c_str()); 172 } 173 174 return skip_call; 175 } 176 177 /** 178 * Validate array count and pointer to array. 179 * 180 * Verify that required count and array parameters are not 0 or NULL. If the 181 * count parameter is not optional, verify that it is not 0. If the array 182 * parameter is NULL, and it is not optional, verify that count is 0. 183 * 184 * @param apiName Name of API call being validated. 185 * @param countName Name of count parameter. 186 * @param arrayName Name of array parameter. 187 * @param count Number of elements in the array. 188 * @param array Array to validate. 189 * @param countRequired The 'count' parameter may not be 0 when true. 190 * @param arrayRequired The 'array' parameter may not be NULL when true. 191 * @return Boolean value indicating that the call should be skipped. 192 */ 193 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)194 bool validate_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, T1 count, 195 const T2 *array, bool countRequired, bool arrayRequired, const char *count_required_vuid, 196 const char *array_required_vuid) { 197 bool skip_call = false; 198 199 // Count parameters not tagged as optional cannot be 0 200 if (countRequired && (count == 0)) { 201 skip_call |= 202 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, count_required_vuid, 203 "%s: parameter %s must be greater than 0.", apiName, countName.get_name().c_str()); 204 } 205 206 // Array parameters not tagged as optional cannot be NULL, unless the count is 0 207 if (arrayRequired && (count != 0) && (*array == NULL)) { 208 skip_call |= 209 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, array_required_vuid, 210 "%s: required parameter %s specified as NULL.", apiName, arrayName.get_name().c_str()); 211 } 212 213 return skip_call; 214 } 215 216 /** 217 * Validate pointer to array count and pointer to array. 218 * 219 * Verify that required count and array parameters are not NULL. If count 220 * is not NULL and its value is not optional, verify that it is not 0. If the 221 * array parameter is NULL, and it is not optional, verify that count is 0. 222 * The array parameter will typically be optional for this case (where count is 223 * a pointer), allowing the caller to retrieve the available count. 224 * 225 * @param apiName Name of API call being validated. 226 * @param countName Name of count parameter. 227 * @param arrayName Name of array parameter. 228 * @param count Pointer to the number of elements in the array. 229 * @param array Array to validate. 230 * @param countPtrRequired The 'count' parameter may not be NULL when true. 231 * @param countValueRequired The '*count' value may not be 0 when true. 232 * @param arrayRequired The 'array' parameter may not be NULL when true. 233 * @return Boolean value indicating that the call should be skipped. 234 */ 235 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)236 bool validate_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, const T1 *count, 237 const T2 *array, bool countPtrRequired, bool countValueRequired, bool arrayRequired, 238 const char *count_required_vuid, const char *array_required_vuid) { 239 bool skip_call = false; 240 241 if (count == NULL) { 242 if (countPtrRequired) { 243 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 244 kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL", apiName, 245 countName.get_name().c_str()); 246 } 247 } else { 248 skip_call |= validate_array(apiName, countName, arrayName, *array ? (*count) : 0, &array, countValueRequired, 249 arrayRequired, count_required_vuid, array_required_vuid); 250 } 251 252 return skip_call; 253 } 254 255 /** 256 * Validate a pointer to a Vulkan structure. 257 * 258 * Verify that a required pointer to a structure is not NULL. If the pointer is 259 * not NULL, verify that each structure's sType field is set to the correct 260 * VkStructureType value. 261 * 262 * @param apiName Name of API call being validated. 263 * @param parameterName Name of struct parameter being validated. 264 * @param sTypeName Name of expected VkStructureType value. 265 * @param value Pointer to the struct to validate. 266 * @param sType VkStructureType for structure validation. 267 * @param required The parameter may not be NULL when true. 268 * @return Boolean value indicating that the call should be skipped. 269 */ 270 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)271 bool validate_struct_type(const char *apiName, const ParameterName ¶meterName, const char *sTypeName, const T *value, 272 VkStructureType sType, bool required, const char *struct_vuid, const char *stype_vuid) { 273 bool skip_call = false; 274 275 if (value == NULL) { 276 if (required) { 277 skip_call |= 278 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, struct_vuid, 279 "%s: required parameter %s specified as NULL", apiName, parameterName.get_name().c_str()); 280 } 281 } else if (value->sType != sType) { 282 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, stype_vuid, 283 "%s: parameter %s->sType must be %s.", apiName, parameterName.get_name().c_str(), sTypeName); 284 } 285 286 return skip_call; 287 } 288 289 /** 290 * Validate an array of Vulkan structures 291 * 292 * Verify that required count and array parameters are not 0 or NULL. If 293 * the array contains 1 or more structures, verify that each structure's 294 * sType field is set to the correct VkStructureType value. 295 * 296 * @param apiName Name of API call being validated. 297 * @param countName Name of count parameter. 298 * @param arrayName Name of array parameter. 299 * @param sTypeName Name of expected VkStructureType value. 300 * @param count Number of elements in the array. 301 * @param array Array to validate. 302 * @param sType VkStructureType for structure validation. 303 * @param countRequired The 'count' parameter may not be 0 when true. 304 * @param arrayRequired The 'array' parameter may not be NULL when true. 305 * @return Boolean value indicating that the call should be skipped. 306 */ 307 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)308 bool validate_struct_type_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, 309 const char *sTypeName, uint32_t count, const T *array, VkStructureType sType, 310 bool countRequired, bool arrayRequired, const char *stype_vuid, const char *param_vuid, 311 const char *count_required_vuid) { 312 bool skip_call = false; 313 314 if ((count == 0) || (array == NULL)) { 315 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired, 316 count_required_vuid, param_vuid); 317 } else { 318 // Verify that all structs in the array have the correct type 319 for (uint32_t i = 0; i < count; ++i) { 320 if (array[i].sType != sType) { 321 skip_call |= 322 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, stype_vuid, 323 "%s: parameter %s[%d].sType must be %s", apiName, arrayName.get_name().c_str(), i, sTypeName); 324 } 325 } 326 } 327 328 return skip_call; 329 } 330 331 /** 332 * Validate an array of Vulkan structures. 333 * 334 * Verify that required count and array parameters are not NULL. If count 335 * is not NULL and its value is not optional, verify that it is not 0. 336 * If the array contains 1 or more structures, verify that each structure's 337 * sType field is set to the correct VkStructureType value. 338 * 339 * @param apiName Name of API call being validated. 340 * @param countName Name of count parameter. 341 * @param arrayName Name of array parameter. 342 * @param sTypeName Name of expected VkStructureType value. 343 * @param count Pointer to the number of elements in the array. 344 * @param array Array to validate. 345 * @param sType VkStructureType for structure validation. 346 * @param countPtrRequired The 'count' parameter may not be NULL when true. 347 * @param countValueRequired The '*count' value may not be 0 when true. 348 * @param arrayRequired The 'array' parameter may not be NULL when true. 349 * @return Boolean value indicating that the call should be skipped. 350 */ 351 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)352 bool validate_struct_type_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, 353 const char *sTypeName, uint32_t *count, const T *array, VkStructureType sType, 354 bool countPtrRequired, bool countValueRequired, bool arrayRequired, const char *stype_vuid, 355 const char *param_vuid, const char *count_required_vuid) { 356 bool skip_call = false; 357 358 if (count == NULL) { 359 if (countPtrRequired) { 360 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 361 kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL", apiName, 362 countName.get_name().c_str()); 363 } 364 } else { 365 skip_call |= validate_struct_type_array(apiName, countName, arrayName, sTypeName, (*count), array, sType, 366 countValueRequired, arrayRequired, stype_vuid, param_vuid, count_required_vuid); 367 } 368 369 return skip_call; 370 } 371 372 /** 373 * Validate a Vulkan handle. 374 * 375 * Verify that the specified handle is not VK_NULL_HANDLE. 376 * 377 * @param api_name Name of API call being validated. 378 * @param parameter_name Name of struct parameter being validated. 379 * @param value Handle to validate. 380 * @return Boolean value indicating that the call should be skipped. 381 */ 382 template <typename T> validate_required_handle(const char * api_name,const ParameterName & parameter_name,T value)383 bool validate_required_handle(const char *api_name, const ParameterName ¶meter_name, T value) { 384 bool skip_call = false; 385 386 if (value == VK_NULL_HANDLE) { 387 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 388 kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as VK_NULL_HANDLE", api_name, 389 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) { 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 |= 429 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 430 kVUID_PVError_RequiredParameter, "%s: required parameter %s[%d] specified as VK_NULL_HANDLE", 431 api_name, array_name.get_name().c_str(), i); 432 } 433 } 434 } 435 436 return skip_call; 437 } 438 439 /** 440 * Validate string array count and content. 441 * 442 * Verify that required count and array parameters are not 0 or NULL. If the 443 * count parameter is not optional, verify that it is not 0. If the array 444 * parameter is NULL, and it is not optional, verify that count is 0. If the 445 * array parameter is not NULL, verify that none of the strings are NULL. 446 * 447 * @param apiName Name of API call being validated. 448 * @param countName Name of count parameter. 449 * @param arrayName Name of array parameter. 450 * @param count Number of strings in the array. 451 * @param array Array of strings to validate. 452 * @param countRequired The 'count' parameter may not be 0 when true. 453 * @param arrayRequired The 'array' parameter may not be NULL when true. 454 * @return Boolean value indicating that the call should be skipped. 455 */ 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)456 bool validate_string_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, uint32_t count, 457 const char *const *array, bool countRequired, bool arrayRequired, const char *count_required_vuid, 458 const char *array_required_vuid) { 459 bool skip_call = false; 460 461 if ((count == 0) || (array == NULL)) { 462 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired, 463 count_required_vuid, array_required_vuid); 464 } else { 465 // Verify that strings in the array are not NULL 466 for (uint32_t i = 0; i < count; ++i) { 467 if (array[i] == NULL) { 468 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 469 kVUID_PVError_RequiredParameter, "%s: required parameter %s[%d] specified as NULL", 470 apiName, arrayName.get_name().c_str(), i); 471 } 472 } 473 } 474 475 return skip_call; 476 } 477 478 // Forward declaration for pNext validation 479 bool ValidatePnextStructContents(const char *api_name, const ParameterName ¶meter_name, const GenericHeader *header); 480 481 /** 482 * Validate a structure's pNext member. 483 * 484 * Verify that the specified pNext value points to the head of a list of 485 * allowed extension structures. If no extension structures are allowed, 486 * verify that pNext is null. 487 * 488 * @param api_name Name of API call being validated. 489 * @param parameter_name Name of parameter being validated. 490 * @param allowed_struct_names Names of allowed structs. 491 * @param next Pointer to validate. 492 * @param allowed_type_count Total number of allowed structure types. 493 * @param allowed_types Array of structure types allowed for pNext. 494 * @param header_version Version of header defining the pNext validation rules. 495 * @return Boolean value indicating that the call should be skipped. 496 */ 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 * vuid)497 bool validate_struct_pnext(const char *api_name, const ParameterName ¶meter_name, const char *allowed_struct_names, 498 const void *next, size_t allowed_type_count, const VkStructureType *allowed_types, 499 uint32_t header_version, const char *vuid) { 500 bool skip_call = false; 501 502 // TODO: The valid pNext structure types are not recursive. Each structure has its own list of valid sTypes for pNext. 503 // Codegen a map of vectors containing the allowable pNext types for each struct and use that here -- also simplifies parms. 504 if (next != NULL) { 505 std::unordered_set<const void *> cycle_check; 506 std::unordered_set<VkStructureType, std::hash<int>> unique_stype_check; 507 508 const char *disclaimer = 509 "This warning is based on the Valid Usage documentation for version %d of the Vulkan header. It is possible that " 510 "you " 511 "are " 512 "using a struct from a private extension or an extension that was added to a later version of the Vulkan header, " 513 "in " 514 "which " 515 "case your use of %s is perfectly valid but is not guaranteed to work correctly with validation enabled"; 516 517 if (allowed_type_count == 0) { 518 std::string message = "%s: value of %s must be NULL. "; 519 message += disclaimer; 520 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 521 message.c_str(), api_name, parameter_name.get_name().c_str(), header_version, 522 parameter_name.get_name().c_str()); 523 } else { 524 const VkStructureType *start = allowed_types; 525 const VkStructureType *end = allowed_types + allowed_type_count; 526 const GenericHeader *current = reinterpret_cast<const GenericHeader *>(next); 527 528 cycle_check.insert(next); 529 530 while (current != NULL) { 531 if (((strncmp(api_name, "vkCreateInstance", strlen(api_name)) != 0) || 532 (current->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)) && 533 ((strncmp(api_name, "vkCreateDevice", strlen(api_name)) != 0) || 534 (current->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO))) { 535 if (cycle_check.find(current->pNext) != cycle_check.end()) { 536 std::string message = "%s: %s chain contains a cycle -- pNext pointer " PRIx64 " is repeated."; 537 skip_call |= 538 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 539 kVUID_PVError_InvalidStructPNext, message.c_str(), api_name, 540 parameter_name.get_name().c_str(), reinterpret_cast<uint64_t>(next)); 541 break; 542 } else { 543 cycle_check.insert(current->pNext); 544 } 545 546 std::string type_name = string_VkStructureType(current->sType); 547 if (unique_stype_check.find(current->sType) != unique_stype_check.end()) { 548 std::string message = "%s: %s chain contains duplicate structure types: %s appears multiple times."; 549 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 550 VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_PVError_InvalidStructPNext, 551 message.c_str(), api_name, parameter_name.get_name().c_str(), type_name.c_str()); 552 } else { 553 unique_stype_check.insert(current->sType); 554 } 555 556 if (std::find(start, end, current->sType) == end) { 557 if (type_name == UnsupportedStructureTypeString) { 558 std::string message = 559 "%s: %s chain includes a structure with unknown VkStructureType (%d); Allowed structures are " 560 "[%s]. "; 561 message += disclaimer; 562 skip_call |= 563 log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 564 0, vuid, message.c_str(), api_name, parameter_name.get_name().c_str(), current->sType, 565 allowed_struct_names, header_version, parameter_name.get_name().c_str()); 566 } else { 567 std::string message = 568 "%s: %s chain includes a structure with unexpected VkStructureType %s; Allowed structures are " 569 "[%s]. "; 570 message += disclaimer; 571 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 572 VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, message.c_str(), api_name, 573 parameter_name.get_name().c_str(), type_name.c_str(), allowed_struct_names, 574 header_version, parameter_name.get_name().c_str()); 575 } 576 } 577 skip_call |= ValidatePnextStructContents(api_name, parameter_name, current); 578 } 579 current = reinterpret_cast<const GenericHeader *>(current->pNext); 580 } 581 } 582 } 583 584 return skip_call; 585 } 586 587 /** 588 * Validate a VkBool32 value. 589 * 590 * Generate a warning if a VkBool32 value is neither VK_TRUE nor VK_FALSE. 591 * 592 * @param apiName Name of API call being validated. 593 * @param parameterName Name of parameter being validated. 594 * @param value Boolean value to validate. 595 * @return Boolean value indicating that the call should be skipped. 596 */ validate_bool32(const char * apiName,const ParameterName & parameterName,VkBool32 value)597 bool validate_bool32(const char *apiName, const ParameterName ¶meterName, VkBool32 value) { 598 bool skip_call = false; 599 600 if ((value != VK_TRUE) && (value != VK_FALSE)) { 601 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 602 kVUID_PVError_UnrecognizedValue, "%s: value of %s (%d) is neither VK_TRUE nor VK_FALSE", apiName, 603 parameterName.get_name().c_str(), value); 604 } 605 606 return skip_call; 607 } 608 609 /** 610 * Validate a Vulkan enumeration value. 611 * 612 * Generate a warning if an enumeration token value does not fall within the core enumeration 613 * begin and end token values, and was not added to the enumeration by an extension. Extension 614 * provided enumerations use the equation specified in Appendix C.10 of the Vulkan specification, 615 * with 1,000,000,000 as the base token value. 616 * 617 * @note This function does not expect to process enumerations defining bitmask flag bits. 618 * 619 * @param apiName Name of API call being validated. 620 * @param parameterName Name of parameter being validated. 621 * @param enumName Name of the enumeration being validated. 622 * @param valid_values The list of valid values for the enumeration. 623 * @param value Enumeration value to validate. 624 * @return Boolean value indicating that the call should be skipped. 625 */ 626 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)627 bool validate_ranged_enum(const char *apiName, const ParameterName ¶meterName, const char *enumName, 628 const std::vector<T> &valid_values, T value, const char *vuid) { 629 bool skip = false; 630 631 if (std::find(valid_values.begin(), valid_values.end(), value) == valid_values.end()) { 632 skip |= 633 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 634 "%s: value of %s (%d) does not fall within the begin..end range of the core %s enumeration tokens and is " 635 "not an extension added token.", 636 apiName, parameterName.get_name().c_str(), value, enumName); 637 } 638 639 return skip; 640 } 641 642 /** 643 * Validate an array of Vulkan enumeration value. 644 * 645 * Process all enumeration token values in the specified array and generate a warning if a value 646 * does not fall within the core enumeration begin and end token values, and was not added to 647 * the enumeration by an extension. Extension provided enumerations use the equation specified 648 * in Appendix C.10 of the Vulkan specification, with 1,000,000,000 as the base token value. 649 * 650 * @note This function does not expect to process enumerations defining bitmask flag bits. 651 * 652 * @param apiName Name of API call being validated. 653 * @param countName Name of count parameter. 654 * @param arrayName Name of array parameter. 655 * @param enumName Name of the enumeration being validated. 656 * @param valid_values The list of valid values for the enumeration. 657 * @param count Number of enumeration values in the array. 658 * @param array Array of enumeration values to validate. 659 * @param countRequired The 'count' parameter may not be 0 when true. 660 * @param arrayRequired The 'array' parameter may not be NULL when true. 661 * @return Boolean value indicating that the call should be skipped. 662 */ 663 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)664 bool validate_ranged_enum_array(const char *apiName, const ParameterName &countName, const ParameterName &arrayName, 665 const char *enumName, const std::vector<T> &valid_values, uint32_t count, const T *array, 666 bool countRequired, bool arrayRequired) { 667 bool skip_call = false; 668 669 if ((count == 0) || (array == NULL)) { 670 skip_call |= validate_array(apiName, countName, arrayName, count, &array, countRequired, arrayRequired, kVUIDUndefined, 671 kVUIDUndefined); 672 } else { 673 for (uint32_t i = 0; i < count; ++i) { 674 if (std::find(valid_values.begin(), valid_values.end(), array[i]) == valid_values.end()) { 675 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 676 kVUID_PVError_UnrecognizedValue, 677 "%s: value of %s[%d] (%d) does not fall within the begin..end range of the core %s " 678 "enumeration tokens and is not an extension added token", 679 apiName, arrayName.get_name().c_str(), i, array[i], enumName); 680 } 681 } 682 } 683 684 return skip_call; 685 } 686 687 /** 688 * Verify that a reserved VkFlags value is zero. 689 * 690 * Verify that the specified value is zero, to check VkFlags values that are reserved for 691 * future use. 692 * 693 * @param api_name Name of API call being validated. 694 * @param parameter_name Name of parameter being validated. 695 * @param value Value to validate. 696 * @return Boolean value indicating that the call should be skipped. 697 */ validate_reserved_flags(const char * api_name,const ParameterName & parameter_name,VkFlags value,const char * vuid)698 bool validate_reserved_flags(const char *api_name, const ParameterName ¶meter_name, VkFlags value, const char *vuid) { 699 bool skip_call = false; 700 701 if (value != 0) { 702 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 703 "%s: parameter %s must be 0.", api_name, parameter_name.get_name().c_str()); 704 } 705 706 return skip_call; 707 } 708 709 /** 710 * Validate a Vulkan bitmask value. 711 * 712 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits 713 * for that type. 714 * 715 * @param api_name Name of API call being validated. 716 * @param parameter_name Name of parameter being validated. 717 * @param flag_bits_name Name of the VkFlags type being validated. 718 * @param all_flags A bit mask combining all valid flag bits for the VkFlags type being validated. 719 * @param value VkFlags value to validate. 720 * @param flags_required The 'value' parameter may not be 0 when true. 721 * @param singleFlag The 'value' parameter may not contain more than one bit from all_flags. 722 * @return Boolean value indicating that the call should be skipped. 723 */ validate_flags(const char * api_name,const ParameterName & parameter_name,const char * flag_bits_name,VkFlags all_flags,VkFlags value,bool flags_required,bool singleFlag,const char * vuid)724 bool validate_flags(const char *api_name, const ParameterName ¶meter_name, const char *flag_bits_name, VkFlags all_flags, 725 VkFlags value, bool flags_required, bool singleFlag, const char *vuid) { 726 bool skip_call = false; 727 728 if (value == 0) { 729 if (flags_required) { 730 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 731 "%s: value of %s must not be 0.", api_name, parameter_name.get_name().c_str()); 732 } 733 } else if ((value & (~all_flags)) != 0) { 734 skip_call |= 735 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 736 kVUID_PVError_UnrecognizedValue, "%s: value of %s contains flag bits that are not recognized members of %s", 737 api_name, parameter_name.get_name().c_str(), flag_bits_name); 738 } else if (singleFlag && (std::bitset<sizeof(VkFlags) * 8>(value).count() > 1)) { 739 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 740 kVUID_PVError_UnrecognizedValue, 741 "%s: value of %s contains multiple members of %s when only a single value is allowed", api_name, 742 parameter_name.get_name().c_str(), flag_bits_name); 743 } 744 745 return skip_call; 746 } 747 748 /** 749 * Validate an array of Vulkan bitmask values. 750 * 751 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits 752 * for that type. 753 * 754 * @param api_name Name of API call being validated. 755 * @param count_name Name of parameter being validated. 756 * @param array_name Name of parameter being validated. 757 * @param flag_bits_name Name of the VkFlags type being validated. 758 * @param all_flags A bitmask combining all valid flag bits for the VkFlags type being validated. 759 * @param count Number of VkFlags values in the array. 760 * @param array Array of VkFlags value to validate. 761 * @param count_required The 'count' parameter may not be 0 when true. 762 * @param array_required The 'array' parameter may not be NULL when true. 763 * @return Boolean value indicating that the call should be skipped. 764 */ 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)765 bool validate_flags_array(const char *api_name, const ParameterName &count_name, const ParameterName &array_name, 766 const char *flag_bits_name, VkFlags all_flags, uint32_t count, const VkFlags *array, 767 bool count_required, bool array_required) { 768 bool skip_call = false; 769 770 if ((count == 0) || (array == NULL)) { 771 skip_call |= validate_array(api_name, count_name, array_name, count, &array, count_required, array_required, 772 kVUIDUndefined, kVUIDUndefined); 773 } else { 774 // Verify that all VkFlags values in the array 775 for (uint32_t i = 0; i < count; ++i) { 776 if (array[i] == 0) { 777 // Current XML registry logic for validity generation uses the array parameter's optional tag to determine if 778 // elements in the array are allowed be 0 779 if (array_required) { 780 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 781 kVUID_PVError_RequiredParameter, "%s: value of %s[%d] must not be 0", api_name, 782 array_name.get_name().c_str(), i); 783 } 784 } else if ((array[i] & (~all_flags)) != 0) { 785 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 786 kVUID_PVError_UnrecognizedValue, 787 "%s: value of %s[%d] contains flag bits that are not recognized members of %s", api_name, 788 array_name.get_name().c_str(), i, flag_bits_name); 789 } 790 } 791 } 792 793 return skip_call; 794 } 795 796 template <typename ExtensionState> validate_extension_reqs(const ExtensionState & extensions,const char * vuid,const char * extension_type,const char * extension_name)797 bool validate_extension_reqs(const ExtensionState &extensions, const char *vuid, const char *extension_type, 798 const char *extension_name) { 799 bool skip = false; 800 if (!extension_name) { 801 return skip; // Robust to invalid char * 802 } 803 auto info = ExtensionState::get_info(extension_name); 804 805 if (!info.state) { 806 return skip; // Unknown extensions cannot be checked so report OK 807 } 808 809 // Check against the required list in the info 810 std::vector<const char *> missing; 811 for (const auto &req : info.requires) { 812 if (!(extensions.*(req.enabled))) { 813 missing.push_back(req.name); 814 } 815 } 816 817 // Report any missing requirements 818 if (missing.size()) { 819 std::string missing_joined_list = string_join(", ", missing); 820 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 821 HandleToUint64(instance), vuid, "Missing extension%s required by the %s extension %s: %s.", 822 ((missing.size() > 1) ? "s" : ""), extension_type, extension_name, missing_joined_list.c_str()); 823 } 824 return skip; 825 } 826 827 enum RenderPassCreateVersion { RENDER_PASS_VERSION_1 = 0, RENDER_PASS_VERSION_2 = 1 }; 828 829 template <typename RenderPassCreateInfoGeneric> CreateRenderPassGeneric(VkDevice device,const RenderPassCreateInfoGeneric * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass,RenderPassCreateVersion rp_version)830 bool CreateRenderPassGeneric(VkDevice device, const RenderPassCreateInfoGeneric *pCreateInfo, 831 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, 832 RenderPassCreateVersion rp_version) { 833 bool skip = false; 834 uint32_t max_color_attachments = device_limits.maxColorAttachments; 835 bool use_rp2 = (rp_version == RENDER_PASS_VERSION_2); 836 const char *vuid; 837 838 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 839 if (pCreateInfo->pAttachments[i].format == VK_FORMAT_UNDEFINED) { 840 std::stringstream ss; 841 ss << (use_rp2 ? "vkCreateRenderPass2KHR" : "vkCreateRenderPass") << ": pCreateInfo->pAttachments[" << i 842 << "].format is VK_FORMAT_UNDEFINED. "; 843 vuid = 844 use_rp2 ? "VUID-VkAttachmentDescription2KHR-format-parameter" : "VUID-VkAttachmentDescription-format-parameter"; 845 skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 846 "%s", ss.str().c_str()); 847 } 848 if (pCreateInfo->pAttachments[i].finalLayout == VK_IMAGE_LAYOUT_UNDEFINED || 849 pCreateInfo->pAttachments[i].finalLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) { 850 vuid = use_rp2 ? "VUID-VkAttachmentDescription2KHR-finalLayout-03061" 851 : "VUID-VkAttachmentDescription-finalLayout-00843"; 852 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 853 "pCreateInfo->pAttachments[%d].finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or " 854 "VK_IMAGE_LAYOUT_PREINITIALIZED.", 855 i); 856 } 857 } 858 859 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 860 if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) { 861 vuid = use_rp2 ? "VUID-VkSubpassDescription2KHR-colorAttachmentCount-03063" 862 : "VUID-VkSubpassDescription-colorAttachmentCount-00845"; 863 skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid, 864 "Cannot create a render pass with %d color attachments. Max is %d.", 865 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments); 866 } 867 } 868 return skip; 869 } 870 871 template <typename T> RecordRenderPass(VkRenderPass renderPass,const T * pCreateInfo)872 void RecordRenderPass(VkRenderPass renderPass, const T *pCreateInfo) { 873 std::unique_lock<std::mutex> lock(renderpass_map_mutex); 874 auto &renderpass_state = renderpasses_states[renderPass]; 875 lock.unlock(); 876 877 for (uint32_t subpass = 0; subpass < pCreateInfo->subpassCount; ++subpass) { 878 bool uses_color = false; 879 for (uint32_t i = 0; i < pCreateInfo->pSubpasses[subpass].colorAttachmentCount && !uses_color; ++i) 880 if (pCreateInfo->pSubpasses[subpass].pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) uses_color = true; 881 882 bool uses_depthstencil = false; 883 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment) 884 if (pCreateInfo->pSubpasses[subpass].pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) 885 uses_depthstencil = true; 886 887 if (uses_color) renderpass_state.subpasses_using_color_attachment.insert(subpass); 888 if (uses_depthstencil) renderpass_state.subpasses_using_depthstencil_attachment.insert(subpass); 889 } 890 } 891 892 bool require_device_extension(bool flag, char const *function_name, char const *extension_name); 893 894 bool validate_instance_extensions(const VkInstanceCreateInfo *pCreateInfo); 895 896 bool validate_api_version(uint32_t api_version, uint32_t effective_api_version); 897 898 bool validate_string(const char *apiName, const ParameterName &stringName, const std::string &vuid, const char *validateString); 899 900 bool ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV *order); 901 902 bool ValidateQueueFamilies(uint32_t queue_family_count, const uint32_t *queue_families, const char *cmd_name, 903 const char *array_parameter_name, const std::string &unique_error_code, 904 const std::string &valid_error_code, bool optional); 905 906 bool ValidateDeviceQueueFamily(uint32_t queue_family, const char *cmd_name, const char *parameter_name, 907 const std::string &error_code, bool optional); 908 909 bool OutputExtensionError(const std::string &api_name, const std::string &extension_name); 910 911 void PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 912 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, VkResult result); 913 void PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, 914 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass, VkResult result); 915 void PostCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator); 916 void PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 917 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result); 918 919 void PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 920 VkInstance *pInstance, VkResult result); 921 922 bool manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, 923 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool); 924 925 bool manual_PreCallValidateCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 926 VkInstance *pInstance); 927 928 bool manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 929 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice); 930 931 bool manual_PreCallValidateCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, 932 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer); 933 934 bool manual_PreCallValidateCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, 935 const VkAllocationCallbacks *pAllocator, VkImage *pImage); 936 937 bool manual_PreCallValidateCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, 938 const VkAllocationCallbacks *pAllocator, VkImageView *pView); 939 940 bool manual_PreCallValidateViewport(const VkViewport &viewport, const char *fn_name, const ParameterName ¶meter_name, 941 VkDebugReportObjectTypeEXT object_type, uint64_t object); 942 943 bool manual_PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, 944 const VkGraphicsPipelineCreateInfo *pCreateInfos, 945 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines); 946 bool manual_PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, 947 const VkComputePipelineCreateInfo *pCreateInfos, 948 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines); 949 950 bool manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, 951 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler); 952 bool manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 953 const VkAllocationCallbacks *pAllocator, 954 VkDescriptorSetLayout *pSetLayout); 955 956 bool manual_PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, 957 const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 958 const VkCopyDescriptorSet *pDescriptorCopies); 959 ; 960 bool manual_PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, 961 const VkDescriptorSet *pDescriptorSets); 962 963 bool manual_PreCallValidateCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 964 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); 965 966 bool manual_PreCallValidateCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo, 967 const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); 968 969 bool manual_PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, 970 const VkCommandBuffer *pCommandBuffers); 971 972 bool manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo); 973 974 bool manual_PreCallValidateCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, 975 const VkViewport *pViewports); 976 977 bool manual_PreCallValidateCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, 978 const VkRect2D *pScissors); 979 bool manual_PreCallValidateCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth); 980 981 bool manual_PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, 982 uint32_t firstVertex, uint32_t firstInstance); 983 984 bool manual_PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, 985 uint32_t stride); 986 987 bool manual_PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 988 uint32_t count, uint32_t stride); 989 990 bool manual_PreCallValidateCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 991 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 992 const VkImageCopy *pRegions); 993 994 bool manual_PreCallValidateCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 995 VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 996 const VkImageBlit *pRegions, VkFilter filter); 997 998 bool manual_PreCallValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, 999 VkImageLayout dstImageLayout, uint32_t regionCount, 1000 const VkBufferImageCopy *pRegions); 1001 1002 bool manual_PreCallValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 1003 VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions); 1004 1005 bool manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 1006 VkDeviceSize dataSize, const void *pData); 1007 1008 bool manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 1009 VkDeviceSize size, uint32_t data); 1010 1011 bool manual_PreCallValidateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, 1012 const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain); 1013 bool manual_PreCallValidateQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo); 1014 1015 #ifdef VK_USE_PLATFORM_WIN32_KHR 1016 bool manual_PreCallValidateCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 1017 const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); 1018 #endif // VK_USE_PLATFORM_WIN32_KHR 1019 1020 bool manual_PreCallValidateCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, 1021 const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool); 1022 bool manual_PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, 1023 uint32_t groupCountZ); 1024 1025 bool manual_PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); 1026 1027 bool manual_PreCallValidateCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, 1028 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, 1029 uint32_t groupCountZ); 1030 bool manual_PreCallValidateCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, 1031 uint32_t exclusiveScissorCount, const VkRect2D *pExclusiveScissors); 1032 bool manual_PreCallValidateCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, 1033 uint32_t viewportCount, 1034 const VkShadingRatePaletteNV *pShadingRatePalettes); 1035 1036 bool manual_PreCallValidateCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, 1037 uint32_t customSampleOrderCount, 1038 const VkCoarseSampleOrderCustomNV *pCustomSampleOrders); 1039 1040 bool manual_PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask); 1041 bool manual_PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1042 uint32_t drawCount, uint32_t stride); 1043 1044 bool manual_PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 1045 VkBuffer countBuffer, VkDeviceSize countBufferOffset, 1046 uint32_t maxDrawCount, uint32_t stride); 1047 1048 bool manual_PreCallValidateEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, 1049 uint32_t *pPropertyCount, VkExtensionProperties *pProperties); 1050 bool manual_PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, 1051 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory); 1052 #include "parameter_validation.h" 1053 }; // Class StatelessValidation 1054