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