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