parameter_validation.cpp revision 059e07e5fff8ea8b6108fe900e573d845fb98bf0
1/* Copyright (c) 2015-2016 The Khronos Group Inc. 2 * Copyright (c) 2015-2016 Valve Corporation 3 * Copyright (c) 2015-2016 LunarG, Inc. 4 * Copyright (C) 2015-2016 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: Jeremy Hayes <jeremy@lunarg.com> 19 * Author: Tony Barbour <tony@LunarG.com> 20 * Author: Mark Lobodzinski <mark@LunarG.com> 21 * Author: Dustin Graves <dustin@lunarg.com> 22 */ 23 24#define NOMINMAX 25 26#include <math.h> 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30 31#include <iostream> 32#include <string> 33#include <sstream> 34#include <unordered_map> 35#include <unordered_set> 36#include <vector> 37 38#include "vk_loader_platform.h" 39#include "vulkan/vk_layer.h" 40#include "vk_layer_config.h" 41#include "vk_enum_validate_helper.h" 42#include "vk_struct_validate_helper.h" 43 44#include "vk_layer_table.h" 45#include "vk_layer_data.h" 46#include "vk_layer_logging.h" 47#include "vk_layer_extension_utils.h" 48#include "vk_layer_utils.h" 49 50#include "parameter_validation.h" 51 52namespace parameter_validation { 53 54struct layer_data { 55 VkInstance instance; 56 57 debug_report_data *report_data; 58 std::vector<VkDebugReportCallbackEXT> logging_callback; 59 60 // The following are for keeping track of the temporary callbacks that can 61 // be used in vkCreateInstance and vkDestroyInstance: 62 uint32_t num_tmp_callbacks; 63 VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos; 64 VkDebugReportCallbackEXT *tmp_callbacks; 65 66 // TODO: Split instance/device structs 67 // Device Data 68 // Map for queue family index to queue count 69 std::unordered_map<uint32_t, uint32_t> queueFamilyIndexMap; 70 VkPhysicalDeviceLimits device_limits; 71 VkPhysicalDeviceFeatures physical_device_features; 72 VkPhysicalDevice physical_device; 73 74 layer_data() 75 : report_data(nullptr), num_tmp_callbacks(0), tmp_dbg_create_infos(nullptr), tmp_callbacks(nullptr), device_limits{}, 76 physical_device_features{}, physical_device{} {}; 77}; 78 79static std::unordered_map<void *, layer_data *> layer_data_map; 80static device_table_map pc_device_table_map; 81static instance_table_map pc_instance_table_map; 82 83// "my instance data" 84debug_report_data *mid(VkInstance object) { 85 dispatch_key key = get_dispatch_key(object); 86 layer_data *data = get_my_data_ptr(key, layer_data_map); 87#if DISPATCH_MAP_DEBUG 88 fprintf(stderr, "MID: map: 0x%p, object: 0x%p, key: 0x%p, data: 0x%p\n", &layer_data_map, object, key, data); 89#endif 90 assert(data != NULL); 91 92 return data->report_data; 93} 94 95// "my device data" 96debug_report_data *mdd(void *object) { 97 dispatch_key key = get_dispatch_key(object); 98 layer_data *data = get_my_data_ptr(key, layer_data_map); 99#if DISPATCH_MAP_DEBUG 100 fprintf(stderr, "MDD: map: 0x%p, object: 0x%p, key: 0x%p, data: 0x%p\n", &layer_data_map, object, key, data); 101#endif 102 assert(data != NULL); 103 return data->report_data; 104} 105 106static void init_parameter_validation(layer_data *my_data, const VkAllocationCallbacks *pAllocator) { 107 108 layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_parameter_validation"); 109} 110 111VKAPI_ATTR VkResult VKAPI_CALL 112CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 113 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { 114 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance); 115 VkResult result = pTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 116 117 if (result == VK_SUCCESS) { 118 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 119 result = layer_create_msg_callback(data->report_data, false, pCreateInfo, pAllocator, pMsgCallback); 120 } 121 122 return result; 123} 124 125VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, 126 VkDebugReportCallbackEXT msgCallback, 127 const VkAllocationCallbacks *pAllocator) { 128 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance); 129 pTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 130 131 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 132 layer_destroy_msg_callback(data->report_data, msgCallback, pAllocator); 133} 134 135VKAPI_ATTR void VKAPI_CALL 136DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, 137 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 138 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance); 139 pTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg); 140} 141 142static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; 143 144static const VkLayerProperties global_layer = { 145 "VK_LAYER_LUNARG_parameter_validation", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", 146}; 147 148static bool ValidateEnumerator(VkFormatFeatureFlagBits const &enumerator) { 149 VkFormatFeatureFlagBits allFlags = (VkFormatFeatureFlagBits)( 150 VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | 151 VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT | 152 VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | 153 VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 154 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | 155 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); 156 if (enumerator & (~allFlags)) { 157 return false; 158 } 159 160 return true; 161} 162 163static std::string EnumeratorString(VkFormatFeatureFlagBits const &enumerator) { 164 if (!ValidateEnumerator(enumerator)) { 165 return "unrecognized enumerator"; 166 } 167 168 std::vector<std::string> strings; 169 if (enumerator & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) { 170 strings.push_back("VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT"); 171 } 172 if (enumerator & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { 173 strings.push_back("VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT"); 174 } 175 if (enumerator & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) { 176 strings.push_back("VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT"); 177 } 178 if (enumerator & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT) { 179 strings.push_back("VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT"); 180 } 181 if (enumerator & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { 182 strings.push_back("VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT"); 183 } 184 if (enumerator & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) { 185 strings.push_back("VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT"); 186 } 187 if (enumerator & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) { 188 strings.push_back("VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT"); 189 } 190 if (enumerator & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) { 191 strings.push_back("VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT"); 192 } 193 if (enumerator & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) { 194 strings.push_back("VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT"); 195 } 196 if (enumerator & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { 197 strings.push_back("VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT"); 198 } 199 if (enumerator & VK_FORMAT_FEATURE_BLIT_SRC_BIT) { 200 strings.push_back("VK_FORMAT_FEATURE_BLIT_SRC_BIT"); 201 } 202 if (enumerator & VK_FORMAT_FEATURE_BLIT_DST_BIT) { 203 strings.push_back("VK_FORMAT_FEATURE_BLIT_DST_BIT"); 204 } 205 if (enumerator & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) { 206 strings.push_back("VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT"); 207 } 208 209 std::string enumeratorString; 210 for (auto const &string : strings) { 211 enumeratorString += string; 212 213 if (string != strings.back()) { 214 enumeratorString += '|'; 215 } 216 } 217 218 return enumeratorString; 219} 220 221static bool ValidateEnumerator(VkImageUsageFlagBits const &enumerator) { 222 VkImageUsageFlagBits allFlags = (VkImageUsageFlagBits)( 223 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 224 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | 225 VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 226 if (enumerator & (~allFlags)) { 227 return false; 228 } 229 230 return true; 231} 232 233static std::string EnumeratorString(VkImageUsageFlagBits const &enumerator) { 234 if (!ValidateEnumerator(enumerator)) { 235 return "unrecognized enumerator"; 236 } 237 238 std::vector<std::string> strings; 239 if (enumerator & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { 240 strings.push_back("VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT"); 241 } 242 if (enumerator & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 243 strings.push_back("VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT"); 244 } 245 if (enumerator & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 246 strings.push_back("VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT"); 247 } 248 if (enumerator & VK_IMAGE_USAGE_STORAGE_BIT) { 249 strings.push_back("VK_IMAGE_USAGE_STORAGE_BIT"); 250 } 251 if (enumerator & VK_IMAGE_USAGE_SAMPLED_BIT) { 252 strings.push_back("VK_IMAGE_USAGE_SAMPLED_BIT"); 253 } 254 if (enumerator & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { 255 strings.push_back("VK_IMAGE_USAGE_TRANSFER_DST_BIT"); 256 } 257 if (enumerator & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { 258 strings.push_back("VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT"); 259 } 260 if (enumerator & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 261 strings.push_back("VK_IMAGE_USAGE_TRANSFER_SRC_BIT"); 262 } 263 264 std::string enumeratorString; 265 for (auto const &string : strings) { 266 enumeratorString += string; 267 268 if (string != strings.back()) { 269 enumeratorString += '|'; 270 } 271 } 272 273 return enumeratorString; 274} 275 276static bool ValidateEnumerator(VkQueueFlagBits const &enumerator) { 277 VkQueueFlagBits allFlags = 278 (VkQueueFlagBits)(VK_QUEUE_TRANSFER_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_SPARSE_BINDING_BIT | VK_QUEUE_GRAPHICS_BIT); 279 if (enumerator & (~allFlags)) { 280 return false; 281 } 282 283 return true; 284} 285 286static std::string EnumeratorString(VkQueueFlagBits const &enumerator) { 287 if (!ValidateEnumerator(enumerator)) { 288 return "unrecognized enumerator"; 289 } 290 291 std::vector<std::string> strings; 292 if (enumerator & VK_QUEUE_TRANSFER_BIT) { 293 strings.push_back("VK_QUEUE_TRANSFER_BIT"); 294 } 295 if (enumerator & VK_QUEUE_COMPUTE_BIT) { 296 strings.push_back("VK_QUEUE_COMPUTE_BIT"); 297 } 298 if (enumerator & VK_QUEUE_SPARSE_BINDING_BIT) { 299 strings.push_back("VK_QUEUE_SPARSE_BINDING_BIT"); 300 } 301 if (enumerator & VK_QUEUE_GRAPHICS_BIT) { 302 strings.push_back("VK_QUEUE_GRAPHICS_BIT"); 303 } 304 305 std::string enumeratorString; 306 for (auto const &string : strings) { 307 enumeratorString += string; 308 309 if (string != strings.back()) { 310 enumeratorString += '|'; 311 } 312 } 313 314 return enumeratorString; 315} 316 317static bool ValidateEnumerator(VkMemoryPropertyFlagBits const &enumerator) { 318 VkMemoryPropertyFlagBits allFlags = (VkMemoryPropertyFlagBits)( 319 VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 320 VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); 321 if (enumerator & (~allFlags)) { 322 return false; 323 } 324 325 return true; 326} 327 328static std::string EnumeratorString(VkMemoryPropertyFlagBits const &enumerator) { 329 if (!ValidateEnumerator(enumerator)) { 330 return "unrecognized enumerator"; 331 } 332 333 std::vector<std::string> strings; 334 if (enumerator & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) { 335 strings.push_back("VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT"); 336 } 337 if (enumerator & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { 338 strings.push_back("VK_MEMORY_PROPERTY_HOST_COHERENT_BIT"); 339 } 340 if (enumerator & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { 341 strings.push_back("VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT"); 342 } 343 if (enumerator & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { 344 strings.push_back("VK_MEMORY_PROPERTY_HOST_CACHED_BIT"); 345 } 346 if (enumerator & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { 347 strings.push_back("VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT"); 348 } 349 350 std::string enumeratorString; 351 for (auto const &string : strings) { 352 enumeratorString += string; 353 354 if (string != strings.back()) { 355 enumeratorString += '|'; 356 } 357 } 358 359 return enumeratorString; 360} 361 362static bool ValidateEnumerator(VkMemoryHeapFlagBits const &enumerator) { 363 VkMemoryHeapFlagBits allFlags = (VkMemoryHeapFlagBits)(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT); 364 if (enumerator & (~allFlags)) { 365 return false; 366 } 367 368 return true; 369} 370 371static std::string EnumeratorString(VkMemoryHeapFlagBits const &enumerator) { 372 if (!ValidateEnumerator(enumerator)) { 373 return "unrecognized enumerator"; 374 } 375 376 std::vector<std::string> strings; 377 if (enumerator & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) { 378 strings.push_back("VK_MEMORY_HEAP_DEVICE_LOCAL_BIT"); 379 } 380 381 std::string enumeratorString; 382 for (auto const &string : strings) { 383 enumeratorString += string; 384 385 if (string != strings.back()) { 386 enumeratorString += '|'; 387 } 388 } 389 390 return enumeratorString; 391} 392 393static bool ValidateEnumerator(VkSparseImageFormatFlagBits const &enumerator) { 394 VkSparseImageFormatFlagBits allFlags = 395 (VkSparseImageFormatFlagBits)(VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT | 396 VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT | VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT); 397 if (enumerator & (~allFlags)) { 398 return false; 399 } 400 401 return true; 402} 403 404static std::string EnumeratorString(VkSparseImageFormatFlagBits const &enumerator) { 405 if (!ValidateEnumerator(enumerator)) { 406 return "unrecognized enumerator"; 407 } 408 409 std::vector<std::string> strings; 410 if (enumerator & VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT) { 411 strings.push_back("VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT"); 412 } 413 if (enumerator & VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT) { 414 strings.push_back("VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT"); 415 } 416 if (enumerator & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) { 417 strings.push_back("VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT"); 418 } 419 420 std::string enumeratorString; 421 for (auto const &string : strings) { 422 enumeratorString += string; 423 424 if (string != strings.back()) { 425 enumeratorString += '|'; 426 } 427 } 428 429 return enumeratorString; 430} 431 432static bool ValidateEnumerator(VkFenceCreateFlagBits const &enumerator) { 433 VkFenceCreateFlagBits allFlags = (VkFenceCreateFlagBits)(VK_FENCE_CREATE_SIGNALED_BIT); 434 if (enumerator & (~allFlags)) { 435 return false; 436 } 437 438 return true; 439} 440 441static std::string EnumeratorString(VkFenceCreateFlagBits const &enumerator) { 442 if (!ValidateEnumerator(enumerator)) { 443 return "unrecognized enumerator"; 444 } 445 446 std::vector<std::string> strings; 447 if (enumerator & VK_FENCE_CREATE_SIGNALED_BIT) { 448 strings.push_back("VK_FENCE_CREATE_SIGNALED_BIT"); 449 } 450 451 std::string enumeratorString; 452 for (auto const &string : strings) { 453 enumeratorString += string; 454 455 if (string != strings.back()) { 456 enumeratorString += '|'; 457 } 458 } 459 460 return enumeratorString; 461} 462 463static bool ValidateEnumerator(VkQueryPipelineStatisticFlagBits const &enumerator) { 464 VkQueryPipelineStatisticFlagBits allFlags = (VkQueryPipelineStatisticFlagBits)( 465 VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT | 466 VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT | 467 VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT | 468 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT | 469 VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT | 470 VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT | 471 VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT); 472 if (enumerator & (~allFlags)) { 473 return false; 474 } 475 476 return true; 477} 478 479static std::string EnumeratorString(VkQueryPipelineStatisticFlagBits const &enumerator) { 480 if (!ValidateEnumerator(enumerator)) { 481 return "unrecognized enumerator"; 482 } 483 484 std::vector<std::string> strings; 485 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT) { 486 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT"); 487 } 488 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT) { 489 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT"); 490 } 491 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT) { 492 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT"); 493 } 494 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT) { 495 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT"); 496 } 497 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT) { 498 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT"); 499 } 500 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT) { 501 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT"); 502 } 503 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT) { 504 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT"); 505 } 506 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT) { 507 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT"); 508 } 509 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT) { 510 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT"); 511 } 512 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT) { 513 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT"); 514 } 515 if (enumerator & VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT) { 516 strings.push_back("VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT"); 517 } 518 519 std::string enumeratorString; 520 for (auto const &string : strings) { 521 enumeratorString += string; 522 523 if (string != strings.back()) { 524 enumeratorString += '|'; 525 } 526 } 527 528 return enumeratorString; 529} 530 531static bool ValidateEnumerator(VkQueryResultFlagBits const &enumerator) { 532 VkQueryResultFlagBits allFlags = (VkQueryResultFlagBits)(VK_QUERY_RESULT_PARTIAL_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT | 533 VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT); 534 if (enumerator & (~allFlags)) { 535 return false; 536 } 537 538 return true; 539} 540 541static std::string EnumeratorString(VkQueryResultFlagBits const &enumerator) { 542 if (!ValidateEnumerator(enumerator)) { 543 return "unrecognized enumerator"; 544 } 545 546 std::vector<std::string> strings; 547 if (enumerator & VK_QUERY_RESULT_PARTIAL_BIT) { 548 strings.push_back("VK_QUERY_RESULT_PARTIAL_BIT"); 549 } 550 if (enumerator & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) { 551 strings.push_back("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT"); 552 } 553 if (enumerator & VK_QUERY_RESULT_WAIT_BIT) { 554 strings.push_back("VK_QUERY_RESULT_WAIT_BIT"); 555 } 556 if (enumerator & VK_QUERY_RESULT_64_BIT) { 557 strings.push_back("VK_QUERY_RESULT_64_BIT"); 558 } 559 560 std::string enumeratorString; 561 for (auto const &string : strings) { 562 enumeratorString += string; 563 564 if (string != strings.back()) { 565 enumeratorString += '|'; 566 } 567 } 568 569 return enumeratorString; 570} 571 572static bool ValidateEnumerator(VkBufferUsageFlagBits const &enumerator) { 573 VkBufferUsageFlagBits allFlags = (VkBufferUsageFlagBits)( 574 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | 575 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | 576 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 577 if (enumerator & (~allFlags)) { 578 return false; 579 } 580 581 return true; 582} 583 584static std::string EnumeratorString(VkBufferUsageFlagBits const &enumerator) { 585 if (!ValidateEnumerator(enumerator)) { 586 return "unrecognized enumerator"; 587 } 588 589 std::vector<std::string> strings; 590 if (enumerator & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) { 591 strings.push_back("VK_BUFFER_USAGE_VERTEX_BUFFER_BIT"); 592 } 593 if (enumerator & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) { 594 strings.push_back("VK_BUFFER_USAGE_INDEX_BUFFER_BIT"); 595 } 596 if (enumerator & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) { 597 strings.push_back("VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT"); 598 } 599 if (enumerator & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { 600 strings.push_back("VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT"); 601 } 602 if (enumerator & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) { 603 strings.push_back("VK_BUFFER_USAGE_STORAGE_BUFFER_BIT"); 604 } 605 if (enumerator & VK_BUFFER_USAGE_TRANSFER_DST_BIT) { 606 strings.push_back("VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 607 } 608 if (enumerator & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { 609 strings.push_back("VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT"); 610 } 611 if (enumerator & VK_BUFFER_USAGE_TRANSFER_SRC_BIT) { 612 strings.push_back("VK_BUFFER_USAGE_TRANSFER_SRC_BIT"); 613 } 614 if (enumerator & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) { 615 strings.push_back("VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT"); 616 } 617 618 std::string enumeratorString; 619 for (auto const &string : strings) { 620 enumeratorString += string; 621 622 if (string != strings.back()) { 623 enumeratorString += '|'; 624 } 625 } 626 627 return enumeratorString; 628} 629 630static bool ValidateEnumerator(VkBufferCreateFlagBits const &enumerator) { 631 VkBufferCreateFlagBits allFlags = (VkBufferCreateFlagBits)( 632 VK_BUFFER_CREATE_SPARSE_ALIASED_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT); 633 if (enumerator & (~allFlags)) { 634 return false; 635 } 636 637 return true; 638} 639 640static std::string EnumeratorString(VkBufferCreateFlagBits const &enumerator) { 641 if (!ValidateEnumerator(enumerator)) { 642 return "unrecognized enumerator"; 643 } 644 645 std::vector<std::string> strings; 646 if (enumerator & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) { 647 strings.push_back("VK_BUFFER_CREATE_SPARSE_ALIASED_BIT"); 648 } 649 if (enumerator & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) { 650 strings.push_back("VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT"); 651 } 652 if (enumerator & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) { 653 strings.push_back("VK_BUFFER_CREATE_SPARSE_BINDING_BIT"); 654 } 655 656 std::string enumeratorString; 657 for (auto const &string : strings) { 658 enumeratorString += string; 659 660 if (string != strings.back()) { 661 enumeratorString += '|'; 662 } 663 } 664 665 return enumeratorString; 666} 667 668static bool ValidateEnumerator(VkImageCreateFlagBits const &enumerator) { 669 VkImageCreateFlagBits allFlags = (VkImageCreateFlagBits)( 670 VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | 671 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT); 672 if (enumerator & (~allFlags)) { 673 return false; 674 } 675 676 return true; 677} 678 679static std::string EnumeratorString(VkImageCreateFlagBits const &enumerator) { 680 if (!ValidateEnumerator(enumerator)) { 681 return "unrecognized enumerator"; 682 } 683 684 std::vector<std::string> strings; 685 if (enumerator & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) { 686 strings.push_back("VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT"); 687 } 688 if (enumerator & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) { 689 strings.push_back("VK_IMAGE_CREATE_SPARSE_ALIASED_BIT"); 690 } 691 if (enumerator & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) { 692 strings.push_back("VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT"); 693 } 694 if (enumerator & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { 695 strings.push_back("VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT"); 696 } 697 if (enumerator & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { 698 strings.push_back("VK_IMAGE_CREATE_SPARSE_BINDING_BIT"); 699 } 700 701 std::string enumeratorString; 702 for (auto const &string : strings) { 703 enumeratorString += string; 704 705 if (string != strings.back()) { 706 enumeratorString += '|'; 707 } 708 } 709 710 return enumeratorString; 711} 712 713static bool ValidateEnumerator(VkColorComponentFlagBits const &enumerator) { 714 VkColorComponentFlagBits allFlags = (VkColorComponentFlagBits)(VK_COLOR_COMPONENT_A_BIT | VK_COLOR_COMPONENT_B_BIT | 715 VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_R_BIT); 716 if (enumerator & (~allFlags)) { 717 return false; 718 } 719 720 return true; 721} 722 723static std::string EnumeratorString(VkColorComponentFlagBits const &enumerator) { 724 if (!ValidateEnumerator(enumerator)) { 725 return "unrecognized enumerator"; 726 } 727 728 std::vector<std::string> strings; 729 if (enumerator & VK_COLOR_COMPONENT_A_BIT) { 730 strings.push_back("VK_COLOR_COMPONENT_A_BIT"); 731 } 732 if (enumerator & VK_COLOR_COMPONENT_B_BIT) { 733 strings.push_back("VK_COLOR_COMPONENT_B_BIT"); 734 } 735 if (enumerator & VK_COLOR_COMPONENT_G_BIT) { 736 strings.push_back("VK_COLOR_COMPONENT_G_BIT"); 737 } 738 if (enumerator & VK_COLOR_COMPONENT_R_BIT) { 739 strings.push_back("VK_COLOR_COMPONENT_R_BIT"); 740 } 741 742 std::string enumeratorString; 743 for (auto const &string : strings) { 744 enumeratorString += string; 745 746 if (string != strings.back()) { 747 enumeratorString += '|'; 748 } 749 } 750 751 return enumeratorString; 752} 753 754static bool ValidateEnumerator(VkPipelineCreateFlagBits const &enumerator) { 755 VkPipelineCreateFlagBits allFlags = (VkPipelineCreateFlagBits)( 756 VK_PIPELINE_CREATE_DERIVATIVE_BIT | VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT | VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT); 757 if (enumerator & (~allFlags)) { 758 return false; 759 } 760 761 return true; 762} 763 764static std::string EnumeratorString(VkPipelineCreateFlagBits const &enumerator) { 765 if (!ValidateEnumerator(enumerator)) { 766 return "unrecognized enumerator"; 767 } 768 769 std::vector<std::string> strings; 770 if (enumerator & VK_PIPELINE_CREATE_DERIVATIVE_BIT) { 771 strings.push_back("VK_PIPELINE_CREATE_DERIVATIVE_BIT"); 772 } 773 if (enumerator & VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT) { 774 strings.push_back("VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT"); 775 } 776 if (enumerator & VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT) { 777 strings.push_back("VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT"); 778 } 779 780 std::string enumeratorString; 781 for (auto const &string : strings) { 782 enumeratorString += string; 783 784 if (string != strings.back()) { 785 enumeratorString += '|'; 786 } 787 } 788 789 return enumeratorString; 790} 791 792static bool ValidateEnumerator(VkShaderStageFlagBits const &enumerator) { 793 VkShaderStageFlagBits allFlags = (VkShaderStageFlagBits)( 794 VK_SHADER_STAGE_ALL | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_COMPUTE_BIT | 795 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_VERTEX_BIT); 796 if (enumerator & (~allFlags)) { 797 return false; 798 } 799 800 return true; 801} 802 803static std::string EnumeratorString(VkShaderStageFlagBits const &enumerator) { 804 if (!ValidateEnumerator(enumerator)) { 805 return "unrecognized enumerator"; 806 } 807 808 std::vector<std::string> strings; 809 if (enumerator & VK_SHADER_STAGE_ALL) { 810 strings.push_back("VK_SHADER_STAGE_ALL"); 811 } 812 if (enumerator & VK_SHADER_STAGE_FRAGMENT_BIT) { 813 strings.push_back("VK_SHADER_STAGE_FRAGMENT_BIT"); 814 } 815 if (enumerator & VK_SHADER_STAGE_GEOMETRY_BIT) { 816 strings.push_back("VK_SHADER_STAGE_GEOMETRY_BIT"); 817 } 818 if (enumerator & VK_SHADER_STAGE_COMPUTE_BIT) { 819 strings.push_back("VK_SHADER_STAGE_COMPUTE_BIT"); 820 } 821 if (enumerator & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) { 822 strings.push_back("VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT"); 823 } 824 if (enumerator & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) { 825 strings.push_back("VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT"); 826 } 827 if (enumerator & VK_SHADER_STAGE_VERTEX_BIT) { 828 strings.push_back("VK_SHADER_STAGE_VERTEX_BIT"); 829 } 830 831 std::string enumeratorString; 832 for (auto const &string : strings) { 833 enumeratorString += string; 834 835 if (string != strings.back()) { 836 enumeratorString += '|'; 837 } 838 } 839 840 return enumeratorString; 841} 842 843static bool ValidateEnumerator(VkPipelineStageFlagBits const &enumerator) { 844 VkPipelineStageFlagBits allFlags = (VkPipelineStageFlagBits)( 845 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_HOST_BIT | 846 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | 847 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | 848 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | 849 VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 850 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | 851 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); 852 if (enumerator & (~allFlags)) { 853 return false; 854 } 855 856 return true; 857} 858 859static std::string EnumeratorString(VkPipelineStageFlagBits const &enumerator) { 860 if (!ValidateEnumerator(enumerator)) { 861 return "unrecognized enumerator"; 862 } 863 864 std::vector<std::string> strings; 865 if (enumerator & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) { 866 strings.push_back("VK_PIPELINE_STAGE_ALL_COMMANDS_BIT"); 867 } 868 if (enumerator & VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT) { 869 strings.push_back("VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT"); 870 } 871 if (enumerator & VK_PIPELINE_STAGE_HOST_BIT) { 872 strings.push_back("VK_PIPELINE_STAGE_HOST_BIT"); 873 } 874 if (enumerator & VK_PIPELINE_STAGE_TRANSFER_BIT) { 875 strings.push_back("VK_PIPELINE_STAGE_TRANSFER_BIT"); 876 } 877 if (enumerator & VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) { 878 strings.push_back("VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT"); 879 } 880 if (enumerator & VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT) { 881 strings.push_back("VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT"); 882 } 883 if (enumerator & VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT) { 884 strings.push_back("VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT"); 885 } 886 if (enumerator & VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) { 887 strings.push_back("VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT"); 888 } 889 if (enumerator & VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT) { 890 strings.push_back("VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT"); 891 } 892 if (enumerator & VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT) { 893 strings.push_back("VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT"); 894 } 895 if (enumerator & VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT) { 896 strings.push_back("VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT"); 897 } 898 if (enumerator & VK_PIPELINE_STAGE_VERTEX_SHADER_BIT) { 899 strings.push_back("VK_PIPELINE_STAGE_VERTEX_SHADER_BIT"); 900 } 901 if (enumerator & VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT) { 902 strings.push_back("VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT"); 903 } 904 if (enumerator & VK_PIPELINE_STAGE_VERTEX_INPUT_BIT) { 905 strings.push_back("VK_PIPELINE_STAGE_VERTEX_INPUT_BIT"); 906 } 907 if (enumerator & VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT) { 908 strings.push_back("VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT"); 909 } 910 if (enumerator & VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT) { 911 strings.push_back("VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT"); 912 } 913 if (enumerator & VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) { 914 strings.push_back("VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT"); 915 } 916 917 std::string enumeratorString; 918 for (auto const &string : strings) { 919 enumeratorString += string; 920 921 if (string != strings.back()) { 922 enumeratorString += '|'; 923 } 924 } 925 926 return enumeratorString; 927} 928 929static bool ValidateEnumerator(VkAccessFlagBits const &enumerator) { 930 VkAccessFlagBits allFlags = (VkAccessFlagBits)( 931 VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | 932 VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | 933 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 934 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT | 935 VK_ACCESS_HOST_READ_BIT | VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT); 936 937 if (enumerator & (~allFlags)) { 938 return false; 939 } 940 941 return true; 942} 943 944static std::string EnumeratorString(VkAccessFlagBits const &enumerator) { 945 if (!ValidateEnumerator(enumerator)) { 946 return "unrecognized enumerator"; 947 } 948 949 std::vector<std::string> strings; 950 if (enumerator & VK_ACCESS_INDIRECT_COMMAND_READ_BIT) { 951 strings.push_back("VK_ACCESS_INDIRECT_COMMAND_READ_BIT"); 952 } 953 if (enumerator & VK_ACCESS_INDEX_READ_BIT) { 954 strings.push_back("VK_ACCESS_INDEX_READ_BIT"); 955 } 956 if (enumerator & VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT) { 957 strings.push_back("VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT"); 958 } 959 if (enumerator & VK_ACCESS_UNIFORM_READ_BIT) { 960 strings.push_back("VK_ACCESS_UNIFORM_READ_BIT"); 961 } 962 if (enumerator & VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) { 963 strings.push_back("VK_ACCESS_INPUT_ATTACHMENT_READ_BIT"); 964 } 965 if (enumerator & VK_ACCESS_SHADER_READ_BIT) { 966 strings.push_back("VK_ACCESS_SHADER_READ_BIT"); 967 } 968 if (enumerator & VK_ACCESS_SHADER_WRITE_BIT) { 969 strings.push_back("VK_ACCESS_SHADER_WRITE_BIT"); 970 } 971 if (enumerator & VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) { 972 strings.push_back("VK_ACCESS_COLOR_ATTACHMENT_READ_BIT"); 973 } 974 if (enumerator & VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) { 975 strings.push_back("VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT"); 976 } 977 if (enumerator & VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT) { 978 strings.push_back("VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT"); 979 } 980 if (enumerator & VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) { 981 strings.push_back("VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT"); 982 } 983 if (enumerator & VK_ACCESS_TRANSFER_READ_BIT) { 984 strings.push_back("VK_ACCESS_TRANSFER_READ_BIT"); 985 } 986 if (enumerator & VK_ACCESS_TRANSFER_WRITE_BIT) { 987 strings.push_back("VK_ACCESS_TRANSFER_WRITE_BIT"); 988 } 989 if (enumerator & VK_ACCESS_HOST_READ_BIT) { 990 strings.push_back("VK_ACCESS_HOST_READ_BIT"); 991 } 992 if (enumerator & VK_ACCESS_HOST_WRITE_BIT) { 993 strings.push_back("VK_ACCESS_HOST_WRITE_BIT"); 994 } 995 if (enumerator & VK_ACCESS_MEMORY_READ_BIT) { 996 strings.push_back("VK_ACCESS_MEMORY_READ_BIT"); 997 } 998 if (enumerator & VK_ACCESS_MEMORY_WRITE_BIT) { 999 strings.push_back("VK_ACCESS_MEMORY_WRITE_BIT"); 1000 } 1001 1002 std::string enumeratorString; 1003 for (auto const &string : strings) { 1004 enumeratorString += string; 1005 1006 if (string != strings.back()) { 1007 enumeratorString += '|'; 1008 } 1009 } 1010 1011 return enumeratorString; 1012} 1013 1014static bool ValidateEnumerator(VkCommandPoolCreateFlagBits const &enumerator) { 1015 VkCommandPoolCreateFlagBits allFlags = 1016 (VkCommandPoolCreateFlagBits)(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); 1017 if (enumerator & (~allFlags)) { 1018 return false; 1019 } 1020 1021 return true; 1022} 1023 1024static std::string EnumeratorString(VkCommandPoolCreateFlagBits const &enumerator) { 1025 if (!ValidateEnumerator(enumerator)) { 1026 return "unrecognized enumerator"; 1027 } 1028 1029 std::vector<std::string> strings; 1030 if (enumerator & VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT) { 1031 strings.push_back("VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT"); 1032 } 1033 if (enumerator & VK_COMMAND_POOL_CREATE_TRANSIENT_BIT) { 1034 strings.push_back("VK_COMMAND_POOL_CREATE_TRANSIENT_BIT"); 1035 } 1036 1037 std::string enumeratorString; 1038 for (auto const &string : strings) { 1039 enumeratorString += string; 1040 1041 if (string != strings.back()) { 1042 enumeratorString += '|'; 1043 } 1044 } 1045 1046 return enumeratorString; 1047} 1048 1049static bool ValidateEnumerator(VkCommandPoolResetFlagBits const &enumerator) { 1050 VkCommandPoolResetFlagBits allFlags = (VkCommandPoolResetFlagBits)(VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); 1051 if (enumerator & (~allFlags)) { 1052 return false; 1053 } 1054 1055 return true; 1056} 1057 1058static std::string EnumeratorString(VkCommandPoolResetFlagBits const &enumerator) { 1059 if (!ValidateEnumerator(enumerator)) { 1060 return "unrecognized enumerator"; 1061 } 1062 1063 std::vector<std::string> strings; 1064 if (enumerator & VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT) { 1065 strings.push_back("VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT"); 1066 } 1067 1068 std::string enumeratorString; 1069 for (auto const &string : strings) { 1070 enumeratorString += string; 1071 1072 if (string != strings.back()) { 1073 enumeratorString += '|'; 1074 } 1075 } 1076 1077 return enumeratorString; 1078} 1079 1080static bool ValidateEnumerator(VkCommandBufferUsageFlags const &enumerator) { 1081 VkCommandBufferUsageFlags allFlags = 1082 (VkCommandBufferUsageFlags)(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | 1083 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT); 1084 if (enumerator & (~allFlags)) { 1085 return false; 1086 } 1087 1088 return true; 1089} 1090 1091static std::string EnumeratorString(VkCommandBufferUsageFlags const &enumerator) { 1092 if (!ValidateEnumerator(enumerator)) { 1093 return "unrecognized enumerator"; 1094 } 1095 1096 std::vector<std::string> strings; 1097 if (enumerator & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) { 1098 strings.push_back("VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT"); 1099 } 1100 if (enumerator & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) { 1101 strings.push_back("VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT"); 1102 } 1103 if (enumerator & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { 1104 strings.push_back("VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT"); 1105 } 1106 1107 std::string enumeratorString; 1108 for (auto const &string : strings) { 1109 enumeratorString += string; 1110 1111 if (string != strings.back()) { 1112 enumeratorString += '|'; 1113 } 1114 } 1115 1116 return enumeratorString; 1117} 1118 1119static bool ValidateEnumerator(VkCommandBufferResetFlagBits const &enumerator) { 1120 VkCommandBufferResetFlagBits allFlags = (VkCommandBufferResetFlagBits)(VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); 1121 if (enumerator & (~allFlags)) { 1122 return false; 1123 } 1124 1125 return true; 1126} 1127 1128static std::string EnumeratorString(VkCommandBufferResetFlagBits const &enumerator) { 1129 if (!ValidateEnumerator(enumerator)) { 1130 return "unrecognized enumerator"; 1131 } 1132 1133 std::vector<std::string> strings; 1134 if (enumerator & VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT) { 1135 strings.push_back("VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT"); 1136 } 1137 1138 std::string enumeratorString; 1139 for (auto const &string : strings) { 1140 enumeratorString += string; 1141 1142 if (string != strings.back()) { 1143 enumeratorString += '|'; 1144 } 1145 } 1146 1147 return enumeratorString; 1148} 1149 1150static bool ValidateEnumerator(VkImageAspectFlagBits const &enumerator) { 1151 VkImageAspectFlagBits allFlags = (VkImageAspectFlagBits)(VK_IMAGE_ASPECT_METADATA_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | 1152 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_COLOR_BIT); 1153 if (enumerator & (~allFlags)) { 1154 return false; 1155 } 1156 1157 return true; 1158} 1159 1160static std::string EnumeratorString(VkImageAspectFlagBits const &enumerator) { 1161 if (!ValidateEnumerator(enumerator)) { 1162 return "unrecognized enumerator"; 1163 } 1164 1165 std::vector<std::string> strings; 1166 if (enumerator & VK_IMAGE_ASPECT_METADATA_BIT) { 1167 strings.push_back("VK_IMAGE_ASPECT_METADATA_BIT"); 1168 } 1169 if (enumerator & VK_IMAGE_ASPECT_STENCIL_BIT) { 1170 strings.push_back("VK_IMAGE_ASPECT_STENCIL_BIT"); 1171 } 1172 if (enumerator & VK_IMAGE_ASPECT_DEPTH_BIT) { 1173 strings.push_back("VK_IMAGE_ASPECT_DEPTH_BIT"); 1174 } 1175 if (enumerator & VK_IMAGE_ASPECT_COLOR_BIT) { 1176 strings.push_back("VK_IMAGE_ASPECT_COLOR_BIT"); 1177 } 1178 1179 std::string enumeratorString; 1180 for (auto const &string : strings) { 1181 enumeratorString += string; 1182 1183 if (string != strings.back()) { 1184 enumeratorString += '|'; 1185 } 1186 } 1187 1188 return enumeratorString; 1189} 1190 1191static bool ValidateEnumerator(VkQueryControlFlagBits const &enumerator) { 1192 VkQueryControlFlagBits allFlags = (VkQueryControlFlagBits)(VK_QUERY_CONTROL_PRECISE_BIT); 1193 if (enumerator & (~allFlags)) { 1194 return false; 1195 } 1196 1197 return true; 1198} 1199 1200static std::string EnumeratorString(VkQueryControlFlagBits const &enumerator) { 1201 if (!ValidateEnumerator(enumerator)) { 1202 return "unrecognized enumerator"; 1203 } 1204 1205 std::vector<std::string> strings; 1206 if (enumerator & VK_QUERY_CONTROL_PRECISE_BIT) { 1207 strings.push_back("VK_QUERY_CONTROL_PRECISE_BIT"); 1208 } 1209 1210 std::string enumeratorString; 1211 for (auto const &string : strings) { 1212 enumeratorString += string; 1213 1214 if (string != strings.back()) { 1215 enumeratorString += '|'; 1216 } 1217 } 1218 1219 return enumeratorString; 1220} 1221 1222static const int MaxParamCheckerStringLength = 256; 1223 1224static bool validate_string(debug_report_data *report_data, const char *apiName, const char *stringName, 1225 const char *validateString) { 1226 assert(apiName != nullptr); 1227 assert(stringName != nullptr); 1228 assert(validateString != nullptr); 1229 1230 bool skipCall = false; 1231 1232 VkStringErrorFlags result = vk_string_validate(MaxParamCheckerStringLength, validateString); 1233 1234 if (result == VK_STRING_ERROR_NONE) { 1235 return skipCall; 1236 } else if (result & VK_STRING_ERROR_LENGTH) { 1237 skipCall = 1238 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE, 1239 LayerName, "%s: string %s exceeds max length %d", apiName, stringName, MaxParamCheckerStringLength); 1240 } else if (result & VK_STRING_ERROR_BAD_DATA) { 1241 skipCall = 1242 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE, 1243 LayerName, "%s: string %s contains invalid characters or is badly formed", apiName, stringName); 1244 } 1245 return skipCall; 1246} 1247 1248static bool validate_queue_family_index(layer_data *device_data, const char *function_name, const char *parameter_name, 1249 uint32_t index) { 1250 assert(device_data != nullptr); 1251 debug_report_data *report_data = device_data->report_data; 1252 bool skip_call = false; 1253 1254 if (index == VK_QUEUE_FAMILY_IGNORED) { 1255 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName, 1256 "%s: %s cannot be VK_QUEUE_FAMILY_IGNORED.", function_name, parameter_name); 1257 } else { 1258 const auto &queue_data = device_data->queueFamilyIndexMap.find(index); 1259 if (queue_data == device_data->queueFamilyIndexMap.end()) { 1260 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 1261 LayerName, "%s: %s (%d) must be one of the indices specified when the device was created, via " 1262 "the VkDeviceQueueCreateInfo structure.", 1263 function_name, parameter_name, index); 1264 return false; 1265 } 1266 } 1267 1268 return skip_call; 1269} 1270 1271static bool validate_queue_family_indices(layer_data *device_data, const char *function_name, const char *parameter_name, 1272 const uint32_t count, const uint32_t *indices) { 1273 assert(device_data != nullptr); 1274 debug_report_data *report_data = device_data->report_data; 1275 bool skip_call = false; 1276 1277 if (indices != nullptr) { 1278 for (uint32_t i = 0; i < count; i++) { 1279 if (indices[i] == VK_QUEUE_FAMILY_IGNORED) { 1280 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 1281 LayerName, "%s: %s[%d] cannot be VK_QUEUE_FAMILY_IGNORED.", function_name, parameter_name, i); 1282 } else { 1283 const auto &queue_data = device_data->queueFamilyIndexMap.find(indices[i]); 1284 if (queue_data == device_data->queueFamilyIndexMap.end()) { 1285 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 1286 LayerName, "%s: %s[%d] (%d) must be one of the indices specified when the device was " 1287 "created, via the VkDeviceQueueCreateInfo structure.", 1288 function_name, parameter_name, i, indices[i]); 1289 return false; 1290 } 1291 } 1292 } 1293 } 1294 1295 return skip_call; 1296} 1297 1298VKAPI_ATTR VkResult VKAPI_CALL 1299CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { 1300 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1301 1302 VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 1303 assert(chain_info != nullptr); 1304 assert(chain_info->u.pLayerInfo != nullptr); 1305 1306 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 1307 PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 1308 if (fpCreateInstance == NULL) { 1309 return VK_ERROR_INITIALIZATION_FAILED; 1310 } 1311 1312 // Advance the link info for the next element on the chain 1313 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 1314 1315 result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 1316 1317 if (result == VK_SUCCESS) { 1318 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); 1319 assert(my_instance_data != nullptr); 1320 1321 VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, pc_instance_table_map); 1322 1323 my_instance_data->instance = *pInstance; 1324 my_instance_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionCount, 1325 pCreateInfo->ppEnabledExtensionNames); 1326 1327 // Look for one or more debug report create info structures 1328 // and setup a callback(s) for each one found. 1329 if (!layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_instance_data->num_tmp_callbacks, 1330 &my_instance_data->tmp_dbg_create_infos, &my_instance_data->tmp_callbacks)) { 1331 if (my_instance_data->num_tmp_callbacks > 0) { 1332 // Setup the temporary callback(s) here to catch early issues: 1333 if (layer_enable_tmp_callbacks(my_instance_data->report_data, my_instance_data->num_tmp_callbacks, 1334 my_instance_data->tmp_dbg_create_infos, my_instance_data->tmp_callbacks)) { 1335 // Failure of setting up one or more of the callback. 1336 // Therefore, clean up and don't use those callbacks: 1337 layer_free_tmp_callbacks(my_instance_data->tmp_dbg_create_infos, my_instance_data->tmp_callbacks); 1338 my_instance_data->num_tmp_callbacks = 0; 1339 } 1340 } 1341 } 1342 1343 init_parameter_validation(my_instance_data, pAllocator); 1344 1345 // Ordinarily we'd check these before calling down the chain, but none of the layer 1346 // support is in place until now, if we survive we can report the issue now. 1347 parameter_validation_vkCreateInstance(my_instance_data->report_data, pCreateInfo, pAllocator, pInstance); 1348 1349 if (pCreateInfo->pApplicationInfo) { 1350 if (pCreateInfo->pApplicationInfo->pApplicationName) { 1351 validate_string(my_instance_data->report_data, "vkCreateInstance", 1352 "pCreateInfo->VkApplicationInfo->pApplicationName", 1353 pCreateInfo->pApplicationInfo->pApplicationName); 1354 } 1355 1356 if (pCreateInfo->pApplicationInfo->pEngineName) { 1357 validate_string(my_instance_data->report_data, "vkCreateInstance", "pCreateInfo->VkApplicationInfo->pEngineName", 1358 pCreateInfo->pApplicationInfo->pEngineName); 1359 } 1360 } 1361 1362 // Disable the tmp callbacks: 1363 if (my_instance_data->num_tmp_callbacks > 0) { 1364 layer_disable_tmp_callbacks(my_instance_data->report_data, my_instance_data->num_tmp_callbacks, 1365 my_instance_data->tmp_callbacks); 1366 } 1367 } 1368 1369 return result; 1370} 1371 1372VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 1373 // Grab the key before the instance is destroyed. 1374 dispatch_key key = get_dispatch_key(instance); 1375 bool skipCall = false; 1376 layer_data *my_data = get_my_data_ptr(key, layer_data_map); 1377 assert(my_data != NULL); 1378 1379 // Enable the temporary callback(s) here to catch vkDestroyInstance issues: 1380 bool callback_setup = false; 1381 if (my_data->num_tmp_callbacks > 0) { 1382 if (!layer_enable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_dbg_create_infos, 1383 my_data->tmp_callbacks)) { 1384 callback_setup = true; 1385 } 1386 } 1387 1388 skipCall |= parameter_validation_vkDestroyInstance(my_data->report_data, pAllocator); 1389 1390 // Disable and cleanup the temporary callback(s): 1391 if (callback_setup) { 1392 layer_disable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_callbacks); 1393 } 1394 if (my_data->num_tmp_callbacks > 0) { 1395 layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos, my_data->tmp_callbacks); 1396 my_data->num_tmp_callbacks = 0; 1397 } 1398 1399 if (!skipCall) { 1400 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(pc_instance_table_map, instance); 1401 pTable->DestroyInstance(instance, pAllocator); 1402 1403 // Clean up logging callback, if any 1404 while (my_data->logging_callback.size() > 0) { 1405 VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); 1406 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); 1407 my_data->logging_callback.pop_back(); 1408 } 1409 1410 layer_debug_report_destroy_instance(mid(instance)); 1411 layer_data_map.erase(pTable); 1412 1413 pc_instance_table_map.erase(key); 1414 layer_data_map.erase(key); 1415 } 1416} 1417 1418VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, 1419 VkPhysicalDevice *pPhysicalDevices) { 1420 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1421 bool skipCall = false; 1422 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 1423 assert(my_data != NULL); 1424 1425 skipCall |= parameter_validation_vkEnumeratePhysicalDevices(my_data->report_data, pPhysicalDeviceCount, pPhysicalDevices); 1426 1427 if (!skipCall) { 1428 result = get_dispatch_table(pc_instance_table_map, instance) 1429 ->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); 1430 1431 validate_result(my_data->report_data, "vkEnumeratePhysicalDevices", result); 1432 if ((result == VK_SUCCESS) && (NULL != pPhysicalDevices)) { 1433 for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { 1434 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map); 1435 // Save the supported features for each physical device 1436 VkLayerInstanceDispatchTable *disp_table = get_dispatch_table(pc_instance_table_map, pPhysicalDevices[i]); 1437 disp_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i], &(phy_dev_data->physical_device_features)); 1438 } 1439 } 1440 } 1441 return result; 1442} 1443 1444VKAPI_ATTR void VKAPI_CALL 1445GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures) { 1446 bool skipCall = false; 1447 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1448 assert(my_data != NULL); 1449 1450 skipCall |= parameter_validation_vkGetPhysicalDeviceFeatures(my_data->report_data, pFeatures); 1451 1452 if (!skipCall) { 1453 get_dispatch_table(pc_instance_table_map, physicalDevice)->GetPhysicalDeviceFeatures(physicalDevice, pFeatures); 1454 } 1455} 1456 1457VKAPI_ATTR void VKAPI_CALL 1458GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) { 1459 bool skipCall = false; 1460 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1461 assert(my_data != NULL); 1462 1463 skipCall |= parameter_validation_vkGetPhysicalDeviceFormatProperties(my_data->report_data, format, pFormatProperties); 1464 1465 if (!skipCall) { 1466 get_dispatch_table(pc_instance_table_map, physicalDevice) 1467 ->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties); 1468 } 1469} 1470 1471VKAPI_ATTR VkResult VKAPI_CALL 1472GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, 1473 VkImageUsageFlags usage, VkImageCreateFlags flags, 1474 VkImageFormatProperties *pImageFormatProperties) { 1475 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1476 bool skipCall = false; 1477 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1478 assert(my_data != NULL); 1479 1480 skipCall |= parameter_validation_vkGetPhysicalDeviceImageFormatProperties(my_data->report_data, format, type, tiling, usage, flags, 1481 pImageFormatProperties); 1482 1483 if (!skipCall) { 1484 result = get_dispatch_table(pc_instance_table_map, physicalDevice) 1485 ->GetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, 1486 pImageFormatProperties); 1487 1488 validate_result(my_data->report_data, "vkGetPhysicalDeviceImageFormatProperties", result); 1489 } 1490 1491 return result; 1492} 1493 1494VKAPI_ATTR void VKAPI_CALL 1495GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties) { 1496 bool skipCall = false; 1497 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1498 assert(my_data != NULL); 1499 1500 skipCall |= parameter_validation_vkGetPhysicalDeviceProperties(my_data->report_data, pProperties); 1501 1502 if (!skipCall) { 1503 get_dispatch_table(pc_instance_table_map, physicalDevice)->GetPhysicalDeviceProperties(physicalDevice, pProperties); 1504 } 1505} 1506 1507VKAPI_ATTR void VKAPI_CALL 1508GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, 1509 VkQueueFamilyProperties *pQueueFamilyProperties) { 1510 bool skipCall = false; 1511 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1512 assert(my_data != NULL); 1513 1514 skipCall |= parameter_validation_vkGetPhysicalDeviceQueueFamilyProperties(my_data->report_data, pQueueFamilyPropertyCount, 1515 pQueueFamilyProperties); 1516 1517 if (!skipCall) { 1518 get_dispatch_table(pc_instance_table_map, physicalDevice) 1519 ->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties); 1520 } 1521} 1522 1523VKAPI_ATTR void VKAPI_CALL 1524GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) { 1525 bool skipCall = false; 1526 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1527 assert(my_data != NULL); 1528 1529 skipCall |= parameter_validation_vkGetPhysicalDeviceMemoryProperties(my_data->report_data, pMemoryProperties); 1530 1531 if (!skipCall) { 1532 get_dispatch_table(pc_instance_table_map, physicalDevice) 1533 ->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties); 1534 } 1535} 1536 1537void validateDeviceCreateInfo(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, 1538 const std::vector<VkQueueFamilyProperties> properties) { 1539 std::unordered_set<uint32_t> set; 1540 1541 if ((pCreateInfo != nullptr) && (pCreateInfo->pQueueCreateInfos != nullptr)) { 1542 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) { 1543 if (set.count(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex)) { 1544 log_msg(mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1545 INVALID_USAGE, LayerName, 1546 "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueFamilyIndex, is not unique within this " 1547 "structure.", 1548 i); 1549 } else { 1550 set.insert(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex); 1551 } 1552 1553 if (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities != nullptr) { 1554 for (uint32_t j = 0; j < pCreateInfo->pQueueCreateInfos[i].queueCount; ++j) { 1555 if ((pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j] < 0.f) || 1556 (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j] > 1.f)) { 1557 log_msg(mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 1558 __LINE__, INVALID_USAGE, LayerName, 1559 "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->pQueuePriorities[%d], must be " 1560 "between 0 and 1. Actual value is %f", 1561 i, j, pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j]); 1562 } 1563 } 1564 } 1565 1566 if (pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex >= properties.size()) { 1567 log_msg( 1568 mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1569 INVALID_USAGE, LayerName, 1570 "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueFamilyIndex cannot be more than the number " 1571 "of queue families.", 1572 i); 1573 } else if (pCreateInfo->pQueueCreateInfos[i].queueCount > 1574 properties[pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex].queueCount) { 1575 log_msg( 1576 mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1577 INVALID_USAGE, LayerName, 1578 "VkDeviceCreateInfo parameter, uint32_t pQueueCreateInfos[%d]->queueCount cannot be more than the number of " 1579 "queues for the given family index.", 1580 i); 1581 } 1582 } 1583 } 1584} 1585 1586void storeCreateDeviceData(VkDevice device, const VkDeviceCreateInfo *pCreateInfo) { 1587 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1588 1589 if ((pCreateInfo != nullptr) && (pCreateInfo->pQueueCreateInfos != nullptr)) { 1590 for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) { 1591 my_device_data->queueFamilyIndexMap.insert( 1592 std::make_pair(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex, pCreateInfo->pQueueCreateInfos[i].queueCount)); 1593 } 1594 } 1595} 1596 1597VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, 1598 const VkDeviceCreateInfo *pCreateInfo, 1599 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 1600 /* 1601 * NOTE: We do not validate physicalDevice or any dispatchable 1602 * object as the first parameter. We couldn't get here if it was wrong! 1603 */ 1604 1605 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1606 bool skipCall = false; 1607 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 1608 assert(my_instance_data != nullptr); 1609 1610 skipCall |= parameter_validation_vkCreateDevice(my_instance_data->report_data, pCreateInfo, pAllocator, pDevice); 1611 1612 if (pCreateInfo != NULL) { 1613 if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) { 1614 for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) { 1615 skipCall |= validate_string(my_instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledLayerNames", 1616 pCreateInfo->ppEnabledLayerNames[i]); 1617 } 1618 } 1619 1620 if ((pCreateInfo->enabledExtensionCount > 0) && (pCreateInfo->ppEnabledExtensionNames != NULL)) { 1621 for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { 1622 skipCall |= validate_string(my_instance_data->report_data, "vkCreateDevice", "pCreateInfo->ppEnabledExtensionNames", 1623 pCreateInfo->ppEnabledExtensionNames[i]); 1624 } 1625 } 1626 } 1627 1628 if (!skipCall) { 1629 VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 1630 assert(chain_info != nullptr); 1631 assert(chain_info->u.pLayerInfo != nullptr); 1632 1633 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 1634 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 1635 PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice"); 1636 if (fpCreateDevice == NULL) { 1637 return VK_ERROR_INITIALIZATION_FAILED; 1638 } 1639 1640 // Advance the link info for the next element on the chain 1641 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 1642 1643 result = fpCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); 1644 1645 validate_result(my_instance_data->report_data, "vkCreateDevice", result); 1646 1647 if (result == VK_SUCCESS) { 1648 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); 1649 assert(my_device_data != nullptr); 1650 1651 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice); 1652 initDeviceTable(*pDevice, fpGetDeviceProcAddr, pc_device_table_map); 1653 1654 1655 uint32_t count; 1656 VkLayerInstanceDispatchTable *instance_dispatch_table = get_dispatch_table(pc_instance_table_map, physicalDevice); 1657 instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr); 1658 std::vector<VkQueueFamilyProperties> properties(count); 1659 instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, &properties[0]); 1660 1661 validateDeviceCreateInfo(physicalDevice, pCreateInfo, properties); 1662 storeCreateDeviceData(*pDevice, pCreateInfo); 1663 1664 // Query and save physical device limits for this device 1665 VkPhysicalDeviceProperties device_properties = {}; 1666 instance_dispatch_table->GetPhysicalDeviceProperties(physicalDevice, &device_properties); 1667 memcpy(&my_device_data->device_limits, &device_properties.limits, sizeof(VkPhysicalDeviceLimits)); 1668 my_device_data->physical_device = physicalDevice; 1669 } 1670 } 1671 1672 return result; 1673} 1674 1675VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 1676 dispatch_key key = get_dispatch_key(device); 1677 bool skipCall = false; 1678 layer_data *my_data = get_my_data_ptr(key, layer_data_map); 1679 assert(my_data != NULL); 1680 1681 skipCall |= parameter_validation_vkDestroyDevice(my_data->report_data, pAllocator); 1682 1683 if (!skipCall) { 1684 layer_debug_report_destroy_device(device); 1685 1686#if DISPATCH_MAP_DEBUG 1687 fprintf(stderr, "Device: 0x%p, key: 0x%p\n", device, key); 1688#endif 1689 1690 get_dispatch_table(pc_device_table_map, device)->DestroyDevice(device, pAllocator); 1691 pc_device_table_map.erase(key); 1692 layer_data_map.erase(key); 1693 } 1694} 1695 1696bool PreGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex) { 1697 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1698 assert(my_device_data != nullptr); 1699 1700 validate_queue_family_index(my_device_data, "vkGetDeviceQueue", "queueFamilyIndex", queueFamilyIndex); 1701 1702 const auto &queue_data = my_device_data->queueFamilyIndexMap.find(queueFamilyIndex); 1703 if (queue_data->second <= queueIndex) { 1704 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, INVALID_USAGE, 1705 LayerName, 1706 "VkGetDeviceQueue parameter, uint32_t queueIndex %d, must be less than the number of queues given when the device " 1707 "was created.", 1708 queueIndex); 1709 return false; 1710 } 1711 return true; 1712} 1713 1714VKAPI_ATTR void VKAPI_CALL 1715GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { 1716 bool skipCall = false; 1717 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1718 assert(my_data != NULL); 1719 1720 skipCall |= parameter_validation_vkGetDeviceQueue(my_data->report_data, queueFamilyIndex, queueIndex, pQueue); 1721 1722 if (!skipCall) { 1723 PreGetDeviceQueue(device, queueFamilyIndex, queueIndex); 1724 1725 get_dispatch_table(pc_device_table_map, device)->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); 1726 } 1727} 1728 1729VKAPI_ATTR VkResult VKAPI_CALL 1730QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) { 1731 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1732 bool skipCall = false; 1733 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map); 1734 assert(my_data != NULL); 1735 1736 skipCall |= parameter_validation_vkQueueSubmit(my_data->report_data, submitCount, pSubmits, fence); 1737 1738 if (!skipCall) { 1739 result = get_dispatch_table(pc_device_table_map, queue)->QueueSubmit(queue, submitCount, pSubmits, fence); 1740 1741 validate_result(my_data->report_data, "vkQueueSubmit", result); 1742 } 1743 1744 return result; 1745} 1746 1747VKAPI_ATTR VkResult VKAPI_CALL QueueWaitIdle(VkQueue queue) { 1748 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map); 1749 assert(my_data != NULL); 1750 1751 VkResult result = get_dispatch_table(pc_device_table_map, queue)->QueueWaitIdle(queue); 1752 1753 validate_result(my_data->report_data, "vkQueueWaitIdle", result); 1754 1755 return result; 1756} 1757 1758VKAPI_ATTR VkResult VKAPI_CALL DeviceWaitIdle(VkDevice device) { 1759 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1760 assert(my_data != NULL); 1761 1762 VkResult result = get_dispatch_table(pc_device_table_map, device)->DeviceWaitIdle(device); 1763 1764 validate_result(my_data->report_data, "vkDeviceWaitIdle", result); 1765 1766 return result; 1767} 1768 1769VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, 1770 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) { 1771 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1772 bool skipCall = false; 1773 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1774 assert(my_data != NULL); 1775 1776 skipCall |= parameter_validation_vkAllocateMemory(my_data->report_data, pAllocateInfo, pAllocator, pMemory); 1777 1778 if (!skipCall) { 1779 result = get_dispatch_table(pc_device_table_map, device)->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory); 1780 1781 validate_result(my_data->report_data, "vkAllocateMemory", result); 1782 } 1783 1784 return result; 1785} 1786 1787VKAPI_ATTR void VKAPI_CALL 1788FreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator) { 1789 bool skipCall = false; 1790 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1791 assert(my_data != NULL); 1792 1793 skipCall |= parameter_validation_vkFreeMemory(my_data->report_data, memory, pAllocator); 1794 1795 if (!skipCall) { 1796 get_dispatch_table(pc_device_table_map, device)->FreeMemory(device, memory, pAllocator); 1797 } 1798} 1799 1800VKAPI_ATTR VkResult VKAPI_CALL 1801MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) { 1802 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1803 bool skipCall = false; 1804 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1805 assert(my_data != NULL); 1806 1807 skipCall |= parameter_validation_vkMapMemory(my_data->report_data, memory, offset, size, flags, ppData); 1808 1809 if (!skipCall) { 1810 result = get_dispatch_table(pc_device_table_map, device)->MapMemory(device, memory, offset, size, flags, ppData); 1811 1812 validate_result(my_data->report_data, "vkMapMemory", result); 1813 } 1814 1815 return result; 1816} 1817 1818VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory memory) { 1819 bool skipCall = false; 1820 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1821 assert(my_data != NULL); 1822 1823 skipCall |= parameter_validation_vkUnmapMemory(my_data->report_data, memory); 1824 1825 if (!skipCall) { 1826 get_dispatch_table(pc_device_table_map, device)->UnmapMemory(device, memory); 1827 } 1828} 1829 1830VKAPI_ATTR VkResult VKAPI_CALL 1831FlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges) { 1832 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1833 bool skipCall = false; 1834 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1835 assert(my_data != NULL); 1836 1837 skipCall |= parameter_validation_vkFlushMappedMemoryRanges(my_data->report_data, memoryRangeCount, pMemoryRanges); 1838 1839 if (!skipCall) { 1840 result = get_dispatch_table(pc_device_table_map, device)->FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges); 1841 1842 validate_result(my_data->report_data, "vkFlushMappedMemoryRanges", result); 1843 } 1844 1845 return result; 1846} 1847 1848VKAPI_ATTR VkResult VKAPI_CALL 1849InvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges) { 1850 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1851 bool skipCall = false; 1852 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1853 assert(my_data != NULL); 1854 1855 skipCall |= parameter_validation_vkInvalidateMappedMemoryRanges(my_data->report_data, memoryRangeCount, pMemoryRanges); 1856 1857 if (!skipCall) { 1858 result = 1859 get_dispatch_table(pc_device_table_map, device)->InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges); 1860 1861 validate_result(my_data->report_data, "vkInvalidateMappedMemoryRanges", result); 1862 } 1863 1864 return result; 1865} 1866 1867VKAPI_ATTR void VKAPI_CALL 1868GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize *pCommittedMemoryInBytes) { 1869 bool skipCall = false; 1870 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1871 assert(my_data != NULL); 1872 1873 skipCall |= parameter_validation_vkGetDeviceMemoryCommitment(my_data->report_data, memory, pCommittedMemoryInBytes); 1874 1875 if (!skipCall) { 1876 get_dispatch_table(pc_device_table_map, device)->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes); 1877 } 1878} 1879 1880VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, 1881 VkDeviceSize memoryOffset) { 1882 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1883 bool skipCall = false; 1884 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1885 assert(my_data != NULL); 1886 1887 skipCall |= parameter_validation_vkBindBufferMemory(my_data->report_data, buffer, memory, memoryOffset); 1888 1889 if (!skipCall) { 1890 result = get_dispatch_table(pc_device_table_map, device)->BindBufferMemory(device, buffer, memory, memoryOffset); 1891 1892 validate_result(my_data->report_data, "vkBindBufferMemory", result); 1893 } 1894 1895 return result; 1896} 1897 1898VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, 1899 VkDeviceSize memoryOffset) { 1900 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 1901 bool skipCall = false; 1902 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1903 assert(my_data != NULL); 1904 1905 skipCall |= parameter_validation_vkBindImageMemory(my_data->report_data, image, memory, memoryOffset); 1906 1907 if (!skipCall) { 1908 result = get_dispatch_table(pc_device_table_map, device)->BindImageMemory(device, image, memory, memoryOffset); 1909 1910 validate_result(my_data->report_data, "vkBindImageMemory", result); 1911 } 1912 1913 return result; 1914} 1915 1916VKAPI_ATTR void VKAPI_CALL 1917GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements) { 1918 bool skipCall = false; 1919 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1920 assert(my_data != NULL); 1921 1922 skipCall |= parameter_validation_vkGetBufferMemoryRequirements(my_data->report_data, buffer, pMemoryRequirements); 1923 1924 if (!skipCall) { 1925 get_dispatch_table(pc_device_table_map, device)->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements); 1926 } 1927} 1928 1929VKAPI_ATTR void VKAPI_CALL 1930GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements) { 1931 bool skipCall = false; 1932 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1933 assert(my_data != NULL); 1934 1935 skipCall |= parameter_validation_vkGetImageMemoryRequirements(my_data->report_data, image, pMemoryRequirements); 1936 1937 if (!skipCall) { 1938 get_dispatch_table(pc_device_table_map, device)->GetImageMemoryRequirements(device, image, pMemoryRequirements); 1939 } 1940} 1941 1942bool PostGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pNumRequirements, 1943 VkSparseImageMemoryRequirements *pSparseMemoryRequirements) { 1944 if (pSparseMemoryRequirements != nullptr) { 1945 if ((pSparseMemoryRequirements->formatProperties.aspectMask & 1946 (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | 1947 VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 1948 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1949 UNRECOGNIZED_VALUE, LayerName, 1950 "vkGetImageSparseMemoryRequirements parameter, VkImageAspect " 1951 "pSparseMemoryRequirements->formatProperties.aspectMask, is an unrecognized enumerator"); 1952 return false; 1953 } 1954 } 1955 1956 return true; 1957} 1958 1959VKAPI_ATTR void VKAPI_CALL 1960GetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount, 1961 VkSparseImageMemoryRequirements *pSparseMemoryRequirements) { 1962 bool skipCall = false; 1963 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 1964 assert(my_data != NULL); 1965 1966 skipCall |= parameter_validation_vkGetImageSparseMemoryRequirements(my_data->report_data, image, pSparseMemoryRequirementCount, 1967 pSparseMemoryRequirements); 1968 1969 if (!skipCall) { 1970 get_dispatch_table(pc_device_table_map, device) 1971 ->GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements); 1972 1973 PostGetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements); 1974 } 1975} 1976 1977bool PostGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, 1978 VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, 1979 uint32_t *pNumProperties, VkSparseImageFormatProperties *pProperties) { 1980 if (pProperties != nullptr) { 1981 if ((pProperties->aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | 1982 VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 1983 log_msg(mdd(physicalDevice), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 1, 1984 LayerName, 1985 "vkGetPhysicalDeviceSparseImageFormatProperties parameter, VkImageAspect pProperties->aspectMask, is an " 1986 "unrecognized enumerator"); 1987 return false; 1988 } 1989 } 1990 1991 return true; 1992} 1993 1994VKAPI_ATTR void VKAPI_CALL 1995GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, 1996 VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, 1997 uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties) { 1998 bool skipCall = false; 1999 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map); 2000 assert(my_data != NULL); 2001 2002 skipCall |= parameter_validation_vkGetPhysicalDeviceSparseImageFormatProperties(my_data->report_data, format, type, samples, usage, 2003 tiling, pPropertyCount, pProperties); 2004 2005 if (!skipCall) { 2006 get_dispatch_table(pc_instance_table_map, physicalDevice) 2007 ->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pPropertyCount, 2008 pProperties); 2009 2010 PostGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pPropertyCount, 2011 pProperties); 2012 } 2013} 2014 2015VKAPI_ATTR VkResult VKAPI_CALL 2016QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, VkFence fence) { 2017 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2018 bool skipCall = false; 2019 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map); 2020 assert(my_data != NULL); 2021 2022 skipCall |= parameter_validation_vkQueueBindSparse(my_data->report_data, bindInfoCount, pBindInfo, fence); 2023 2024 if (!skipCall) { 2025 result = get_dispatch_table(pc_device_table_map, queue)->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence); 2026 2027 validate_result(my_data->report_data, "vkQueueBindSparse", result); 2028 } 2029 2030 return result; 2031} 2032 2033VKAPI_ATTR VkResult VKAPI_CALL 2034CreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFence *pFence) { 2035 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2036 bool skipCall = false; 2037 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2038 assert(my_data != NULL); 2039 2040 skipCall |= parameter_validation_vkCreateFence(my_data->report_data, pCreateInfo, pAllocator, pFence); 2041 2042 if (!skipCall) { 2043 result = get_dispatch_table(pc_device_table_map, device)->CreateFence(device, pCreateInfo, pAllocator, pFence); 2044 2045 validate_result(my_data->report_data, "vkCreateFence", result); 2046 } 2047 2048 return result; 2049} 2050 2051VKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) { 2052 bool skipCall = false; 2053 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2054 assert(my_data != NULL); 2055 2056 skipCall |= parameter_validation_vkDestroyFence(my_data->report_data, fence, pAllocator); 2057 2058 if (!skipCall) { 2059 get_dispatch_table(pc_device_table_map, device)->DestroyFence(device, fence, pAllocator); 2060 } 2061} 2062 2063VKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) { 2064 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2065 bool skipCall = false; 2066 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2067 assert(my_data != NULL); 2068 2069 skipCall |= parameter_validation_vkResetFences(my_data->report_data, fenceCount, pFences); 2070 2071 if (!skipCall) { 2072 result = get_dispatch_table(pc_device_table_map, device)->ResetFences(device, fenceCount, pFences); 2073 2074 validate_result(my_data->report_data, "vkResetFences", result); 2075 } 2076 2077 return result; 2078} 2079 2080VKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence) { 2081 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2082 bool skipCall = false; 2083 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2084 assert(my_data != NULL); 2085 2086 skipCall |= parameter_validation_vkGetFenceStatus(my_data->report_data, fence); 2087 2088 if (!skipCall) { 2089 result = get_dispatch_table(pc_device_table_map, device)->GetFenceStatus(device, fence); 2090 2091 validate_result(my_data->report_data, "vkGetFenceStatus", result); 2092 } 2093 2094 return result; 2095} 2096 2097VKAPI_ATTR VkResult VKAPI_CALL 2098WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout) { 2099 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2100 bool skipCall = false; 2101 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2102 assert(my_data != NULL); 2103 2104 skipCall |= parameter_validation_vkWaitForFences(my_data->report_data, fenceCount, pFences, waitAll, timeout); 2105 2106 if (!skipCall) { 2107 result = get_dispatch_table(pc_device_table_map, device)->WaitForFences(device, fenceCount, pFences, waitAll, timeout); 2108 2109 validate_result(my_data->report_data, "vkWaitForFences", result); 2110 } 2111 2112 return result; 2113} 2114 2115VKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, 2116 const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) { 2117 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2118 bool skipCall = false; 2119 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2120 assert(my_data != NULL); 2121 2122 skipCall |= parameter_validation_vkCreateSemaphore(my_data->report_data, pCreateInfo, pAllocator, pSemaphore); 2123 2124 if (!skipCall) { 2125 result = get_dispatch_table(pc_device_table_map, device)->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore); 2126 2127 validate_result(my_data->report_data, "vkCreateSemaphore", result); 2128 } 2129 2130 return result; 2131} 2132 2133VKAPI_ATTR void VKAPI_CALL 2134DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) { 2135 bool skipCall = false; 2136 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2137 assert(my_data != NULL); 2138 2139 skipCall |= parameter_validation_vkDestroySemaphore(my_data->report_data, semaphore, pAllocator); 2140 2141 if (!skipCall) { 2142 get_dispatch_table(pc_device_table_map, device)->DestroySemaphore(device, semaphore, pAllocator); 2143 } 2144} 2145 2146VKAPI_ATTR VkResult VKAPI_CALL 2147CreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) { 2148 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2149 bool skipCall = false; 2150 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2151 assert(my_data != NULL); 2152 2153 skipCall |= parameter_validation_vkCreateEvent(my_data->report_data, pCreateInfo, pAllocator, pEvent); 2154 2155 if (!skipCall) { 2156 result = get_dispatch_table(pc_device_table_map, device)->CreateEvent(device, pCreateInfo, pAllocator, pEvent); 2157 2158 validate_result(my_data->report_data, "vkCreateEvent", result); 2159 } 2160 2161 return result; 2162} 2163 2164VKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) { 2165 bool skipCall = false; 2166 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2167 assert(my_data != NULL); 2168 2169 skipCall |= parameter_validation_vkDestroyEvent(my_data->report_data, event, pAllocator); 2170 2171 if (!skipCall) { 2172 get_dispatch_table(pc_device_table_map, device)->DestroyEvent(device, event, pAllocator); 2173 } 2174} 2175 2176VKAPI_ATTR VkResult VKAPI_CALL GetEventStatus(VkDevice device, VkEvent event) { 2177 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2178 bool skipCall = false; 2179 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2180 assert(my_data != NULL); 2181 2182 skipCall |= parameter_validation_vkGetEventStatus(my_data->report_data, event); 2183 2184 if (!skipCall) { 2185 result = get_dispatch_table(pc_device_table_map, device)->GetEventStatus(device, event); 2186 2187 validate_result(my_data->report_data, "vkGetEventStatus", result); 2188 } 2189 2190 return result; 2191} 2192 2193VKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event) { 2194 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2195 bool skipCall = false; 2196 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2197 assert(my_data != NULL); 2198 2199 skipCall |= parameter_validation_vkSetEvent(my_data->report_data, event); 2200 2201 if (!skipCall) { 2202 result = get_dispatch_table(pc_device_table_map, device)->SetEvent(device, event); 2203 2204 validate_result(my_data->report_data, "vkSetEvent", result); 2205 } 2206 2207 return result; 2208} 2209 2210VKAPI_ATTR VkResult VKAPI_CALL ResetEvent(VkDevice device, VkEvent event) { 2211 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2212 bool skipCall = false; 2213 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2214 assert(my_data != NULL); 2215 2216 skipCall |= parameter_validation_vkResetEvent(my_data->report_data, event); 2217 2218 if (!skipCall) { 2219 result = get_dispatch_table(pc_device_table_map, device)->ResetEvent(device, event); 2220 2221 validate_result(my_data->report_data, "vkResetEvent", result); 2222 } 2223 2224 return result; 2225} 2226 2227VKAPI_ATTR VkResult VKAPI_CALL CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, 2228 const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) { 2229 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2230 bool skip_call = false; 2231 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2232 assert(device_data != nullptr); 2233 debug_report_data *report_data = device_data->report_data; 2234 2235 skip_call |= parameter_validation_vkCreateQueryPool(device_data->report_data, pCreateInfo, pAllocator, pQueryPool); 2236 2237 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 2238 if (pCreateInfo != nullptr) { 2239 // If queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, pipelineStatistics must be a valid combination of 2240 // VkQueryPipelineStatisticFlagBits values 2241 if ((pCreateInfo->queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) && (pCreateInfo->pipelineStatistics != 0) && 2242 ((pCreateInfo->pipelineStatistics & (~AllVkQueryPipelineStatisticFlagBits)) != 0)) { 2243 skip_call |= 2244 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2245 UNRECOGNIZED_VALUE, LayerName, "vkCreateQueryPool: if pCreateInfo->queryType is " 2246 "VK_QUERY_TYPE_PIPELINE_STATISTICS, pCreateInfo->pipelineStatistics must be " 2247 "a valid combination of VkQueryPipelineStatisticFlagBits values"); 2248 } 2249 } 2250 2251 if (!skip_call) { 2252 result = get_dispatch_table(pc_device_table_map, device)->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool); 2253 2254 validate_result(report_data, "vkCreateQueryPool", result); 2255 } 2256 2257 return result; 2258} 2259 2260VKAPI_ATTR void VKAPI_CALL 2261DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) { 2262 bool skipCall = false; 2263 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2264 assert(my_data != NULL); 2265 2266 skipCall |= parameter_validation_vkDestroyQueryPool(my_data->report_data, queryPool, pAllocator); 2267 2268 if (!skipCall) { 2269 get_dispatch_table(pc_device_table_map, device)->DestroyQueryPool(device, queryPool, pAllocator); 2270 } 2271} 2272 2273VKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, 2274 uint32_t queryCount, size_t dataSize, void *pData, 2275 VkDeviceSize stride, VkQueryResultFlags flags) { 2276 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2277 bool skipCall = false; 2278 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2279 assert(my_data != NULL); 2280 2281 skipCall |= 2282 parameter_validation_vkGetQueryPoolResults(my_data->report_data, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags); 2283 2284 if (!skipCall) { 2285 result = get_dispatch_table(pc_device_table_map, device) 2286 ->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags); 2287 2288 validate_result(my_data->report_data, "vkGetQueryPoolResults", result); 2289 } 2290 2291 return result; 2292} 2293 2294VKAPI_ATTR VkResult VKAPI_CALL 2295CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) { 2296 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2297 bool skip_call = false; 2298 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2299 assert(device_data != nullptr); 2300 debug_report_data *report_data = device_data->report_data; 2301 2302 skip_call |= parameter_validation_vkCreateBuffer(report_data, pCreateInfo, pAllocator, pBuffer); 2303 2304 if (pCreateInfo != nullptr) { 2305 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 2306 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) { 2307 // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1 2308 if (pCreateInfo->queueFamilyIndexCount <= 1) { 2309 skip_call |= 2310 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2311 INVALID_USAGE, LayerName, "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, " 2312 "pCreateInfo->queueFamilyIndexCount must be greater than 1"); 2313 } 2314 2315 // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of 2316 // queueFamilyIndexCount uint32_t values 2317 if (pCreateInfo->pQueueFamilyIndices == nullptr) { 2318 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2319 __LINE__, REQUIRED_PARAMETER, LayerName, 2320 "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, " 2321 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of " 2322 "pCreateInfo->queueFamilyIndexCount uint32_t values"); 2323 } 2324 2325 // Ensure that the queue family indices were specified at device creation 2326 skip_call |= validate_queue_family_indices(device_data, "vkCreateBuffer", "pCreateInfo->pQueueFamilyIndices", 2327 pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices); 2328 } 2329 } 2330 2331 if (!skip_call) { 2332 result = get_dispatch_table(pc_device_table_map, device)->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer); 2333 2334 validate_result(report_data, "vkCreateBuffer", result); 2335 } 2336 2337 return result; 2338} 2339 2340VKAPI_ATTR void VKAPI_CALL 2341DestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) { 2342 bool skipCall = false; 2343 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2344 assert(my_data != NULL); 2345 2346 skipCall |= parameter_validation_vkDestroyBuffer(my_data->report_data, buffer, pAllocator); 2347 2348 if (!skipCall) { 2349 get_dispatch_table(pc_device_table_map, device)->DestroyBuffer(device, buffer, pAllocator); 2350 } 2351} 2352 2353VKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo, 2354 const VkAllocationCallbacks *pAllocator, VkBufferView *pView) { 2355 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2356 bool skipCall = false; 2357 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2358 assert(my_data != NULL); 2359 2360 skipCall |= parameter_validation_vkCreateBufferView(my_data->report_data, pCreateInfo, pAllocator, pView); 2361 2362 if (!skipCall) { 2363 result = get_dispatch_table(pc_device_table_map, device)->CreateBufferView(device, pCreateInfo, pAllocator, pView); 2364 2365 validate_result(my_data->report_data, "vkCreateBufferView", result); 2366 } 2367 2368 return result; 2369} 2370 2371VKAPI_ATTR void VKAPI_CALL 2372DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) { 2373 bool skipCall = false; 2374 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2375 assert(my_data != NULL); 2376 2377 skipCall |= parameter_validation_vkDestroyBufferView(my_data->report_data, bufferView, pAllocator); 2378 2379 if (!skipCall) { 2380 get_dispatch_table(pc_device_table_map, device)->DestroyBufferView(device, bufferView, pAllocator); 2381 } 2382} 2383 2384VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, 2385 const VkAllocationCallbacks *pAllocator, VkImage *pImage) { 2386 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2387 bool skip_call = false; 2388 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2389 assert(device_data != nullptr); 2390 debug_report_data *report_data = device_data->report_data; 2391 2392 skip_call |= parameter_validation_vkCreateImage(report_data, pCreateInfo, pAllocator, pImage); 2393 2394 if (pCreateInfo != nullptr) { 2395 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 2396 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) { 2397 // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1 2398 if (pCreateInfo->queueFamilyIndexCount <= 1) { 2399 skip_call |= 2400 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2401 INVALID_USAGE, LayerName, "vkCreateImage: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, " 2402 "pCreateInfo->queueFamilyIndexCount must be greater than 1"); 2403 } 2404 2405 // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of 2406 // queueFamilyIndexCount uint32_t values 2407 if (pCreateInfo->pQueueFamilyIndices == nullptr) { 2408 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2409 __LINE__, REQUIRED_PARAMETER, LayerName, 2410 "vkCreateImage: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, " 2411 "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of " 2412 "pCreateInfo->queueFamilyIndexCount uint32_t values"); 2413 } 2414 2415 skip_call |= validate_queue_family_indices(device_data, "vkCreateImage", "pCreateInfo->pQueueFamilyIndices", 2416 pCreateInfo->queueFamilyIndexCount, pCreateInfo->pQueueFamilyIndices); 2417 } 2418 2419 // width, height, and depth members of extent must be greater than 0 2420 skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.width", pCreateInfo->extent.width, 2421 0u); 2422 skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.height", pCreateInfo->extent.height, 2423 0u); 2424 skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->extent.depth", pCreateInfo->extent.depth, 2425 0u); 2426 2427 // mipLevels must be greater than 0 2428 skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->mipLevels", pCreateInfo->mipLevels, 2429 0u); 2430 2431 // arrayLayers must be greater than 0 2432 skip_call |= ValidateGreaterThan(report_data, "vkCreateImage", "pCreateInfo->arrayLayers", pCreateInfo->arrayLayers, 2433 0u); 2434 2435 // If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1 2436 if ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) && (pCreateInfo->extent.height != 1) && (pCreateInfo->extent.depth != 1)) { 2437 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2438 LayerName, "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_1D, both " 2439 "pCreateInfo->extent.height and pCreateInfo->extent.depth must be 1"); 2440 } 2441 2442 if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D) { 2443 // If imageType is VK_IMAGE_TYPE_2D and flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and 2444 // extent.height must be equal 2445 if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 2446 (pCreateInfo->extent.width != pCreateInfo->extent.height)) { 2447 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2448 LayerName, "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_2D and " 2449 "pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, " 2450 "pCreateInfo->extent.width and pCreateInfo->extent.height must be equal"); 2451 } 2452 2453 if (pCreateInfo->extent.depth != 1) { 2454 skip_call |= 2455 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName, 2456 "vkCreateImage: if pCreateInfo->imageType is VK_IMAGE_TYPE_2D, pCreateInfo->extent.depth must be 1"); 2457 } 2458 } 2459 2460 // mipLevels must be less than or equal to floor(log2(max(extent.width,extent.height,extent.depth)))+1 2461 uint32_t maxDim = std::max(std::max(pCreateInfo->extent.width, pCreateInfo->extent.height), pCreateInfo->extent.depth); 2462 if (pCreateInfo->mipLevels > (floor(log2(maxDim)) + 1)) { 2463 skip_call |= log_msg( 2464 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, LayerName, 2465 "vkCreateImage: pCreateInfo->mipLevels must be less than or equal to " 2466 "floor(log2(max(pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth)))+1"); 2467 } 2468 2469 // If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain 2470 // VK_IMAGE_CREATE_SPARSE_BINDING_BIT 2471 if (((pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) != 0) && 2472 ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { 2473 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2474 LayerName, 2475 "vkCreateImage: pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or " 2476 "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT"); 2477 } 2478 } 2479 2480 if (!skip_call) { 2481 result = get_dispatch_table(pc_device_table_map, device)->CreateImage(device, pCreateInfo, pAllocator, pImage); 2482 2483 validate_result(report_data, "vkCreateImage", result); 2484 } 2485 2486 return result; 2487} 2488 2489VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) { 2490 bool skipCall = false; 2491 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2492 assert(my_data != NULL); 2493 2494 skipCall |= parameter_validation_vkDestroyImage(my_data->report_data, image, pAllocator); 2495 2496 if (!skipCall) { 2497 get_dispatch_table(pc_device_table_map, device)->DestroyImage(device, image, pAllocator); 2498 } 2499} 2500 2501bool PreGetImageSubresourceLayout(VkDevice device, const VkImageSubresource *pSubresource) { 2502 if (pSubresource != nullptr) { 2503 if ((pSubresource->aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | 2504 VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 2505 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2506 UNRECOGNIZED_VALUE, LayerName, 2507 "vkGetImageSubresourceLayout parameter, VkImageAspect pSubresource->aspectMask, is an unrecognized enumerator"); 2508 return false; 2509 } 2510 } 2511 2512 return true; 2513} 2514 2515VKAPI_ATTR void VKAPI_CALL 2516GetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) { 2517 bool skipCall = false; 2518 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2519 assert(my_data != NULL); 2520 2521 skipCall |= parameter_validation_vkGetImageSubresourceLayout(my_data->report_data, image, pSubresource, pLayout); 2522 2523 if (!skipCall) { 2524 PreGetImageSubresourceLayout(device, pSubresource); 2525 2526 get_dispatch_table(pc_device_table_map, device)->GetImageSubresourceLayout(device, image, pSubresource, pLayout); 2527 } 2528} 2529 2530VKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, 2531 const VkAllocationCallbacks *pAllocator, VkImageView *pView) { 2532 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2533 bool skip_call = false; 2534 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2535 assert(my_data != NULL); 2536 debug_report_data *report_data = my_data->report_data; 2537 2538 skip_call |= parameter_validation_vkCreateImageView(report_data, pCreateInfo, pAllocator, pView); 2539 2540 if (pCreateInfo != nullptr) { 2541 if ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D) || (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_2D)) { 2542 if ((pCreateInfo->subresourceRange.layerCount != 1) && 2543 (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) { 2544 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2545 LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_%dD, " 2546 "pCreateInfo->subresourceRange.layerCount must be 1", 2547 ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D) ? 1 : 2)); 2548 } 2549 } else if ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY) || 2550 (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY)) { 2551 if ((pCreateInfo->subresourceRange.layerCount < 1) && 2552 (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) { 2553 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2554 LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_%dD_ARRAY, " 2555 "pCreateInfo->subresourceRange.layerCount must be >= 1", 2556 ((pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? 1 : 2)); 2557 } 2558 } else if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE) { 2559 if ((pCreateInfo->subresourceRange.layerCount != 6) && 2560 (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) { 2561 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2562 LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_CUBE, " 2563 "pCreateInfo->subresourceRange.layerCount must be 6"); 2564 } 2565 } else if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) { 2566 if (((pCreateInfo->subresourceRange.layerCount == 0) || ((pCreateInfo->subresourceRange.layerCount % 6) != 0)) && 2567 (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) { 2568 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2569 LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_CUBE_ARRAY, " 2570 "pCreateInfo->subresourceRange.layerCount must be a multiple of 6"); 2571 } 2572 } else if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) { 2573 if (pCreateInfo->subresourceRange.baseArrayLayer != 0) { 2574 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2575 LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_3D, " 2576 "pCreateInfo->subresourceRange.baseArrayLayer must be 0"); 2577 } 2578 2579 if ((pCreateInfo->subresourceRange.layerCount != 1) && 2580 (pCreateInfo->subresourceRange.layerCount != VK_REMAINING_ARRAY_LAYERS)) { 2581 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, 2582 LayerName, "vkCreateImageView: if pCreateInfo->viewType is VK_IMAGE_TYPE_3D, " 2583 "pCreateInfo->subresourceRange.layerCount must be 1"); 2584 } 2585 } 2586 } 2587 2588 if (!skip_call) { 2589 result = get_dispatch_table(pc_device_table_map, device)->CreateImageView(device, pCreateInfo, pAllocator, pView); 2590 2591 validate_result(my_data->report_data, "vkCreateImageView", result); 2592 } 2593 2594 return result; 2595} 2596 2597VKAPI_ATTR void VKAPI_CALL 2598DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) { 2599 bool skipCall = false; 2600 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2601 assert(my_data != NULL); 2602 2603 skipCall |= parameter_validation_vkDestroyImageView(my_data->report_data, imageView, pAllocator); 2604 2605 if (!skipCall) { 2606 get_dispatch_table(pc_device_table_map, device)->DestroyImageView(device, imageView, pAllocator); 2607 } 2608} 2609 2610VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo, 2611 const VkAllocationCallbacks *pAllocator, 2612 VkShaderModule *pShaderModule) { 2613 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2614 bool skipCall = false; 2615 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2616 assert(my_data != NULL); 2617 2618 skipCall |= parameter_validation_vkCreateShaderModule(my_data->report_data, pCreateInfo, pAllocator, pShaderModule); 2619 2620 if (!skipCall) { 2621 result = 2622 get_dispatch_table(pc_device_table_map, device)->CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule); 2623 2624 validate_result(my_data->report_data, "vkCreateShaderModule", result); 2625 } 2626 2627 return result; 2628} 2629 2630VKAPI_ATTR void VKAPI_CALL 2631DestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator) { 2632 bool skipCall = false; 2633 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2634 assert(my_data != NULL); 2635 2636 skipCall |= parameter_validation_vkDestroyShaderModule(my_data->report_data, shaderModule, pAllocator); 2637 2638 if (!skipCall) { 2639 get_dispatch_table(pc_device_table_map, device)->DestroyShaderModule(device, shaderModule, pAllocator); 2640 } 2641} 2642 2643VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo, 2644 const VkAllocationCallbacks *pAllocator, 2645 VkPipelineCache *pPipelineCache) { 2646 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2647 bool skipCall = false; 2648 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2649 assert(my_data != NULL); 2650 2651 skipCall |= parameter_validation_vkCreatePipelineCache(my_data->report_data, pCreateInfo, pAllocator, pPipelineCache); 2652 2653 if (!skipCall) { 2654 result = 2655 get_dispatch_table(pc_device_table_map, device)->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache); 2656 2657 validate_result(my_data->report_data, "vkCreatePipelineCache", result); 2658 } 2659 2660 return result; 2661} 2662 2663VKAPI_ATTR void VKAPI_CALL 2664DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks *pAllocator) { 2665 bool skipCall = false; 2666 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2667 assert(my_data != NULL); 2668 2669 skipCall |= parameter_validation_vkDestroyPipelineCache(my_data->report_data, pipelineCache, pAllocator); 2670 2671 if (!skipCall) { 2672 get_dispatch_table(pc_device_table_map, device)->DestroyPipelineCache(device, pipelineCache, pAllocator); 2673 } 2674} 2675 2676VKAPI_ATTR VkResult VKAPI_CALL 2677GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, void *pData) { 2678 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2679 bool skipCall = false; 2680 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2681 assert(my_data != NULL); 2682 2683 skipCall |= parameter_validation_vkGetPipelineCacheData(my_data->report_data, pipelineCache, pDataSize, pData); 2684 2685 if (!skipCall) { 2686 result = get_dispatch_table(pc_device_table_map, device)->GetPipelineCacheData(device, pipelineCache, pDataSize, pData); 2687 2688 validate_result(my_data->report_data, "vkGetPipelineCacheData", result); 2689 } 2690 2691 return result; 2692} 2693 2694VKAPI_ATTR VkResult VKAPI_CALL 2695MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches) { 2696 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2697 bool skipCall = false; 2698 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2699 assert(my_data != NULL); 2700 2701 skipCall |= parameter_validation_vkMergePipelineCaches(my_data->report_data, dstCache, srcCacheCount, pSrcCaches); 2702 2703 if (!skipCall) { 2704 result = get_dispatch_table(pc_device_table_map, device)->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches); 2705 2706 validate_result(my_data->report_data, "vkMergePipelineCaches", result); 2707 } 2708 2709 return result; 2710} 2711 2712bool PreCreateGraphicsPipelines(VkDevice device, const VkGraphicsPipelineCreateInfo *pCreateInfos) { 2713 layer_data *data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2714 2715 // TODO: Handle count 2716 if (pCreateInfos != nullptr) { 2717 if (pCreateInfos->flags | VK_PIPELINE_CREATE_DERIVATIVE_BIT) { 2718 if (pCreateInfos->basePipelineIndex != -1) { 2719 if (pCreateInfos->basePipelineHandle != VK_NULL_HANDLE) { 2720 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2721 INVALID_USAGE, LayerName, 2722 "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineHandle, must be VK_NULL_HANDLE if " 2723 "pCreateInfos->flags " 2724 "contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag and pCreateInfos->basePipelineIndex is not -1"); 2725 return false; 2726 } 2727 } 2728 2729 if (pCreateInfos->basePipelineHandle != VK_NULL_HANDLE) { 2730 if (pCreateInfos->basePipelineIndex != -1) { 2731 log_msg( 2732 mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2733 INVALID_USAGE, LayerName, 2734 "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineIndex, must be -1 if pCreateInfos->flags " 2735 "contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag and pCreateInfos->basePipelineHandle is not " 2736 "VK_NULL_HANDLE"); 2737 return false; 2738 } 2739 } 2740 } 2741 2742 if (pCreateInfos->pRasterizationState != nullptr) { 2743 if (pCreateInfos->pRasterizationState->cullMode & ~VK_CULL_MODE_FRONT_AND_BACK) { 2744 log_msg(mdd(device), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2745 UNRECOGNIZED_VALUE, LayerName, 2746 "vkCreateGraphicsPipelines parameter, VkCullMode pCreateInfos->pRasterizationState->cullMode, is an " 2747 "unrecognized enumerator"); 2748 return false; 2749 } 2750 } 2751 2752 int i = 0; 2753 for (size_t j = 0; j < pCreateInfos[i].stageCount; j++) { 2754 validate_string(data->report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pStages[j].pName", 2755 pCreateInfos[i].pStages[j].pName); 2756 } 2757 } 2758 2759 return true; 2760} 2761 2762VKAPI_ATTR VkResult VKAPI_CALL 2763CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, 2764 const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, 2765 VkPipeline *pPipelines) { 2766 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 2767 bool skip_call = false; 2768 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 2769 assert(device_data != nullptr); 2770 debug_report_data *report_data = device_data->report_data; 2771 2772 skip_call |= parameter_validation_vkCreateGraphicsPipelines(report_data, pipelineCache, createInfoCount, pCreateInfos, 2773 pAllocator, pPipelines); 2774 2775 if (pCreateInfos != nullptr) { 2776 for (uint32_t i = 0; i < createInfoCount; ++i) { 2777 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 2778 if (pCreateInfos[i].pTessellationState == nullptr) { 2779 if (pCreateInfos[i].pStages != nullptr) { 2780 // If pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, 2781 // pTessellationState must not be NULL 2782 bool has_control = false; 2783 bool has_eval = false; 2784 2785 for (uint32_t stage_index = 0; stage_index < pCreateInfos[i].stageCount; ++stage_index) { 2786 if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) { 2787 has_control = true; 2788 } else if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) { 2789 has_eval = true; 2790 } 2791 } 2792 2793 if (has_control && has_eval) { 2794 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2795 __LINE__, REQUIRED_PARAMETER, LayerName, 2796 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pStages includes a tessellation " 2797 "control shader stage and a tessellation evaluation shader stage, " 2798 "pCreateInfos[%d].pTessellationState must not be NULL", 2799 i, i); 2800 } 2801 } 2802 } else { 2803 skip_call |= 2804 validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->pNext", 2805 NULL, pCreateInfos[i].pTessellationState->pNext, 0, NULL, GeneratedHeaderVersion); 2806 2807 skip_call |= 2808 validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->flags", 2809 pCreateInfos[i].pTessellationState->flags); 2810 2811 if (pCreateInfos[i].pTessellationState->sType != VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) { 2812 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2813 __LINE__, INVALID_STRUCT_STYPE, LayerName, 2814 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pTessellationState->sType must be " 2815 "VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO", 2816 i); 2817 } 2818 } 2819 2820 if (pCreateInfos[i].pViewportState == nullptr) { 2821 // If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, pViewportState must be a pointer to a 2822 // valid VkPipelineViewportStateCreateInfo structure 2823 if ((pCreateInfos[i].pRasterizationState != nullptr) && 2824 (pCreateInfos[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) { 2825 skip_call |= log_msg( 2826 report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2827 REQUIRED_PARAMETER, LayerName, 2828 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pRasterizationState->rasterizerDiscardEnable is VK_FALSE, " 2829 "pCreateInfos[%d].pViewportState must be a pointer to a valid VkPipelineViewportStateCreateInfo structure", 2830 i, i); 2831 } 2832 } else { 2833 skip_call |= 2834 validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pViewportState->pNext", NULL, 2835 pCreateInfos[i].pViewportState->pNext, 0, NULL, GeneratedHeaderVersion); 2836 2837 skip_call |= 2838 validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pViewportState->flags", 2839 pCreateInfos[i].pViewportState->flags); 2840 2841 if (pCreateInfos[i].pViewportState->sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) { 2842 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2843 __LINE__, INVALID_STRUCT_STYPE, LayerName, 2844 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pViewportState->sType must be " 2845 "VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO", 2846 i); 2847 } 2848 2849 if (pCreateInfos[i].pDynamicState != nullptr) { 2850 bool has_dynamic_viewport = false; 2851 bool has_dynamic_scissor = false; 2852 2853 for (uint32_t state_index = 0; state_index < pCreateInfos[i].pDynamicState->dynamicStateCount; ++state_index) { 2854 if (pCreateInfos[i].pDynamicState->pDynamicStates[state_index] == VK_DYNAMIC_STATE_VIEWPORT) { 2855 has_dynamic_viewport = true; 2856 } else if (pCreateInfos[i].pDynamicState->pDynamicStates[state_index] == VK_DYNAMIC_STATE_SCISSOR) { 2857 has_dynamic_scissor = true; 2858 } 2859 } 2860 2861 // viewportCount must be greater than 0 2862 // TODO: viewportCount must be 1 when multiple_viewport feature is not enabled 2863 if (pCreateInfos[i].pViewportState->viewportCount == 0) { 2864 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2865 __LINE__, REQUIRED_PARAMETER, LayerName, 2866 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pDynamicState->pDynamicStates " 2867 "contains VK_DYNAMIC_STATE_VIEWPORT, pCreateInfos[%d].pViewportState->viewportCount " 2868 "must be greater than 0", 2869 i, i); 2870 } 2871 2872 // If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_VIEWPORT, the pViewports 2873 // member of pViewportState must be a pointer to an array of pViewportState->viewportCount VkViewport structures 2874 if (!has_dynamic_viewport && (pCreateInfos[i].pViewportState->pViewports == nullptr)) { 2875 skip_call |= 2876 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2877 __LINE__, REQUIRED_PARAMETER, LayerName, 2878 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pDynamicState->pDynamicStates contains " 2879 "VK_DYNAMIC_STATE_VIEWPORT, pCreateInfos[%d].pViewportState->pViewports must not be NULL", 2880 i, i); 2881 } 2882 2883 // scissorCount must be greater than 0 2884 // TODO: scissorCount must be 1 when multiple_viewport feature is not enabled 2885 if (pCreateInfos[i].pViewportState->scissorCount == 0) { 2886 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2887 __LINE__, REQUIRED_PARAMETER, LayerName, 2888 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pDynamicState->pDynamicStates " 2889 "contains VK_DYNAMIC_STATE_SCISSOR, pCreateInfos[%d].pViewportState->scissorCount " 2890 "must be greater than 0", 2891 i, i); 2892 } 2893 2894 // If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_SCISSOR, the pScissors member 2895 // of pViewportState must be a pointer to an array of pViewportState->scissorCount VkRect2D structures 2896 if (!has_dynamic_scissor && (pCreateInfos[i].pViewportState->pScissors == nullptr)) { 2897 skip_call |= 2898 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2899 __LINE__, REQUIRED_PARAMETER, LayerName, 2900 "vkCreateGraphicsPipelines: if pCreateInfos[%d].pDynamicState->pDynamicStates contains " 2901 "VK_DYNAMIC_STATE_SCISSOR, pCreateInfos[%d].pViewportState->pScissors must not be NULL", 2902 i, i); 2903 } 2904 } 2905 } 2906 2907 if (pCreateInfos[i].pMultisampleState == nullptr) { 2908 // If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, pMultisampleState must be a pointer to 2909 // a valid VkPipelineMultisampleStateCreateInfo structure 2910 if ((pCreateInfos[i].pRasterizationState != nullptr) && 2911 pCreateInfos[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE) { 2912 skip_call |= 2913 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2914 REQUIRED_PARAMETER, LayerName, "vkCreateGraphicsPipelines: if " 2915 "pCreateInfos[%d].pRasterizationState->rasterizerDiscardEnable is " 2916 "VK_FALSE, pCreateInfos[%d].pMultisampleState must not be NULL", 2917 i, i); 2918 } 2919 } else { 2920 skip_call |= 2921 validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->pNext", 2922 NULL, pCreateInfos[i].pMultisampleState->pNext, 0, NULL, GeneratedHeaderVersion); 2923 2924 skip_call |= 2925 validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->flags", 2926 pCreateInfos[i].pMultisampleState->flags); 2927 2928 skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines", 2929 "pCreateInfos[i].pMultisampleState->sampleShadingEnable", 2930 pCreateInfos[i].pMultisampleState->sampleShadingEnable); 2931 2932 skip_call |= validate_array( 2933 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->rasterizationSamples", 2934 "pCreateInfos[i].pMultisampleState->pSampleMask", pCreateInfos[i].pMultisampleState->rasterizationSamples, 2935 pCreateInfos[i].pMultisampleState->pSampleMask, true, false); 2936 2937 skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines", 2938 "pCreateInfos[i].pMultisampleState->alphaToCoverageEnable", 2939 pCreateInfos[i].pMultisampleState->alphaToCoverageEnable); 2940 2941 skip_call |= 2942 validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pMultisampleState->alphaToOneEnable", 2943 pCreateInfos[i].pMultisampleState->alphaToOneEnable); 2944 2945 if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) { 2946 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 2947 __LINE__, INVALID_STRUCT_STYPE, LayerName, 2948 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pMultisampleState->sType must be " 2949 "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO", 2950 i); 2951 } 2952 } 2953 2954 // TODO: Conditional NULL check based on rasterizerDiscardEnable and subpass 2955 if (pCreateInfos[i].pDepthStencilState != nullptr) { 2956 skip_call |= 2957 validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->pNext", 2958 NULL, pCreateInfos[i].pDepthStencilState->pNext, 0, NULL, GeneratedHeaderVersion); 2959 2960 skip_call |= 2961 validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->flags", 2962 pCreateInfos[i].pDepthStencilState->flags); 2963 2964 skip_call |= 2965 validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->depthTestEnable", 2966 pCreateInfos[i].pDepthStencilState->depthTestEnable); 2967 2968 skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines", 2969 "pCreateInfos[i].pDepthStencilState->depthWriteEnable", 2970 pCreateInfos[i].pDepthStencilState->depthWriteEnable); 2971 2972 skip_call |= validate_ranged_enum( 2973 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->depthCompareOp", "VkCompareOp", 2974 VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->depthCompareOp); 2975 2976 skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines", 2977 "pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable", 2978 pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable); 2979 2980 skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines", 2981 "pCreateInfos[i].pDepthStencilState->stencilTestEnable", 2982 pCreateInfos[i].pDepthStencilState->stencilTestEnable); 2983 2984 skip_call |= validate_ranged_enum( 2985 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.failOp", "VkStencilOp", 2986 VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.failOp); 2987 2988 skip_call |= validate_ranged_enum( 2989 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.passOp", "VkStencilOp", 2990 VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.passOp); 2991 2992 skip_call |= validate_ranged_enum(report_data, "vkCreateGraphicsPipelines", 2993 "pCreateInfos[i].pDepthStencilState->front.depthFailOp", "VkStencilOp", 2994 VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, 2995 pCreateInfos[i].pDepthStencilState->front.depthFailOp); 2996 2997 skip_call |= validate_ranged_enum( 2998 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->front.compareOp", "VkCompareOp", 2999 VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->front.compareOp); 3000 3001 skip_call |= validate_ranged_enum( 3002 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.failOp", "VkStencilOp", 3003 VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.failOp); 3004 3005 skip_call |= validate_ranged_enum( 3006 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.passOp", "VkStencilOp", 3007 VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.passOp); 3008 3009 skip_call |= validate_ranged_enum( 3010 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.depthFailOp", "VkStencilOp", 3011 VK_STENCIL_OP_BEGIN_RANGE, VK_STENCIL_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.depthFailOp); 3012 3013 skip_call |= validate_ranged_enum( 3014 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pDepthStencilState->back.compareOp", "VkCompareOp", 3015 VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfos[i].pDepthStencilState->back.compareOp); 3016 3017 if (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) { 3018 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3019 __LINE__, INVALID_STRUCT_STYPE, LayerName, 3020 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pDepthStencilState->sType must be " 3021 "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO", 3022 i); 3023 } 3024 } 3025 3026 // TODO: Conditional NULL check based on rasterizerDiscardEnable and subpass 3027 if (pCreateInfos[i].pColorBlendState != nullptr) { 3028 skip_call |= 3029 validate_struct_pnext(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->pNext", NULL, 3030 pCreateInfos[i].pColorBlendState->pNext, 0, NULL, GeneratedHeaderVersion); 3031 3032 skip_call |= 3033 validate_reserved_flags(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->flags", 3034 pCreateInfos[i].pColorBlendState->flags); 3035 3036 skip_call |= 3037 validate_bool32(report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->logicOpEnable", 3038 pCreateInfos[i].pColorBlendState->logicOpEnable); 3039 3040 skip_call |= validate_array( 3041 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->attachmentCount", 3042 "pCreateInfos[i].pColorBlendState->pAttachments", pCreateInfos[i].pColorBlendState->attachmentCount, 3043 pCreateInfos[i].pColorBlendState->pAttachments, false, true); 3044 3045 if (pCreateInfos[i].pColorBlendState->pAttachments != NULL) { 3046 for (uint32_t attachmentIndex = 0; attachmentIndex < pCreateInfos[i].pColorBlendState->attachmentCount; 3047 ++attachmentIndex) { 3048 skip_call |= validate_bool32(report_data, "vkCreateGraphicsPipelines", 3049 "pCreateInfos[i].pColorBlendState->pAttachments[i].blendEnable", 3050 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].blendEnable); 3051 3052 skip_call |= validate_ranged_enum( 3053 report_data, "vkCreateGraphicsPipelines", 3054 "pCreateInfos[i].pColorBlendState->pAttachments[i].srcColorBlendFactor", "VkBlendFactor", 3055 VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE, 3056 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcColorBlendFactor); 3057 3058 skip_call |= validate_ranged_enum( 3059 report_data, "vkCreateGraphicsPipelines", 3060 "pCreateInfos[i].pColorBlendState->pAttachments[i].dstColorBlendFactor", "VkBlendFactor", 3061 VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE, 3062 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstColorBlendFactor); 3063 3064 skip_call |= validate_ranged_enum( 3065 report_data, "vkCreateGraphicsPipelines", 3066 "pCreateInfos[i].pColorBlendState->pAttachments[i].colorBlendOp", "VkBlendOp", VK_BLEND_OP_BEGIN_RANGE, 3067 VK_BLEND_OP_END_RANGE, pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorBlendOp); 3068 3069 skip_call |= validate_ranged_enum( 3070 report_data, "vkCreateGraphicsPipelines", 3071 "pCreateInfos[i].pColorBlendState->pAttachments[i].srcAlphaBlendFactor", "VkBlendFactor", 3072 VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE, 3073 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcAlphaBlendFactor); 3074 3075 skip_call |= validate_ranged_enum( 3076 report_data, "vkCreateGraphicsPipelines", 3077 "pCreateInfos[i].pColorBlendState->pAttachments[i].dstAlphaBlendFactor", "VkBlendFactor", 3078 VK_BLEND_FACTOR_BEGIN_RANGE, VK_BLEND_FACTOR_END_RANGE, 3079 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstAlphaBlendFactor); 3080 3081 skip_call |= validate_ranged_enum( 3082 report_data, "vkCreateGraphicsPipelines", 3083 "pCreateInfos[i].pColorBlendState->pAttachments[i].alphaBlendOp", "VkBlendOp", VK_BLEND_OP_BEGIN_RANGE, 3084 VK_BLEND_OP_END_RANGE, pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].alphaBlendOp); 3085 3086 skip_call |= 3087 validate_flags(report_data, "vkCreateGraphicsPipelines", 3088 "pCreateInfos[i].pColorBlendState->pAttachments[i].colorWriteMask", 3089 "VkColorComponentFlagBits", AllVkColorComponentFlagBits, 3090 pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorWriteMask, false); 3091 } 3092 } 3093 3094 if (pCreateInfos[i].pColorBlendState->sType != VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO) { 3095 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3096 __LINE__, INVALID_STRUCT_STYPE, LayerName, 3097 "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pColorBlendState->sType must be " 3098 "VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO", 3099 i); 3100 } 3101 3102 // If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value 3103 if (pCreateInfos[i].pColorBlendState->logicOpEnable == VK_TRUE) { 3104 skip_call |= validate_ranged_enum( 3105 report_data, "vkCreateGraphicsPipelines", "pCreateInfos[i].pColorBlendState->logicOp", "VkLogicOp", 3106 VK_LOGIC_OP_BEGIN_RANGE, VK_LOGIC_OP_END_RANGE, pCreateInfos[i].pColorBlendState->logicOp); 3107 } 3108 } 3109 } 3110 } 3111 3112 if (!skip_call) { 3113 PreCreateGraphicsPipelines(device, pCreateInfos); 3114 3115 result = get_dispatch_table(pc_device_table_map, device) 3116 ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 3117 3118 validate_result(report_data, "vkCreateGraphicsPipelines", result); 3119 } 3120 3121 return result; 3122} 3123 3124bool PreCreateComputePipelines(VkDevice device, const VkComputePipelineCreateInfo *pCreateInfos) { 3125 layer_data *data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3126 3127 if (pCreateInfos != nullptr) { 3128 // TODO: Handle count! 3129 int i = 0; 3130 validate_string(data->report_data, "vkCreateComputePipelines", "pCreateInfos[i].stage.pName", pCreateInfos[i].stage.pName); 3131 } 3132 3133 return true; 3134} 3135 3136VKAPI_ATTR VkResult VKAPI_CALL 3137CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, 3138 const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, 3139 VkPipeline *pPipelines) { 3140 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3141 bool skipCall = false; 3142 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3143 assert(my_data != NULL); 3144 3145 skipCall |= parameter_validation_vkCreateComputePipelines(my_data->report_data, pipelineCache, createInfoCount, pCreateInfos, pAllocator, 3146 pPipelines); 3147 3148 if (!skipCall) { 3149 PreCreateComputePipelines(device, pCreateInfos); 3150 3151 result = get_dispatch_table(pc_device_table_map, device) 3152 ->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines); 3153 3154 validate_result(my_data->report_data, "vkCreateComputePipelines", result); 3155 } 3156 3157 return result; 3158} 3159 3160VKAPI_ATTR void VKAPI_CALL 3161DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) { 3162 bool skipCall = false; 3163 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3164 assert(my_data != NULL); 3165 3166 skipCall |= parameter_validation_vkDestroyPipeline(my_data->report_data, pipeline, pAllocator); 3167 3168 if (!skipCall) { 3169 get_dispatch_table(pc_device_table_map, device)->DestroyPipeline(device, pipeline, pAllocator); 3170 } 3171} 3172 3173VKAPI_ATTR VkResult VKAPI_CALL 3174CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 3175 VkPipelineLayout *pPipelineLayout) { 3176 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3177 bool skipCall = false; 3178 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3179 assert(my_data != NULL); 3180 3181 skipCall |= parameter_validation_vkCreatePipelineLayout(my_data->report_data, pCreateInfo, pAllocator, pPipelineLayout); 3182 3183 if (!skipCall) { 3184 result = 3185 get_dispatch_table(pc_device_table_map, device)->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); 3186 3187 validate_result(my_data->report_data, "vkCreatePipelineLayout", result); 3188 } 3189 3190 return result; 3191} 3192 3193VKAPI_ATTR void VKAPI_CALL 3194DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks *pAllocator) { 3195 bool skipCall = false; 3196 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3197 assert(my_data != NULL); 3198 3199 skipCall |= parameter_validation_vkDestroyPipelineLayout(my_data->report_data, pipelineLayout, pAllocator); 3200 3201 if (!skipCall) { 3202 get_dispatch_table(pc_device_table_map, device)->DestroyPipelineLayout(device, pipelineLayout, pAllocator); 3203 } 3204} 3205 3206VKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, 3207 const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) { 3208 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3209 bool skip_call = false; 3210 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3211 assert(device_data != NULL); 3212 debug_report_data *report_data = device_data->report_data; 3213 3214 skip_call |= parameter_validation_vkCreateSampler(report_data, pCreateInfo, pAllocator, pSampler); 3215 3216 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 3217 if (pCreateInfo != nullptr) { 3218 // If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value 3219 if (pCreateInfo->compareEnable == VK_TRUE) { 3220 skip_call |= validate_ranged_enum(report_data, "vkCreateSampler", "pCreateInfo->compareOp", "VkCompareOp", 3221 VK_COMPARE_OP_BEGIN_RANGE, VK_COMPARE_OP_END_RANGE, pCreateInfo->compareOp); 3222 } 3223 3224 // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor must be a 3225 // valid VkBorderColor value 3226 if ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) || 3227 (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) || 3228 (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) { 3229 skip_call |= validate_ranged_enum(report_data, "vkCreateSampler", "pCreateInfo->borderColor", "VkBorderColor", 3230 VK_BORDER_COLOR_BEGIN_RANGE, VK_BORDER_COLOR_END_RANGE, pCreateInfo->borderColor); 3231 } 3232 } 3233 3234 if (!skip_call) { 3235 result = get_dispatch_table(pc_device_table_map, device)->CreateSampler(device, pCreateInfo, pAllocator, pSampler); 3236 3237 validate_result(report_data, "vkCreateSampler", result); 3238 } 3239 3240 return result; 3241} 3242 3243VKAPI_ATTR void VKAPI_CALL 3244DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) { 3245 bool skipCall = false; 3246 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3247 assert(my_data != NULL); 3248 3249 skipCall |= parameter_validation_vkDestroySampler(my_data->report_data, sampler, pAllocator); 3250 3251 if (!skipCall) { 3252 get_dispatch_table(pc_device_table_map, device)->DestroySampler(device, sampler, pAllocator); 3253 } 3254} 3255 3256VKAPI_ATTR VkResult VKAPI_CALL 3257CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 3258 const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) { 3259 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3260 bool skip_call = false; 3261 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3262 assert(device_data != nullptr); 3263 debug_report_data *report_data = device_data->report_data; 3264 3265 skip_call |= parameter_validation_vkCreateDescriptorSetLayout(report_data, pCreateInfo, pAllocator, pSetLayout); 3266 3267 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 3268 if ((pCreateInfo != nullptr) && (pCreateInfo->pBindings != nullptr)) { 3269 for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) { 3270 if (pCreateInfo->pBindings[i].descriptorCount != 0) { 3271 // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and descriptorCount 3272 // is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a pointer to an array of descriptorCount 3273 // valid VkSampler handles 3274 if (((pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) || 3275 (pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) && 3276 (pCreateInfo->pBindings[i].pImmutableSamplers != nullptr)) { 3277 for (uint32_t descriptor_index = 0; descriptor_index < pCreateInfo->pBindings[i].descriptorCount; 3278 ++descriptor_index) { 3279 if (pCreateInfo->pBindings[i].pImmutableSamplers[descriptor_index] == VK_NULL_HANDLE) { 3280 skip_call |= 3281 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3282 __LINE__, REQUIRED_PARAMETER, LayerName, "vkCreateDescriptorSetLayout: required parameter " 3283 "pCreateInfo->pBindings[%d].pImmutableSamplers[%d]" 3284 " specified as VK_NULL_HANDLE", 3285 i, descriptor_index); 3286 } 3287 } 3288 } 3289 3290 // If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values 3291 if ((pCreateInfo->pBindings[i].stageFlags != 0) && 3292 ((pCreateInfo->pBindings[i].stageFlags & (~AllVkShaderStageFlagBits)) != 0)) { 3293 skip_call |= 3294 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 3295 UNRECOGNIZED_VALUE, LayerName, 3296 "vkCreateDescriptorSetLayout: if pCreateInfo->pBindings[%d].descriptorCount is not 0, " 3297 "pCreateInfo->pBindings[%d].stageFlags must be a valid combination of VkShaderStageFlagBits values", 3298 i, i); 3299 } 3300 } 3301 } 3302 } 3303 3304 if (!skip_call) { 3305 result = 3306 get_dispatch_table(pc_device_table_map, device)->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout); 3307 3308 validate_result(report_data, "vkCreateDescriptorSetLayout", result); 3309 } 3310 3311 return result; 3312} 3313 3314VKAPI_ATTR void VKAPI_CALL 3315DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks *pAllocator) { 3316 bool skipCall = false; 3317 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3318 assert(my_data != NULL); 3319 3320 skipCall |= parameter_validation_vkDestroyDescriptorSetLayout(my_data->report_data, descriptorSetLayout, pAllocator); 3321 3322 if (!skipCall) { 3323 get_dispatch_table(pc_device_table_map, device)->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator); 3324 } 3325} 3326 3327VKAPI_ATTR VkResult VKAPI_CALL 3328CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 3329 VkDescriptorPool *pDescriptorPool) { 3330 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3331 bool skipCall = false; 3332 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3333 assert(my_data != NULL); 3334 3335 skipCall |= parameter_validation_vkCreateDescriptorPool(my_data->report_data, pCreateInfo, pAllocator, pDescriptorPool); 3336 3337 /* TODOVV: How do we validate maxSets? Probably belongs in the limits layer? */ 3338 3339 if (!skipCall) { 3340 result = 3341 get_dispatch_table(pc_device_table_map, device)->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool); 3342 3343 validate_result(my_data->report_data, "vkCreateDescriptorPool", result); 3344 } 3345 3346 return result; 3347} 3348 3349VKAPI_ATTR void VKAPI_CALL 3350DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) { 3351 bool skipCall = false; 3352 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3353 assert(my_data != NULL); 3354 3355 skipCall |= parameter_validation_vkDestroyDescriptorPool(my_data->report_data, descriptorPool, pAllocator); 3356 3357 if (!skipCall) { 3358 get_dispatch_table(pc_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator); 3359 } 3360} 3361 3362VKAPI_ATTR VkResult VKAPI_CALL 3363ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags) { 3364 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3365 bool skipCall = false; 3366 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3367 assert(my_data != NULL); 3368 3369 skipCall |= parameter_validation_vkResetDescriptorPool(my_data->report_data, descriptorPool, flags); 3370 3371 if (!skipCall) { 3372 result = get_dispatch_table(pc_device_table_map, device)->ResetDescriptorPool(device, descriptorPool, flags); 3373 3374 validate_result(my_data->report_data, "vkResetDescriptorPool", result); 3375 } 3376 3377 return result; 3378} 3379 3380VKAPI_ATTR VkResult VKAPI_CALL 3381AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets) { 3382 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3383 bool skipCall = false; 3384 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3385 assert(my_data != NULL); 3386 3387 skipCall |= parameter_validation_vkAllocateDescriptorSets(my_data->report_data, pAllocateInfo, pDescriptorSets); 3388 3389 if (!skipCall) { 3390 result = get_dispatch_table(pc_device_table_map, device)->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets); 3391 3392 validate_result(my_data->report_data, "vkAllocateDescriptorSets", result); 3393 } 3394 3395 return result; 3396} 3397 3398VKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, 3399 uint32_t descriptorSetCount, 3400 const VkDescriptorSet *pDescriptorSets) { 3401 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3402 bool skip_call = false; 3403 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3404 assert(device_data != nullptr); 3405 debug_report_data *report_data = device_data->report_data; 3406 3407 skip_call |= parameter_validation_vkFreeDescriptorSets(report_data, descriptorPool, descriptorSetCount, pDescriptorSets); 3408 3409 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 3410 // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond 3411 // validate_array() 3412 skip_call |= validate_array(report_data, "vkFreeDescriptorSets", "descriptorSetCount", "pDescriptorSets", descriptorSetCount, 3413 pDescriptorSets, true, true); 3414 3415 if (!skip_call) { 3416 result = get_dispatch_table(pc_device_table_map, device) 3417 ->FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets); 3418 3419 validate_result(report_data, "vkFreeDescriptorSets", result); 3420 } 3421 3422 return result; 3423} 3424 3425VKAPI_ATTR void VKAPI_CALL 3426UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites, 3427 uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) { 3428 bool skip_call = false; 3429 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3430 assert(device_data != NULL); 3431 debug_report_data *report_data = device_data->report_data; 3432 3433 skip_call |= parameter_validation_vkUpdateDescriptorSets(report_data, descriptorWriteCount, pDescriptorWrites, 3434 descriptorCopyCount, pDescriptorCopies); 3435 3436 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 3437 if (pDescriptorWrites != NULL) { 3438 for (uint32_t i = 0; i < descriptorWriteCount; ++i) { 3439 // descriptorCount must be greater than 0 3440 if (pDescriptorWrites[i].descriptorCount == 0) { 3441 skip_call |= 3442 log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 3443 REQUIRED_PARAMETER, LayerName, 3444 "vkUpdateDescriptorSets: parameter pDescriptorWrites[%d].descriptorCount must be greater than 0", i); 3445 } 3446 3447 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) || 3448 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) || 3449 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || 3450 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) || 3451 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) { 3452 // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3453 // VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 3454 // pImageInfo must be a pointer to an array of descriptorCount valid VkDescriptorImageInfo structures 3455 if (pDescriptorWrites[i].pImageInfo == nullptr) { 3456 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3457 __LINE__, REQUIRED_PARAMETER, LayerName, 3458 "vkUpdateDescriptorSets: if pDescriptorWrites[%d].descriptorType is " 3459 "VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, " 3460 "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or " 3461 "VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pDescriptorWrites[%d].pImageInfo must not be NULL", 3462 i, i); 3463 } else if (pDescriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER) { 3464 // If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3465 // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout 3466 // members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively 3467 for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount; 3468 ++descriptor_index) { 3469 skip_call |= validate_required_handle(report_data, "vkUpdateDescriptorSets", 3470 "pDescriptorWrites[i].pImageInfo[i].imageView", 3471 pDescriptorWrites[i].pImageInfo[descriptor_index].imageView); 3472 skip_call |= validate_ranged_enum(report_data, "vkUpdateDescriptorSets", 3473 "pDescriptorWrites[i].pImageInfo[i].imageLayout", "VkImageLayout", 3474 VK_IMAGE_LAYOUT_BEGIN_RANGE, VK_IMAGE_LAYOUT_END_RANGE, 3475 pDescriptorWrites[i].pImageInfo[descriptor_index].imageLayout); 3476 } 3477 } 3478 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) || 3479 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) || 3480 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || 3481 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { 3482 // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3483 // VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a 3484 // pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures 3485 if (pDescriptorWrites[i].pBufferInfo == nullptr) { 3486 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3487 __LINE__, REQUIRED_PARAMETER, LayerName, 3488 "vkUpdateDescriptorSets: if pDescriptorWrites[%d].descriptorType is " 3489 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, " 3490 "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, " 3491 "pDescriptorWrites[%d].pBufferInfo must not be NULL", 3492 i, i); 3493 } else { 3494 for (uint32_t descriptorIndex = 0; descriptorIndex < pDescriptorWrites[i].descriptorCount; ++descriptorIndex) { 3495 skip_call |= validate_required_handle(report_data, "vkUpdateDescriptorSets", 3496 "pDescriptorWrites[i].pBufferInfo[i].buffer", 3497 pDescriptorWrites[i].pBufferInfo[descriptorIndex].buffer); 3498 } 3499 } 3500 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) || 3501 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) { 3502 // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 3503 // pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles 3504 if (pDescriptorWrites[i].pTexelBufferView == nullptr) { 3505 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3506 __LINE__, REQUIRED_PARAMETER, LayerName, 3507 "vkUpdateDescriptorSets: if pDescriptorWrites[%d].descriptorType is " 3508 "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, " 3509 "pDescriptorWrites[%d].pTexelBufferView must not be NULL", 3510 i, i); 3511 } else { 3512 for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount; 3513 ++descriptor_index) { 3514 skip_call |= validate_required_handle(report_data, "vkUpdateDescriptorSets", 3515 "pDescriptorWrites[i].pTexelBufferView[i]", 3516 pDescriptorWrites[i].pTexelBufferView[descriptor_index]); 3517 } 3518 } 3519 } 3520 3521 if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) || 3522 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) { 3523 VkDeviceSize uniformAlignment = device_data->device_limits.minUniformBufferOffsetAlignment; 3524 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) { 3525 if (pDescriptorWrites[i].pBufferInfo != NULL) { 3526 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) { 3527 skip_call |= 3528 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 3529 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVICE_LIMIT, LayerName, 3530 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64 3531 ") must be a multiple of device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64, 3532 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment); 3533 } 3534 } 3535 } 3536 } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) || 3537 (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { 3538 VkDeviceSize storageAlignment = device_data->device_limits.minStorageBufferOffsetAlignment; 3539 for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) { 3540 if (pDescriptorWrites[i].pBufferInfo != NULL) { 3541 if (vk_safe_modulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) { 3542 skip_call |= 3543 log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 3544 VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVICE_LIMIT, LayerName, 3545 "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64 3546 ") must be a multiple of device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64, 3547 i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment); 3548 } 3549 } 3550 } 3551 } 3552 } 3553 } 3554 3555 if (!skip_call) { 3556 get_dispatch_table(pc_device_table_map, device) 3557 ->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies); 3558 } 3559} 3560 3561VKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo, 3562 const VkAllocationCallbacks *pAllocator, 3563 VkFramebuffer *pFramebuffer) { 3564 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3565 bool skipCall = false; 3566 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3567 assert(my_data != NULL); 3568 3569 skipCall |= parameter_validation_vkCreateFramebuffer(my_data->report_data, pCreateInfo, pAllocator, pFramebuffer); 3570 3571 if (!skipCall) { 3572 result = get_dispatch_table(pc_device_table_map, device)->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer); 3573 3574 validate_result(my_data->report_data, "vkCreateFramebuffer", result); 3575 } 3576 3577 return result; 3578} 3579 3580VKAPI_ATTR void VKAPI_CALL 3581DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) { 3582 bool skipCall = false; 3583 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3584 assert(my_data != NULL); 3585 3586 skipCall |= parameter_validation_vkDestroyFramebuffer(my_data->report_data, framebuffer, pAllocator); 3587 3588 if (!skipCall) { 3589 get_dispatch_table(pc_device_table_map, device)->DestroyFramebuffer(device, framebuffer, pAllocator); 3590 } 3591} 3592 3593bool PreCreateRenderPass(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo) { 3594 bool skip_call = false; 3595 uint32_t max_color_attachments = dev_data->device_limits.maxColorAttachments; 3596 3597 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 3598 if (pCreateInfo->pSubpasses[i].colorAttachmentCount > max_color_attachments) { 3599 skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 3600 __LINE__, DEVICE_LIMIT, "DL", 3601 "Cannot create a render pass with %d color attachments. Max is %d.", 3602 pCreateInfo->pSubpasses[i].colorAttachmentCount, max_color_attachments); 3603 } 3604 } 3605 return skip_call; 3606} 3607 3608VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 3609 const VkAllocationCallbacks *pAllocator, 3610 VkRenderPass *pRenderPass) { 3611 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3612 bool skipCall = false; 3613 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3614 assert(my_data != NULL); 3615 3616 skipCall |= parameter_validation_vkCreateRenderPass(my_data->report_data, pCreateInfo, pAllocator, pRenderPass); 3617 skipCall |= PreCreateRenderPass(my_data, pCreateInfo); 3618 3619 if (!skipCall) { 3620 result = get_dispatch_table(pc_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass); 3621 3622 validate_result(my_data->report_data, "vkCreateRenderPass", result); 3623 } 3624 3625 return result; 3626} 3627 3628VKAPI_ATTR void VKAPI_CALL 3629DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) { 3630 bool skipCall = false; 3631 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3632 assert(my_data != NULL); 3633 3634 skipCall |= parameter_validation_vkDestroyRenderPass(my_data->report_data, renderPass, pAllocator); 3635 3636 if (!skipCall) { 3637 get_dispatch_table(pc_device_table_map, device)->DestroyRenderPass(device, renderPass, pAllocator); 3638 } 3639} 3640 3641VKAPI_ATTR void VKAPI_CALL 3642GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity) { 3643 bool skipCall = false; 3644 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3645 assert(my_data != NULL); 3646 3647 skipCall |= parameter_validation_vkGetRenderAreaGranularity(my_data->report_data, renderPass, pGranularity); 3648 3649 if (!skipCall) { 3650 get_dispatch_table(pc_device_table_map, device)->GetRenderAreaGranularity(device, renderPass, pGranularity); 3651 } 3652} 3653 3654VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, 3655 const VkAllocationCallbacks *pAllocator, 3656 VkCommandPool *pCommandPool) { 3657 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3658 bool skipCall = false; 3659 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3660 assert(my_data != NULL); 3661 3662 skipCall |= 3663 validate_queue_family_index(my_data, "vkCreateCommandPool", "pCreateInfo->queueFamilyIndex", pCreateInfo->queueFamilyIndex); 3664 3665 skipCall |= parameter_validation_vkCreateCommandPool(my_data->report_data, pCreateInfo, pAllocator, pCommandPool); 3666 3667 if (!skipCall) { 3668 result = get_dispatch_table(pc_device_table_map, device)->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool); 3669 3670 validate_result(my_data->report_data, "vkCreateCommandPool", result); 3671 } 3672 3673 return result; 3674} 3675 3676VKAPI_ATTR void VKAPI_CALL 3677DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) { 3678 bool skipCall = false; 3679 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3680 assert(my_data != NULL); 3681 3682 skipCall |= parameter_validation_vkDestroyCommandPool(my_data->report_data, commandPool, pAllocator); 3683 3684 if (!skipCall) { 3685 get_dispatch_table(pc_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator); 3686 } 3687} 3688 3689VKAPI_ATTR VkResult VKAPI_CALL 3690ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) { 3691 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3692 bool skipCall = false; 3693 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3694 assert(my_data != NULL); 3695 3696 skipCall |= parameter_validation_vkResetCommandPool(my_data->report_data, commandPool, flags); 3697 3698 if (!skipCall) { 3699 result = get_dispatch_table(pc_device_table_map, device)->ResetCommandPool(device, commandPool, flags); 3700 3701 validate_result(my_data->report_data, "vkResetCommandPool", result); 3702 } 3703 3704 return result; 3705} 3706 3707VKAPI_ATTR VkResult VKAPI_CALL 3708AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers) { 3709 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3710 bool skipCall = false; 3711 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3712 assert(my_data != NULL); 3713 3714 skipCall |= parameter_validation_vkAllocateCommandBuffers(my_data->report_data, pAllocateInfo, pCommandBuffers); 3715 3716 if (!skipCall) { 3717 result = get_dispatch_table(pc_device_table_map, device)->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers); 3718 3719 validate_result(my_data->report_data, "vkAllocateCommandBuffers", result); 3720 } 3721 3722 return result; 3723} 3724 3725VKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, 3726 uint32_t commandBufferCount, 3727 const VkCommandBuffer *pCommandBuffers) { 3728 bool skip_call = false; 3729 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 3730 assert(device_data != nullptr); 3731 debug_report_data *report_data = device_data->report_data; 3732 3733 skip_call |= parameter_validation_vkFreeCommandBuffers(report_data, commandPool, commandBufferCount, pCommandBuffers); 3734 3735 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 3736 // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond 3737 // validate_array() 3738 skip_call |= validate_array(report_data, "vkFreeCommandBuffers", "commandBufferCount", "pCommandBuffers", commandBufferCount, 3739 pCommandBuffers, true, true); 3740 3741 if (!skip_call) { 3742 get_dispatch_table(pc_device_table_map, device) 3743 ->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers); 3744 } 3745} 3746 3747bool PreBeginCommandBuffer(layer_data *dev_data, VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) { 3748 bool skip_call = false; 3749 layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(dev_data->physical_device), layer_data_map); 3750 const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo; 3751 3752 if (pInfo != NULL) { 3753 if ((phy_dev_data->physical_device_features.inheritedQueries == VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE)) { 3754 skip_call |= 3755 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 3756 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVICE_FEATURE, LayerName, 3757 "Cannot set inherited occlusionQueryEnable in vkBeginCommandBuffer() when device does not support " 3758 "inheritedQueries."); 3759 } 3760 3761 if ((phy_dev_data->physical_device_features.inheritedQueries != VK_FALSE) && (pInfo->occlusionQueryEnable != VK_FALSE) && 3762 (!validate_VkQueryControlFlagBits(VkQueryControlFlagBits(pInfo->queryFlags)))) { 3763 skip_call |= 3764 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 3765 reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DEVICE_FEATURE, LayerName, 3766 "Cannot enable in occlusion queries in vkBeginCommandBuffer() and set queryFlags to %d which is not a " 3767 "valid combination of VkQueryControlFlagBits.", 3768 pInfo->queryFlags); 3769 } 3770 } 3771 return skip_call; 3772} 3773 3774VKAPI_ATTR VkResult VKAPI_CALL BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) { 3775 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3776 bool skip_call = false; 3777 layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3778 assert(device_data != nullptr); 3779 debug_report_data *report_data = device_data->report_data; 3780 3781 skip_call |= parameter_validation_vkBeginCommandBuffer(report_data, pBeginInfo); 3782 3783 // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml 3784 // TODO: pBeginInfo->pInheritanceInfo must not be NULL if commandBuffer is a secondary command buffer 3785 skip_call |= validate_struct_type(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo", 3786 "VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO", pBeginInfo->pInheritanceInfo, 3787 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, false); 3788 3789 if (pBeginInfo->pInheritanceInfo != NULL) { 3790 skip_call |= validate_struct_pnext(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pNext", NULL, 3791 pBeginInfo->pInheritanceInfo->pNext, 0, NULL, GeneratedHeaderVersion); 3792 3793 skip_call |= validate_bool32(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->occlusionQueryEnable", 3794 pBeginInfo->pInheritanceInfo->occlusionQueryEnable); 3795 3796 // TODO: This only needs to be validated when the inherited queries feature is enabled 3797 // skip_call |= validate_flags(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->queryFlags", 3798 // "VkQueryControlFlagBits", AllVkQueryControlFlagBits, pBeginInfo->pInheritanceInfo->queryFlags, false); 3799 3800 // TODO: This must be 0 if the pipeline statistics queries feature is not enabled 3801 skip_call |= validate_flags(report_data, "vkBeginCommandBuffer", "pBeginInfo->pInheritanceInfo->pipelineStatistics", 3802 "VkQueryPipelineStatisticFlagBits", AllVkQueryPipelineStatisticFlagBits, 3803 pBeginInfo->pInheritanceInfo->pipelineStatistics, false); 3804 } 3805 3806 skip_call |= PreBeginCommandBuffer(device_data, commandBuffer, pBeginInfo); 3807 3808 if (!skip_call) { 3809 result = get_dispatch_table(pc_device_table_map, commandBuffer)->BeginCommandBuffer(commandBuffer, pBeginInfo); 3810 3811 validate_result(report_data, "vkBeginCommandBuffer", result); 3812 } 3813 3814 return result; 3815} 3816 3817VKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) { 3818 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3819 assert(my_data != NULL); 3820 3821 VkResult result = get_dispatch_table(pc_device_table_map, commandBuffer)->EndCommandBuffer(commandBuffer); 3822 3823 validate_result(my_data->report_data, "vkEndCommandBuffer", result); 3824 3825 return result; 3826} 3827 3828VKAPI_ATTR VkResult VKAPI_CALL 3829ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) { 3830 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3831 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3832 assert(my_data != NULL); 3833 3834 bool skip_call = parameter_validation_vkResetCommandBuffer(my_data->report_data, flags); 3835 3836 if (!skip_call) { 3837 result = get_dispatch_table(pc_device_table_map, commandBuffer)->ResetCommandBuffer(commandBuffer, flags); 3838 3839 validate_result(my_data->report_data, "vkResetCommandBuffer", result); 3840 } 3841 3842 return result; 3843} 3844 3845VKAPI_ATTR void VKAPI_CALL 3846CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) { 3847 bool skipCall = false; 3848 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3849 assert(my_data != NULL); 3850 3851 skipCall |= parameter_validation_vkCmdBindPipeline(my_data->report_data, pipelineBindPoint, pipeline); 3852 3853 if (!skipCall) { 3854 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline); 3855 } 3856} 3857 3858VKAPI_ATTR void VKAPI_CALL 3859CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports) { 3860 bool skipCall = false; 3861 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3862 assert(my_data != NULL); 3863 3864 skipCall |= parameter_validation_vkCmdSetViewport(my_data->report_data, firstViewport, viewportCount, pViewports); 3865 3866 if (!skipCall) { 3867 get_dispatch_table(pc_device_table_map, commandBuffer) 3868 ->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports); 3869 } 3870} 3871 3872VKAPI_ATTR void VKAPI_CALL 3873CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) { 3874 bool skipCall = false; 3875 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3876 assert(my_data != NULL); 3877 3878 skipCall |= parameter_validation_vkCmdSetScissor(my_data->report_data, firstScissor, scissorCount, pScissors); 3879 3880 if (!skipCall) { 3881 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors); 3882 } 3883} 3884 3885VKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) { 3886 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetLineWidth(commandBuffer, lineWidth); 3887} 3888 3889VKAPI_ATTR void VKAPI_CALL 3890CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) { 3891 get_dispatch_table(pc_device_table_map, commandBuffer) 3892 ->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor); 3893} 3894 3895VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) { 3896 bool skipCall = false; 3897 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3898 assert(my_data != NULL); 3899 3900 skipCall |= parameter_validation_vkCmdSetBlendConstants(my_data->report_data, blendConstants); 3901 3902 if (!skipCall) { 3903 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetBlendConstants(commandBuffer, blendConstants); 3904 } 3905} 3906 3907VKAPI_ATTR void VKAPI_CALL 3908CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) { 3909 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds); 3910} 3911 3912VKAPI_ATTR void VKAPI_CALL 3913CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask) { 3914 bool skipCall = false; 3915 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3916 assert(my_data != NULL); 3917 3918 skipCall |= parameter_validation_vkCmdSetStencilCompareMask(my_data->report_data, faceMask, compareMask); 3919 3920 if (!skipCall) { 3921 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask); 3922 } 3923} 3924 3925VKAPI_ATTR void VKAPI_CALL 3926CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) { 3927 bool skipCall = false; 3928 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3929 assert(my_data != NULL); 3930 3931 skipCall |= parameter_validation_vkCmdSetStencilWriteMask(my_data->report_data, faceMask, writeMask); 3932 3933 if (!skipCall) { 3934 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask); 3935 } 3936} 3937 3938VKAPI_ATTR void VKAPI_CALL 3939CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) { 3940 bool skipCall = false; 3941 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3942 assert(my_data != NULL); 3943 3944 skipCall |= parameter_validation_vkCmdSetStencilReference(my_data->report_data, faceMask, reference); 3945 3946 if (!skipCall) { 3947 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetStencilReference(commandBuffer, faceMask, reference); 3948 } 3949} 3950 3951VKAPI_ATTR void VKAPI_CALL 3952CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, 3953 uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets, 3954 uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) { 3955 bool skipCall = false; 3956 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3957 assert(my_data != NULL); 3958 3959 skipCall |= parameter_validation_vkCmdBindDescriptorSets(my_data->report_data, pipelineBindPoint, layout, firstSet, descriptorSetCount, 3960 pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); 3961 3962 if (!skipCall) { 3963 get_dispatch_table(pc_device_table_map, commandBuffer) 3964 ->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, 3965 dynamicOffsetCount, pDynamicOffsets); 3966 } 3967} 3968 3969VKAPI_ATTR void VKAPI_CALL 3970CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) { 3971 bool skipCall = false; 3972 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3973 assert(my_data != NULL); 3974 3975 skipCall |= parameter_validation_vkCmdBindIndexBuffer(my_data->report_data, buffer, offset, indexType); 3976 3977 if (!skipCall) { 3978 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType); 3979 } 3980} 3981 3982VKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, 3983 uint32_t bindingCount, const VkBuffer *pBuffers, 3984 const VkDeviceSize *pOffsets) { 3985 bool skipCall = false; 3986 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 3987 assert(my_data != NULL); 3988 3989 skipCall |= parameter_validation_vkCmdBindVertexBuffers(my_data->report_data, firstBinding, bindingCount, pBuffers, pOffsets); 3990 3991 if (!skipCall) { 3992 get_dispatch_table(pc_device_table_map, commandBuffer) 3993 ->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); 3994 } 3995} 3996 3997bool PreCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, 3998 uint32_t firstInstance) { 3999 if (vertexCount == 0) { 4000 // TODO: Verify against Valid Usage section. I don't see a non-zero vertexCount listed, may need to add that and make 4001 // this an error or leave as is. 4002 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4003 REQUIRED_PARAMETER, LayerName, "vkCmdDraw parameter, uint32_t vertexCount, is 0"); 4004 return false; 4005 } 4006 4007 if (instanceCount == 0) { 4008 // TODO: Verify against Valid Usage section. I don't see a non-zero instanceCount listed, may need to add that and make 4009 // this an error or leave as is. 4010 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4011 REQUIRED_PARAMETER, LayerName, "vkCmdDraw parameter, uint32_t instanceCount, is 0"); 4012 return false; 4013 } 4014 4015 return true; 4016} 4017 4018VKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, 4019 uint32_t firstVertex, uint32_t firstInstance) { 4020 PreCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); 4021 4022 get_dispatch_table(pc_device_table_map, commandBuffer) 4023 ->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); 4024} 4025 4026VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, 4027 uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, 4028 uint32_t firstInstance) { 4029 get_dispatch_table(pc_device_table_map, commandBuffer) 4030 ->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); 4031} 4032 4033VKAPI_ATTR void VKAPI_CALL 4034CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) { 4035 bool skipCall = false; 4036 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4037 assert(my_data != NULL); 4038 4039 skipCall |= parameter_validation_vkCmdDrawIndirect(my_data->report_data, buffer, offset, count, stride); 4040 4041 if (!skipCall) { 4042 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDrawIndirect(commandBuffer, buffer, offset, count, stride); 4043 } 4044} 4045 4046VKAPI_ATTR void VKAPI_CALL 4047CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride) { 4048 bool skipCall = false; 4049 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4050 assert(my_data != NULL); 4051 4052 skipCall |= parameter_validation_vkCmdDrawIndexedIndirect(my_data->report_data, buffer, offset, count, stride); 4053 4054 if (!skipCall) { 4055 get_dispatch_table(pc_device_table_map, commandBuffer) 4056 ->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride); 4057 } 4058} 4059 4060VKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) { 4061 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDispatch(commandBuffer, x, y, z); 4062} 4063 4064VKAPI_ATTR void VKAPI_CALL 4065CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) { 4066 bool skipCall = false; 4067 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4068 assert(my_data != NULL); 4069 4070 skipCall |= parameter_validation_vkCmdDispatchIndirect(my_data->report_data, buffer, offset); 4071 4072 if (!skipCall) { 4073 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDispatchIndirect(commandBuffer, buffer, offset); 4074 } 4075} 4076 4077VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, 4078 uint32_t regionCount, const VkBufferCopy *pRegions) { 4079 bool skipCall = false; 4080 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4081 assert(my_data != NULL); 4082 4083 skipCall |= parameter_validation_vkCmdCopyBuffer(my_data->report_data, srcBuffer, dstBuffer, regionCount, pRegions); 4084 4085 if (!skipCall) { 4086 get_dispatch_table(pc_device_table_map, commandBuffer) 4087 ->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions); 4088 } 4089} 4090 4091bool PreCmdCopyImage(VkCommandBuffer commandBuffer, const VkImageCopy *pRegions) { 4092 if (pRegions != nullptr) { 4093 if ((pRegions->srcSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4094 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4095 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4096 UNRECOGNIZED_VALUE, LayerName, 4097 "vkCmdCopyImage parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator"); 4098 return false; 4099 } 4100 if ((pRegions->dstSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4101 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4102 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4103 UNRECOGNIZED_VALUE, LayerName, 4104 "vkCmdCopyImage parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator"); 4105 return false; 4106 } 4107 } 4108 4109 return true; 4110} 4111 4112VKAPI_ATTR void VKAPI_CALL 4113CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, 4114 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy *pRegions) { 4115 bool skipCall = false; 4116 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4117 assert(my_data != NULL); 4118 4119 skipCall |= 4120 parameter_validation_vkCmdCopyImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); 4121 4122 if (!skipCall) { 4123 PreCmdCopyImage(commandBuffer, pRegions); 4124 4125 get_dispatch_table(pc_device_table_map, commandBuffer) 4126 ->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); 4127 } 4128} 4129 4130bool PreCmdBlitImage(VkCommandBuffer commandBuffer, const VkImageBlit *pRegions) { 4131 if (pRegions != nullptr) { 4132 if ((pRegions->srcSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4133 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4134 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4135 UNRECOGNIZED_VALUE, LayerName, 4136 "vkCmdCopyImage parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator"); 4137 return false; 4138 } 4139 if ((pRegions->dstSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4140 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4141 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4142 UNRECOGNIZED_VALUE, LayerName, 4143 "vkCmdCopyImage parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator"); 4144 return false; 4145 } 4146 } 4147 4148 return true; 4149} 4150 4151VKAPI_ATTR void VKAPI_CALL 4152CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, 4153 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit *pRegions, VkFilter filter) { 4154 bool skipCall = false; 4155 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4156 assert(my_data != NULL); 4157 4158 skipCall |= parameter_validation_vkCmdBlitImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 4159 pRegions, filter); 4160 4161 if (!skipCall) { 4162 PreCmdBlitImage(commandBuffer, pRegions); 4163 4164 get_dispatch_table(pc_device_table_map, commandBuffer) 4165 ->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter); 4166 } 4167} 4168 4169bool PreCmdCopyBufferToImage(VkCommandBuffer commandBuffer, const VkBufferImageCopy *pRegions) { 4170 if (pRegions != nullptr) { 4171 if ((pRegions->imageSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4172 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4173 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4174 UNRECOGNIZED_VALUE, LayerName, 4175 "vkCmdCopyBufferToImage parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an unrecognized " 4176 "enumerator"); 4177 return false; 4178 } 4179 } 4180 4181 return true; 4182} 4183 4184VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, 4185 VkImage dstImage, VkImageLayout dstImageLayout, 4186 uint32_t regionCount, const VkBufferImageCopy *pRegions) { 4187 bool skipCall = false; 4188 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4189 assert(my_data != NULL); 4190 4191 skipCall |= 4192 parameter_validation_vkCmdCopyBufferToImage(my_data->report_data, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); 4193 4194 if (!skipCall) { 4195 PreCmdCopyBufferToImage(commandBuffer, pRegions); 4196 4197 get_dispatch_table(pc_device_table_map, commandBuffer) 4198 ->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); 4199 } 4200} 4201 4202bool PreCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, const VkBufferImageCopy *pRegions) { 4203 if (pRegions != nullptr) { 4204 if ((pRegions->imageSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4205 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4206 log_msg(mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4207 UNRECOGNIZED_VALUE, LayerName, 4208 "vkCmdCopyImageToBuffer parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an unrecognized " 4209 "enumerator"); 4210 return false; 4211 } 4212 } 4213 4214 return true; 4215} 4216 4217VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, 4218 VkImageLayout srcImageLayout, VkBuffer dstBuffer, 4219 uint32_t regionCount, const VkBufferImageCopy *pRegions) { 4220 bool skipCall = false; 4221 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4222 assert(my_data != NULL); 4223 4224 skipCall |= 4225 parameter_validation_vkCmdCopyImageToBuffer(my_data->report_data, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); 4226 4227 if (!skipCall) { 4228 PreCmdCopyImageToBuffer(commandBuffer, pRegions); 4229 4230 get_dispatch_table(pc_device_table_map, commandBuffer) 4231 ->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); 4232 } 4233} 4234 4235VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 4236 VkDeviceSize dataSize, const uint32_t *pData) { 4237 bool skip_call = false; 4238 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4239 assert(my_data != NULL); 4240 4241 skip_call |= parameter_validation_vkCmdUpdateBuffer(my_data->report_data, dstBuffer, dstOffset, dataSize, pData); 4242 4243 if (dstOffset & 3) { 4244 skip_call |= log_msg( 4245 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, 4246 LayerName, "CmdUpdateBuffer parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4", dstOffset); 4247 } 4248 4249 if ((dataSize <= 0) || (dataSize > 65536)) { 4250 skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, 4251 INVALID_USAGE, LayerName, "CmdUpdateBuffer parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 4252 "), must be greater than zero and less than or equal to 65536", 4253 dataSize); 4254 } else if (dataSize & 3) { 4255 skip_call |= log_msg( 4256 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, 4257 LayerName, "CmdUpdateBuffer parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 "), is not a multiple of 4", dataSize); 4258 } 4259 4260 if (!skip_call) { 4261 get_dispatch_table(pc_device_table_map, commandBuffer) 4262 ->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData); 4263 } 4264} 4265 4266VKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 4267 VkDeviceSize size, uint32_t data) { 4268 bool skip_call = false; 4269 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4270 assert(my_data != NULL); 4271 4272 skip_call |= parameter_validation_vkCmdFillBuffer(my_data->report_data, dstBuffer, dstOffset, size, data); 4273 4274 if (dstOffset & 3) { 4275 skip_call |= log_msg( 4276 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, 4277 LayerName, "vkCmdFillBuffer parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4", dstOffset); 4278 } 4279 4280 if (size != VK_WHOLE_SIZE) { 4281 if (size <= 0) { 4282 skip_call |= log_msg( 4283 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, INVALID_USAGE, 4284 LayerName, "vkCmdFillBuffer parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), must be greater than zero", size); 4285 } else if (size & 3) { 4286 skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__, 4287 INVALID_USAGE, LayerName, 4288 "vkCmdFillBuffer parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), is not a multiple of 4", size); 4289 } 4290 } 4291 4292 if (!skip_call) { 4293 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data); 4294 } 4295} 4296 4297VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, 4298 VkImageLayout imageLayout, const VkClearColorValue *pColor, 4299 uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { 4300 bool skipCall = false; 4301 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4302 assert(my_data != NULL); 4303 4304 skipCall |= parameter_validation_vkCmdClearColorImage(my_data->report_data, image, imageLayout, pColor, rangeCount, pRanges); 4305 4306 if (!skipCall) { 4307 get_dispatch_table(pc_device_table_map, commandBuffer) 4308 ->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); 4309 } 4310} 4311 4312VKAPI_ATTR void VKAPI_CALL 4313CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 4314 const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, 4315 const VkImageSubresourceRange *pRanges) { 4316 bool skipCall = false; 4317 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4318 assert(my_data != NULL); 4319 4320 skipCall |= 4321 parameter_validation_vkCmdClearDepthStencilImage(my_data->report_data, image, imageLayout, pDepthStencil, rangeCount, pRanges); 4322 4323 if (!skipCall) { 4324 get_dispatch_table(pc_device_table_map, commandBuffer) 4325 ->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); 4326 } 4327} 4328 4329VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, 4330 const VkClearAttachment *pAttachments, uint32_t rectCount, 4331 const VkClearRect *pRects) { 4332 bool skipCall = false; 4333 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4334 assert(my_data != NULL); 4335 4336 skipCall |= parameter_validation_vkCmdClearAttachments(my_data->report_data, attachmentCount, pAttachments, rectCount, pRects); 4337 4338 if (!skipCall) { 4339 get_dispatch_table(pc_device_table_map, commandBuffer) 4340 ->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects); 4341 } 4342} 4343 4344bool PreCmdResolveImage(VkCommandBuffer commandBuffer, const VkImageResolve *pRegions) { 4345 if (pRegions != nullptr) { 4346 if ((pRegions->srcSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4347 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4348 log_msg( 4349 mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4350 UNRECOGNIZED_VALUE, LayerName, 4351 "vkCmdResolveImage parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator"); 4352 return false; 4353 } 4354 if ((pRegions->dstSubresource.aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | 4355 VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT)) == 0) { 4356 log_msg( 4357 mdd(commandBuffer), VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 4358 UNRECOGNIZED_VALUE, LayerName, 4359 "vkCmdResolveImage parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator"); 4360 return false; 4361 } 4362 } 4363 4364 return true; 4365} 4366 4367VKAPI_ATTR void VKAPI_CALL 4368CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, 4369 VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions) { 4370 bool skipCall = false; 4371 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4372 assert(my_data != NULL); 4373 4374 skipCall |= parameter_validation_vkCmdResolveImage(my_data->report_data, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 4375 pRegions); 4376 4377 if (!skipCall) { 4378 PreCmdResolveImage(commandBuffer, pRegions); 4379 4380 get_dispatch_table(pc_device_table_map, commandBuffer) 4381 ->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); 4382 } 4383} 4384 4385VKAPI_ATTR void VKAPI_CALL 4386CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 4387 bool skipCall = false; 4388 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4389 assert(my_data != NULL); 4390 4391 skipCall |= parameter_validation_vkCmdSetEvent(my_data->report_data, event, stageMask); 4392 4393 if (!skipCall) { 4394 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdSetEvent(commandBuffer, event, stageMask); 4395 } 4396} 4397 4398VKAPI_ATTR void VKAPI_CALL 4399CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 4400 bool skipCall = false; 4401 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4402 assert(my_data != NULL); 4403 4404 skipCall |= parameter_validation_vkCmdResetEvent(my_data->report_data, event, stageMask); 4405 4406 if (!skipCall) { 4407 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdResetEvent(commandBuffer, event, stageMask); 4408 } 4409} 4410 4411VKAPI_ATTR void VKAPI_CALL 4412CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, VkPipelineStageFlags srcStageMask, 4413 VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 4414 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 4415 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 4416 bool skipCall = false; 4417 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4418 assert(my_data != NULL); 4419 4420 skipCall |= parameter_validation_vkCmdWaitEvents(my_data->report_data, eventCount, pEvents, srcStageMask, dstStageMask, 4421 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, 4422 imageMemoryBarrierCount, pImageMemoryBarriers); 4423 4424 if (!skipCall) { 4425 get_dispatch_table(pc_device_table_map, commandBuffer) 4426 ->CmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers, 4427 bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 4428 } 4429} 4430 4431VKAPI_ATTR void VKAPI_CALL 4432CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, 4433 VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 4434 uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 4435 uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 4436 bool skipCall = false; 4437 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4438 assert(my_data != NULL); 4439 4440 skipCall |= parameter_validation_vkCmdPipelineBarrier(my_data->report_data, srcStageMask, dstStageMask, dependencyFlags, 4441 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 4442 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 4443 4444 if (!skipCall) { 4445 get_dispatch_table(pc_device_table_map, commandBuffer) 4446 ->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, 4447 bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 4448 } 4449} 4450 4451VKAPI_ATTR void VKAPI_CALL 4452CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot, VkQueryControlFlags flags) { 4453 bool skipCall = false; 4454 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4455 assert(my_data != NULL); 4456 4457 skipCall |= parameter_validation_vkCmdBeginQuery(my_data->report_data, queryPool, slot, flags); 4458 4459 if (!skipCall) { 4460 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBeginQuery(commandBuffer, queryPool, slot, flags); 4461 } 4462} 4463 4464VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) { 4465 bool skipCall = false; 4466 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4467 assert(my_data != NULL); 4468 4469 skipCall |= parameter_validation_vkCmdEndQuery(my_data->report_data, queryPool, slot); 4470 4471 if (!skipCall) { 4472 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdEndQuery(commandBuffer, queryPool, slot); 4473 } 4474} 4475 4476VKAPI_ATTR void VKAPI_CALL 4477CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) { 4478 bool skipCall = false; 4479 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4480 assert(my_data != NULL); 4481 4482 skipCall |= parameter_validation_vkCmdResetQueryPool(my_data->report_data, queryPool, firstQuery, queryCount); 4483 4484 if (!skipCall) { 4485 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount); 4486 } 4487} 4488 4489bool PostCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, 4490 uint32_t slot) { 4491 4492 ValidateEnumerator(pipelineStage); 4493 4494 return true; 4495} 4496 4497VKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, 4498 VkQueryPool queryPool, uint32_t query) { 4499 bool skipCall = false; 4500 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4501 assert(my_data != NULL); 4502 4503 skipCall |= parameter_validation_vkCmdWriteTimestamp(my_data->report_data, pipelineStage, queryPool, query); 4504 4505 if (!skipCall) { 4506 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query); 4507 4508 PostCmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, query); 4509 } 4510} 4511 4512VKAPI_ATTR void VKAPI_CALL 4513CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, 4514 VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags) { 4515 bool skipCall = false; 4516 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4517 assert(my_data != NULL); 4518 4519 skipCall |= parameter_validation_vkCmdCopyQueryPoolResults(my_data->report_data, queryPool, firstQuery, queryCount, dstBuffer, 4520 dstOffset, stride, flags); 4521 4522 if (!skipCall) { 4523 get_dispatch_table(pc_device_table_map, commandBuffer) 4524 ->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags); 4525 } 4526} 4527 4528VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, 4529 VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, 4530 const void *pValues) { 4531 bool skipCall = false; 4532 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4533 assert(my_data != NULL); 4534 4535 skipCall |= parameter_validation_vkCmdPushConstants(my_data->report_data, layout, stageFlags, offset, size, pValues); 4536 4537 if (!skipCall) { 4538 get_dispatch_table(pc_device_table_map, commandBuffer) 4539 ->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues); 4540 } 4541} 4542 4543VKAPI_ATTR void VKAPI_CALL 4544CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents) { 4545 bool skipCall = false; 4546 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4547 assert(my_data != NULL); 4548 4549 skipCall |= parameter_validation_vkCmdBeginRenderPass(my_data->report_data, pRenderPassBegin, contents); 4550 4551 if (!skipCall) { 4552 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents); 4553 } 4554} 4555 4556VKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) { 4557 bool skipCall = false; 4558 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4559 assert(my_data != NULL); 4560 4561 skipCall |= parameter_validation_vkCmdNextSubpass(my_data->report_data, contents); 4562 4563 if (!skipCall) { 4564 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdNextSubpass(commandBuffer, contents); 4565 } 4566} 4567 4568VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) { 4569 get_dispatch_table(pc_device_table_map, commandBuffer)->CmdEndRenderPass(commandBuffer); 4570} 4571 4572VKAPI_ATTR void VKAPI_CALL 4573CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) { 4574 bool skipCall = false; 4575 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); 4576 assert(my_data != NULL); 4577 4578 skipCall |= parameter_validation_vkCmdExecuteCommands(my_data->report_data, commandBufferCount, pCommandBuffers); 4579 4580 if (!skipCall) { 4581 get_dispatch_table(pc_device_table_map, commandBuffer) 4582 ->CmdExecuteCommands(commandBuffer, commandBufferCount, pCommandBuffers); 4583 } 4584} 4585 4586VKAPI_ATTR VkResult VKAPI_CALL 4587EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 4588 return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 4589} 4590 4591VKAPI_ATTR VkResult VKAPI_CALL 4592EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) { 4593 return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 4594} 4595 4596VKAPI_ATTR VkResult VKAPI_CALL 4597EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) { 4598 if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) 4599 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties); 4600 4601 return VK_ERROR_LAYER_NOT_PRESENT; 4602} 4603 4604VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 4605 const char *pLayerName, uint32_t *pCount, 4606 VkExtensionProperties *pProperties) { 4607 /* parameter_validation does not have any physical device extensions */ 4608 if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) 4609 return util_GetExtensionProperties(0, NULL, pCount, pProperties); 4610 4611 assert(physicalDevice); 4612 4613 return get_dispatch_table(pc_instance_table_map, physicalDevice) 4614 ->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties); 4615} 4616 4617static PFN_vkVoidFunction 4618intercept_core_instance_command(const char *name); 4619 4620static PFN_vkVoidFunction 4621intercept_core_device_command(const char *name); 4622 4623VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) { 4624 assert(device); 4625 4626 layer_data *data = get_my_data_ptr(get_dispatch_key(device), layer_data_map); 4627 4628 if (validate_string(data->report_data, "vkGetDeviceProcAddr", "funcName", funcName)) { 4629 return NULL; 4630 } 4631 4632 PFN_vkVoidFunction proc = intercept_core_device_command(funcName); 4633 if (proc) 4634 return proc; 4635 4636 if (get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr == NULL) 4637 return NULL; 4638 return get_dispatch_table(pc_device_table_map, device)->GetDeviceProcAddr(device, funcName); 4639} 4640 4641VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) { 4642 PFN_vkVoidFunction proc = intercept_core_instance_command(funcName); 4643 if (!proc) 4644 proc = intercept_core_device_command(funcName); 4645 if (proc) 4646 return proc; 4647 4648 assert(instance); 4649 4650 layer_data *data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); 4651 4652 proc = debug_report_get_instance_proc_addr(data->report_data, funcName); 4653 if (proc) 4654 return proc; 4655 4656 if (get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr == NULL) 4657 return NULL; 4658 return get_dispatch_table(pc_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName); 4659} 4660 4661static PFN_vkVoidFunction 4662intercept_core_instance_command(const char *name) { 4663 static const struct { 4664 const char *name; 4665 PFN_vkVoidFunction proc; 4666 } core_instance_commands[] = { 4667 { "vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr) }, 4668 { "vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance) }, 4669 { "vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance) }, 4670 { "vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice) }, 4671 { "vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices) }, 4672 { "vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceProperties) }, 4673 { "vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFeatures) }, 4674 { "vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceFormatProperties) }, 4675 { "vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceImageFormatProperties) }, 4676 { "vkGetPhysicalDeviceSparseImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSparseImageFormatProperties) }, 4677 { "vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceQueueFamilyProperties) }, 4678 { "vkGetPhysicalDeviceMemoryProperties", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceMemoryProperties) }, 4679 { "vkEnumerateInstanceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties) }, 4680 { "vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties) }, 4681 { "vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties) }, 4682 { "vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties) }, 4683 }; 4684 4685 for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) { 4686 if (!strcmp(core_instance_commands[i].name, name)) 4687 return core_instance_commands[i].proc; 4688 } 4689 4690 return nullptr; 4691} 4692 4693static PFN_vkVoidFunction 4694intercept_core_device_command(const char *name) { 4695 static const struct { 4696 const char *name; 4697 PFN_vkVoidFunction proc; 4698 } core_device_commands[] = { 4699 { "vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr) }, 4700 { "vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice) }, 4701 { "vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue) }, 4702 { "vkQueueSubmit", reinterpret_cast<PFN_vkVoidFunction>(QueueSubmit) }, 4703 { "vkQueueWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(QueueWaitIdle) }, 4704 { "vkDeviceWaitIdle", reinterpret_cast<PFN_vkVoidFunction>(DeviceWaitIdle) }, 4705 { "vkAllocateMemory", reinterpret_cast<PFN_vkVoidFunction>(AllocateMemory) }, 4706 { "vkFreeMemory", reinterpret_cast<PFN_vkVoidFunction>(FreeMemory) }, 4707 { "vkMapMemory", reinterpret_cast<PFN_vkVoidFunction>(MapMemory) }, 4708 { "vkUnmapMemory", reinterpret_cast<PFN_vkVoidFunction>(UnmapMemory) }, 4709 { "vkFlushMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(FlushMappedMemoryRanges) }, 4710 { "vkInvalidateMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(InvalidateMappedMemoryRanges) }, 4711 { "vkGetDeviceMemoryCommitment", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceMemoryCommitment) }, 4712 { "vkBindBufferMemory", reinterpret_cast<PFN_vkVoidFunction>(BindBufferMemory) }, 4713 { "vkBindImageMemory", reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory) }, 4714 { "vkCreateFence", reinterpret_cast<PFN_vkVoidFunction>(CreateFence) }, 4715 { "vkDestroyFence", reinterpret_cast<PFN_vkVoidFunction>(DestroyFence) }, 4716 { "vkResetFences", reinterpret_cast<PFN_vkVoidFunction>(ResetFences) }, 4717 { "vkGetFenceStatus", reinterpret_cast<PFN_vkVoidFunction>(GetFenceStatus) }, 4718 { "vkWaitForFences", reinterpret_cast<PFN_vkVoidFunction>(WaitForFences) }, 4719 { "vkCreateSemaphore", reinterpret_cast<PFN_vkVoidFunction>(CreateSemaphore) }, 4720 { "vkDestroySemaphore", reinterpret_cast<PFN_vkVoidFunction>(DestroySemaphore) }, 4721 { "vkCreateEvent", reinterpret_cast<PFN_vkVoidFunction>(CreateEvent) }, 4722 { "vkDestroyEvent", reinterpret_cast<PFN_vkVoidFunction>(DestroyEvent) }, 4723 { "vkGetEventStatus", reinterpret_cast<PFN_vkVoidFunction>(GetEventStatus) }, 4724 { "vkSetEvent", reinterpret_cast<PFN_vkVoidFunction>(SetEvent) }, 4725 { "vkResetEvent", reinterpret_cast<PFN_vkVoidFunction>(ResetEvent) }, 4726 { "vkCreateQueryPool", reinterpret_cast<PFN_vkVoidFunction>(CreateQueryPool) }, 4727 { "vkDestroyQueryPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyQueryPool) }, 4728 { "vkGetQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(GetQueryPoolResults) }, 4729 { "vkCreateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CreateBuffer) }, 4730 { "vkDestroyBuffer", reinterpret_cast<PFN_vkVoidFunction>(DestroyBuffer) }, 4731 { "vkCreateBufferView", reinterpret_cast<PFN_vkVoidFunction>(CreateBufferView) }, 4732 { "vkDestroyBufferView", reinterpret_cast<PFN_vkVoidFunction>(DestroyBufferView) }, 4733 { "vkCreateImage", reinterpret_cast<PFN_vkVoidFunction>(CreateImage) }, 4734 { "vkDestroyImage", reinterpret_cast<PFN_vkVoidFunction>(DestroyImage) }, 4735 { "vkGetImageSubresourceLayout", reinterpret_cast<PFN_vkVoidFunction>(GetImageSubresourceLayout) }, 4736 { "vkCreateImageView", reinterpret_cast<PFN_vkVoidFunction>(CreateImageView) }, 4737 { "vkDestroyImageView", reinterpret_cast<PFN_vkVoidFunction>(DestroyImageView) }, 4738 { "vkCreateShaderModule", reinterpret_cast<PFN_vkVoidFunction>(CreateShaderModule) }, 4739 { "vkDestroyShaderModule", reinterpret_cast<PFN_vkVoidFunction>(DestroyShaderModule) }, 4740 { "vkCreatePipelineCache", reinterpret_cast<PFN_vkVoidFunction>(CreatePipelineCache) }, 4741 { "vkDestroyPipelineCache", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipelineCache) }, 4742 { "vkGetPipelineCacheData", reinterpret_cast<PFN_vkVoidFunction>(GetPipelineCacheData) }, 4743 { "vkMergePipelineCaches", reinterpret_cast<PFN_vkVoidFunction>(MergePipelineCaches) }, 4744 { "vkCreateGraphicsPipelines", reinterpret_cast<PFN_vkVoidFunction>(CreateGraphicsPipelines) }, 4745 { "vkCreateComputePipelines", reinterpret_cast<PFN_vkVoidFunction>(CreateComputePipelines) }, 4746 { "vkDestroyPipeline", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipeline) }, 4747 { "vkCreatePipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(CreatePipelineLayout) }, 4748 { "vkDestroyPipelineLayout", reinterpret_cast<PFN_vkVoidFunction>(DestroyPipelineLayout) }, 4749 { "vkCreateSampler", reinterpret_cast<PFN_vkVoidFunction>(CreateSampler) }, 4750 { "vkDestroySampler", reinterpret_cast<PFN_vkVoidFunction>(DestroySampler) }, 4751 { "vkCreateDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(CreateDescriptorSetLayout) }, 4752 { "vkDestroyDescriptorSetLayout", reinterpret_cast<PFN_vkVoidFunction>(DestroyDescriptorSetLayout) }, 4753 { "vkCreateDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(CreateDescriptorPool) }, 4754 { "vkDestroyDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyDescriptorPool) }, 4755 { "vkResetDescriptorPool", reinterpret_cast<PFN_vkVoidFunction>(ResetDescriptorPool) }, 4756 { "vkAllocateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(AllocateDescriptorSets) }, 4757 { "vkFreeDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(FreeDescriptorSets) }, 4758 { "vkUpdateDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(UpdateDescriptorSets) }, 4759 { "vkCmdSetViewport", reinterpret_cast<PFN_vkVoidFunction>(CmdSetViewport) }, 4760 { "vkCmdSetScissor", reinterpret_cast<PFN_vkVoidFunction>(CmdSetScissor) }, 4761 { "vkCmdSetLineWidth", reinterpret_cast<PFN_vkVoidFunction>(CmdSetLineWidth) }, 4762 { "vkCmdSetDepthBias", reinterpret_cast<PFN_vkVoidFunction>(CmdSetDepthBias) }, 4763 { "vkCmdSetBlendConstants", reinterpret_cast<PFN_vkVoidFunction>(CmdSetBlendConstants) }, 4764 { "vkCmdSetDepthBounds", reinterpret_cast<PFN_vkVoidFunction>(CmdSetDepthBounds) }, 4765 { "vkCmdSetStencilCompareMask", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilCompareMask) }, 4766 { "vkCmdSetStencilWriteMask", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilWriteMask) }, 4767 { "vkCmdSetStencilReference", reinterpret_cast<PFN_vkVoidFunction>(CmdSetStencilReference) }, 4768 { "vkAllocateCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers) }, 4769 { "vkFreeCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(FreeCommandBuffers) }, 4770 { "vkBeginCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(BeginCommandBuffer) }, 4771 { "vkEndCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(EndCommandBuffer) }, 4772 { "vkResetCommandBuffer", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandBuffer) }, 4773 { "vkCmdBindPipeline", reinterpret_cast<PFN_vkVoidFunction>(CmdBindPipeline) }, 4774 { "vkCmdBindDescriptorSets", reinterpret_cast<PFN_vkVoidFunction>(CmdBindDescriptorSets) }, 4775 { "vkCmdBindVertexBuffers", reinterpret_cast<PFN_vkVoidFunction>(CmdBindVertexBuffers) }, 4776 { "vkCmdBindIndexBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdBindIndexBuffer) }, 4777 { "vkCmdDraw", reinterpret_cast<PFN_vkVoidFunction>(CmdDraw) }, 4778 { "vkCmdDrawIndexed", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndexed) }, 4779 { "vkCmdDrawIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndirect) }, 4780 { "vkCmdDrawIndexedIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDrawIndexedIndirect) }, 4781 { "vkCmdDispatch", reinterpret_cast<PFN_vkVoidFunction>(CmdDispatch) }, 4782 { "vkCmdDispatchIndirect", reinterpret_cast<PFN_vkVoidFunction>(CmdDispatchIndirect) }, 4783 { "vkCmdCopyBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyBuffer) }, 4784 { "vkCmdCopyImage", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyImage) }, 4785 { "vkCmdBlitImage", reinterpret_cast<PFN_vkVoidFunction>(CmdBlitImage) }, 4786 { "vkCmdCopyBufferToImage", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyBufferToImage) }, 4787 { "vkCmdCopyImageToBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyImageToBuffer) }, 4788 { "vkCmdUpdateBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdUpdateBuffer) }, 4789 { "vkCmdFillBuffer", reinterpret_cast<PFN_vkVoidFunction>(CmdFillBuffer) }, 4790 { "vkCmdClearColorImage", reinterpret_cast<PFN_vkVoidFunction>(CmdClearColorImage) }, 4791 { "vkCmdResolveImage", reinterpret_cast<PFN_vkVoidFunction>(CmdResolveImage) }, 4792 { "vkCmdSetEvent", reinterpret_cast<PFN_vkVoidFunction>(CmdSetEvent) }, 4793 { "vkCmdResetEvent", reinterpret_cast<PFN_vkVoidFunction>(CmdResetEvent) }, 4794 { "vkCmdWaitEvents", reinterpret_cast<PFN_vkVoidFunction>(CmdWaitEvents) }, 4795 { "vkCmdPipelineBarrier", reinterpret_cast<PFN_vkVoidFunction>(CmdPipelineBarrier) }, 4796 { "vkCmdBeginQuery", reinterpret_cast<PFN_vkVoidFunction>(CmdBeginQuery) }, 4797 { "vkCmdEndQuery", reinterpret_cast<PFN_vkVoidFunction>(CmdEndQuery) }, 4798 { "vkCmdResetQueryPool", reinterpret_cast<PFN_vkVoidFunction>(CmdResetQueryPool) }, 4799 { "vkCmdWriteTimestamp", reinterpret_cast<PFN_vkVoidFunction>(CmdWriteTimestamp) }, 4800 { "vkCmdCopyQueryPoolResults", reinterpret_cast<PFN_vkVoidFunction>(CmdCopyQueryPoolResults) }, 4801 { "vkCreateFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(CreateFramebuffer) }, 4802 { "vkDestroyFramebuffer", reinterpret_cast<PFN_vkVoidFunction>(DestroyFramebuffer) }, 4803 { "vkCreateRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CreateRenderPass) }, 4804 { "vkDestroyRenderPass", reinterpret_cast<PFN_vkVoidFunction>(DestroyRenderPass) }, 4805 { "vkGetRenderAreaGranularity", reinterpret_cast<PFN_vkVoidFunction>(GetRenderAreaGranularity) }, 4806 { "vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(CreateCommandPool) }, 4807 { "vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyCommandPool) }, 4808 { "vkResetCommandPool", reinterpret_cast<PFN_vkVoidFunction>(ResetCommandPool) }, 4809 { "vkCmdBeginRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CmdBeginRenderPass) }, 4810 { "vkCmdNextSubpass", reinterpret_cast<PFN_vkVoidFunction>(CmdNextSubpass) }, 4811 }; 4812 4813 for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) { 4814 if (!strcmp(core_device_commands[i].name, name)) 4815 return core_device_commands[i].proc; 4816 } 4817 4818 return nullptr; 4819} 4820 4821} // namespace parameter_validation 4822 4823// vk_layer_logging.h expects these to be defined 4824 4825VKAPI_ATTR VkResult VKAPI_CALL 4826vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 4827 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) { 4828 return parameter_validation::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 4829} 4830 4831VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, 4832 VkDebugReportCallbackEXT msgCallback, 4833 const VkAllocationCallbacks *pAllocator) { 4834 parameter_validation::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 4835} 4836 4837VKAPI_ATTR void VKAPI_CALL 4838vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object, 4839 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 4840 parameter_validation::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg); 4841} 4842 4843// loader-layer interface v0 4844 4845VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 4846vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) { 4847 return parameter_validation::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties); 4848} 4849 4850VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 4851vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 4852 return parameter_validation::EnumerateInstanceLayerProperties(pCount, pProperties); 4853} 4854 4855VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL 4856vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) { 4857 // the layer command handles VK_NULL_HANDLE just fine internally 4858 assert(physicalDevice == VK_NULL_HANDLE); 4859 return parameter_validation::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties); 4860} 4861 4862VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 4863 const char *pLayerName, uint32_t *pCount, 4864 VkExtensionProperties *pProperties) { 4865 // the layer command handles VK_NULL_HANDLE just fine internally 4866 assert(physicalDevice == VK_NULL_HANDLE); 4867 return parameter_validation::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); 4868} 4869 4870VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) { 4871 return parameter_validation::GetDeviceProcAddr(dev, funcName); 4872} 4873 4874VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 4875 return parameter_validation::GetInstanceProcAddr(instance, funcName); 4876} 4877