• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2015-2016 The Khronos Group Inc.
2  * Copyright (c) 2015-2016 Valve Corporation
3  * Copyright (c) 2015-2016 LunarG, Inc.
4  * Copyright (C) 2015-2016 Google Inc.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: Jeremy Hayes <jeremy@lunarg.com>
19  * Author: Tony Barbour <tony@LunarG.com>
20  * Author: Mark Lobodzinski <mark@LunarG.com>
21  * Author: Dustin Graves <dustin@lunarg.com>
22  */
23 
24 #define NOMINMAX
25 
26 #include <math.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include <iostream>
32 #include <string>
33 #include <sstream>
34 #include <unordered_map>
35 #include <unordered_set>
36 #include <vector>
37 
38 #include "vk_loader_platform.h"
39 #include "vulkan/vk_layer.h"
40 #include "vk_layer_config.h"
41 #include "vk_enum_validate_helper.h"
42 #include "vk_struct_validate_helper.h"
43 
44 #include "vk_layer_table.h"
45 #include "vk_layer_data.h"
46 #include "vk_layer_logging.h"
47 #include "vk_layer_extension_utils.h"
48 #include "vk_layer_utils.h"
49 
50 #include "parameter_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 
layer_dataparameter_validation::layer_data78     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"
mid(VkInstance object)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"
mdd(void * object)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 
init_parameter_validation(layer_data * my_data,const VkAllocationCallbacks * pAllocator)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 
CreateDebugReportCallbackEXT(VkInstance instance,const VkDebugReportCallbackCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugReportCallbackEXT * pMsgCallback)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 
DestroyDebugReportCallbackEXT(VkInstance instance,VkDebugReportCallbackEXT msgCallback,const VkAllocationCallbacks * pAllocator)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 
DebugReportMessageEXT(VkInstance instance,VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT objType,uint64_t object,size_t location,int32_t msgCode,const char * pLayerPrefix,const char * pMsg)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 
ValidateEnumerator(VkFormatFeatureFlagBits const & enumerator)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 
EnumeratorString(VkFormatFeatureFlagBits const & enumerator)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 
ValidateEnumerator(VkImageUsageFlagBits const & enumerator)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 
EnumeratorString(VkImageUsageFlagBits const & enumerator)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 
ValidateEnumerator(VkQueueFlagBits const & enumerator)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 
EnumeratorString(VkQueueFlagBits const & enumerator)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 
ValidateEnumerator(VkMemoryPropertyFlagBits const & enumerator)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 
EnumeratorString(VkMemoryPropertyFlagBits const & enumerator)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 
ValidateEnumerator(VkMemoryHeapFlagBits const & enumerator)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 
EnumeratorString(VkMemoryHeapFlagBits const & enumerator)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 
ValidateEnumerator(VkSparseImageFormatFlagBits const & enumerator)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 
EnumeratorString(VkSparseImageFormatFlagBits const & enumerator)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 
ValidateEnumerator(VkFenceCreateFlagBits const & enumerator)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 
EnumeratorString(VkFenceCreateFlagBits const & enumerator)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 
ValidateEnumerator(VkQueryPipelineStatisticFlagBits const & enumerator)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 
EnumeratorString(VkQueryPipelineStatisticFlagBits const & enumerator)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 
ValidateEnumerator(VkQueryResultFlagBits const & enumerator)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 
EnumeratorString(VkQueryResultFlagBits const & enumerator)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 
ValidateEnumerator(VkBufferUsageFlagBits const & enumerator)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 
EnumeratorString(VkBufferUsageFlagBits const & enumerator)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 
ValidateEnumerator(VkBufferCreateFlagBits const & enumerator)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 
EnumeratorString(VkBufferCreateFlagBits const & enumerator)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 
ValidateEnumerator(VkImageCreateFlagBits const & enumerator)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 
EnumeratorString(VkImageCreateFlagBits const & enumerator)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 
ValidateEnumerator(VkColorComponentFlagBits const & enumerator)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 
EnumeratorString(VkColorComponentFlagBits const & enumerator)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 
ValidateEnumerator(VkPipelineCreateFlagBits const & enumerator)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 
EnumeratorString(VkPipelineCreateFlagBits const & enumerator)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 
ValidateEnumerator(VkShaderStageFlagBits const & enumerator)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 
EnumeratorString(VkShaderStageFlagBits const & enumerator)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 
ValidateEnumerator(VkPipelineStageFlagBits const & enumerator)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 
EnumeratorString(VkPipelineStageFlagBits const & enumerator)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 
ValidateEnumerator(VkAccessFlagBits const & enumerator)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 
EnumeratorString(VkAccessFlagBits const & enumerator)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 
ValidateEnumerator(VkCommandPoolCreateFlagBits const & enumerator)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 
EnumeratorString(VkCommandPoolCreateFlagBits const & enumerator)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 
ValidateEnumerator(VkCommandPoolResetFlagBits const & enumerator)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 
EnumeratorString(VkCommandPoolResetFlagBits const & enumerator)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 
ValidateEnumerator(VkCommandBufferUsageFlags const & enumerator)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 
EnumeratorString(VkCommandBufferUsageFlags const & enumerator)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 
ValidateEnumerator(VkCommandBufferResetFlagBits const & enumerator)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 
EnumeratorString(VkCommandBufferResetFlagBits const & enumerator)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 
ValidateEnumerator(VkImageAspectFlagBits const & enumerator)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 
EnumeratorString(VkImageAspectFlagBits const & enumerator)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 
ValidateEnumerator(VkQueryControlFlagBits const & enumerator)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 
EnumeratorString(VkQueryControlFlagBits const & enumerator)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 
validate_string(debug_report_data * report_data,const char * apiName,const ParameterName & stringName,const char * validateString)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 
validate_queue_family_index(layer_data * device_data,const char * function_name,const char * parameter_name,uint32_t index)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 
validate_queue_family_indices(layer_data * device_data,const char * function_name,const char * parameter_name,const uint32_t count,const uint32_t * indices)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 
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)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 
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)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 
EnumeratePhysicalDevices(VkInstance instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)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 
GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)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 
GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)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 
GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)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 
GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties * pProperties)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 
GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties * pQueueFamilyProperties)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 
GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties * pMemoryProperties)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 
validateDeviceCreateInfo(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const std::vector<VkQueueFamilyProperties> properties)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 
CheckInstanceRegisterExtensions(const VkInstanceCreateInfo * pCreateInfo,VkInstance instance)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 
CheckDeviceRegisterExtensions(const VkDeviceCreateInfo * pCreateInfo,VkDevice device)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 
storeCreateDeviceData(VkDevice device,const VkDeviceCreateInfo * pCreateInfo)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 
CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)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 
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)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 
PreGetDeviceQueue(VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex)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 
GetDeviceQueue(VkDevice device,uint32_t queueFamilyIndex,uint32_t queueIndex,VkQueue * pQueue)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 
QueueSubmit(VkQueue queue,uint32_t submitCount,const VkSubmitInfo * pSubmits,VkFence fence)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 
QueueWaitIdle(VkQueue queue)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 
DeviceWaitIdle(VkDevice device)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 
AllocateMemory(VkDevice device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMemory)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 
FreeMemory(VkDevice device,VkDeviceMemory memory,const VkAllocationCallbacks * pAllocator)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 
MapMemory(VkDevice device,VkDeviceMemory memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)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 
UnmapMemory(VkDevice device,VkDeviceMemory memory)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 
FlushMappedMemoryRanges(VkDevice device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)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 
InvalidateMappedMemoryRanges(VkDevice device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)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 
GetDeviceMemoryCommitment(VkDevice device,VkDeviceMemory memory,VkDeviceSize * pCommittedMemoryInBytes)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 
BindBufferMemory(VkDevice device,VkBuffer buffer,VkDeviceMemory memory,VkDeviceSize memoryOffset)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 
BindImageMemory(VkDevice device,VkImage image,VkDeviceMemory memory,VkDeviceSize memoryOffset)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 
GetBufferMemoryRequirements(VkDevice device,VkBuffer buffer,VkMemoryRequirements * pMemoryRequirements)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 
GetImageMemoryRequirements(VkDevice device,VkImage image,VkMemoryRequirements * pMemoryRequirements)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 
PostGetImageSparseMemoryRequirements(VkDevice device,VkImage image,uint32_t * pNumRequirements,VkSparseImageMemoryRequirements * pSparseMemoryRequirements)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 
GetImageSparseMemoryRequirements(VkDevice device,VkImage image,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements * pSparseMemoryRequirements)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 
PostGetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pNumProperties,VkSparseImageFormatProperties * pProperties)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 
GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pPropertyCount,VkSparseImageFormatProperties * pProperties)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 
QueueBindSparse(VkQueue queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)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 
CreateFence(VkDevice device,const VkFenceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFence * pFence)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 
DestroyFence(VkDevice device,VkFence fence,const VkAllocationCallbacks * pAllocator)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 
ResetFences(VkDevice device,uint32_t fenceCount,const VkFence * pFences)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 
GetFenceStatus(VkDevice device,VkFence fence)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 
WaitForFences(VkDevice device,uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout)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 
CreateSemaphore(VkDevice device,const VkSemaphoreCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSemaphore * pSemaphore)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 
DestroySemaphore(VkDevice device,VkSemaphore semaphore,const VkAllocationCallbacks * pAllocator)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 
CreateEvent(VkDevice device,const VkEventCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkEvent * pEvent)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 
DestroyEvent(VkDevice device,VkEvent event,const VkAllocationCallbacks * pAllocator)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 
GetEventStatus(VkDevice device,VkEvent event)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 
SetEvent(VkDevice device,VkEvent event)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 
ResetEvent(VkDevice device,VkEvent event)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 
CreateQueryPool(VkDevice device,const VkQueryPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkQueryPool * pQueryPool)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 
DestroyQueryPool(VkDevice device,VkQueryPool queryPool,const VkAllocationCallbacks * pAllocator)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 
GetQueryPoolResults(VkDevice device,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,size_t dataSize,void * pData,VkDeviceSize stride,VkQueryResultFlags flags)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 
CreateBuffer(VkDevice device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)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 
DestroyBuffer(VkDevice device,VkBuffer buffer,const VkAllocationCallbacks * pAllocator)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 
CreateBufferView(VkDevice device,const VkBufferViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBufferView * pView)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 
DestroyBufferView(VkDevice device,VkBufferView bufferView,const VkAllocationCallbacks * pAllocator)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 
CreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)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 
DestroyImage(VkDevice device,VkImage image,const VkAllocationCallbacks * pAllocator)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 
PreGetImageSubresourceLayout(VkDevice device,const VkImageSubresource * pSubresource)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 
GetImageSubresourceLayout(VkDevice device,VkImage image,const VkImageSubresource * pSubresource,VkSubresourceLayout * pLayout)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 
CreateImageView(VkDevice device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)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 
DestroyImageView(VkDevice device,VkImageView imageView,const VkAllocationCallbacks * pAllocator)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 
CreateShaderModule(VkDevice device,const VkShaderModuleCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkShaderModule * pShaderModule)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 
DestroyShaderModule(VkDevice device,VkShaderModule shaderModule,const VkAllocationCallbacks * pAllocator)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 
CreatePipelineCache(VkDevice device,const VkPipelineCacheCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineCache * pPipelineCache)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 
DestroyPipelineCache(VkDevice device,VkPipelineCache pipelineCache,const VkAllocationCallbacks * pAllocator)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 
GetPipelineCacheData(VkDevice device,VkPipelineCache pipelineCache,size_t * pDataSize,void * pData)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 
MergePipelineCaches(VkDevice device,VkPipelineCache dstCache,uint32_t srcCacheCount,const VkPipelineCache * pSrcCaches)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 
PreCreateGraphicsPipelines(VkDevice device,const VkGraphicsPipelineCreateInfo * pCreateInfos)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 
CreateGraphicsPipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)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 
PreCreateComputePipelines(VkDevice device,const VkComputePipelineCreateInfo * pCreateInfos)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 
CreateComputePipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)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 
DestroyPipeline(VkDevice device,VkPipeline pipeline,const VkAllocationCallbacks * pAllocator)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 
CreatePipelineLayout(VkDevice device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)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 
DestroyPipelineLayout(VkDevice device,VkPipelineLayout pipelineLayout,const VkAllocationCallbacks * pAllocator)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 
CreateSampler(VkDevice device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)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 
DestroySampler(VkDevice device,VkSampler sampler,const VkAllocationCallbacks * pAllocator)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 
CreateDescriptorSetLayout(VkDevice device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)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 
DestroyDescriptorSetLayout(VkDevice device,VkDescriptorSetLayout descriptorSetLayout,const VkAllocationCallbacks * pAllocator)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 
CreateDescriptorPool(VkDevice device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)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 
DestroyDescriptorPool(VkDevice device,VkDescriptorPool descriptorPool,const VkAllocationCallbacks * pAllocator)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 
ResetDescriptorPool(VkDevice device,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags flags)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 
AllocateDescriptorSets(VkDevice device,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)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 
FreeDescriptorSets(VkDevice device,VkDescriptorPool descriptorPool,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets)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 
UpdateDescriptorSets(VkDevice device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)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 
CreateFramebuffer(VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFramebuffer * pFramebuffer)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 
DestroyFramebuffer(VkDevice device,VkFramebuffer framebuffer,const VkAllocationCallbacks * pAllocator)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 
PreCreateRenderPass(layer_data * dev_data,const VkRenderPassCreateInfo * pCreateInfo)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 
CreateRenderPass(VkDevice device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)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 
DestroyRenderPass(VkDevice device,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)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 
GetRenderAreaGranularity(VkDevice device,VkRenderPass renderPass,VkExtent2D * pGranularity)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 
CreateCommandPool(VkDevice device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCommandPool)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 
DestroyCommandPool(VkDevice device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)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 
ResetCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)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 
AllocateCommandBuffers(VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)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 
FreeCommandBuffers(VkDevice device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)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 
PreBeginCommandBuffer(layer_data * dev_data,VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)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 
BeginCommandBuffer(VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)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 
EndCommandBuffer(VkCommandBuffer commandBuffer)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 
ResetCommandBuffer(VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)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 
CmdBindPipeline(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline pipeline)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 
CmdSetViewport(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkViewport * pViewports)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 
CmdSetScissor(VkCommandBuffer commandBuffer,uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * pScissors)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 
CmdSetLineWidth(VkCommandBuffer commandBuffer,float lineWidth)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 
CmdSetDepthBias(VkCommandBuffer commandBuffer,float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)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 
CmdSetBlendConstants(VkCommandBuffer commandBuffer,const float blendConstants[4])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 
CmdSetDepthBounds(VkCommandBuffer commandBuffer,float minDepthBounds,float maxDepthBounds)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 
CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t compareMask)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 
CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t writeMask)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 
CmdSetStencilReference(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t reference)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 
CmdBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)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 
CmdBindIndexBuffer(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,VkIndexType indexType)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 
CmdBindVertexBuffers(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets)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 
PreCmdDraw(VkCommandBuffer commandBuffer,uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)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 
CmdDraw(VkCommandBuffer commandBuffer,uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)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 
CmdDrawIndexed(VkCommandBuffer commandBuffer,uint32_t indexCount,uint32_t instanceCount,uint32_t firstIndex,int32_t vertexOffset,uint32_t firstInstance)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 
CmdDrawIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,uint32_t count,uint32_t stride)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 
CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,uint32_t count,uint32_t stride)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 
CmdDispatch(VkCommandBuffer commandBuffer,uint32_t x,uint32_t y,uint32_t z)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 
CmdDispatchIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset)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 
CmdCopyBuffer(VkCommandBuffer commandBuffer,VkBuffer srcBuffer,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferCopy * pRegions)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 
PreCmdCopyImage(VkCommandBuffer commandBuffer,const VkImageCopy * pRegions)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 
CmdCopyImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)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 
PreCmdBlitImage(VkCommandBuffer commandBuffer,const VkImageBlit * pRegions)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 
CmdBlitImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * pRegions,VkFilter filter)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 
PreCmdCopyBufferToImage(VkCommandBuffer commandBuffer,const VkBufferImageCopy * pRegions)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 
CmdCopyBufferToImage(VkCommandBuffer commandBuffer,VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions)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 
PreCmdCopyImageToBuffer(VkCommandBuffer commandBuffer,const VkBufferImageCopy * pRegions)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 
CmdCopyImageToBuffer(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)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 
CmdUpdateBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize dataSize,const uint32_t * pData)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 
CmdFillBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)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 
CmdClearColorImage(VkCommandBuffer commandBuffer,VkImage image,VkImageLayout imageLayout,const VkClearColorValue * pColor,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)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 
CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,VkImage image,VkImageLayout imageLayout,const VkClearDepthStencilValue * pDepthStencil,uint32_t rangeCount,const VkImageSubresourceRange * pRanges)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 
CmdClearAttachments(VkCommandBuffer commandBuffer,uint32_t attachmentCount,const VkClearAttachment * pAttachments,uint32_t rectCount,const VkClearRect * pRects)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 
PreCmdResolveImage(VkCommandBuffer commandBuffer,const VkImageResolve * pRegions)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 
CmdResolveImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * pRegions)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 
CmdSetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags stageMask)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 
CmdResetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags stageMask)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 
CmdWaitEvents(VkCommandBuffer commandBuffer,uint32_t eventCount,const VkEvent * pEvents,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)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 
CmdPipelineBarrier(VkCommandBuffer commandBuffer,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkDependencyFlags dependencyFlags,uint32_t memoryBarrierCount,const VkMemoryBarrier * pMemoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * pBufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * pImageMemoryBarriers)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 
CmdBeginQuery(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t slot,VkQueryControlFlags flags)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 
CmdEndQuery(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t slot)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 
CmdResetQueryPool(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount)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 
PostCmdWriteTimestamp(VkCommandBuffer commandBuffer,VkPipelineStageFlagBits pipelineStage,VkQueryPool queryPool,uint32_t slot)4592 bool PostCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool,
4593                            uint32_t slot) {
4594 
4595     ValidateEnumerator(pipelineStage);
4596 
4597     return true;
4598 }
4599 
CmdWriteTimestamp(VkCommandBuffer commandBuffer,VkPipelineStageFlagBits pipelineStage,VkQueryPool queryPool,uint32_t query)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 
CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize stride,VkQueryResultFlags flags)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 
CmdPushConstants(VkCommandBuffer commandBuffer,VkPipelineLayout layout,VkShaderStageFlags stageFlags,uint32_t offset,uint32_t size,const void * pValues)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 
CmdBeginRenderPass(VkCommandBuffer commandBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,VkSubpassContents contents)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 
CmdNextSubpass(VkCommandBuffer commandBuffer,VkSubpassContents contents)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 
CmdEndRenderPass(VkCommandBuffer commandBuffer)4670 VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) {
4671     get_dispatch_table(pc_device_table_map, commandBuffer)->CmdEndRenderPass(commandBuffer);
4672 }
4673 
CmdExecuteCommands(VkCommandBuffer commandBuffer,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)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 
EnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)4688 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
4689     return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
4690 }
4691 
EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)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 
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)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 
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)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 
CreateSwapchainKHR(VkDevice device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)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 
GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR swapchain,uint32_t * pSwapchainImageCount,VkImage * pSwapchainImages)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 
AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchain,uint64_t timeout,VkSemaphore semaphore,VkFence fence,uint32_t * pImageIndex)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 
QueuePresentKHR(VkQueue queue,const VkPresentInfoKHR * pPresentInfo)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 
GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,VkSurfaceKHR surface,VkBool32 * pSupported)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 
GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * pSurfaceCapabilities)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 
GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pSurfaceFormatCount,VkSurfaceFormatKHR * pSurfaceFormats)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 
GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pPresentModeCount,VkPresentModeKHR * pPresentModes)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
CreateWin32SurfaceKHR(VkInstance instance,const VkWin32SurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)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
CreateXcbSurfaceKHR(VkInstance instance,const VkXcbSurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)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 
GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,xcb_connection_t * connection,xcb_visualid_t visual_id)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
CreateXlibSurfaceKHR(VkInstance instance,const VkXlibSurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)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 
GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,Display * dpy,VisualID visualID)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
CreateMirSurfaceKHR(VkInstance instance,const VkMirSurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)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 
GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,MirConnection * connection)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
CreateWaylandSurfaceKHR(VkInstance instance,const VkWaylandSurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)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 
GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,struct wl_display * display)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
CreateAndroidSurfaceKHR(VkInstance instance,const VkAndroidSurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)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 
CreateSharedSwapchainsKHR(VkDevice device,uint32_t swapchainCount,const VkSwapchainCreateInfoKHR * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchains)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
DebugMarkerSetObjectTagEXT(VkDevice device,VkDebugMarkerObjectTagInfoEXT * pTagInfo)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 
DebugMarkerSetObjectNameEXT(VkDevice device,VkDebugMarkerObjectNameInfoEXT * pNameInfo)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 
CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer,VkDebugMarkerMarkerInfoEXT * pMarkerInfo)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 
CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer,VkDebugMarkerMarkerInfoEXT * pMarkerInfo)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
GetPhysicalDeviceExternalImageFormatPropertiesNV(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkExternalMemoryHandleTypeFlagsNV externalHandleType,VkExternalImageFormatPropertiesNV * pExternalImageFormatProperties)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
GetMemoryWin32HandleNV(VkDevice device,VkDeviceMemory memory,VkExternalMemoryHandleTypeFlagsNV handleType,HANDLE * pHandle)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 
GetDeviceProcAddr(VkDevice device,const char * funcName)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 
GetInstanceProcAddr(VkInstance instance,const char * funcName)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 
intercept_core_instance_command(const char * name)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 
intercept_core_device_command(const char * name)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 
InterceptWsiEnabledCommand(const char * name,VkDevice device)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 
InterceptWsiEnabledCommand(const char * name,VkInstance instance)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 
vkCreateDebugReportCallbackEXT(VkInstance instance,const VkDebugReportCallbackCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugReportCallbackEXT * pMsgCallback)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 
vkDestroyDebugReportCallbackEXT(VkInstance instance,VkDebugReportCallbackEXT msgCallback,const VkAllocationCallbacks * pAllocator)5530 VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
5531                                                            const VkAllocationCallbacks *pAllocator) {
5532     parameter_validation::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
5533 }
5534 
vkDebugReportMessageEXT(VkInstance instance,VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT objType,uint64_t object,size_t location,int32_t msgCode,const char * pLayerPrefix,const char * pMsg)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 
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)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 
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)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 
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)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 
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)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 
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)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 
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)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