summaryrefslogtreecommitdiff
path: root/thirdparty/vulkan/loader
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/vulkan/loader')
-rw-r--r--thirdparty/vulkan/loader/adapters.h80
-rw-r--r--thirdparty/vulkan/loader/asm_offset.c94
-rw-r--r--thirdparty/vulkan/loader/cJSON.c1215
-rw-r--r--thirdparty/vulkan/loader/cJSON.h174
-rw-r--r--thirdparty/vulkan/loader/debug_utils.c996
-rw-r--r--thirdparty/vulkan/loader/debug_utils.h101
-rw-r--r--thirdparty/vulkan/loader/dev_ext_trampoline.c538
-rw-r--r--thirdparty/vulkan/loader/dirent_on_windows.c128
-rw-r--r--thirdparty/vulkan/loader/dirent_on_windows.h51
-rw-r--r--thirdparty/vulkan/loader/dxgi_loader.c23
-rw-r--r--thirdparty/vulkan/loader/dxgi_loader.h8
-rw-r--r--thirdparty/vulkan/loader/extension_manual.c443
-rw-r--r--thirdparty/vulkan/loader/extension_manual.h106
-rw-r--r--thirdparty/vulkan/loader/gpa_helper.h233
-rw-r--r--thirdparty/vulkan/loader/loader.c8139
-rw-r--r--thirdparty/vulkan/loader/loader.h532
-rw-r--r--thirdparty/vulkan/loader/murmurhash.c98
-rw-r--r--thirdparty/vulkan/loader/murmurhash.h52
-rw-r--r--thirdparty/vulkan/loader/phys_dev_ext.c1056
-rw-r--r--thirdparty/vulkan/loader/trampoline.c2480
-rw-r--r--thirdparty/vulkan/loader/unknown_ext_chain.c819
-rw-r--r--thirdparty/vulkan/loader/unknown_ext_chain_gas.S885
-rw-r--r--thirdparty/vulkan/loader/unknown_ext_chain_masm.asm883
-rw-r--r--thirdparty/vulkan/loader/vk_dispatch_table_helper.h761
-rw-r--r--thirdparty/vulkan/loader/vk_layer_dispatch_table.h651
-rw-r--r--thirdparty/vulkan/loader/vk_loader_extensions.c4448
-rw-r--r--thirdparty/vulkan/loader/vk_loader_extensions.h444
-rw-r--r--thirdparty/vulkan/loader/vk_loader_layer.h46
-rw-r--r--thirdparty/vulkan/loader/vk_loader_platform.h411
-rw-r--r--thirdparty/vulkan/loader/vk_object_types.h383
-rw-r--r--thirdparty/vulkan/loader/wsi.c2023
-rw-r--r--thirdparty/vulkan/loader/wsi.h184
32 files changed, 28485 insertions, 0 deletions
diff --git a/thirdparty/vulkan/loader/adapters.h b/thirdparty/vulkan/loader/adapters.h
new file mode 100644
index 0000000000..ef97d66573
--- /dev/null
+++ b/thirdparty/vulkan/loader/adapters.h
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2019 The Khronos Group Inc.
+* Copyright (c) 2019 Valve Corporation
+* Copyright (c) 2019 LunarG, Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* Author: Lenny Komow <lenny@lunarg.com>
+*/
+
+typedef struct LoaderEnumAdapters2 {
+ ULONG adapter_count;
+ struct {
+ UINT handle;
+ LUID luid;
+ ULONG source_count;
+ BOOL present_move_regions_preferred;
+ } * adapters;
+} LoaderEnumAdapters2;
+
+typedef _Check_return_ NTSTATUS(APIENTRY *PFN_LoaderEnumAdapters2)(const LoaderEnumAdapters2 *);
+
+typedef enum AdapterInfoType {
+ LOADER_QUERY_TYPE_REGISTRY = 48,
+} AdapterInfoType;
+
+typedef struct LoaderQueryAdapterInfo {
+ UINT handle;
+ AdapterInfoType type;
+ VOID *private_data;
+ UINT private_data_size;
+} LoaderQueryAdapterInfo;
+
+typedef _Check_return_ NTSTATUS(APIENTRY *PFN_LoaderQueryAdapterInfo)(const LoaderQueryAdapterInfo *);
+
+typedef enum LoaderQueryRegistryType {
+ LOADER_QUERY_REGISTRY_ADAPTER_KEY = 1,
+} LoaderQueryRegistryType;
+
+typedef enum LoaderQueryRegistryStatus {
+ LOADER_QUERY_REGISTRY_STATUS_SUCCESS = 0,
+ LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW = 1,
+} LoaderQueryRegistryStatus;
+
+typedef struct LoaderQueryRegistryFlags {
+ union {
+ struct {
+ UINT translate_path : 1;
+ UINT mutable_value : 1;
+ UINT reserved : 30;
+ };
+ UINT value;
+ };
+} LoaderQueryRegistryFlags;
+
+typedef struct LoaderQueryRegistryInfo {
+ LoaderQueryRegistryType query_type;
+ LoaderQueryRegistryFlags query_flags;
+ WCHAR value_name[MAX_PATH];
+ ULONG value_type;
+ ULONG physical_adapter_index;
+ ULONG output_value_size;
+ LoaderQueryRegistryStatus status;
+ union {
+ DWORD output_dword;
+ UINT64 output_qword;
+ WCHAR output_string[1];
+ BYTE output_binary[1];
+ };
+} LoaderQueryRegistryInfo;
diff --git a/thirdparty/vulkan/loader/asm_offset.c b/thirdparty/vulkan/loader/asm_offset.c
new file mode 100644
index 0000000000..97832afa03
--- /dev/null
+++ b/thirdparty/vulkan/loader/asm_offset.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017-2018 The Khronos Group Inc.
+ * Copyright (c) 2017-2018 Valve Corporation
+ * Copyright (c) 2017-2018 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Lenny Komow <lenny@lunarg.com>
+ */
+
+// This code generates an assembly file which provides offsets to get struct members from assembly code.
+
+#include <stdio.h>
+#include "loader.h"
+
+#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
+#define SIZE_T_FMT "%-8zu"
+#else
+#define SIZE_T_FMT "%-8lu"
+#endif
+
+struct ValueInfo
+{
+ const char *name;
+ size_t value;
+ const char *comment;
+};
+
+int main(int argc, char **argv) {
+ const char *assembler = NULL;
+ for (int i = 0; i < argc; ++i) {
+ if (!strcmp(argv[i], "MASM")) {
+ assembler = "MASM";
+ } else if (!strcmp(argv[i], "GAS")) {
+ assembler = "GAS";
+ }
+ }
+ if (assembler == NULL) {
+ return 1;
+ }
+
+ struct ValueInfo values[] = {
+ { .name = "VK_DEBUG_REPORT_ERROR_BIT_EXT", .value = (size_t) VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ .comment = "The numerical value of the enum value 'VK_DEBUG_REPORT_ERROR_BIT_EXT'" },
+ { .name = "PTR_SIZE", .value = sizeof(void*),
+ .comment = "The size of a pointer" },
+ { .name = "HASH_SIZE", .value = sizeof(struct loader_dispatch_hash_entry),
+ .comment = "The size of a 'loader_dispatch_hash_entry' struct" },
+ { .name = "HASH_OFFSET_INSTANCE", .value = offsetof(struct loader_instance, phys_dev_ext_disp_hash),
+ .comment = "The offset of 'phys_dev_ext_disp_hash' within a 'loader_instance' struct" },
+ { .name = "PHYS_DEV_OFFSET_INST_DISPATCH", .value = offsetof(struct loader_instance_dispatch_table, phys_dev_ext),
+ .comment = "The offset of 'phys_dev_ext' within in 'loader_instance_dispatch_table' struct" },
+ { .name = "PHYS_DEV_OFFSET_PHYS_DEV_TRAMP", .value = offsetof(struct loader_physical_device_tramp, phys_dev),
+ .comment = "The offset of 'phys_dev' within a 'loader_physical_device_tramp' struct" },
+ { .name = "ICD_TERM_OFFSET_PHYS_DEV_TERM", .value = offsetof(struct loader_physical_device_term, this_icd_term),
+ .comment = "The offset of 'this_icd_term' within a 'loader_physical_device_term' struct" },
+ { .name = "PHYS_DEV_OFFSET_PHYS_DEV_TERM", .value = offsetof(struct loader_physical_device_term, phys_dev),
+ .comment = "The offset of 'phys_dev' within a 'loader_physical_device_term' struct" },
+ { .name = "INSTANCE_OFFSET_ICD_TERM", .value = offsetof(struct loader_icd_term, this_instance),
+ .comment = "The offset of 'this_instance' within a 'loader_icd_term' struct" },
+ { .name = "DISPATCH_OFFSET_ICD_TERM", .value = offsetof(struct loader_icd_term, phys_dev_ext),
+ .comment = "The offset of 'phys_dev_ext' within a 'loader_icd_term' struct" },
+ { .name = "FUNC_NAME_OFFSET_HASH", .value = offsetof(struct loader_dispatch_hash_entry, func_name),
+ .comment = "The offset of 'func_name' within a 'loader_dispatch_hash_entry' struct" },
+ { .name = "EXT_OFFSET_DEVICE_DISPATCH", .value = offsetof(struct loader_dev_dispatch_table, ext_dispatch),
+ .comment = "The offset of 'ext_dispatch' within a 'loader_dev_dispatch_table' struct" },
+ };
+
+ FILE *file = fopen("gen_defines.asm", "w");
+ fprintf(file, "\n");
+ if (!strcmp(assembler, "MASM")) {
+ for (size_t i = 0; i < sizeof(values)/sizeof(values[0]); ++i) {
+ fprintf(file, "%-32s equ " SIZE_T_FMT "; %s\n", values[i].name, values[i].value, values[i].comment);
+ }
+ } else if (!strcmp(assembler, "GAS")) {
+#ifdef __x86_64__
+ fprintf(file, ".set X86_64, 1\n");
+#endif // __x86_64__
+ for (size_t i = 0; i < sizeof(values)/sizeof(values[0]); ++i) {
+ fprintf(file, ".set %-32s, " SIZE_T_FMT "# %s\n", values[i].name, values[i].value, values[i].comment);
+ }
+ }
+ return fclose(file);
+}
diff --git a/thirdparty/vulkan/loader/cJSON.c b/thirdparty/vulkan/loader/cJSON.c
new file mode 100644
index 0000000000..8da6d83c32
--- /dev/null
+++ b/thirdparty/vulkan/loader/cJSON.c
@@ -0,0 +1,1215 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+ Copyright (c) 2015-2016 The Khronos Group Inc.
+ Copyright (c) 2015-2016 Valve Corporation
+ Copyright (c) 2015-2016 LunarG, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/* cJSON */
+/* JSON parser in C. */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <float.h>
+#include <limits.h>
+#include <ctype.h>
+#include "cJSON.h"
+
+static const char *ep;
+
+const char *cJSON_GetErrorPtr(void) { return ep; }
+
+static void *(*cJSON_malloc)(size_t sz) = malloc;
+static void (*cJSON_free)(void *ptr) = free;
+
+static char *cJSON_strdup(const char *str) {
+ size_t len;
+ char *copy;
+
+ len = strlen(str) + 1;
+ if (!(copy = (char *)cJSON_malloc(len))) return 0;
+ memcpy(copy, str, len);
+ return copy;
+}
+
+void cJSON_InitHooks(cJSON_Hooks *hooks) {
+ if (!hooks) { /* Reset hooks */
+ cJSON_malloc = malloc;
+ cJSON_free = free;
+ return;
+ }
+
+ cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc;
+ cJSON_free = (hooks->free_fn) ? hooks->free_fn : free;
+}
+
+/* Internal constructor. */
+static cJSON *cJSON_New_Item(void) {
+ cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON));
+ if (node) memset(node, 0, sizeof(cJSON));
+ return node;
+}
+
+/* Delete a cJSON structure. */
+void cJSON_Delete(cJSON *c) {
+ cJSON *next;
+ while (c) {
+ next = c->next;
+ if (!(c->type & cJSON_IsReference) && c->child) cJSON_Delete(c->child);
+ if (!(c->type & cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
+ if (!(c->type & cJSON_StringIsConst) && c->string) cJSON_free(c->string);
+ cJSON_free(c);
+ c = next;
+ }
+}
+
+void cJSON_Free(void *p) { cJSON_free(p); }
+
+/* Parse the input text to generate a number, and populate the result into item.
+ */
+static const char *parse_number(cJSON *item, const char *num) {
+ double n = 0, sign = 1, scale = 0;
+ int subscale = 0, signsubscale = 1;
+
+ if (*num == '-') sign = -1, num++; /* Has sign? */
+ if (*num == '0') num++; /* is zero */
+ if (*num >= '1' && *num <= '9') do
+ n = (n * 10.0) + (*num++ - '0');
+ while (*num >= '0' && *num <= '9'); /* Number? */
+ if (*num == '.' && num[1] >= '0' && num[1] <= '9') {
+ num++;
+ do
+ n = (n * 10.0) + (*num++ - '0'), scale--;
+ while (*num >= '0' && *num <= '9');
+ } /* Fractional part? */
+ if (*num == 'e' || *num == 'E') /* Exponent? */
+ {
+ num++;
+ if (*num == '+')
+ num++;
+ else if (*num == '-')
+ signsubscale = -1, num++; /* With sign? */
+ while (*num >= '0' && *num <= '9') subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
+ }
+
+ n = sign * n * pow(10.0, (scale + subscale * signsubscale)); /* number = +/-
+ number.fraction *
+ 10^+/- exponent */
+
+ item->valuedouble = n;
+ item->valueint = (int)n;
+ item->type = cJSON_Number;
+ return num;
+}
+
+static size_t pow2gt(size_t x) {
+ --x;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x + 1;
+}
+
+typedef struct {
+ char *buffer;
+ size_t length;
+ size_t offset;
+} printbuffer;
+
+static char *ensure(printbuffer *p, size_t needed) {
+ char *newbuffer;
+ size_t newsize;
+ if (!p || !p->buffer) return 0;
+ needed += p->offset;
+ if (needed <= p->length) return p->buffer + p->offset;
+
+ newsize = pow2gt(needed);
+ newbuffer = (char *)cJSON_malloc(newsize);
+ if (!newbuffer) {
+ cJSON_free(p->buffer);
+ p->length = 0, p->buffer = 0;
+ return 0;
+ }
+ if (newbuffer) memcpy(newbuffer, p->buffer, p->length);
+ cJSON_free(p->buffer);
+ p->length = newsize;
+ p->buffer = newbuffer;
+ return newbuffer + p->offset;
+}
+
+static size_t update(printbuffer *p) {
+ char *str;
+ if (!p || !p->buffer) return 0;
+ str = p->buffer + p->offset;
+ return p->offset + strlen(str);
+}
+
+/* Render the number nicely from the given item into a string. */
+static char *print_number(cJSON *item, printbuffer *p) {
+ char *str = 0;
+ double d = item->valuedouble;
+ if (d == 0) {
+ if (p)
+ str = ensure(p, 2);
+ else
+ str = (char *)cJSON_malloc(2); /* special case for 0. */
+ if (str) strcpy(str, "0");
+ } else if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) {
+ if (p)
+ str = ensure(p, 21);
+ else
+ str = (char *)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
+ if (str) sprintf(str, "%d", item->valueint);
+ } else {
+ if (p)
+ str = ensure(p, 64);
+ else
+ str = (char *)cJSON_malloc(64); /* This is a nice tradeoff. */
+ if (str) {
+ if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)
+ sprintf(str, "%.0f", d);
+ else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9)
+ sprintf(str, "%e", d);
+ else
+ sprintf(str, "%f", d);
+ }
+ }
+ return str;
+}
+
+static unsigned parse_hex4(const char *str) {
+ unsigned h = 0;
+ if (*str >= '0' && *str <= '9')
+ h += (*str) - '0';
+ else if (*str >= 'A' && *str <= 'F')
+ h += 10 + (*str) - 'A';
+ else if (*str >= 'a' && *str <= 'f')
+ h += 10 + (*str) - 'a';
+ else
+ return 0;
+ h = h << 4;
+ str++;
+ if (*str >= '0' && *str <= '9')
+ h += (*str) - '0';
+ else if (*str >= 'A' && *str <= 'F')
+ h += 10 + (*str) - 'A';
+ else if (*str >= 'a' && *str <= 'f')
+ h += 10 + (*str) - 'a';
+ else
+ return 0;
+ h = h << 4;
+ str++;
+ if (*str >= '0' && *str <= '9')
+ h += (*str) - '0';
+ else if (*str >= 'A' && *str <= 'F')
+ h += 10 + (*str) - 'A';
+ else if (*str >= 'a' && *str <= 'f')
+ h += 10 + (*str) - 'a';
+ else
+ return 0;
+ h = h << 4;
+ str++;
+ if (*str >= '0' && *str <= '9')
+ h += (*str) - '0';
+ else if (*str >= 'A' && *str <= 'F')
+ h += 10 + (*str) - 'A';
+ else if (*str >= 'a' && *str <= 'f')
+ h += 10 + (*str) - 'a';
+ else
+ return 0;
+ return h;
+}
+
+/* Parse the input text into an unescaped cstring, and populate item. */
+static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
+static const char *parse_string(cJSON *item, const char *str) {
+ const char *ptr = str + 1;
+ char *ptr2;
+ char *out;
+ int len = 0;
+ unsigned uc, uc2;
+ if (*str != '\"') {
+ ep = str;
+ return 0;
+ } /* not a string! */
+
+ while (*ptr != '\"' && *ptr && ++len)
+ if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
+
+ out = (char *)cJSON_malloc(len + 1); /* This is how long we need for the string, roughly. */
+ if (!out) return 0;
+
+ ptr = str + 1;
+ ptr2 = out;
+ while (*ptr != '\"' && *ptr) {
+ if (*ptr != '\\')
+ *ptr2++ = *ptr++;
+ else {
+ ptr++;
+ switch (*ptr) {
+ case 'b':
+ *ptr2++ = '\b';
+ break;
+ case 'f':
+ *ptr2++ = '\f';
+ break;
+ case 'n':
+ *ptr2++ = '\n';
+ break;
+ case 'r':
+ *ptr2++ = '\r';
+ break;
+ case 't':
+ *ptr2++ = '\t';
+ break;
+ case 'u': /* transcode utf16 to utf8. */
+ uc = parse_hex4(ptr + 1);
+ ptr += 4; /* get the unicode char. */
+
+ if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) break; /* check for invalid. */
+
+ if (uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs. */
+ {
+ if (ptr[1] != '\\' || ptr[2] != 'u') break; /* missing second-half of surrogate. */
+ uc2 = parse_hex4(ptr + 3);
+ ptr += 6;
+ if (uc2 < 0xDC00 || uc2 > 0xDFFF) break; /* invalid second-half of surrogate. */
+ uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
+ }
+
+ len = 4;
+ if (uc < 0x80)
+ len = 1;
+ else if (uc < 0x800)
+ len = 2;
+ else if (uc < 0x10000)
+ len = 3;
+ ptr2 += len;
+
+ switch (len) {
+ case 4:
+ *--ptr2 = ((uc | 0x80) & 0xBF);
+ uc >>= 6;
+ // fall through
+ case 3:
+ *--ptr2 = ((uc | 0x80) & 0xBF);
+ uc >>= 6;
+ // fall through
+ case 2:
+ *--ptr2 = ((uc | 0x80) & 0xBF);
+ uc >>= 6;
+ // fall through
+ case 1:
+ *--ptr2 = ((unsigned char)uc | firstByteMark[len]);
+ }
+ ptr2 += len;
+ break;
+ default:
+ *ptr2++ = *ptr;
+ break;
+ }
+ ptr++;
+ }
+ }
+ *ptr2 = 0;
+ if (*ptr == '\"') ptr++;
+ item->valuestring = out;
+ item->type = cJSON_String;
+ return ptr;
+}
+
+/* Render the cstring provided to an escaped version that can be printed. */
+static char *print_string_ptr(const char *str, printbuffer *p) {
+ const char *ptr;
+ char *ptr2;
+ char *out;
+ size_t len = 0, flag = 0;
+ unsigned char token;
+
+ for (ptr = str; *ptr; ptr++) flag |= ((*ptr > 0 && *ptr < 32) || (*ptr == '\"') || (*ptr == '\\')) ? 1 : 0;
+ if (!flag) {
+ len = ptr - str;
+ if (p)
+ out = ensure(p, len + 3);
+ else
+ out = (char *)cJSON_malloc(len + 3);
+ if (!out) return 0;
+ ptr2 = out;
+ *ptr2++ = '\"';
+ strcpy(ptr2, str);
+ ptr2[len] = '\"';
+ ptr2[len + 1] = 0;
+ return out;
+ }
+
+ if (!str) {
+ if (p)
+ out = ensure(p, 3);
+ else
+ out = (char *)cJSON_malloc(3);
+ if (!out) return 0;
+ strcpy(out, "\"\"");
+ return out;
+ }
+ ptr = str;
+ while ((token = *ptr) && ++len) {
+ if (strchr("\"\\\b\f\n\r\t", token))
+ len++;
+ else if (token < 32)
+ len += 5;
+ ptr++;
+ }
+
+ if (p)
+ out = ensure(p, len + 3);
+ else
+ out = (char *)cJSON_malloc(len + 3);
+ if (!out) return 0;
+
+ ptr2 = out;
+ ptr = str;
+ *ptr2++ = '\"';
+ while (*ptr) {
+ if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\')
+ *ptr2++ = *ptr++;
+ else {
+ switch (token = *ptr++) {
+ case '\\':
+ *ptr2++ = '\\';
+ break;
+ case '\"':
+ *ptr2++ = '\"';
+ break;
+ case '\b':
+ *ptr2++ = '\b';
+ break;
+ case '\f':
+ *ptr2++ = '\f';
+ break;
+ case '\n':
+ *ptr2++ = '\n';
+ break;
+ case '\r':
+ *ptr2++ = '\r';
+ break;
+ case '\t':
+ *ptr2++ = '\t';
+ break;
+ default:
+ sprintf(ptr2, "u%04x", token);
+ ptr2 += 5;
+ break; /* escape and print */
+ }
+ }
+ }
+ *ptr2++ = '\"';
+ *ptr2++ = 0;
+ return out;
+}
+/* Invote print_string_ptr (which is useful) on an item. */
+static char *print_string(cJSON *item, printbuffer *p) { return print_string_ptr(item->valuestring, p); }
+
+/* Predeclare these prototypes. */
+static const char *parse_value(cJSON *item, const char *value);
+static char *print_value(cJSON *item, int depth, int fmt, printbuffer *p);
+static const char *parse_array(cJSON *item, const char *value);
+static char *print_array(cJSON *item, int depth, int fmt, printbuffer *p);
+static const char *parse_object(cJSON *item, const char *value);
+static char *print_object(cJSON *item, int depth, int fmt, printbuffer *p);
+
+/* Utility to jump whitespace and cr/lf */
+static const char *skip(const char *in) {
+ while (in && *in && (unsigned char)*in <= 32) in++;
+ return in;
+}
+
+/* Parse an object - create a new root, and populate. */
+cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int require_null_terminated) {
+ const char *end = 0;
+ cJSON *c = cJSON_New_Item();
+ ep = 0;
+ if (!c) return 0; /* memory fail */
+
+ end = parse_value(c, skip(value));
+ if (!end) {
+ cJSON_Delete(c);
+ return 0;
+ } /* parse failure. ep is set. */
+
+ /* if we require null-terminated JSON without appended garbage, skip and
+ * then check for a null terminator */
+ if (require_null_terminated) {
+ end = skip(end);
+ if (*end) {
+ cJSON_Delete(c);
+ ep = end;
+ return 0;
+ }
+ }
+ if (return_parse_end) *return_parse_end = end;
+ return c;
+}
+/* Default options for cJSON_Parse */
+cJSON *cJSON_Parse(const char *value) { return cJSON_ParseWithOpts(value, 0, 0); }
+
+/* Render a cJSON item/entity/structure to text. */
+char *cJSON_Print(cJSON *item) { return print_value(item, 0, 1, 0); }
+char *cJSON_PrintUnformatted(cJSON *item) { return print_value(item, 0, 0, 0); }
+
+char *cJSON_PrintBuffered(cJSON *item, int prebuffer, int fmt) {
+ printbuffer p;
+ p.buffer = (char *)cJSON_malloc(prebuffer);
+ p.length = prebuffer;
+ p.offset = 0;
+ return print_value(item, 0, fmt, &p);
+}
+
+/* Parser core - when encountering text, process appropriately. */
+static const char *parse_value(cJSON *item, const char *value) {
+ if (!value) return 0; /* Fail on null. */
+ if (!strncmp(value, "null", 4)) {
+ item->type = cJSON_NULL;
+ return value + 4;
+ }
+ if (!strncmp(value, "false", 5)) {
+ item->type = cJSON_False;
+ return value + 5;
+ }
+ if (!strncmp(value, "true", 4)) {
+ item->type = cJSON_True;
+ item->valueint = 1;
+ return value + 4;
+ }
+ if (*value == '\"') {
+ return parse_string(item, value);
+ }
+ if (*value == '-' || (*value >= '0' && *value <= '9')) {
+ return parse_number(item, value);
+ }
+ if (*value == '[') {
+ return parse_array(item, value);
+ }
+ if (*value == '{') {
+ return parse_object(item, value);
+ }
+
+ ep = value;
+ return 0; /* failure. */
+}
+
+/* Render a value to text. */
+static char *print_value(cJSON *item, int depth, int fmt, printbuffer *p) {
+ char *out = 0;
+ if (!item) return 0;
+ if (p) {
+ switch ((item->type) & 255) {
+ case cJSON_NULL: {
+ out = ensure(p, 5);
+ if (out) strcpy(out, "null");
+ break;
+ }
+ case cJSON_False: {
+ out = ensure(p, 6);
+ if (out) strcpy(out, "false");
+ break;
+ }
+ case cJSON_True: {
+ out = ensure(p, 5);
+ if (out) strcpy(out, "true");
+ break;
+ }
+ case cJSON_Number:
+ out = print_number(item, p);
+ break;
+ case cJSON_String:
+ out = print_string(item, p);
+ break;
+ case cJSON_Array:
+ out = print_array(item, depth, fmt, p);
+ break;
+ case cJSON_Object:
+ out = print_object(item, depth, fmt, p);
+ break;
+ }
+ } else {
+ switch ((item->type) & 255) {
+ case cJSON_NULL:
+ out = cJSON_strdup("null");
+ break;
+ case cJSON_False:
+ out = cJSON_strdup("false");
+ break;
+ case cJSON_True:
+ out = cJSON_strdup("true");
+ break;
+ case cJSON_Number:
+ out = print_number(item, 0);
+ break;
+ case cJSON_String:
+ out = print_string(item, 0);
+ break;
+ case cJSON_Array:
+ out = print_array(item, depth, fmt, 0);
+ break;
+ case cJSON_Object:
+ out = print_object(item, depth, fmt, 0);
+ break;
+ }
+ }
+ return out;
+}
+
+/* Build an array from input text. */
+static const char *parse_array(cJSON *item, const char *value) {
+ cJSON *child;
+ if (*value != '[') {
+ ep = value;
+ return 0;
+ } /* not an array! */
+
+ item->type = cJSON_Array;
+ value = skip(value + 1);
+ if (*value == ']') return value + 1; /* empty array. */
+
+ item->child = child = cJSON_New_Item();
+ if (!item->child) return 0; /* memory fail */
+ value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value == ',') {
+ cJSON *new_item;
+ if (!(new_item = cJSON_New_Item())) return 0; /* memory fail */
+ child->next = new_item;
+ new_item->prev = child;
+ child = new_item;
+ value = skip(parse_value(child, skip(value + 1)));
+ if (!value) return 0; /* memory fail */
+ }
+
+ if (*value == ']') return value + 1; /* end of array */
+ ep = value;
+ return 0; /* malformed. */
+}
+
+/* Render an array to text */
+static char *print_array(cJSON *item, int depth, int fmt, printbuffer *p) {
+ char **entries;
+ char *out = 0, *ptr, *ret;
+ size_t len = 5;
+ cJSON *child = item->child;
+ int numentries = 0, fail = 0, j = 0;
+ size_t tmplen = 0, i = 0;
+
+ /* How many entries in the array? */
+ while (child) numentries++, child = child->next;
+ /* Explicitly handle numentries==0 */
+ if (!numentries) {
+ if (p)
+ out = ensure(p, 3);
+ else
+ out = (char *)cJSON_malloc(3);
+ if (out) strcpy(out, "[]");
+ return out;
+ }
+
+ if (p) {
+ /* Compose the output array. */
+ i = p->offset;
+ ptr = ensure(p, 1);
+ if (!ptr) return 0;
+ *ptr = '[';
+ p->offset++;
+ child = item->child;
+ while (child && !fail) {
+ print_value(child, depth + 1, fmt, p);
+ p->offset = update(p);
+ if (child->next) {
+ len = fmt ? 2 : 1;
+ ptr = ensure(p, len + 1);
+ if (!ptr) return 0;
+ *ptr++ = ',';
+ if (fmt) *ptr++ = ' ';
+ *ptr = 0;
+ p->offset += len;
+ }
+ child = child->next;
+ }
+ ptr = ensure(p, 2);
+ if (!ptr) return 0;
+ *ptr++ = ']';
+ *ptr = 0;
+ out = (p->buffer) + i;
+ } else {
+ /* Allocate an array to hold the values for each */
+ entries = (char **)cJSON_malloc(numentries * sizeof(char *));
+ if (!entries) return 0;
+ memset(entries, 0, numentries * sizeof(char *));
+ /* Retrieve all the results: */
+ child = item->child;
+ while (child && !fail) {
+ ret = print_value(child, depth + 1, fmt, 0);
+ entries[i++] = ret;
+ if (ret)
+ len += strlen(ret) + 2 + (fmt ? 1 : 0);
+ else
+ fail = 1;
+ child = child->next;
+ }
+
+ /* If we didn't fail, try to malloc the output string */
+ if (!fail) out = (char *)cJSON_malloc(len);
+ /* If that fails, we fail. */
+ if (!out) fail = 1;
+
+ /* Handle failure. */
+ if (fail) {
+ for (j = 0; j < numentries; j++)
+ if (entries[j]) cJSON_free(entries[j]);
+ cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output array. */
+ *out = '[';
+ ptr = out + 1;
+ *ptr = 0;
+ for (j = 0; j < numentries; j++) {
+ tmplen = strlen(entries[j]);
+ memcpy(ptr, entries[j], tmplen);
+ ptr += tmplen;
+ if (j != numentries - 1) {
+ *ptr++ = ',';
+ if (fmt) *ptr++ = ' ';
+ *ptr = 0;
+ }
+ cJSON_free(entries[j]);
+ }
+ cJSON_free(entries);
+ *ptr++ = ']';
+ *ptr++ = 0;
+ }
+ return out;
+}
+
+/* Build an object from the text. */
+static const char *parse_object(cJSON *item, const char *value) {
+ cJSON *child;
+ if (*value != '{') {
+ ep = value;
+ return 0;
+ } /* not an object! */
+
+ item->type = cJSON_Object;
+ value = skip(value + 1);
+ if (*value == '}') return value + 1; /* empty array. */
+
+ item->child = child = cJSON_New_Item();
+ if (!item->child) return 0;
+ value = skip(parse_string(child, skip(value)));
+ if (!value) return 0;
+ child->string = child->valuestring;
+ child->valuestring = 0;
+ if (*value != ':') {
+ ep = value;
+ return 0;
+ } /* fail! */
+ value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value == ',') {
+ cJSON *new_item;
+ if (!(new_item = cJSON_New_Item())) return 0; /* memory fail */
+ child->next = new_item;
+ new_item->prev = child;
+ child = new_item;
+ value = skip(parse_string(child, skip(value + 1)));
+ if (!value) return 0;
+ child->string = child->valuestring;
+ child->valuestring = 0;
+ if (*value != ':') {
+ ep = value;
+ return 0;
+ } /* fail! */
+ value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+ }
+
+ if (*value == '}') return value + 1; /* end of array */
+ ep = value;
+ return 0; /* malformed. */
+}
+
+/* Render an object to text. */
+static char *print_object(cJSON *item, int depth, int fmt, printbuffer *p) {
+ char **entries = 0, **names = 0;
+ char *out = 0, *ptr, *ret, *str;
+ int j;
+ cJSON *child = item->child;
+ int numentries = 0, fail = 0, k;
+ size_t tmplen = 0, i = 0, len = 7;
+ /* Count the number of entries. */
+ while (child) numentries++, child = child->next;
+ /* Explicitly handle empty object case */
+ if (!numentries) {
+ if (p)
+ out = ensure(p, fmt ? depth + 4 : 3);
+ else
+ out = (char *)cJSON_malloc(fmt ? depth + 4 : 3);
+ if (!out) return 0;
+ ptr = out;
+ *ptr++ = '{';
+ if (fmt) {
+ *ptr++ = '\n';
+ for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
+ }
+ *ptr++ = '}';
+ *ptr++ = 0;
+ return out;
+ }
+ if (p) {
+ /* Compose the output: */
+ i = p->offset;
+ len = fmt ? 2 : 1;
+ ptr = ensure(p, len + 1);
+ if (!ptr) return 0;
+ *ptr++ = '{';
+ if (fmt) *ptr++ = '\n';
+ *ptr = 0;
+ p->offset += len;
+ child = item->child;
+ depth++;
+ while (child) {
+ if (fmt) {
+ ptr = ensure(p, depth);
+ if (!ptr) return 0;
+ for (j = 0; j < depth; j++) *ptr++ = '\t';
+ p->offset += depth;
+ }
+ print_string_ptr(child->string, p);
+ p->offset = update(p);
+
+ len = fmt ? 2 : 1;
+ ptr = ensure(p, len);
+ if (!ptr) return 0;
+ *ptr++ = ':';
+ if (fmt) *ptr++ = '\t';
+ p->offset += len;
+
+ print_value(child, depth, fmt, p);
+ p->offset = update(p);
+
+ len = (fmt ? 1 : 0) + (child->next ? 1 : 0);
+ ptr = ensure(p, len + 1);
+ if (!ptr) return 0;
+ if (child->next) *ptr++ = ',';
+ if (fmt) *ptr++ = '\n';
+ *ptr = 0;
+ p->offset += len;
+ child = child->next;
+ }
+ ptr = ensure(p, fmt ? (depth + 1) : 2);
+ if (!ptr) return 0;
+ if (fmt)
+ for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
+ *ptr++ = '}';
+ *ptr = 0;
+ out = (p->buffer) + i;
+ } else {
+ /* Allocate space for the names and the objects */
+ entries = (char **)cJSON_malloc(numentries * sizeof(char *));
+ if (!entries) return 0;
+ names = (char **)cJSON_malloc(numentries * sizeof(char *));
+ if (!names) {
+ cJSON_free(entries);
+ return 0;
+ }
+ memset(entries, 0, sizeof(char *) * numentries);
+ memset(names, 0, sizeof(char *) * numentries);
+
+ /* Collect all the results into our arrays: */
+ child = item->child;
+ depth++;
+ if (fmt) len += depth;
+ while (child) {
+ names[i] = str = print_string_ptr(child->string, 0);
+ entries[i++] = ret = print_value(child, depth, fmt, 0);
+ if (str && ret)
+ len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0);
+ else
+ fail = 1;
+ child = child->next;
+ }
+
+ /* Try to allocate the output string */
+ if (!fail) out = (char *)cJSON_malloc(len);
+ if (!out) fail = 1;
+
+ /* Handle failure */
+ if (fail) {
+ for (j = 0; j < numentries; j++) {
+ if (names[i]) cJSON_free(names[j]);
+ if (entries[j]) cJSON_free(entries[j]);
+ }
+ cJSON_free(names);
+ cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output: */
+ *out = '{';
+ ptr = out + 1;
+ if (fmt) *ptr++ = '\n';
+ *ptr = 0;
+ for (j = 0; j < numentries; j++) {
+ if (fmt)
+ for (k = 0; k < depth; k++) *ptr++ = '\t';
+ tmplen = strlen(names[j]);
+ memcpy(ptr, names[j], tmplen);
+ ptr += tmplen;
+ *ptr++ = ':';
+ if (fmt) *ptr++ = '\t';
+ strcpy(ptr, entries[j]);
+ ptr += strlen(entries[j]);
+ if (j != numentries - 1) *ptr++ = ',';
+ if (fmt) *ptr++ = '\n';
+ *ptr = 0;
+ cJSON_free(names[j]);
+ cJSON_free(entries[j]);
+ }
+
+ cJSON_free(names);
+ cJSON_free(entries);
+ if (fmt)
+ for (j = 0; j < depth - 1; j++) *ptr++ = '\t';
+ *ptr++ = '}';
+ *ptr++ = 0;
+ }
+ return out;
+}
+
+/* Get Array size/item / object item. */
+int cJSON_GetArraySize(cJSON *array) {
+ cJSON *c = array->child;
+ int i = 0;
+ while (c) i++, c = c->next;
+ return i;
+}
+cJSON *cJSON_GetArrayItem(cJSON *array, int item) {
+ cJSON *c = array->child;
+ while (c && item > 0) item--, c = c->next;
+ return c;
+}
+cJSON *cJSON_GetObjectItem(cJSON *object, const char *string) {
+ cJSON *c = object->child;
+ while (c && strcmp(c->string, string)) c = c->next;
+ return c;
+}
+
+/* Utility for array list handling. */
+static void suffix_object(cJSON *prev, cJSON *item) {
+ prev->next = item;
+ item->prev = prev;
+}
+/* Utility for handling references. */
+static cJSON *create_reference(cJSON *item) {
+ cJSON *ref = cJSON_New_Item();
+ if (!ref) return 0;
+ memcpy(ref, item, sizeof(cJSON));
+ ref->string = 0;
+ ref->type |= cJSON_IsReference;
+ ref->next = ref->prev = 0;
+ return ref;
+}
+
+/* Add item to array/object. */
+void cJSON_AddItemToArray(cJSON *array, cJSON *item) {
+ cJSON *c = array->child;
+ if (!item) return;
+ if (!c) {
+ array->child = item;
+ } else {
+ while (c && c->next) c = c->next;
+ suffix_object(c, item);
+ }
+}
+void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) {
+ if (!item) return;
+ if (item->string) cJSON_free(item->string);
+ item->string = cJSON_strdup(string);
+ cJSON_AddItemToArray(object, item);
+}
+void cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) {
+ if (!item) return;
+ if (!(item->type & cJSON_StringIsConst) && item->string) cJSON_free(item->string);
+ item->string = (char *)string;
+ item->type |= cJSON_StringIsConst;
+ cJSON_AddItemToArray(object, item);
+}
+void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { cJSON_AddItemToArray(array, create_reference(item)); }
+void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) {
+ cJSON_AddItemToObject(object, string, create_reference(item));
+}
+
+cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) {
+ cJSON *c = array->child;
+ while (c && which > 0) c = c->next, which--;
+ if (!c) return 0;
+ if (c->prev) c->prev->next = c->next;
+ if (c->next) c->next->prev = c->prev;
+ if (c == array->child) array->child = c->next;
+ c->prev = c->next = 0;
+ return c;
+}
+void cJSON_DeleteItemFromArray(cJSON *array, int which) { cJSON_Delete(cJSON_DetachItemFromArray(array, which)); }
+cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) {
+ int i = 0;
+ cJSON *c = object->child;
+ while (c && strcmp(c->string, string)) i++, c = c->next;
+ if (c) return cJSON_DetachItemFromArray(object, i);
+ return 0;
+}
+void cJSON_DeleteItemFromObject(cJSON *object, const char *string) { cJSON_Delete(cJSON_DetachItemFromObject(object, string)); }
+
+/* Replace array/object items with new ones. */
+void cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) {
+ cJSON *c = array->child;
+ while (c && which > 0) c = c->next, which--;
+ if (!c) {
+ cJSON_AddItemToArray(array, newitem);
+ return;
+ }
+ newitem->next = c;
+ newitem->prev = c->prev;
+ c->prev = newitem;
+ if (c == array->child)
+ array->child = newitem;
+ else
+ newitem->prev->next = newitem;
+}
+void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) {
+ cJSON *c = array->child;
+ while (c && which > 0) c = c->next, which--;
+ if (!c) return;
+ newitem->next = c->next;
+ newitem->prev = c->prev;
+ if (newitem->next) newitem->next->prev = newitem;
+ if (c == array->child)
+ array->child = newitem;
+ else
+ newitem->prev->next = newitem;
+ c->next = c->prev = 0;
+ cJSON_Delete(c);
+}
+void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) {
+ int i = 0;
+ cJSON *c = object->child;
+ while (c && strcmp(c->string, string)) i++, c = c->next;
+ if (c) {
+ newitem->string = cJSON_strdup(string);
+ cJSON_ReplaceItemInArray(object, i, newitem);
+ }
+}
+
+/* Create basic types: */
+cJSON *cJSON_CreateNull(void) {
+ cJSON *item = cJSON_New_Item();
+ if (item) item->type = cJSON_NULL;
+ return item;
+}
+cJSON *cJSON_CreateTrue(void) {
+ cJSON *item = cJSON_New_Item();
+ if (item) item->type = cJSON_True;
+ return item;
+}
+cJSON *cJSON_CreateFalse(void) {
+ cJSON *item = cJSON_New_Item();
+ if (item) item->type = cJSON_False;
+ return item;
+}
+cJSON *cJSON_CreateBool(int b) {
+ cJSON *item = cJSON_New_Item();
+ if (item) item->type = b ? cJSON_True : cJSON_False;
+ return item;
+}
+cJSON *cJSON_CreateNumber(double num) {
+ cJSON *item = cJSON_New_Item();
+ if (item) {
+ item->type = cJSON_Number;
+ item->valuedouble = num;
+ item->valueint = (int)num;
+ }
+ return item;
+}
+cJSON *cJSON_CreateString(const char *string) {
+ cJSON *item = cJSON_New_Item();
+ if (item) {
+ item->type = cJSON_String;
+ item->valuestring = cJSON_strdup(string);
+ }
+ return item;
+}
+cJSON *cJSON_CreateArray(void) {
+ cJSON *item = cJSON_New_Item();
+ if (item) item->type = cJSON_Array;
+ return item;
+}
+cJSON *cJSON_CreateObject(void) {
+ cJSON *item = cJSON_New_Item();
+ if (item) item->type = cJSON_Object;
+ return item;
+}
+
+/* Create Arrays: */
+cJSON *cJSON_CreateIntArray(const int *numbers, int count) {
+ int i;
+ cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
+ for (i = 0; a && i < count; i++) {
+ n = cJSON_CreateNumber(numbers[i]);
+ if (!i)
+ a->child = n;
+ else
+ suffix_object(p, n);
+ p = n;
+ }
+ return a;
+}
+cJSON *cJSON_CreateFloatArray(const float *numbers, int count) {
+ int i;
+ cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
+ for (i = 0; a && i < count; i++) {
+ n = cJSON_CreateNumber(numbers[i]);
+ if (!i)
+ a->child = n;
+ else
+ suffix_object(p, n);
+ p = n;
+ }
+ return a;
+}
+cJSON *cJSON_CreateDoubleArray(const double *numbers, int count) {
+ int i;
+ cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
+ for (i = 0; a && i < count; i++) {
+ n = cJSON_CreateNumber(numbers[i]);
+ if (!i)
+ a->child = n;
+ else
+ suffix_object(p, n);
+ p = n;
+ }
+ return a;
+}
+cJSON *cJSON_CreateStringArray(const char **strings, int count) {
+ int i;
+ cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
+ for (i = 0; a && i < count; i++) {
+ n = cJSON_CreateString(strings[i]);
+ if (!i)
+ a->child = n;
+ else
+ suffix_object(p, n);
+ p = n;
+ }
+ return a;
+}
+
+/* Duplication */
+cJSON *cJSON_Duplicate(cJSON *item, int recurse) {
+ cJSON *newitem, *cptr, *nptr = 0, *newchild;
+ /* Bail on bad ptr */
+ if (!item) return 0;
+ /* Create new item */
+ newitem = cJSON_New_Item();
+ if (!newitem) return 0;
+ /* Copy over all vars */
+ newitem->type = item->type & (~cJSON_IsReference), newitem->valueint = item->valueint, newitem->valuedouble = item->valuedouble;
+ if (item->valuestring) {
+ newitem->valuestring = cJSON_strdup(item->valuestring);
+ if (!newitem->valuestring) {
+ cJSON_Delete(newitem);
+ return 0;
+ }
+ }
+ if (item->string) {
+ newitem->string = cJSON_strdup(item->string);
+ if (!newitem->string) {
+ cJSON_Delete(newitem);
+ return 0;
+ }
+ }
+ /* If non-recursive, then we're done! */
+ if (!recurse) return newitem;
+ /* Walk the ->next chain for the child. */
+ cptr = item->child;
+ while (cptr) {
+ newchild = cJSON_Duplicate(cptr, 1); /* Duplicate (with recurse) each item in the ->next chain */
+ if (!newchild) {
+ cJSON_Delete(newitem);
+ return 0;
+ }
+ if (nptr) {
+ nptr->next = newchild, newchild->prev = nptr;
+ nptr = newchild;
+ } /* If newitem->child already set, then crosswire ->prev and ->next and
+ move on */
+ else {
+ newitem->child = newchild;
+ nptr = newchild;
+ } /* Set newitem->child and move to it */
+ cptr = cptr->next;
+ }
+ return newitem;
+}
+
+void cJSON_Minify(char *json) {
+ char *into = json;
+ while (*json) {
+ if (*json == ' ')
+ json++;
+ else if (*json == '\t')
+ json++; /* Whitespace characters. */
+ else if (*json == '\r')
+ json++;
+ else if (*json == '\n')
+ json++;
+ else if (*json == '/' && json[1] == '/')
+ while (*json && *json != '\n') json++; /* double-slash comments, to end of line. */
+ else if (*json == '/' && json[1] == '*') {
+ while (*json && !(*json == '*' && json[1] == '/')) json++;
+ json += 2;
+ } /* multiline comments. */
+ else if (*json == '\"') {
+ *into++ = *json++;
+ while (*json && *json != '\"') {
+ if (*json == '\\') *into++ = *json++;
+ *into++ = *json++;
+ }
+ *into++ = *json++;
+ } /* string literals, which are \" sensitive. */
+ else
+ *into++ = *json++; /* All other characters. */
+ }
+ *into = 0; /* and null-terminate. */
+}
diff --git a/thirdparty/vulkan/loader/cJSON.h b/thirdparty/vulkan/loader/cJSON.h
new file mode 100644
index 0000000000..f0059abdcb
--- /dev/null
+++ b/thirdparty/vulkan/loader/cJSON.h
@@ -0,0 +1,174 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+ Copyright (c) 2015-2016 The Khronos Group Inc.
+ Copyright (c) 2015-2016 Valve Corporation
+ Copyright (c) 2015-2016 LunarG, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* cJSON Types: */
+#define cJSON_False 0
+#define cJSON_True 1
+#define cJSON_NULL 2
+#define cJSON_Number 3
+#define cJSON_String 4
+#define cJSON_Array 5
+#define cJSON_Object 6
+
+#define cJSON_IsReference 256
+#define cJSON_StringIsConst 512
+
+/* The cJSON structure: */
+typedef struct cJSON {
+ struct cJSON *next, *prev; /* next/prev allow you to walk array/object
+ chains. Alternatively, use
+ GetArraySize/GetArrayItem/GetObjectItem */
+ struct cJSON *child; /* An array or object item will have a child pointer
+ pointing to a chain of the items in the
+ array/object. */
+
+ int type; /* The type of the item, as above. */
+
+ char *valuestring; /* The item's string, if type==cJSON_String */
+ int valueint; /* The item's number, if type==cJSON_Number */
+ double valuedouble; /* The item's number, if type==cJSON_Number */
+
+ char *string; /* The item's name string, if this item is the child of, or is
+ in the list of subitems of an object. */
+} cJSON;
+
+typedef struct cJSON_Hooks {
+ void *(*malloc_fn)(size_t sz);
+ void (*free_fn)(void *ptr);
+} cJSON_Hooks;
+
+/* Supply malloc, realloc and free functions to cJSON */
+extern void cJSON_InitHooks(cJSON_Hooks *hooks);
+
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate.
+ * Call cJSON_Delete when finished. */
+extern cJSON *cJSON_Parse(const char *value);
+/* Render a cJSON entity to text for transfer/storage. Free the char* when
+ * finished. */
+extern char *cJSON_Print(cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting.
+ * Free the char* when finished. */
+extern char *cJSON_PrintUnformatted(cJSON *item);
+/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess
+ * at the final size. guessing well reduces reallocation. fmt=0 gives
+ * unformatted, =1 gives formatted */
+extern char *cJSON_PrintBuffered(cJSON *item, int prebuffer, int fmt);
+/* Delete a cJSON entity and all subentities. */
+extern void cJSON_Delete(cJSON *c);
+/* Delete an item allocated inside the JSON parser*/
+extern void cJSON_Free(void *p);
+
+/* Returns the number of items in an array (or object). */
+extern int cJSON_GetArraySize(cJSON *array);
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
+ */
+extern cJSON *cJSON_GetArrayItem(cJSON *array, int item);
+/* Get item "string" from object. Case insensitive. */
+extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);
+
+/* For analysing failed parses. This returns a pointer to the parse error.
+ * You'll probably need to look a few chars back to make sense of it. Defined
+ * when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+extern const char *cJSON_GetErrorPtr(void);
+
+/* These calls create a cJSON item of the appropriate type. */
+extern cJSON *cJSON_CreateNull(void);
+extern cJSON *cJSON_CreateTrue(void);
+extern cJSON *cJSON_CreateFalse(void);
+extern cJSON *cJSON_CreateBool(int b);
+extern cJSON *cJSON_CreateNumber(double num);
+extern cJSON *cJSON_CreateString(const char *string);
+extern cJSON *cJSON_CreateArray(void);
+extern cJSON *cJSON_CreateObject(void);
+
+/* These utilities create an Array of count items. */
+extern cJSON *cJSON_CreateIntArray(const int *numbers, int count);
+extern cJSON *cJSON_CreateFloatArray(const float *numbers, int count);
+extern cJSON *cJSON_CreateDoubleArray(const double *numbers, int count);
+extern cJSON *cJSON_CreateStringArray(const char **strings, int count);
+
+/* Append item to the specified array/object. */
+extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
+extern void cJSON_AddItemToObjectCS(cJSON *object, const char *string,
+ cJSON *item); /* Use this when string is definitely const (i.e. a literal,
+ or as good as), and will definitely survive the cJSON
+ object */
+/* Append reference to item to the specified array/object. Use this when you
+ * want to add an existing cJSON to a new cJSON, but don't want to corrupt your
+ * existing cJSON. */
+extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
+
+/* Remove/Detatch items from Arrays/Objects. */
+extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
+extern void cJSON_DeleteItemFromArray(cJSON *array, int which);
+extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
+extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string);
+
+/* Update array items. */
+extern void cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
+extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
+extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
+
+/* Duplicate a cJSON item */
+extern cJSON *cJSON_Duplicate(cJSON *item, int recurse);
+/* Duplicate will create a new, identical cJSON item to the one you pass, in new
+memory that will
+need to be released. With recurse!=0, it will duplicate any children connected
+to the item.
+The item->next and ->prev pointers are always zero on return from Duplicate. */
+
+/* ParseWithOpts allows you to require (and check) that the JSON is null
+ * terminated, and to retrieve the pointer to the final byte parsed. */
+extern cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, int require_null_terminated);
+
+extern void cJSON_Minify(char *json);
+
+/* Macros for creating things quickly. */
+#define cJSON_AddNullToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddBoolToObject(object, name, b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
+#define cJSON_AddNumberToObject(object, name, n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object, name, s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+
+/* When assigning an integer value, it needs to be propagated to valuedouble
+ * too. */
+#define cJSON_SetIntValue(object, val) ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
+#define cJSON_SetNumberValue(object, val) ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/vulkan/loader/debug_utils.c b/thirdparty/vulkan/loader/debug_utils.c
new file mode 100644
index 0000000000..10701e7991
--- /dev/null
+++ b/thirdparty/vulkan/loader/debug_utils.c
@@ -0,0 +1,996 @@
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ * Copyright (C) 2015-2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Jon Ashburn <jon@LunarG.com>
+ * Author: Mark Young <marky@lunarg.com>
+ *
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#ifndef WIN32
+#include <signal.h>
+#else
+#endif
+#include "vk_loader_platform.h"
+#include "debug_utils.h"
+#include "vulkan/vk_layer.h"
+#include "vk_object_types.h"
+
+// VK_EXT_debug_report related items
+
+VkResult util_CreateDebugUtilsMessenger(struct loader_instance *inst, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT messenger) {
+ VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
+ sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ } else {
+#endif
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ }
+ if (!pNewDbgFuncNode) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
+
+ pNewDbgFuncNode->is_messenger = true;
+ pNewDbgFuncNode->messenger.messenger = messenger;
+ pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
+ pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
+ pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
+ pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
+ pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
+ inst->DbgFunctionHead = pNewDbgFuncNode;
+
+ return VK_SUCCESS;
+}
+
+static VKAPI_ATTR VkResult VKAPI_CALL
+debug_utils_CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger) {
+ struct loader_instance *inst = loader_get_instance(instance);
+ loader_platform_thread_lock_mutex(&loader_lock);
+ VkResult result = inst->disp->layer_inst_disp.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return result;
+}
+
+VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
+ VkBool32 bail = false;
+
+ if (NULL != pCallbackData) {
+ VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkDebugReportObjectTypeEXT object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
+ VkDebugReportFlagsEXT object_flags = 0;
+ uint64_t object_handle = 0;
+
+ debug_utils_AnnotFlagsToReportFlags(messageSeverity, messageTypes, &object_flags);
+ if (0 < pCallbackData->objectCount) {
+ debug_utils_AnnotObjectToDebugReportObject(pCallbackData->pObjects, &object_type, &object_handle);
+ }
+
+ while (pTrav) {
+ if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & messageSeverity) &&
+ (pTrav->messenger.messageType & messageTypes)) {
+ if (pTrav->messenger.pfnUserCallback(messageSeverity, messageTypes, pCallbackData, pTrav->pUserData)) {
+ bail = true;
+ }
+ }
+ if (!pTrav->is_messenger && pTrav->report.msgFlags & object_flags) {
+ if (pTrav->report.pfnMsgCallback(object_flags, object_type, object_handle, 0, pCallbackData->messageIdNumber,
+ pCallbackData->pMessageIdName, pCallbackData->pMessage, pTrav->pUserData)) {
+ bail = true;
+ }
+ }
+
+ pTrav = pTrav->pNext;
+ }
+ }
+
+ return bail;
+}
+
+void util_DestroyDebugUtilsMessenger(struct loader_instance *inst, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkLayerDbgFunctionNode *pPrev = pTrav;
+
+ while (pTrav) {
+ if (pTrav->is_messenger && pTrav->messenger.messenger == messenger) {
+ pPrev->pNext = pTrav->pNext;
+ if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pAllocator->pfnFree(pAllocator->pUserData, pTrav);
+ } else {
+#endif
+ loader_instance_heap_free(inst, pTrav);
+ }
+ break;
+ }
+ pPrev = pTrav;
+ pTrav = pTrav->pNext;
+ }
+}
+
+// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
+// counts any VkDebugUtilsMessengerCreateInfoEXT structs that it finds. It
+// then allocates array that can hold that many structs, as well as that many
+// VkDebugUtilsMessengerEXT handles. It then copies each
+// VkDebugUtilsMessengerCreateInfoEXT, and initializes each handle.
+VkResult util_CopyDebugUtilsMessengerCreateInfos(const void *pChain, const VkAllocationCallbacks *pAllocator,
+ uint32_t *num_messengers, VkDebugUtilsMessengerCreateInfoEXT **infos,
+ VkDebugUtilsMessengerEXT **messengers) {
+ uint32_t n = *num_messengers = 0;
+ VkDebugUtilsMessengerCreateInfoEXT *pInfos = NULL;
+ VkDebugUtilsMessengerEXT *pMessengers = NULL;
+
+ const void *pNext = pChain;
+ while (pNext) {
+ // 1st, count the number VkDebugUtilsMessengerCreateInfoEXT:
+ if (((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
+ n++;
+ }
+ pNext = (void *)((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->pNext;
+ }
+ if (n == 0) {
+ return VK_SUCCESS;
+ }
+
+// 2nd, allocate memory for each VkDebugUtilsMessengerCreateInfoEXT:
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pInfos = *infos = ((VkDebugUtilsMessengerCreateInfoEXT *)pAllocator->pfnAllocation(
+ pAllocator->pUserData, n * sizeof(VkDebugUtilsMessengerCreateInfoEXT), sizeof(void *),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+ } else {
+#endif
+ pInfos = *infos = ((VkDebugUtilsMessengerCreateInfoEXT *)malloc(n * sizeof(VkDebugUtilsMessengerCreateInfoEXT)));
+ }
+ if (!pInfos) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+// 3rd, allocate memory for a unique handle for each callback:
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pMessengers = *messengers = ((VkDebugUtilsMessengerEXT *)pAllocator->pfnAllocation(
+ pAllocator->pUserData, n * sizeof(VkDebugUtilsMessengerEXT), sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+ if (NULL == pMessengers) {
+ pAllocator->pfnFree(pAllocator->pUserData, pInfos);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ } else {
+#endif
+ pMessengers = *messengers = ((VkDebugUtilsMessengerEXT *)malloc(n * sizeof(VkDebugUtilsMessengerEXT)));
+ if (NULL == pMessengers) {
+ free(pInfos);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ }
+ // 4th, copy each VkDebugUtilsMessengerCreateInfoEXT for use by
+ // vkDestroyInstance, and assign a unique handle to each messenger (just
+ // use the address of the copied VkDebugUtilsMessengerCreateInfoEXT):
+ pNext = pChain;
+ while (pNext) {
+ if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
+ memcpy(pInfos, pNext, sizeof(VkDebugUtilsMessengerCreateInfoEXT));
+ *pMessengers++ = (VkDebugUtilsMessengerEXT)(uintptr_t)pInfos++;
+ }
+ pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
+ }
+
+ *num_messengers = n;
+ return VK_SUCCESS;
+}
+
+void util_FreeDebugUtilsMessengerCreateInfos(const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerCreateInfoEXT *infos,
+ VkDebugUtilsMessengerEXT *messengers) {
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pAllocator->pfnFree(pAllocator->pUserData, infos);
+ pAllocator->pfnFree(pAllocator->pUserData, messengers);
+ } else {
+#endif
+ free(infos);
+ free(messengers);
+ }
+}
+
+VkResult util_CreateDebugUtilsMessengers(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
+ uint32_t num_messengers, VkDebugUtilsMessengerCreateInfoEXT *infos,
+ VkDebugUtilsMessengerEXT *messengers) {
+ VkResult rtn = VK_SUCCESS;
+ for (uint32_t i = 0; i < num_messengers; i++) {
+ rtn = util_CreateDebugUtilsMessenger(inst, &infos[i], pAllocator, messengers[i]);
+ if (rtn != VK_SUCCESS) {
+ for (uint32_t j = 0; j < i; j++) {
+ util_DestroyDebugUtilsMessenger(inst, messengers[j], pAllocator);
+ }
+ return rtn;
+ }
+ }
+ return rtn;
+}
+
+void util_DestroyDebugUtilsMessengers(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
+ uint32_t num_messengers, VkDebugUtilsMessengerEXT *messengers) {
+ for (uint32_t i = 0; i < num_messengers; i++) {
+ util_DestroyDebugUtilsMessenger(inst, messengers[i], pAllocator);
+ }
+}
+
+static VKAPI_ATTR void VKAPI_CALL debug_utils_SubmitDebugUtilsMessageEXT(
+ VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
+ struct loader_instance *inst = loader_get_instance(instance);
+
+ inst->disp->layer_inst_disp.SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
+}
+
+static VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ struct loader_instance *inst = loader_get_instance(instance);
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ inst->disp->layer_inst_disp.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+}
+
+// This is the instance chain terminator function for CreateDebugUtilsMessenger
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger) {
+ VkDebugUtilsMessengerEXT *icd_info = NULL;
+ const struct loader_icd_term *icd_term;
+ struct loader_instance *inst = (struct loader_instance *)instance;
+ VkResult res = VK_SUCCESS;
+ uint32_t storage_idx;
+ VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ icd_info = ((VkDebugUtilsMessengerEXT *)pAllocator->pfnAllocation(pAllocator->pUserData,
+ inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT),
+ sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+ if (icd_info) {
+ memset(icd_info, 0, inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT));
+ }
+ } else {
+#endif
+ icd_info = calloc(sizeof(VkDebugUtilsMessengerEXT), inst->total_icd_count);
+ }
+ if (!icd_info) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ storage_idx = 0;
+ for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ if (!icd_term->dispatch.CreateDebugUtilsMessengerEXT) {
+ continue;
+ }
+
+ res = icd_term->dispatch.CreateDebugUtilsMessengerEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
+
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+ storage_idx++;
+ }
+
+// Setup the debug report callback in the terminator since a layer may want
+// to grab the information itself (RenderDoc) and then return back to the
+// user callback a sub-set of the messages.
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 0)
+ if (pAllocator != NULL) {
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
+ sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ } else {
+#else
+ {
+#endif
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ }
+ if (!pNewDbgFuncNode) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
+
+ pNewDbgFuncNode->is_messenger = true;
+ pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
+ pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
+ pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
+ pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
+ pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
+ inst->DbgFunctionHead = pNewDbgFuncNode;
+
+ *(VkDebugUtilsMessengerEXT **)pMessenger = icd_info;
+ pNewDbgFuncNode->messenger.messenger = *pMessenger;
+
+out:
+
+ // Roll back on errors
+ if (VK_SUCCESS != res) {
+ storage_idx = 0;
+ for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
+ continue;
+ }
+
+ if (icd_info && icd_info[storage_idx]) {
+ icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
+ }
+ storage_idx++;
+ }
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ if (NULL != pNewDbgFuncNode) {
+ pAllocator->pfnFree(pAllocator->pUserData, pNewDbgFuncNode);
+ }
+ if (NULL != icd_info) {
+ pAllocator->pfnFree(pAllocator->pUserData, icd_info);
+ }
+ } else {
+#endif
+ if (NULL != pNewDbgFuncNode) {
+ free(pNewDbgFuncNode);
+ }
+ if (NULL != icd_info) {
+ free(icd_info);
+ }
+ }
+ }
+
+ return res;
+}
+
+// This is the instance chain terminator function for DestroyDebugUtilsMessenger
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ uint32_t storage_idx;
+ VkDebugUtilsMessengerEXT *icd_info;
+ const struct loader_icd_term *icd_term;
+
+ struct loader_instance *inst = (struct loader_instance *)instance;
+ icd_info = *(VkDebugUtilsMessengerEXT **)&messenger;
+ storage_idx = 0;
+ for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
+ continue;
+ }
+
+ if (icd_info[storage_idx]) {
+ icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
+ }
+ storage_idx++;
+ }
+
+ util_DestroyDebugUtilsMessenger(inst, messenger, pAllocator);
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pAllocator->pfnFree(pAllocator->pUserData, icd_info);
+ } else {
+#endif
+ free(icd_info);
+ }
+}
+
+// This is the instance chain terminator function for SubmitDebugUtilsMessageEXT
+VKAPI_ATTR void VKAPI_CALL terminator_SubmitDebugUtilsMessageEXT(VkInstance instance,
+ VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
+ loader_platform_thread_lock_mutex(&loader_lock);
+ // NOTE: Just make the callback ourselves because there could be one or more ICDs that support this extension
+ // and each one will trigger the callback to the user. This would result in multiple callback triggers
+ // per message. Instead, if we get a messaged up to here, then just trigger the message ourselves and
+ // return. This would still allow the ICDs to trigger their own messages, but won't get any external ones.
+ struct loader_instance *inst = (struct loader_instance *)instance;
+ util_SubmitDebugUtilsMessageEXT(inst, messageSeverity, messageTypes, pCallbackData);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+}
+
+// VK_EXT_debug_report related items
+
+VkResult util_CreateDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT callback) {
+ VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
+ sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ } else {
+#endif
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ }
+ if (!pNewDbgFuncNode) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
+
+ pNewDbgFuncNode->is_messenger = false;
+ pNewDbgFuncNode->report.msgCallback = callback;
+ pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
+ pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
+ pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
+ pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
+ inst->DbgFunctionHead = pNewDbgFuncNode;
+
+ return VK_SUCCESS;
+}
+
+static VKAPI_ATTR VkResult VKAPI_CALL
+debug_utils_CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
+ struct loader_instance *inst = loader_get_instance(instance);
+ loader_platform_thread_lock_mutex(&loader_lock);
+ VkResult result = inst->disp->layer_inst_disp.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return result;
+}
+
+// Utility function to handle reporting
+VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
+ uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+ VkBool32 bail = false;
+ VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkDebugUtilsMessageSeverityFlagBitsEXT severity;
+ VkDebugUtilsMessageTypeFlagsEXT types;
+ VkDebugUtilsMessengerCallbackDataEXT callback_data;
+ VkDebugUtilsObjectNameInfoEXT object_name;
+
+ debug_utils_ReportFlagsToAnnotFlags(msgFlags, false, &severity, &types);
+ debug_utils_ReportObjectToAnnotObject(objectType, srcObject, &object_name);
+
+ callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
+ callback_data.pNext = NULL;
+ callback_data.flags = 0;
+ callback_data.pMessageIdName = pLayerPrefix;
+ callback_data.messageIdNumber = msgCode;
+ callback_data.pMessage = pMsg;
+ callback_data.cmdBufLabelCount = 0;
+ callback_data.pCmdBufLabels = NULL;
+ callback_data.queueLabelCount = 0;
+ callback_data.pQueueLabels = NULL;
+ callback_data.objectCount = 1;
+ callback_data.pObjects = &object_name;
+
+ while (pTrav) {
+ if (!pTrav->is_messenger && pTrav->report.msgFlags & msgFlags) {
+ if (pTrav->report.pfnMsgCallback(msgFlags, objectType, srcObject, location, msgCode, pLayerPrefix, pMsg,
+ pTrav->pUserData)) {
+ bail = true;
+ }
+ }
+ if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & severity) && (pTrav->messenger.messageType & types)) {
+ if (pTrav->messenger.pfnUserCallback(severity, types, &callback_data, pTrav->pUserData)) {
+ bail = true;
+ }
+ }
+
+ pTrav = pTrav->pNext;
+ }
+
+ return bail;
+}
+
+void util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks *pAllocator) {
+ VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkLayerDbgFunctionNode *pPrev = pTrav;
+
+ while (pTrav) {
+ if (!pTrav->is_messenger && pTrav->report.msgCallback == callback) {
+ pPrev->pNext = pTrav->pNext;
+ if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pAllocator->pfnFree(pAllocator->pUserData, pTrav);
+ } else {
+#endif
+ loader_instance_heap_free(inst, pTrav);
+ }
+ break;
+ }
+ pPrev = pTrav;
+ pTrav = pTrav->pNext;
+ }
+}
+
+// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
+// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It
+// then allocates array that can hold that many structs, as well as that many
+// VkDebugReportCallbackEXT handles. It then copies each
+// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
+VkResult util_CopyDebugReportCreateInfos(const void *pChain, const VkAllocationCallbacks *pAllocator, uint32_t *num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT **infos, VkDebugReportCallbackEXT **callbacks) {
+ uint32_t n = *num_callbacks = 0;
+ VkDebugReportCallbackCreateInfoEXT *pInfos = NULL;
+ VkDebugReportCallbackEXT *pCallbacks = NULL;
+
+ const void *pNext = pChain;
+ while (pNext) {
+ // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
+ if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
+ n++;
+ }
+ pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
+ }
+ if (n == 0) {
+ return VK_SUCCESS;
+ }
+
+// 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pInfos = *infos = ((VkDebugReportCallbackCreateInfoEXT *)pAllocator->pfnAllocation(
+ pAllocator->pUserData, n * sizeof(VkDebugReportCallbackCreateInfoEXT), sizeof(void *),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+ } else {
+#endif
+ pInfos = *infos = ((VkDebugReportCallbackCreateInfoEXT *)malloc(n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
+ }
+ if (!pInfos) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+// 3rd, allocate memory for a unique handle for each callback:
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(
+ pAllocator->pUserData, n * sizeof(VkDebugReportCallbackEXT), sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+ if (!pCallbacks) {
+ pAllocator->pfnFree(pAllocator->pUserData, pInfos);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ } else {
+#endif
+ pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)malloc(n * sizeof(VkDebugReportCallbackEXT)));
+ if (!pCallbacks) {
+ free(pInfos);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ }
+ // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
+ // vkDestroyInstance, and assign a unique handle to each callback (just
+ // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
+ pNext = pChain;
+ while (pNext) {
+ if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
+ memcpy(pInfos, pNext, sizeof(VkDebugReportCallbackCreateInfoEXT));
+ *pCallbacks++ = (VkDebugReportCallbackEXT)(uintptr_t)pInfos++;
+ }
+ pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
+ }
+
+ *num_callbacks = n;
+ return VK_SUCCESS;
+}
+
+void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks) {
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pAllocator->pfnFree(pAllocator->pUserData, infos);
+ pAllocator->pfnFree(pAllocator->pUserData, callbacks);
+ } else {
+#endif
+ free(infos);
+ free(callbacks);
+ }
+}
+
+VkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks) {
+ VkResult rtn = VK_SUCCESS;
+ for (uint32_t i = 0; i < num_callbacks; i++) {
+ rtn = util_CreateDebugReportCallback(inst, &infos[i], pAllocator, callbacks[i]);
+ if (rtn != VK_SUCCESS) {
+ for (uint32_t j = 0; j < i; j++) {
+ util_DestroyDebugReportCallback(inst, callbacks[j], pAllocator);
+ }
+ return rtn;
+ }
+ }
+ return rtn;
+}
+
+void util_DestroyDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator, uint32_t num_callbacks,
+ VkDebugReportCallbackEXT *callbacks) {
+ for (uint32_t i = 0; i < num_callbacks; i++) {
+ util_DestroyDebugReportCallback(inst, callbacks[i], pAllocator);
+ }
+}
+
+static VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks *pAllocator) {
+ struct loader_instance *inst = loader_get_instance(instance);
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ inst->disp->layer_inst_disp.DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+}
+
+static VKAPI_ATTR void VKAPI_CALL debug_utils_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objType, uint64_t object,
+ size_t location, int32_t msgCode, const char *pLayerPrefix,
+ const char *pMsg) {
+ struct loader_instance *inst = loader_get_instance(instance);
+
+ inst->disp->layer_inst_disp.DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
+}
+
+// This is the instance chain terminator function
+// for CreateDebugReportCallback
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstance instance,
+ const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugReportCallbackEXT *pCallback) {
+ VkDebugReportCallbackEXT *icd_info = NULL;
+ const struct loader_icd_term *icd_term;
+ struct loader_instance *inst = (struct loader_instance *)instance;
+ VkResult res = VK_SUCCESS;
+ uint32_t storage_idx;
+ VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ icd_info = ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(pAllocator->pUserData,
+ inst->total_icd_count * sizeof(VkDebugReportCallbackEXT),
+ sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+ if (icd_info) {
+ memset(icd_info, 0, inst->total_icd_count * sizeof(VkDebugReportCallbackEXT));
+ }
+ } else {
+#endif
+ icd_info = calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
+ }
+ if (!icd_info) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ storage_idx = 0;
+ for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ if (!icd_term->dispatch.CreateDebugReportCallbackEXT) {
+ continue;
+ }
+
+ res = icd_term->dispatch.CreateDebugReportCallbackEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
+
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+ storage_idx++;
+ }
+
+// Setup the debug report callback in the terminator since a layer may want
+// to grab the information itself (RenderDoc) and then return back to the
+// user callback a sub-set of the messages.
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 0)
+ if (pAllocator != NULL) {
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
+ sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ } else {
+#else
+ {
+#endif
+ pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ }
+ if (!pNewDbgFuncNode) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
+
+ pNewDbgFuncNode->is_messenger = false;
+ pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
+ pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
+ pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
+ pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
+ inst->DbgFunctionHead = pNewDbgFuncNode;
+
+ *(VkDebugReportCallbackEXT **)pCallback = icd_info;
+ pNewDbgFuncNode->report.msgCallback = *pCallback;
+
+out:
+
+ // Roll back on errors
+ if (VK_SUCCESS != res) {
+ storage_idx = 0;
+ for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
+ continue;
+ }
+
+ if (icd_info && icd_info[storage_idx]) {
+ icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
+ }
+ storage_idx++;
+ }
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ if (NULL != pNewDbgFuncNode) {
+ pAllocator->pfnFree(pAllocator->pUserData, pNewDbgFuncNode);
+ }
+ if (NULL != icd_info) {
+ pAllocator->pfnFree(pAllocator->pUserData, icd_info);
+ }
+ } else {
+#endif
+ if (NULL != pNewDbgFuncNode) {
+ free(pNewDbgFuncNode);
+ }
+ if (NULL != icd_info) {
+ free(icd_info);
+ }
+ }
+ }
+
+ return res;
+}
+
+// This is the instance chain terminator function for DestroyDebugReportCallback
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks *pAllocator) {
+ uint32_t storage_idx;
+ VkDebugReportCallbackEXT *icd_info;
+ const struct loader_icd_term *icd_term;
+
+ struct loader_instance *inst = (struct loader_instance *)instance;
+ icd_info = *(VkDebugReportCallbackEXT **)&callback;
+ storage_idx = 0;
+ for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
+ continue;
+ }
+
+ if (icd_info[storage_idx]) {
+ icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
+ }
+ storage_idx++;
+ }
+
+ util_DestroyDebugReportCallback(inst, callback, pAllocator);
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator != NULL) {
+ pAllocator->pfnFree(pAllocator->pUserData, icd_info);
+ } else {
+#endif
+ free(icd_info);
+ }
+}
+
+// This is the instance chain terminator function for DebugReportMessage
+VKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+ int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+ const struct loader_icd_term *icd_term;
+
+ struct loader_instance *inst = (struct loader_instance *)instance;
+
+ loader_platform_thread_lock_mutex(&loader_lock);
+ for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ if (icd_term->dispatch.DebugReportMessageEXT != NULL) {
+ icd_term->dispatch.DebugReportMessageEXT(icd_term->instance, flags, objType, object, location, msgCode, pLayerPrefix,
+ pMsg);
+ }
+ }
+
+ // Now that all ICDs have seen the message, call the necessary callbacks. Ignoring "bail" return value
+ // as there is nothing to bail from at this point.
+
+ util_DebugReportMessage(inst, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+}
+
+// General utilities
+
+static const VkExtensionProperties debug_utils_extension_info[] = {
+ {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
+ {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION},
+};
+
+void debug_utils_AddInstanceExtensions(const struct loader_instance *inst, struct loader_extension_list *ext_list) {
+ loader_add_to_ext_list(inst, ext_list, sizeof(debug_utils_extension_info) / sizeof(VkExtensionProperties),
+ debug_utils_extension_info);
+}
+
+void debug_utils_CreateInstance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
+ ptr_instance->enabled_known_extensions.ext_debug_report = 0;
+ ptr_instance->enabled_known_extensions.ext_debug_utils = 0;
+
+ for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
+ ptr_instance->enabled_known_extensions.ext_debug_report = 1;
+ } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) {
+ ptr_instance->enabled_known_extensions.ext_debug_utils = 1;
+ }
+ }
+}
+
+bool debug_utils_InstanceGpa(struct loader_instance *ptr_instance, const char *name, void **addr) {
+ bool ret_type = false;
+
+ *addr = NULL;
+
+ if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
+ *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_CreateDebugReportCallbackEXT : NULL;
+ ret_type = true;
+ } else if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
+ *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DestroyDebugReportCallbackEXT : NULL;
+ ret_type = true;
+ } else if (!strcmp("vkDebugReportMessageEXT", name)) {
+ *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DebugReportMessageEXT : NULL;
+ return true;
+ }
+ if (!strcmp("vkCreateDebugUtilsMessengerEXT", name)) {
+ *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_CreateDebugUtilsMessengerEXT : NULL;
+ ret_type = true;
+ } else if (!strcmp("vkDestroyDebugUtilsMessengerEXT", name)) {
+ *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_DestroyDebugUtilsMessengerEXT : NULL;
+ ret_type = true;
+ } else if (!strcmp("vkSubmitDebugUtilsMessageEXT", name)) {
+ *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_SubmitDebugUtilsMessageEXT : NULL;
+ ret_type = true;
+ }
+
+ return ret_type;
+}
+
+bool debug_utils_ReportFlagsToAnnotFlags(VkDebugReportFlagsEXT dr_flags, bool default_flag_is_spec,
+ VkDebugUtilsMessageSeverityFlagBitsEXT *da_severity,
+ VkDebugUtilsMessageTypeFlagsEXT *da_type) {
+ bool type_set = false;
+ if (NULL == da_severity || NULL == da_type) {
+ return false;
+ }
+ *da_type = 0;
+ *da_severity = 0;
+
+ if ((dr_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0) {
+ *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
+ type_set = true;
+ } else if ((dr_flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)) != 0) {
+ *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
+ } else if ((dr_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0) {
+ *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+ } else if ((dr_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0) {
+ *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
+ type_set = true;
+ }
+
+ if ((dr_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0) {
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+ } else if (!type_set) {
+ if (default_flag_is_spec) {
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
+ } else {
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
+ }
+ }
+
+ return true;
+}
+
+bool debug_utils_AnnotFlagsToReportFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
+ VkDebugUtilsMessageTypeFlagsEXT da_type, VkDebugReportFlagsEXT *dr_flags) {
+ if (NULL == dr_flags) {
+ return false;
+ }
+
+ *dr_flags = 0;
+
+ if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
+ } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0) {
+ if ((da_type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
+ } else {
+ *dr_flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
+ }
+ } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
+ } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
+ }
+
+ return true;
+}
+
+bool debug_utils_ReportObjectToAnnotObject(VkDebugReportObjectTypeEXT dr_object_type, uint64_t object_handle,
+ VkDebugUtilsObjectNameInfoEXT *da_object_name_info) {
+ if (NULL == da_object_name_info) {
+ return false;
+ }
+ da_object_name_info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+ da_object_name_info->pNext = NULL;
+ da_object_name_info->objectHandle = (uint64_t)(uintptr_t)object_handle;
+ da_object_name_info->pObjectName = NULL;
+ da_object_name_info->objectType = convertDebugReportObjectToCoreObject(dr_object_type);
+ return true;
+}
+
+bool debug_utils_AnnotObjectToDebugReportObject(const VkDebugUtilsObjectNameInfoEXT *da_object_name_info,
+ VkDebugReportObjectTypeEXT *dr_object_type, uint64_t *dr_object_handle) {
+ if (NULL == da_object_name_info || NULL == dr_object_type || NULL == dr_object_handle) {
+ return false;
+ }
+ *dr_object_type = convertCoreObjectToDebugReportObject(da_object_name_info->objectType);
+ *dr_object_handle = da_object_name_info->objectHandle;
+ return true;
+}
diff --git a/thirdparty/vulkan/loader/debug_utils.h b/thirdparty/vulkan/loader/debug_utils.h
new file mode 100644
index 0000000000..c33a6fcee6
--- /dev/null
+++ b/thirdparty/vulkan/loader/debug_utils.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ * Copyright (C) 2015-2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Mark Young <markyk@lunarg.com>
+ *
+ */
+
+#include "vk_loader_platform.h"
+#include "loader.h"
+
+// General utilities
+
+void debug_utils_AddInstanceExtensions(const struct loader_instance *inst, struct loader_extension_list *ext_list);
+void debug_utils_CreateInstance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);
+bool debug_utils_InstanceGpa(struct loader_instance *ptr_instance, const char *name, void **addr);
+bool debug_utils_ReportFlagsToAnnotFlags(VkDebugReportFlagsEXT dr_flags, bool default_flag_is_spec,
+ VkDebugUtilsMessageSeverityFlagBitsEXT *da_severity,
+ VkDebugUtilsMessageTypeFlagsEXT *da_type);
+bool debug_utils_AnnotFlagsToReportFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
+ VkDebugUtilsMessageTypeFlagsEXT da_type, VkDebugReportFlagsEXT *dr_flags);
+bool debug_utils_ReportObjectToAnnotObject(VkDebugReportObjectTypeEXT dr_object_type, uint64_t object_handle,
+ VkDebugUtilsObjectNameInfoEXT *da_object_name_info);
+bool debug_utils_AnnotObjectToDebugReportObject(const VkDebugUtilsObjectNameInfoEXT *da_object_name_info,
+ VkDebugReportObjectTypeEXT *dr_object_type, uint64_t *dr_object_handle);
+
+// VK_EXT_debug_utils related items
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger);
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator);
+VKAPI_ATTR void VKAPI_CALL terminator_SubmitDebugUtilsMessageEXT(VkInstance instance,
+ VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData);
+VkResult util_CreateDebugUtilsMessenger(struct loader_instance *inst, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT messenger);
+VkResult util_CreateDebugUtilsMessengers(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
+ uint32_t num_messengers, VkDebugUtilsMessengerCreateInfoEXT *infos,
+ VkDebugUtilsMessengerEXT *messengers);
+VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData);
+VkResult util_CopyDebugUtilsMessengerCreateInfos(const void *pChain, const VkAllocationCallbacks *pAllocator,
+ uint32_t *num_messengers, VkDebugUtilsMessengerCreateInfoEXT **infos,
+ VkDebugUtilsMessengerEXT **messengers);
+void util_DestroyDebugUtilsMessenger(struct loader_instance *inst, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator);
+void util_DestroyDebugUtilsMessengers(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
+ uint32_t num_messengers, VkDebugUtilsMessengerEXT *messengers);
+void util_FreeDebugUtilsMessengerCreateInfos(const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerCreateInfoEXT *infos,
+ VkDebugUtilsMessengerEXT *messengers);
+
+// VK_EXT_debug_report related items
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstance instance,
+ const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugReportCallbackEXT *pCallback);
+
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks *pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+ int32_t msgCode, const char *pLayerPrefix, const char *pMsg);
+
+VkResult util_CreateDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT callback);
+VkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks);
+VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
+ uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg);
+VkResult util_CopyDebugReportCreateInfos(const void *pChain, const VkAllocationCallbacks *pAllocator, uint32_t *num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT **infos, VkDebugReportCallbackEXT **callbacks);
+void util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks *pAllocator);
+void util_DestroyDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator, uint32_t num_callbacks,
+ VkDebugReportCallbackEXT *callbacks);
+void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks);
diff --git a/thirdparty/vulkan/loader/dev_ext_trampoline.c b/thirdparty/vulkan/loader/dev_ext_trampoline.c
new file mode 100644
index 0000000000..55eee0c25f
--- /dev/null
+++ b/thirdparty/vulkan/loader/dev_ext_trampoline.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ */
+
+#include "vk_loader_platform.h"
+#include "loader.h"
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC optimize(3) // force gcc to use tail-calls
+#endif
+
+// Clang-format does not understand macros.
+// clang-format off
+
+VKAPI_ATTR void VKAPI_CALL vkdev_ext0(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext1(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext2(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext3(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext4(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext5(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext6(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext7(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext8(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext9(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext10(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext11(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext12(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext13(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext14(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext15(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext16(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext17(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext18(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext19(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext20(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext21(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext22(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext23(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext24(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext25(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext26(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext27(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext28(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext29(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext30(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext31(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext32(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext33(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext34(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext35(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext36(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext37(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext38(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext39(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext40(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext41(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext42(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext43(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext44(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext45(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext46(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext47(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext48(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext49(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext50(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext51(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext52(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext53(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext54(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext55(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext56(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext57(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext58(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext59(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext60(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext61(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext62(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext63(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext64(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext65(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext66(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext67(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext68(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext69(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext70(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext71(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext72(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext73(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext74(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext75(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext76(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext77(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext78(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext79(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext80(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext81(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext82(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext83(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext84(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext85(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext86(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext87(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext88(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext89(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext90(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext91(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext92(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext93(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext94(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext95(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext96(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext97(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext98(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext99(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext100(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext101(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext102(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext103(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext104(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext105(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext106(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext107(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext108(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext109(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext110(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext111(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext112(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext113(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext114(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext115(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext116(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext117(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext118(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext119(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext120(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext121(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext122(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext123(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext124(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext125(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext126(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext127(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext128(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext129(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext130(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext131(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext132(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext133(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext134(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext135(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext136(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext137(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext138(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext139(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext140(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext141(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext142(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext143(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext144(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext145(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext146(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext147(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext148(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext149(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext150(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext151(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext152(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext153(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext154(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext155(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext156(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext157(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext158(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext159(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext160(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext161(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext162(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext163(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext164(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext165(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext166(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext167(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext168(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext169(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext170(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext171(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext172(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext173(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext174(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext175(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext176(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext177(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext178(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext179(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext180(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext181(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext182(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext183(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext184(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext185(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext186(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext187(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext188(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext189(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext190(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext191(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext192(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext193(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext194(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext195(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext196(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext197(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext198(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext199(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext200(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext201(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext202(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext203(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext204(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext205(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext206(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext207(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext208(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext209(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext210(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext211(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext212(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext213(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext214(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext215(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext216(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext217(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext218(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext219(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext220(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext221(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext222(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext223(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext224(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext225(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext226(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext227(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext228(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext229(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext230(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext231(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext232(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext233(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext234(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext235(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext236(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext237(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext238(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext239(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext240(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext241(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext242(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext243(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext244(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext245(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext246(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext247(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext248(VkDevice device);
+VKAPI_ATTR void VKAPI_CALL vkdev_ext249(VkDevice device);
+
+void *loader_get_dev_ext_trampoline(uint32_t index) {
+ switch (index) {
+#define CASE_HANDLE(num) case num: return vkdev_ext##num
+ CASE_HANDLE(0);
+ CASE_HANDLE(1);
+ CASE_HANDLE(2);
+ CASE_HANDLE(3);
+ CASE_HANDLE(4);
+ CASE_HANDLE(5);
+ CASE_HANDLE(6);
+ CASE_HANDLE(7);
+ CASE_HANDLE(8);
+ CASE_HANDLE(9);
+ CASE_HANDLE(10);
+ CASE_HANDLE(11);
+ CASE_HANDLE(12);
+ CASE_HANDLE(13);
+ CASE_HANDLE(14);
+ CASE_HANDLE(15);
+ CASE_HANDLE(16);
+ CASE_HANDLE(17);
+ CASE_HANDLE(18);
+ CASE_HANDLE(19);
+ CASE_HANDLE(20);
+ CASE_HANDLE(21);
+ CASE_HANDLE(22);
+ CASE_HANDLE(23);
+ CASE_HANDLE(24);
+ CASE_HANDLE(25);
+ CASE_HANDLE(26);
+ CASE_HANDLE(27);
+ CASE_HANDLE(28);
+ CASE_HANDLE(29);
+ CASE_HANDLE(30);
+ CASE_HANDLE(31);
+ CASE_HANDLE(32);
+ CASE_HANDLE(33);
+ CASE_HANDLE(34);
+ CASE_HANDLE(35);
+ CASE_HANDLE(36);
+ CASE_HANDLE(37);
+ CASE_HANDLE(38);
+ CASE_HANDLE(39);
+ CASE_HANDLE(40);
+ CASE_HANDLE(41);
+ CASE_HANDLE(42);
+ CASE_HANDLE(43);
+ CASE_HANDLE(44);
+ CASE_HANDLE(45);
+ CASE_HANDLE(46);
+ CASE_HANDLE(47);
+ CASE_HANDLE(48);
+ CASE_HANDLE(49);
+ CASE_HANDLE(50);
+ CASE_HANDLE(51);
+ CASE_HANDLE(52);
+ CASE_HANDLE(53);
+ CASE_HANDLE(54);
+ CASE_HANDLE(55);
+ CASE_HANDLE(56);
+ CASE_HANDLE(57);
+ CASE_HANDLE(58);
+ CASE_HANDLE(59);
+ CASE_HANDLE(60);
+ CASE_HANDLE(61);
+ CASE_HANDLE(62);
+ CASE_HANDLE(63);
+ CASE_HANDLE(64);
+ CASE_HANDLE(65);
+ CASE_HANDLE(66);
+ CASE_HANDLE(67);
+ CASE_HANDLE(68);
+ CASE_HANDLE(69);
+ CASE_HANDLE(70);
+ CASE_HANDLE(71);
+ CASE_HANDLE(72);
+ CASE_HANDLE(73);
+ CASE_HANDLE(74);
+ CASE_HANDLE(75);
+ CASE_HANDLE(76);
+ CASE_HANDLE(77);
+ CASE_HANDLE(78);
+ CASE_HANDLE(79);
+ CASE_HANDLE(80);
+ CASE_HANDLE(81);
+ CASE_HANDLE(82);
+ CASE_HANDLE(83);
+ CASE_HANDLE(84);
+ CASE_HANDLE(85);
+ CASE_HANDLE(86);
+ CASE_HANDLE(87);
+ CASE_HANDLE(88);
+ CASE_HANDLE(89);
+ CASE_HANDLE(90);
+ CASE_HANDLE(91);
+ CASE_HANDLE(92);
+ CASE_HANDLE(93);
+ CASE_HANDLE(94);
+ CASE_HANDLE(95);
+ CASE_HANDLE(96);
+ CASE_HANDLE(97);
+ CASE_HANDLE(98);
+ CASE_HANDLE(99);
+ CASE_HANDLE(100);
+ CASE_HANDLE(101);
+ CASE_HANDLE(102);
+ CASE_HANDLE(103);
+ CASE_HANDLE(104);
+ CASE_HANDLE(105);
+ CASE_HANDLE(106);
+ CASE_HANDLE(107);
+ CASE_HANDLE(108);
+ CASE_HANDLE(109);
+ CASE_HANDLE(110);
+ CASE_HANDLE(111);
+ CASE_HANDLE(112);
+ CASE_HANDLE(113);
+ CASE_HANDLE(114);
+ CASE_HANDLE(115);
+ CASE_HANDLE(116);
+ CASE_HANDLE(117);
+ CASE_HANDLE(118);
+ CASE_HANDLE(119);
+ CASE_HANDLE(120);
+ CASE_HANDLE(121);
+ CASE_HANDLE(122);
+ CASE_HANDLE(123);
+ CASE_HANDLE(124);
+ CASE_HANDLE(125);
+ CASE_HANDLE(126);
+ CASE_HANDLE(127);
+ CASE_HANDLE(128);
+ CASE_HANDLE(129);
+ CASE_HANDLE(130);
+ CASE_HANDLE(131);
+ CASE_HANDLE(132);
+ CASE_HANDLE(133);
+ CASE_HANDLE(134);
+ CASE_HANDLE(135);
+ CASE_HANDLE(136);
+ CASE_HANDLE(137);
+ CASE_HANDLE(138);
+ CASE_HANDLE(139);
+ CASE_HANDLE(140);
+ CASE_HANDLE(141);
+ CASE_HANDLE(142);
+ CASE_HANDLE(143);
+ CASE_HANDLE(144);
+ CASE_HANDLE(145);
+ CASE_HANDLE(146);
+ CASE_HANDLE(147);
+ CASE_HANDLE(148);
+ CASE_HANDLE(149);
+ CASE_HANDLE(150);
+ CASE_HANDLE(151);
+ CASE_HANDLE(152);
+ CASE_HANDLE(153);
+ CASE_HANDLE(154);
+ CASE_HANDLE(155);
+ CASE_HANDLE(156);
+ CASE_HANDLE(157);
+ CASE_HANDLE(158);
+ CASE_HANDLE(159);
+ CASE_HANDLE(160);
+ CASE_HANDLE(161);
+ CASE_HANDLE(162);
+ CASE_HANDLE(163);
+ CASE_HANDLE(164);
+ CASE_HANDLE(165);
+ CASE_HANDLE(166);
+ CASE_HANDLE(167);
+ CASE_HANDLE(168);
+ CASE_HANDLE(169);
+ CASE_HANDLE(170);
+ CASE_HANDLE(171);
+ CASE_HANDLE(172);
+ CASE_HANDLE(173);
+ CASE_HANDLE(174);
+ CASE_HANDLE(175);
+ CASE_HANDLE(176);
+ CASE_HANDLE(177);
+ CASE_HANDLE(178);
+ CASE_HANDLE(179);
+ CASE_HANDLE(180);
+ CASE_HANDLE(181);
+ CASE_HANDLE(182);
+ CASE_HANDLE(183);
+ CASE_HANDLE(184);
+ CASE_HANDLE(185);
+ CASE_HANDLE(186);
+ CASE_HANDLE(187);
+ CASE_HANDLE(188);
+ CASE_HANDLE(189);
+ CASE_HANDLE(190);
+ CASE_HANDLE(191);
+ CASE_HANDLE(192);
+ CASE_HANDLE(193);
+ CASE_HANDLE(194);
+ CASE_HANDLE(195);
+ CASE_HANDLE(196);
+ CASE_HANDLE(197);
+ CASE_HANDLE(198);
+ CASE_HANDLE(199);
+ CASE_HANDLE(200);
+ CASE_HANDLE(201);
+ CASE_HANDLE(202);
+ CASE_HANDLE(203);
+ CASE_HANDLE(204);
+ CASE_HANDLE(205);
+ CASE_HANDLE(206);
+ CASE_HANDLE(207);
+ CASE_HANDLE(208);
+ CASE_HANDLE(209);
+ CASE_HANDLE(210);
+ CASE_HANDLE(211);
+ CASE_HANDLE(212);
+ CASE_HANDLE(213);
+ CASE_HANDLE(214);
+ CASE_HANDLE(215);
+ CASE_HANDLE(216);
+ CASE_HANDLE(217);
+ CASE_HANDLE(218);
+ CASE_HANDLE(219);
+ CASE_HANDLE(220);
+ CASE_HANDLE(221);
+ CASE_HANDLE(222);
+ CASE_HANDLE(223);
+ CASE_HANDLE(224);
+ CASE_HANDLE(225);
+ CASE_HANDLE(226);
+ CASE_HANDLE(227);
+ CASE_HANDLE(228);
+ CASE_HANDLE(229);
+ CASE_HANDLE(230);
+ CASE_HANDLE(231);
+ CASE_HANDLE(232);
+ CASE_HANDLE(233);
+ CASE_HANDLE(234);
+ CASE_HANDLE(235);
+ CASE_HANDLE(236);
+ CASE_HANDLE(237);
+ CASE_HANDLE(238);
+ CASE_HANDLE(239);
+ CASE_HANDLE(240);
+ CASE_HANDLE(241);
+ CASE_HANDLE(242);
+ CASE_HANDLE(243);
+ CASE_HANDLE(244);
+ CASE_HANDLE(245);
+ CASE_HANDLE(246);
+ CASE_HANDLE(247);
+ CASE_HANDLE(248);
+ CASE_HANDLE(249);
+ }
+
+ return NULL;
+}
diff --git a/thirdparty/vulkan/loader/dirent_on_windows.c b/thirdparty/vulkan/loader/dirent_on_windows.c
new file mode 100644
index 0000000000..16318cc70d
--- /dev/null
+++ b/thirdparty/vulkan/loader/dirent_on_windows.c
@@ -0,0 +1,128 @@
+/*
+
+ Implementation of POSIX directory browsing functions and types for Win32.
+
+ Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
+ History: Created March 1997. Updated June 2003 and July 2012.
+ Rights: See end of file.
+
+*/
+#include "dirent_on_windows.h"
+#include <errno.h>
+#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
+#include <stdlib.h>
+#include <string.h>
+#include "vk_loader_platform.h"
+#include "loader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */
+
+struct DIR {
+ handle_type handle; /* -1 for failed rewind */
+ struct _finddata_t info;
+ struct dirent result; /* d_name null iff first time */
+ char *name; /* null-terminated char string */
+};
+
+DIR *opendir(const char *name) {
+ DIR *dir = 0;
+
+ if (name && name[0]) {
+ size_t base_length = strlen(name);
+ const char *all = /* search pattern must end with suitable wildcard */
+ strchr("/\\", name[base_length - 1]) ? "*" : "/*";
+
+ if ((dir = (DIR *)loader_instance_tls_heap_alloc(sizeof *dir)) != 0 &&
+ (dir->name = (char *)loader_instance_tls_heap_alloc(base_length + strlen(all) + 1)) != 0) {
+ strcat(strcpy(dir->name, name), all);
+
+ if ((dir->handle = (handle_type)_findfirst(dir->name, &dir->info)) != -1) {
+ dir->result.d_name = 0;
+ } else /* rollback */
+ {
+ loader_instance_tls_heap_free(dir->name);
+ loader_instance_tls_heap_free(dir);
+ dir = 0;
+ }
+ } else /* rollback */
+ {
+ loader_instance_tls_heap_free(dir);
+ dir = 0;
+ errno = ENOMEM;
+ }
+ } else {
+ errno = EINVAL;
+ }
+
+ return dir;
+}
+
+int closedir(DIR *dir) {
+ int result = -1;
+
+ if (dir) {
+ if (dir->handle != -1) {
+ result = _findclose(dir->handle);
+ }
+
+ loader_instance_tls_heap_free(dir->name);
+ loader_instance_tls_heap_free(dir);
+ }
+
+ if (result == -1) /* map all errors to EBADF */
+ {
+ errno = EBADF;
+ }
+
+ return result;
+}
+
+struct dirent *readdir(DIR *dir) {
+ struct dirent *result = 0;
+
+ if (dir && dir->handle != -1) {
+ if (!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) {
+ result = &dir->result;
+ result->d_name = dir->info.name;
+ }
+ } else {
+ errno = EBADF;
+ }
+
+ return result;
+}
+
+void rewinddir(DIR *dir) {
+ if (dir && dir->handle != -1) {
+ _findclose(dir->handle);
+ dir->handle = (handle_type)_findfirst(dir->name, &dir->info);
+ dir->result.d_name = 0;
+ } else {
+ errno = EBADF;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+
+ Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
+ Copyright (c) 2015 The Khronos Group Inc.
+ Copyright (c) 2015 Valve Corporation
+ Copyright (c) 2015 LunarG, Inc.
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose is hereby granted without fee, provided
+ that this copyright and permissions notice appear in all copies and
+ derivatives.
+
+ This software is supplied "as is" without express or implied warranty.
+
+ But that said, if there are any problems please get in touch.
+
+*/
diff --git a/thirdparty/vulkan/loader/dirent_on_windows.h b/thirdparty/vulkan/loader/dirent_on_windows.h
new file mode 100644
index 0000000000..8600f8ef04
--- /dev/null
+++ b/thirdparty/vulkan/loader/dirent_on_windows.h
@@ -0,0 +1,51 @@
+#ifndef DIRENT_INCLUDED
+#define DIRENT_INCLUDED
+
+/*
+
+ Declaration of POSIX directory browsing functions and types for Win32.
+
+ Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
+ History: Created March 1997. Updated June 2003.
+ Rights: See end of file.
+
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DIR DIR;
+
+struct dirent {
+ char *d_name;
+};
+
+DIR *opendir(const char *);
+int closedir(DIR *);
+struct dirent *readdir(DIR *);
+void rewinddir(DIR *);
+
+/*
+
+ Copyright Kevlin Henney, 1997, 2003. All rights reserved.
+ Copyright (c) 2015 The Khronos Group Inc.
+ Copyright (c) 2015 Valve Corporation
+ Copyright (c) 2015 LunarG, Inc.
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose is hereby granted without fee, provided
+ that this copyright and permissions notice appear in all copies and
+ derivatives.
+
+ This software is supplied "as is" without express or implied warranty.
+
+ But that said, if there are any problems please get in touch.
+
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/vulkan/loader/dxgi_loader.c b/thirdparty/vulkan/loader/dxgi_loader.c
new file mode 100644
index 0000000000..c2a3fa5638
--- /dev/null
+++ b/thirdparty/vulkan/loader/dxgi_loader.c
@@ -0,0 +1,23 @@
+#include "dxgi_loader.h"
+
+#include <strsafe.h>
+
+static HMODULE load_dxgi_module() {
+ TCHAR systemPath[MAX_PATH] = "";
+ GetSystemDirectory(systemPath, MAX_PATH);
+ StringCchCat(systemPath, MAX_PATH, TEXT("\\dxgi.dll"));
+
+ return LoadLibrary(systemPath);
+}
+
+typedef HRESULT (APIENTRY *PFN_CreateDXGIFactory1)(REFIID riid, void **ppFactory);
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory) {
+ PFN_CreateDXGIFactory1 fpCreateDXGIFactory1 =
+ (PFN_CreateDXGIFactory1)GetProcAddress(load_dxgi_module(), "CreateDXGIFactory1");
+
+ if (fpCreateDXGIFactory1 != NULL)
+ return fpCreateDXGIFactory1(riid, ppFactory);
+
+ return DXGI_ERROR_NOT_FOUND;
+} \ No newline at end of file
diff --git a/thirdparty/vulkan/loader/dxgi_loader.h b/thirdparty/vulkan/loader/dxgi_loader.h
new file mode 100644
index 0000000000..00daf08ed2
--- /dev/null
+++ b/thirdparty/vulkan/loader/dxgi_loader.h
@@ -0,0 +1,8 @@
+#ifndef DXGI_LOADER_H
+#define DXGI_LOADER_H
+
+#include <dxgi1_2.h>
+
+HRESULT dyn_CreateDXGIFactory1(REFIID riid, void **ppFactory);
+
+#endif \ No newline at end of file
diff --git a/thirdparty/vulkan/loader/extension_manual.c b/thirdparty/vulkan/loader/extension_manual.c
new file mode 100644
index 0000000000..490496d7c7
--- /dev/null
+++ b/thirdparty/vulkan/loader/extension_manual.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Young <marky@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "vk_loader_platform.h"
+#include "loader.h"
+#include "vk_loader_extensions.h"
+#include <vulkan/vk_icd.h>
+#include "wsi.h"
+#include "debug_utils.h"
+
+// ---- Manually added trampoline/terminator functions
+
+// These functions, for whatever reason, require more complex changes than
+// can easily be automatically generated.
+
+// ---- VK_KHR_device_group extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
+ VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceSurfaceCapabilities2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceCapabilities);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
+ VkSurfaceCapabilities2KHR *pSurfaceCapabilities) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
+ uint8_t icd_index = phys_dev_term->icd_index;
+
+ if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR != NULL) {
+ VkBaseOutStructure *pNext = (VkBaseOutStructure *)pSurfaceCapabilities->pNext;
+ while (pNext != NULL) {
+ if ((int)pNext->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
+ // Not all ICDs may be supporting VK_KHR_surface_protected_capabilities
+ // Initialize VkSurfaceProtectedCapabilitiesKHR.supportsProtected to false and
+ // if an ICD supports protected surfaces, it will reset it to true accordingly.
+ ((VkSurfaceProtectedCapabilitiesKHR *)pNext)->supportsProtected = VK_FALSE;
+ }
+ pNext = (VkBaseOutStructure *)pNext->pNext;
+ }
+
+ // Pass the call to the driver, possibly unwrapping the ICD surface
+ if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
+ VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
+ info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, &info_copy,
+ pSurfaceCapabilities);
+ } else {
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
+ pSurfaceCapabilities);
+ }
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulating call in ICD \"%s\" using "
+ "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
+ icd_term->scanned_icd->lib_name);
+
+ if (pSurfaceInfo->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
+ "pSurfaceInfo->pNext - this struct will be ignored");
+ }
+
+ // Write to the VkSurfaceCapabilities2KHR struct
+ VkSurfaceKHR surface = pSurfaceInfo->surface;
+ if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
+ surface = icd_surface->real_icd_surfaces[icd_index];
+ }
+ VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface,
+ &pSurfaceCapabilities->surfaceCapabilities);
+
+ if (pSurfaceCapabilities->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceCapabilities2KHR: Emulation found unrecognized structure type in "
+ "pSurfaceCapabilities->pNext - this struct will be ignored");
+ }
+ return res;
+ }
+}
+
+// ---- VK_NV_external_memory_capabilities extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL
+GetPhysicalDeviceExternalImageFormatPropertiesNV(
+ VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
+ VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
+ VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+ VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+
+ return disp->GetPhysicalDeviceExternalImageFormatPropertiesNV(
+ unwrapped_phys_dev, format, type, tiling, usage, flags,
+ externalHandleType, pExternalImageFormatProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
+ VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
+ VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
+ VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+ VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
+ struct loader_physical_device_term *phys_dev_term =
+ (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ if (!icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV) {
+ if (externalHandleType) {
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
+ }
+
+ if (!icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ pExternalImageFormatProperties->externalMemoryFeatures = 0;
+ pExternalImageFormatProperties->exportFromImportedHandleTypes = 0;
+ pExternalImageFormatProperties->compatibleHandleTypes = 0;
+
+ return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
+ phys_dev_term->phys_dev, format, type, tiling, usage, flags,
+ &pExternalImageFormatProperties->imageFormatProperties);
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceExternalImageFormatPropertiesNV(
+ phys_dev_term->phys_dev, format, type, tiling, usage, flags,
+ externalHandleType, pExternalImageFormatProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
+ uint32_t *pSurfaceFormatCount,
+ VkSurfaceFormat2KHR *pSurfaceFormats) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceSurfaceFormats2KHR(unwrapped_phys_dev, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
+ uint32_t *pSurfaceFormatCount,
+ VkSurfaceFormat2KHR *pSurfaceFormats) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
+ uint8_t icd_index = phys_dev_term->icd_index;
+
+ if (icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR != NULL) {
+ // Pass the call to the driver, possibly unwrapping the ICD surface
+ if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
+ VkPhysicalDeviceSurfaceInfo2KHR info_copy = *pSurfaceInfo;
+ info_copy.surface = icd_surface->real_icd_surfaces[icd_index];
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, &info_copy, pSurfaceFormatCount,
+ pSurfaceFormats);
+ } else {
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceFormats2KHR(phys_dev_term->phys_dev, pSurfaceInfo,
+ pSurfaceFormatCount, pSurfaceFormats);
+ }
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceSurfaceFormatsKHR",
+ icd_term->scanned_icd->lib_name);
+
+ if (pSurfaceInfo->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in pSurfaceInfo->pNext "
+ "- this struct will be ignored");
+ }
+
+ VkSurfaceKHR surface = pSurfaceInfo->surface;
+ if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
+ surface = icd_surface->real_icd_surfaces[icd_index];
+ }
+
+ if (*pSurfaceFormatCount == 0 || pSurfaceFormats == NULL) {
+ // Write to pSurfaceFormatCount
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
+ NULL);
+ } else {
+ // Allocate a temporary array for the output of the old function
+ VkSurfaceFormatKHR *formats = loader_stack_alloc(*pSurfaceFormatCount * sizeof(VkSurfaceFormatKHR));
+ if (formats == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ VkResult res = icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface,
+ pSurfaceFormatCount, formats);
+ for (uint32_t i = 0; i < *pSurfaceFormatCount; ++i) {
+ pSurfaceFormats[i].surfaceFormat = formats[i];
+ if (pSurfaceFormats[i].pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceFormats2KHR: Emulation found unrecognized structure type in "
+ "pSurfaceFormats[%d].pNext - this struct will be ignored",
+ i);
+ }
+ }
+ return res;
+ }
+ }
+}
+
+// ---- VK_EXT_display_surface_counter extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceSurfaceCapabilities2EXT(unwrapped_phys_dev, surface, pSurfaceCapabilities);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT(
+ VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT *pSurfaceCapabilities) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+ uint8_t icd_index = phys_dev_term->icd_index;
+
+ // Unwrap the surface if needed
+ VkSurfaceKHR unwrapped_surface = surface;
+ if (icd_surface->real_icd_surfaces != NULL && (void *)icd_surface->real_icd_surfaces[icd_index] != NULL) {
+ unwrapped_surface = icd_surface->real_icd_surfaces[icd_index];
+ }
+
+ if (icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT != NULL) {
+ // Pass the call to the driver
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev_term->phys_dev, unwrapped_surface,
+ pSurfaceCapabilities);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulating call in ICD \"%s\" using "
+ "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
+ icd_term->scanned_icd->lib_name);
+
+ VkSurfaceCapabilitiesKHR surface_caps;
+ VkResult res =
+ icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, unwrapped_surface, &surface_caps);
+ pSurfaceCapabilities->minImageCount = surface_caps.minImageCount;
+ pSurfaceCapabilities->maxImageCount = surface_caps.maxImageCount;
+ pSurfaceCapabilities->currentExtent = surface_caps.currentExtent;
+ pSurfaceCapabilities->minImageExtent = surface_caps.minImageExtent;
+ pSurfaceCapabilities->maxImageExtent = surface_caps.maxImageExtent;
+ pSurfaceCapabilities->maxImageArrayLayers = surface_caps.maxImageArrayLayers;
+ pSurfaceCapabilities->supportedTransforms = surface_caps.supportedTransforms;
+ pSurfaceCapabilities->currentTransform = surface_caps.currentTransform;
+ pSurfaceCapabilities->supportedCompositeAlpha = surface_caps.supportedCompositeAlpha;
+ pSurfaceCapabilities->supportedUsageFlags = surface_caps.supportedUsageFlags;
+ pSurfaceCapabilities->supportedSurfaceCounters = 0;
+
+ if (pSurfaceCapabilities->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSurfaceCapabilities2EXT: Emulation found unrecognized structure type in "
+ "pSurfaceCapabilities->pNext - this struct will be ignored");
+ }
+
+ return res;
+ }
+}
+
+// ---- VK_EXT_direct_mode_display extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->ReleaseDisplayEXT(unwrapped_phys_dev, display);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ if (icd_term->dispatch.ReleaseDisplayEXT == NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD \"%s\" associated with VkPhysicalDevice does not support vkReleaseDisplayEXT - Consequently, the call is "
+ "invalid because it should not be possible to acquire a display on this device",
+ icd_term->scanned_icd->lib_name);
+ }
+ return icd_term->dispatch.ReleaseDisplayEXT(phys_dev_term->phys_dev, display);
+}
+
+// ---- VK_EXT_acquire_xlib_display extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, VkDisplayKHR display) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->AcquireXlibDisplayEXT(unwrapped_phys_dev, dpy, display);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy,
+ VkDisplayKHR display) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ if (icd_term->dispatch.AcquireXlibDisplayEXT != NULL) {
+ // Pass the call to the driver
+ return icd_term->dispatch.AcquireXlibDisplayEXT(phys_dev_term->phys_dev, dpy, display);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkAcquireXLibDisplayEXT: Emulating call in ICD \"%s\" by returning error", icd_term->scanned_icd->lib_name);
+
+ // Fail for the unsupported command
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
+ VkDisplayKHR *pDisplay) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetRandROutputDisplayEXT(unwrapped_phys_dev, dpy, rrOutput, pDisplay);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display *dpy, RROutput rrOutput,
+ VkDisplayKHR *pDisplay) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ if (icd_term->dispatch.GetRandROutputDisplayEXT != NULL) {
+ // Pass the call to the driver
+ return icd_term->dispatch.GetRandROutputDisplayEXT(phys_dev_term->phys_dev, dpy, rrOutput, pDisplay);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetRandROutputDisplayEXT: Emulating call in ICD \"%s\" by returning null display",
+ icd_term->scanned_icd->lib_name);
+
+ // Return a null handle to indicate this can't be done
+ *pDisplay = VK_NULL_HANDLE;
+ return VK_SUCCESS;
+ }
+}
+
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pPresentModeCount,
+ VkPresentModeKHR* pPresentModes) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceSurfacePresentModes2EXT(unwrapped_phys_dev, pSurfaceInfo, pPresentModeCount, pPresentModes);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2EXT(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pPresentModeCount,
+ VkPresentModeKHR* pPresentModes) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSurfacePresentModes2EXT");
+ }
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(pSurfaceInfo->surface);
+ uint8_t icd_index = phys_dev_term->icd_index;
+ if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {
+ const VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy = {
+ .sType = pSurfaceInfo->sType,
+ .pNext = pSurfaceInfo->pNext,
+ .surface = icd_surface->real_icd_surfaces[icd_index],
+ };
+ return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, &surface_info_copy, pPresentModeCount, pPresentModes);
+ }
+ return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModes2EXT(phys_dev_term->phys_dev, pSurfaceInfo, pPresentModeCount, pPresentModes);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(
+ VkDevice device,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkDeviceGroupPresentModeFlagsKHR* pModes) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(
+ VkDevice device,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkDeviceGroupPresentModeFlagsKHR* pModes) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pSurfaceInfo->surface;
+ if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {
+ const VkPhysicalDeviceSurfaceInfo2KHR surface_info_copy = {
+ .sType = pSurfaceInfo->sType,
+ .pNext = pSurfaceInfo->pNext,
+ .surface = icd_surface->real_icd_surfaces[icd_index],
+ };
+ return icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, &surface_info_copy, pModes);
+ }
+ return icd_term->dispatch.GetDeviceGroupSurfacePresentModes2EXT(device, pSurfaceInfo, pModes);
+ }
+ return VK_SUCCESS;
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
diff --git a/thirdparty/vulkan/loader/extension_manual.h b/thirdparty/vulkan/loader/extension_manual.h
new file mode 100644
index 0000000000..e07b9102dc
--- /dev/null
+++ b/thirdparty/vulkan/loader/extension_manual.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Young <marky@lunarg.com>
+ */
+
+#pragma once
+
+// ---- Manually added trampoline/terminator functions
+
+// These functions, for whatever reason, require more complex changes than
+// can easily be automatically generated.
+
+VKAPI_ATTR VkResult VKAPI_CALL
+GetPhysicalDeviceExternalImageFormatPropertiesNV(
+ VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
+ VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
+ VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+ VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL
+terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV(
+ VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
+ VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
+ VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+ VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2KHR(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormat2KHR* pSurfaceFormats);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormat2KHR* pSurfaceFormats);
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+VKAPI_ATTR VkResult VKAPI_CALL AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy,
+ VkDisplayKHR display);
+
+VKAPI_ATTR VkResult VKAPI_CALL GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput,
+ VkDisplayKHR* pDisplay);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput,
+ VkDisplayKHR* pDisplay);
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModes2EXT(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pPresentModeCount,
+ VkPresentModeKHR* pPresentModes);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModes2EXT(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pPresentModeCount,
+ VkPresentModeKHR* pPresentModes);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDeviceGroupSurfacePresentModes2EXT(
+ VkDevice device,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkDeviceGroupPresentModeFlagsKHR* pModes);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModes2EXT(
+ VkDevice device,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkDeviceGroupPresentModeFlagsKHR* pModes);
diff --git a/thirdparty/vulkan/loader/gpa_helper.h b/thirdparty/vulkan/loader/gpa_helper.h
new file mode 100644
index 0000000000..e08898b6d8
--- /dev/null
+++ b/thirdparty/vulkan/loader/gpa_helper.h
@@ -0,0 +1,233 @@
+/*
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Valve Corporation
+ * Copyright (c) 2015 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Jon Ashburn <jon@lunarg.com>
+ */
+
+#include <string.h>
+#include "debug_utils.h"
+#include "wsi.h"
+
+static inline void *trampolineGetProcAddr(struct loader_instance *inst, const char *funcName) {
+ // Don't include or check global functions
+ if (!strcmp(funcName, "vkGetInstanceProcAddr")) return vkGetInstanceProcAddr;
+ if (!strcmp(funcName, "vkDestroyInstance")) return vkDestroyInstance;
+ if (!strcmp(funcName, "vkEnumeratePhysicalDevices")) return vkEnumeratePhysicalDevices;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures")) return vkGetPhysicalDeviceFeatures;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties")) return vkGetPhysicalDeviceFormatProperties;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties")) return vkGetPhysicalDeviceImageFormatProperties;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties")) return vkGetPhysicalDeviceSparseImageFormatProperties;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceProperties")) return vkGetPhysicalDeviceProperties;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties")) return vkGetPhysicalDeviceQueueFamilyProperties;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties")) return vkGetPhysicalDeviceMemoryProperties;
+ if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties")) return vkEnumerateDeviceLayerProperties;
+ if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties")) return vkEnumerateDeviceExtensionProperties;
+ if (!strcmp(funcName, "vkCreateDevice")) return vkCreateDevice;
+ if (!strcmp(funcName, "vkGetDeviceProcAddr")) return vkGetDeviceProcAddr;
+ if (!strcmp(funcName, "vkDestroyDevice")) return vkDestroyDevice;
+ if (!strcmp(funcName, "vkGetDeviceQueue")) return vkGetDeviceQueue;
+ if (!strcmp(funcName, "vkQueueSubmit")) return vkQueueSubmit;
+ if (!strcmp(funcName, "vkQueueWaitIdle")) return vkQueueWaitIdle;
+ if (!strcmp(funcName, "vkDeviceWaitIdle")) return vkDeviceWaitIdle;
+ if (!strcmp(funcName, "vkAllocateMemory")) return vkAllocateMemory;
+ if (!strcmp(funcName, "vkFreeMemory")) return vkFreeMemory;
+ if (!strcmp(funcName, "vkMapMemory")) return vkMapMemory;
+ if (!strcmp(funcName, "vkUnmapMemory")) return vkUnmapMemory;
+ if (!strcmp(funcName, "vkFlushMappedMemoryRanges")) return vkFlushMappedMemoryRanges;
+ if (!strcmp(funcName, "vkInvalidateMappedMemoryRanges")) return vkInvalidateMappedMemoryRanges;
+ if (!strcmp(funcName, "vkGetDeviceMemoryCommitment")) return vkGetDeviceMemoryCommitment;
+ if (!strcmp(funcName, "vkGetImageSparseMemoryRequirements")) return vkGetImageSparseMemoryRequirements;
+ if (!strcmp(funcName, "vkGetImageMemoryRequirements")) return vkGetImageMemoryRequirements;
+ if (!strcmp(funcName, "vkGetBufferMemoryRequirements")) return vkGetBufferMemoryRequirements;
+ if (!strcmp(funcName, "vkBindImageMemory")) return vkBindImageMemory;
+ if (!strcmp(funcName, "vkBindBufferMemory")) return vkBindBufferMemory;
+ if (!strcmp(funcName, "vkQueueBindSparse")) return vkQueueBindSparse;
+ if (!strcmp(funcName, "vkCreateFence")) return vkCreateFence;
+ if (!strcmp(funcName, "vkDestroyFence")) return vkDestroyFence;
+ if (!strcmp(funcName, "vkGetFenceStatus")) return vkGetFenceStatus;
+ if (!strcmp(funcName, "vkResetFences")) return vkResetFences;
+ if (!strcmp(funcName, "vkWaitForFences")) return vkWaitForFences;
+ if (!strcmp(funcName, "vkCreateSemaphore")) return vkCreateSemaphore;
+ if (!strcmp(funcName, "vkDestroySemaphore")) return vkDestroySemaphore;
+ if (!strcmp(funcName, "vkCreateEvent")) return vkCreateEvent;
+ if (!strcmp(funcName, "vkDestroyEvent")) return vkDestroyEvent;
+ if (!strcmp(funcName, "vkGetEventStatus")) return vkGetEventStatus;
+ if (!strcmp(funcName, "vkSetEvent")) return vkSetEvent;
+ if (!strcmp(funcName, "vkResetEvent")) return vkResetEvent;
+ if (!strcmp(funcName, "vkCreateQueryPool")) return vkCreateQueryPool;
+ if (!strcmp(funcName, "vkDestroyQueryPool")) return vkDestroyQueryPool;
+ if (!strcmp(funcName, "vkGetQueryPoolResults")) return vkGetQueryPoolResults;
+ if (!strcmp(funcName, "vkCreateBuffer")) return vkCreateBuffer;
+ if (!strcmp(funcName, "vkDestroyBuffer")) return vkDestroyBuffer;
+ if (!strcmp(funcName, "vkCreateBufferView")) return vkCreateBufferView;
+ if (!strcmp(funcName, "vkDestroyBufferView")) return vkDestroyBufferView;
+ if (!strcmp(funcName, "vkCreateImage")) return vkCreateImage;
+ if (!strcmp(funcName, "vkDestroyImage")) return vkDestroyImage;
+ if (!strcmp(funcName, "vkGetImageSubresourceLayout")) return vkGetImageSubresourceLayout;
+ if (!strcmp(funcName, "vkCreateImageView")) return vkCreateImageView;
+ if (!strcmp(funcName, "vkDestroyImageView")) return vkDestroyImageView;
+ if (!strcmp(funcName, "vkCreateShaderModule")) return vkCreateShaderModule;
+ if (!strcmp(funcName, "vkDestroyShaderModule")) return vkDestroyShaderModule;
+ if (!strcmp(funcName, "vkCreatePipelineCache")) return vkCreatePipelineCache;
+ if (!strcmp(funcName, "vkDestroyPipelineCache")) return vkDestroyPipelineCache;
+ if (!strcmp(funcName, "vkGetPipelineCacheData")) return vkGetPipelineCacheData;
+ if (!strcmp(funcName, "vkMergePipelineCaches")) return vkMergePipelineCaches;
+ if (!strcmp(funcName, "vkCreateGraphicsPipelines")) return vkCreateGraphicsPipelines;
+ if (!strcmp(funcName, "vkCreateComputePipelines")) return vkCreateComputePipelines;
+ if (!strcmp(funcName, "vkDestroyPipeline")) return vkDestroyPipeline;
+ if (!strcmp(funcName, "vkCreatePipelineLayout")) return vkCreatePipelineLayout;
+ if (!strcmp(funcName, "vkDestroyPipelineLayout")) return vkDestroyPipelineLayout;
+ if (!strcmp(funcName, "vkCreateSampler")) return vkCreateSampler;
+ if (!strcmp(funcName, "vkDestroySampler")) return vkDestroySampler;
+ if (!strcmp(funcName, "vkCreateDescriptorSetLayout")) return vkCreateDescriptorSetLayout;
+ if (!strcmp(funcName, "vkDestroyDescriptorSetLayout")) return vkDestroyDescriptorSetLayout;
+ if (!strcmp(funcName, "vkCreateDescriptorPool")) return vkCreateDescriptorPool;
+ if (!strcmp(funcName, "vkDestroyDescriptorPool")) return vkDestroyDescriptorPool;
+ if (!strcmp(funcName, "vkResetDescriptorPool")) return vkResetDescriptorPool;
+ if (!strcmp(funcName, "vkAllocateDescriptorSets")) return vkAllocateDescriptorSets;
+ if (!strcmp(funcName, "vkFreeDescriptorSets")) return vkFreeDescriptorSets;
+ if (!strcmp(funcName, "vkUpdateDescriptorSets")) return vkUpdateDescriptorSets;
+ if (!strcmp(funcName, "vkCreateFramebuffer")) return vkCreateFramebuffer;
+ if (!strcmp(funcName, "vkDestroyFramebuffer")) return vkDestroyFramebuffer;
+ if (!strcmp(funcName, "vkCreateRenderPass")) return vkCreateRenderPass;
+ if (!strcmp(funcName, "vkDestroyRenderPass")) return vkDestroyRenderPass;
+ if (!strcmp(funcName, "vkGetRenderAreaGranularity")) return vkGetRenderAreaGranularity;
+ if (!strcmp(funcName, "vkCreateCommandPool")) return vkCreateCommandPool;
+ if (!strcmp(funcName, "vkDestroyCommandPool")) return vkDestroyCommandPool;
+ if (!strcmp(funcName, "vkResetCommandPool")) return vkResetCommandPool;
+ if (!strcmp(funcName, "vkAllocateCommandBuffers")) return vkAllocateCommandBuffers;
+ if (!strcmp(funcName, "vkFreeCommandBuffers")) return vkFreeCommandBuffers;
+ if (!strcmp(funcName, "vkBeginCommandBuffer")) return vkBeginCommandBuffer;
+ if (!strcmp(funcName, "vkEndCommandBuffer")) return vkEndCommandBuffer;
+ if (!strcmp(funcName, "vkResetCommandBuffer")) return vkResetCommandBuffer;
+ if (!strcmp(funcName, "vkCmdBindPipeline")) return vkCmdBindPipeline;
+ if (!strcmp(funcName, "vkCmdBindDescriptorSets")) return vkCmdBindDescriptorSets;
+ if (!strcmp(funcName, "vkCmdBindVertexBuffers")) return vkCmdBindVertexBuffers;
+ if (!strcmp(funcName, "vkCmdBindIndexBuffer")) return vkCmdBindIndexBuffer;
+ if (!strcmp(funcName, "vkCmdSetViewport")) return vkCmdSetViewport;
+ if (!strcmp(funcName, "vkCmdSetScissor")) return vkCmdSetScissor;
+ if (!strcmp(funcName, "vkCmdSetLineWidth")) return vkCmdSetLineWidth;
+ if (!strcmp(funcName, "vkCmdSetDepthBias")) return vkCmdSetDepthBias;
+ if (!strcmp(funcName, "vkCmdSetBlendConstants")) return vkCmdSetBlendConstants;
+ if (!strcmp(funcName, "vkCmdSetDepthBounds")) return vkCmdSetDepthBounds;
+ if (!strcmp(funcName, "vkCmdSetStencilCompareMask")) return vkCmdSetStencilCompareMask;
+ if (!strcmp(funcName, "vkCmdSetStencilWriteMask")) return vkCmdSetStencilWriteMask;
+ if (!strcmp(funcName, "vkCmdSetStencilReference")) return vkCmdSetStencilReference;
+ if (!strcmp(funcName, "vkCmdDraw")) return vkCmdDraw;
+ if (!strcmp(funcName, "vkCmdDrawIndexed")) return vkCmdDrawIndexed;
+ if (!strcmp(funcName, "vkCmdDrawIndirect")) return vkCmdDrawIndirect;
+ if (!strcmp(funcName, "vkCmdDrawIndexedIndirect")) return vkCmdDrawIndexedIndirect;
+ if (!strcmp(funcName, "vkCmdDispatch")) return vkCmdDispatch;
+ if (!strcmp(funcName, "vkCmdDispatchIndirect")) return vkCmdDispatchIndirect;
+ if (!strcmp(funcName, "vkCmdCopyBuffer")) return vkCmdCopyBuffer;
+ if (!strcmp(funcName, "vkCmdCopyImage")) return vkCmdCopyImage;
+ if (!strcmp(funcName, "vkCmdBlitImage")) return vkCmdBlitImage;
+ if (!strcmp(funcName, "vkCmdCopyBufferToImage")) return vkCmdCopyBufferToImage;
+ if (!strcmp(funcName, "vkCmdCopyImageToBuffer")) return vkCmdCopyImageToBuffer;
+ if (!strcmp(funcName, "vkCmdUpdateBuffer")) return vkCmdUpdateBuffer;
+ if (!strcmp(funcName, "vkCmdFillBuffer")) return vkCmdFillBuffer;
+ if (!strcmp(funcName, "vkCmdClearColorImage")) return vkCmdClearColorImage;
+ if (!strcmp(funcName, "vkCmdClearDepthStencilImage")) return vkCmdClearDepthStencilImage;
+ if (!strcmp(funcName, "vkCmdClearAttachments")) return vkCmdClearAttachments;
+ if (!strcmp(funcName, "vkCmdResolveImage")) return vkCmdResolveImage;
+ if (!strcmp(funcName, "vkCmdSetEvent")) return vkCmdSetEvent;
+ if (!strcmp(funcName, "vkCmdResetEvent")) return vkCmdResetEvent;
+ if (!strcmp(funcName, "vkCmdWaitEvents")) return vkCmdWaitEvents;
+ if (!strcmp(funcName, "vkCmdPipelineBarrier")) return vkCmdPipelineBarrier;
+ if (!strcmp(funcName, "vkCmdBeginQuery")) return vkCmdBeginQuery;
+ if (!strcmp(funcName, "vkCmdEndQuery")) return vkCmdEndQuery;
+ if (!strcmp(funcName, "vkCmdResetQueryPool")) return vkCmdResetQueryPool;
+ if (!strcmp(funcName, "vkCmdWriteTimestamp")) return vkCmdWriteTimestamp;
+ if (!strcmp(funcName, "vkCmdCopyQueryPoolResults")) return vkCmdCopyQueryPoolResults;
+ if (!strcmp(funcName, "vkCmdPushConstants")) return vkCmdPushConstants;
+ if (!strcmp(funcName, "vkCmdBeginRenderPass")) return vkCmdBeginRenderPass;
+ if (!strcmp(funcName, "vkCmdNextSubpass")) return vkCmdNextSubpass;
+ if (!strcmp(funcName, "vkCmdEndRenderPass")) return vkCmdEndRenderPass;
+ if (!strcmp(funcName, "vkCmdExecuteCommands")) return vkCmdExecuteCommands;
+
+ // Core 1.1 functions
+ if (!strcmp(funcName, "vkEnumeratePhysicalDeviceGroups")) return vkEnumeratePhysicalDeviceGroups;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceFeatures2")) return vkGetPhysicalDeviceFeatures2;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceProperties2")) return vkGetPhysicalDeviceProperties2;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceFormatProperties2")) return vkGetPhysicalDeviceFormatProperties2;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceImageFormatProperties2")) return vkGetPhysicalDeviceImageFormatProperties2;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceQueueFamilyProperties2")) return vkGetPhysicalDeviceQueueFamilyProperties2;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties2")) return vkGetPhysicalDeviceMemoryProperties2;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceSparseImageFormatProperties2"))
+ return vkGetPhysicalDeviceSparseImageFormatProperties2;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceExternalBufferProperties")) return vkGetPhysicalDeviceExternalBufferProperties;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceExternalSemaphoreProperties")) return vkGetPhysicalDeviceExternalSemaphoreProperties;
+ if (!strcmp(funcName, "vkGetPhysicalDeviceExternalFenceProperties")) return vkGetPhysicalDeviceExternalFenceProperties;
+ if (!strcmp(funcName, "vkBindBufferMemory2")) return vkBindBufferMemory2;
+ if (!strcmp(funcName, "vkBindImageMemory2")) return vkBindImageMemory2;
+ if (!strcmp(funcName, "vkGetDeviceGroupPeerMemoryFeatures")) return vkGetDeviceGroupPeerMemoryFeatures;
+ if (!strcmp(funcName, "vkCmdSetDeviceMask")) return vkCmdSetDeviceMask;
+ if (!strcmp(funcName, "vkCmdDispatchBase")) return vkCmdDispatchBase;
+ if (!strcmp(funcName, "vkGetImageMemoryRequirements2")) return vkGetImageMemoryRequirements2;
+ if (!strcmp(funcName, "vkTrimCommandPool")) return vkTrimCommandPool;
+ if (!strcmp(funcName, "vkGetDeviceQueue2")) return vkGetDeviceQueue2;
+ if (!strcmp(funcName, "vkCreateSamplerYcbcrConversion")) return vkCreateSamplerYcbcrConversion;
+ if (!strcmp(funcName, "vkDestroySamplerYcbcrConversion")) return vkDestroySamplerYcbcrConversion;
+ if (!strcmp(funcName, "vkGetDescriptorSetLayoutSupport")) return vkGetDescriptorSetLayoutSupport;
+ if (!strcmp(funcName, "vkCreateDescriptorUpdateTemplate")) return vkCreateDescriptorUpdateTemplate;
+ if (!strcmp(funcName, "vkDestroyDescriptorUpdateTemplate")) return vkDestroyDescriptorUpdateTemplate;
+ if (!strcmp(funcName, "vkUpdateDescriptorSetWithTemplate")) return vkUpdateDescriptorSetWithTemplate;
+ if (!strcmp(funcName, "vkGetImageSparseMemoryRequirements2")) return vkGetImageSparseMemoryRequirements2;
+ if (!strcmp(funcName, "vkGetBufferMemoryRequirements2")) return vkGetBufferMemoryRequirements2;
+
+ // Instance extensions
+ void *addr;
+ if (debug_utils_InstanceGpa(inst, funcName, &addr)) return addr;
+
+ if (wsi_swapchain_instance_gpa(inst, funcName, &addr)) return addr;
+
+ if (extension_instance_gpa(inst, funcName, &addr)) return addr;
+
+ // Unknown physical device extensions
+ if (loader_phys_dev_ext_gpa(inst, funcName, true, &addr, NULL)) return addr;
+
+ // Unknown device extensions
+ addr = loader_dev_ext_gpa(inst, funcName);
+ return addr;
+}
+
+static inline void *globalGetProcAddr(const char *name) {
+ if (!name || name[0] != 'v' || name[1] != 'k') return NULL;
+
+ name += 2;
+ if (!strcmp(name, "CreateInstance")) return vkCreateInstance;
+ if (!strcmp(name, "EnumerateInstanceExtensionProperties")) return vkEnumerateInstanceExtensionProperties;
+ if (!strcmp(name, "EnumerateInstanceLayerProperties")) return vkEnumerateInstanceLayerProperties;
+ if (!strcmp(name, "EnumerateInstanceVersion")) return vkEnumerateInstanceVersion;
+
+ return NULL;
+}
+
+static inline void *loader_non_passthrough_gdpa(const char *name) {
+ if (!name || name[0] != 'v' || name[1] != 'k') return NULL;
+
+ name += 2;
+
+ if (!strcmp(name, "GetDeviceProcAddr")) return vkGetDeviceProcAddr;
+ if (!strcmp(name, "DestroyDevice")) return vkDestroyDevice;
+ if (!strcmp(name, "GetDeviceQueue")) return vkGetDeviceQueue;
+ if (!strcmp(name, "GetDeviceQueue2")) return vkGetDeviceQueue2;
+ if (!strcmp(name, "AllocateCommandBuffers")) return vkAllocateCommandBuffers;
+
+ return NULL;
+}
diff --git a/thirdparty/vulkan/loader/loader.c b/thirdparty/vulkan/loader/loader.c
new file mode 100644
index 0000000000..398c44bf9c
--- /dev/null
+++ b/thirdparty/vulkan/loader/loader.c
@@ -0,0 +1,8139 @@
+/*
+ *
+ * Copyright (c) 2014-2019 The Khronos Group Inc.
+ * Copyright (c) 2014-2019 Valve Corporation
+ * Copyright (c) 2014-2019 LunarG, Inc.
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ *
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Mark Young <marky@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ *
+ */
+
+// This needs to be defined first, or else we'll get redefinitions on NTSTATUS values
+#ifdef _WIN32
+#define UMDF_USING_NTSTATUS
+#include <ntstatus.h>
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stddef.h>
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CoreFoundation.h>
+#include <sys/param.h>
+#endif
+
+// Time related functions
+#include <time.h>
+
+#include <sys/types.h>
+#if defined(_WIN32)
+#include "dirent_on_windows.h"
+#else // _WIN32
+#include <dirent.h>
+#endif // _WIN32
+#include "vk_loader_platform.h"
+#include "loader.h"
+#include "gpa_helper.h"
+#include "debug_utils.h"
+#include "wsi.h"
+#include "vulkan/vk_icd.h"
+#include "cJSON.h"
+#include "murmurhash.h"
+
+#if defined(_WIN32)
+#include <cfgmgr32.h>
+#include <initguid.h>
+#include <devpkey.h>
+#include <winternl.h>
+#include "adapters.h"
+#include "dxgi_loader.h"
+#endif
+
+// This is a CMake generated file with #defines for any functions/includes
+// that it found present. This is currently necessary to properly determine
+// if secure_getenv or __secure_getenv are present
+#if !defined(VULKAN_NON_CMAKE_BUILD)
+#include "loader_cmake_config.h"
+#endif // !defined(VULKAN_NON_CMAKE_BUILD)
+
+// Generated file containing all the extension data
+#include "vk_loader_extensions.c"
+
+// Override layer information
+#define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override"
+
+struct loader_struct loader = {0};
+// TLS for instance for alloc/free callbacks
+THREAD_LOCAL_DECL struct loader_instance *tls_instance;
+
+static size_t loader_platform_combine_path(char *dest, size_t len, ...);
+
+struct loader_phys_dev_per_icd {
+ uint32_t count;
+ VkPhysicalDevice *phys_devs;
+ struct loader_icd_term *this_icd_term;
+};
+
+enum loader_debug {
+ LOADER_INFO_BIT = 0x01,
+ LOADER_WARN_BIT = 0x02,
+ LOADER_PERF_BIT = 0x04,
+ LOADER_ERROR_BIT = 0x08,
+ LOADER_DEBUG_BIT = 0x10,
+};
+
+uint32_t g_loader_debug = 0;
+uint32_t g_loader_log_msgs = 0;
+
+enum loader_data_files_type {
+ LOADER_DATA_FILE_MANIFEST_ICD = 0,
+ LOADER_DATA_FILE_MANIFEST_LAYER,
+ LOADER_DATA_FILE_NUM_TYPES // Not a real field, used for possible loop terminator
+};
+
+// thread safety lock for accessing global data structures such as "loader"
+// all entrypoints on the instance chain need to be locked except GPA
+// additionally CreateDevice and DestroyDevice needs to be locked
+loader_platform_thread_mutex loader_lock;
+loader_platform_thread_mutex loader_json_lock;
+
+LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_init);
+
+// This loader supports Vulkan API version 1.1
+uint32_t loader_major_version = 1;
+uint32_t loader_minor_version = 1;
+
+void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope alloc_scope) {
+ void *pMemory = NULL;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (instance && instance->alloc_callbacks.pfnAllocation) {
+ // These are internal structures, so it's best to align everything to
+ // the largest unit size which is the size of a uint64_t.
+ pMemory = instance->alloc_callbacks.pfnAllocation(instance->alloc_callbacks.pUserData, size, sizeof(uint64_t), alloc_scope);
+ } else {
+#endif
+ pMemory = malloc(size);
+ }
+
+ return pMemory;
+}
+
+void loader_instance_heap_free(const struct loader_instance *instance, void *pMemory) {
+ if (pMemory != NULL) {
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (instance && instance->alloc_callbacks.pfnFree) {
+ instance->alloc_callbacks.pfnFree(instance->alloc_callbacks.pUserData, pMemory);
+ } else {
+#endif
+ free(pMemory);
+ }
+ }
+}
+
+void *loader_instance_heap_realloc(const struct loader_instance *instance, void *pMemory, size_t orig_size, size_t size,
+ VkSystemAllocationScope alloc_scope) {
+ void *pNewMem = NULL;
+ if (pMemory == NULL || orig_size == 0) {
+ pNewMem = loader_instance_heap_alloc(instance, size, alloc_scope);
+ } else if (size == 0) {
+ loader_instance_heap_free(instance, pMemory);
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+#else
+ } else if (instance && instance->alloc_callbacks.pfnReallocation) {
+ // These are internal structures, so it's best to align everything to
+ // the largest unit size which is the size of a uint64_t.
+ pNewMem = instance->alloc_callbacks.pfnReallocation(instance->alloc_callbacks.pUserData, pMemory, size, sizeof(uint64_t),
+ alloc_scope);
+#endif
+ } else {
+ pNewMem = realloc(pMemory, size);
+ }
+ return pNewMem;
+}
+
+void *loader_instance_tls_heap_alloc(size_t size) {
+ return loader_instance_heap_alloc(tls_instance, size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+}
+
+void loader_instance_tls_heap_free(void *pMemory) { loader_instance_heap_free(tls_instance, pMemory); }
+
+void *loader_device_heap_alloc(const struct loader_device *device, size_t size, VkSystemAllocationScope alloc_scope) {
+ void *pMemory = NULL;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (device && device->alloc_callbacks.pfnAllocation) {
+ // These are internal structures, so it's best to align everything to
+ // the largest unit size which is the size of a uint64_t.
+ pMemory = device->alloc_callbacks.pfnAllocation(device->alloc_callbacks.pUserData, size, sizeof(uint64_t), alloc_scope);
+ } else {
+#endif
+ pMemory = malloc(size);
+ }
+ return pMemory;
+}
+
+void loader_device_heap_free(const struct loader_device *device, void *pMemory) {
+ if (pMemory != NULL) {
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (device && device->alloc_callbacks.pfnFree) {
+ device->alloc_callbacks.pfnFree(device->alloc_callbacks.pUserData, pMemory);
+ } else {
+#endif
+ free(pMemory);
+ }
+ }
+}
+
+void *loader_device_heap_realloc(const struct loader_device *device, void *pMemory, size_t orig_size, size_t size,
+ VkSystemAllocationScope alloc_scope) {
+ void *pNewMem = NULL;
+ if (pMemory == NULL || orig_size == 0) {
+ pNewMem = loader_device_heap_alloc(device, size, alloc_scope);
+ } else if (size == 0) {
+ loader_device_heap_free(device, pMemory);
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+#else
+ } else if (device && device->alloc_callbacks.pfnReallocation) {
+ // These are internal structures, so it's best to align everything to
+ // the largest unit size which is the size of a uint64_t.
+ pNewMem = device->alloc_callbacks.pfnReallocation(device->alloc_callbacks.pUserData, pMemory, size, sizeof(uint64_t),
+ alloc_scope);
+#endif
+ } else {
+ pNewMem = realloc(pMemory, size);
+ }
+ return pNewMem;
+}
+
+// Environment variables
+#if defined(__linux__) || defined(__APPLE__)
+
+static inline bool IsHighIntegrity() {
+ return geteuid() != getuid() || getegid() != getgid();
+}
+
+static inline char *loader_getenv(const char *name, const struct loader_instance *inst) {
+ // No allocation of memory necessary for Linux, but we should at least touch
+ // the inst pointer to get rid of compiler warnings.
+ (void)inst;
+ return getenv(name);
+}
+
+static inline char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
+#if defined(__APPLE__)
+ // Apple does not appear to have a secure getenv implementation.
+ // The main difference between secure getenv and getenv is that secure getenv
+ // returns NULL if the process is being run with elevated privileges by a normal user.
+ // The idea is to prevent the reading of malicious environment variables by a process
+ // that can do damage.
+ // This algorithm is derived from glibc code that sets an internal
+ // variable (__libc_enable_secure) if the process is running under setuid or setgid.
+ return IsHighIntegrity() ? NULL : loader_getenv(name, inst);
+#else
+// Linux
+#ifdef HAVE_SECURE_GETENV
+ (void)inst;
+ return secure_getenv(name);
+#elif defined(HAVE___SECURE_GETENV)
+ (void)inst;
+ return __secure_getenv(name);
+#else
+#pragma message( \
+ "Warning: Falling back to non-secure getenv for environmental lookups! Consider" \
+ " updating to a different libc.")
+ return loader_getenv(name, inst);
+#endif
+#endif
+}
+
+static inline void loader_free_getenv(char *val, const struct loader_instance *inst) {
+ // No freeing of memory necessary for Linux, but we should at least touch
+ // the val and inst pointers to get rid of compiler warnings.
+ (void)val;
+ (void)inst;
+}
+
+#elif defined(WIN32)
+
+static inline bool IsHighIntegrity() {
+ HANDLE process_token;
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
+ // Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
+ uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
+ DWORD buffer_size;
+ if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
+ &buffer_size) != 0) {
+ const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
+ const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
+ const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);
+
+ CloseHandle(process_token);
+ return integrity_level > SECURITY_MANDATORY_MEDIUM_RID;
+ }
+
+ CloseHandle(process_token);
+ }
+
+ return false;
+}
+
+static inline char *loader_getenv(const char *name, const struct loader_instance *inst) {
+ char *retVal;
+ DWORD valSize;
+
+ valSize = GetEnvironmentVariableA(name, NULL, 0);
+
+ // valSize DOES include the null terminator, so for any set variable
+ // will always be at least 1. If it's 0, the variable wasn't set.
+ if (valSize == 0) return NULL;
+
+ // Allocate the space necessary for the registry entry
+ if (NULL != inst && NULL != inst->alloc_callbacks.pfnAllocation) {
+ retVal = (char *)inst->alloc_callbacks.pfnAllocation(inst->alloc_callbacks.pUserData, valSize, sizeof(char *),
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ } else {
+ retVal = (char *)malloc(valSize);
+ }
+
+ if (NULL != retVal) {
+ GetEnvironmentVariableA(name, retVal, valSize);
+ }
+
+ return retVal;
+}
+
+static inline char *loader_secure_getenv(const char *name, const struct loader_instance *inst) {
+ if (IsHighIntegrity()) {
+ return NULL;
+ }
+
+ return loader_getenv(name, inst);
+}
+
+static inline void loader_free_getenv(char *val, const struct loader_instance *inst) {
+ if (NULL != inst && NULL != inst->alloc_callbacks.pfnFree) {
+ inst->alloc_callbacks.pfnFree(inst->alloc_callbacks.pUserData, val);
+ } else {
+ free((void *)val);
+ }
+}
+
+#else
+
+static inline char *loader_getenv(const char *name, const struct loader_instance *inst) {
+ // stub func
+ (void)inst;
+ (void)name;
+ return NULL;
+}
+static inline void loader_free_getenv(char *val, const struct loader_instance *inst) {
+ // stub func
+ (void)val;
+ (void)inst;
+}
+
+#endif
+
+void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code, const char *format, ...) {
+ char msg[512];
+ char cmd_line_msg[512];
+ size_t cmd_line_size = sizeof(cmd_line_msg);
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = vsnprintf(msg, sizeof(msg), format, ap);
+ if ((ret >= (int)sizeof(msg)) || ret < 0) {
+ msg[sizeof(msg) - 1] = '\0';
+ }
+ va_end(ap);
+
+ if (inst) {
+ VkDebugUtilsMessageSeverityFlagBitsEXT severity = 0;
+ VkDebugUtilsMessageTypeFlagsEXT type;
+ VkDebugUtilsMessengerCallbackDataEXT callback_data;
+ VkDebugUtilsObjectNameInfoEXT object_name;
+
+ if ((msg_type & LOADER_INFO_BIT) != 0) {
+ severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
+ } else if ((msg_type & LOADER_WARN_BIT) != 0) {
+ severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
+ } else if ((msg_type & LOADER_ERROR_BIT) != 0) {
+ severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+ } else if ((msg_type & LOADER_DEBUG_BIT) != 0) {
+ severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
+ }
+
+ if ((msg_type & LOADER_PERF_BIT) != 0) {
+ type = VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+ } else {
+ type = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
+ }
+
+ callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
+ callback_data.pNext = NULL;
+ callback_data.flags = 0;
+ callback_data.pMessageIdName = "Loader Message";
+ callback_data.messageIdNumber = 0;
+ callback_data.pMessage = msg;
+ callback_data.queueLabelCount = 0;
+ callback_data.pQueueLabels = NULL;
+ callback_data.cmdBufLabelCount = 0;
+ callback_data.pCmdBufLabels = NULL;
+ callback_data.objectCount = 1;
+ callback_data.pObjects = &object_name;
+ object_name.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+ object_name.pNext = NULL;
+ object_name.objectType = VK_OBJECT_TYPE_INSTANCE;
+ object_name.objectHandle = (uint64_t)(uintptr_t)inst;
+ object_name.pObjectName = NULL;
+
+ util_SubmitDebugUtilsMessageEXT(inst, severity, type, &callback_data);
+ }
+
+ if (!(msg_type & g_loader_log_msgs)) {
+ return;
+ }
+
+ cmd_line_msg[0] = '\0';
+ cmd_line_size -= 1;
+ size_t original_size = cmd_line_size;
+
+ if ((msg_type & LOADER_INFO_BIT) != 0) {
+ strncat(cmd_line_msg, "INFO", cmd_line_size);
+ cmd_line_size -= 4;
+ }
+ if ((msg_type & LOADER_WARN_BIT) != 0) {
+ if (cmd_line_size != original_size) {
+ strncat(cmd_line_msg, " | ", cmd_line_size);
+ cmd_line_size -= 3;
+ }
+ strncat(cmd_line_msg, "WARNING", cmd_line_size);
+ cmd_line_size -= 7;
+ }
+ if ((msg_type & LOADER_PERF_BIT) != 0) {
+ if (cmd_line_size != original_size) {
+ strncat(cmd_line_msg, " | ", cmd_line_size);
+ cmd_line_size -= 3;
+ }
+ strncat(cmd_line_msg, "PERF", cmd_line_size);
+ cmd_line_size -= 4;
+ }
+ if ((msg_type & LOADER_ERROR_BIT) != 0) {
+ if (cmd_line_size != original_size) {
+ strncat(cmd_line_msg, " | ", cmd_line_size);
+ cmd_line_size -= 3;
+ }
+ strncat(cmd_line_msg, "ERROR", cmd_line_size);
+ cmd_line_size -= 5;
+ }
+ if ((msg_type & LOADER_DEBUG_BIT) != 0) {
+ if (cmd_line_size != original_size) {
+ strncat(cmd_line_msg, " | ", cmd_line_size);
+ cmd_line_size -= 3;
+ }
+ strncat(cmd_line_msg, "DEBUG", cmd_line_size);
+ cmd_line_size -= 5;
+ }
+ if (cmd_line_size != original_size) {
+ strncat(cmd_line_msg, ": ", cmd_line_size);
+ cmd_line_size -= 2;
+ }
+
+ if (0 < cmd_line_size) {
+ // If the message is too long, trim it down
+ if (strlen(msg) > cmd_line_size) {
+ msg[cmd_line_size - 1] = '\0';
+ }
+ strncat(cmd_line_msg, msg, cmd_line_size);
+ } else {
+ // Shouldn't get here, but check to make sure if we've already overrun
+ // the string boundary
+ assert(false);
+ }
+
+#if defined(WIN32)
+ OutputDebugString(cmd_line_msg);
+ OutputDebugString("\n");
+#endif
+
+ fputs(cmd_line_msg, stderr);
+ fputc('\n', stderr);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetInstanceDispatch(VkInstance instance, void *object) {
+ struct loader_instance *inst = loader_get_instance(instance);
+ if (!inst) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkSetInstanceDispatch: Can not retrieve Instance "
+ "dispatch table.");
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ loader_set_dispatch(object, inst->disp);
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetDeviceDispatch(VkDevice device, void *object) {
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, NULL);
+
+ if (NULL == icd_term) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ loader_set_dispatch(object, &dev->loader_dispatch);
+ return VK_SUCCESS;
+}
+
+#if defined(_WIN32)
+
+// Append the JSON path data to the list and allocate/grow the list if it's not large enough.
+// Function returns true if filename was appended to reg_data list.
+// Caller should free reg_data.
+static bool loaderAddJsonEntry(const struct loader_instance *inst,
+ char **reg_data, // list of JSON files
+ PDWORD total_size, // size of reg_data
+ LPCSTR key_name, // key name - used for debug prints - i.e. VulkanDriverName
+ DWORD key_type, // key data type
+ LPSTR json_path, // JSON string to add to the list reg_data
+ DWORD json_size, // size in bytes of json_path
+ VkResult *result) {
+ // Check for and ignore duplicates.
+ if (*reg_data && strstr(*reg_data, json_path)) {
+ // Success. The json_path is already in the list.
+ return true;
+ }
+
+ if (NULL == *reg_data) {
+ *reg_data = loader_instance_heap_alloc(inst, *total_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == *reg_data) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderAddJsonEntry: Failed to allocate space for registry data for key %s", json_path);
+ *result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ return false;
+ }
+ *reg_data[0] = '\0';
+ } else if (strlen(*reg_data) + json_size + 1 > *total_size) {
+ void *new_ptr =
+ loader_instance_heap_realloc(inst, *reg_data, *total_size, *total_size * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_ptr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderAddJsonEntry: Failed to reallocate space for registry value of size %d for key %s", *total_size * 2,
+ json_path);
+ *result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ return false;
+ }
+ *reg_data = new_ptr;
+ *total_size *= 2;
+ }
+
+ for (char *curr_filename = json_path; curr_filename[0] != '\0'; curr_filename += strlen(curr_filename) + 1) {
+ if (strlen(*reg_data) == 0) {
+ (void)snprintf(*reg_data, json_size + 1, "%s", curr_filename);
+ } else {
+ (void)snprintf(*reg_data + strlen(*reg_data), json_size + 2, "%c%s", PATH_SEPARATOR, curr_filename);
+ }
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "%s: Located json file \"%s\" from PnP registry: %s", __FUNCTION__,
+ curr_filename, key_name);
+
+ if (key_type == REG_SZ) {
+ break;
+ }
+ }
+ return true;
+}
+
+// Find the list of registry files (names VulkanDriverName/VulkanDriverNameWow) in hkr.
+//
+// This function looks for filename in given device handle, filename is then added to return list
+// function return true if filename was appended to reg_data list
+// If error occures result is updated with failure reason
+bool loaderGetDeviceRegistryEntry(const struct loader_instance *inst, char **reg_data, PDWORD total_size, DEVINST dev_id,
+ LPCSTR value_name, VkResult *result) {
+ HKEY hkrKey = INVALID_HANDLE_VALUE;
+ DWORD requiredSize, data_type;
+ char *manifest_path = NULL;
+ bool found = false;
+
+ if (NULL == total_size || NULL == reg_data) {
+ *result = VK_ERROR_INITIALIZATION_FAILED;
+ return false;
+ }
+
+ CONFIGRET status = CM_Open_DevNode_Key(dev_id, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &hkrKey, CM_REGISTRY_SOFTWARE);
+ if (status != CR_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderGetDeviceRegistryEntry: Failed to open registry key for DeviceID(%d)", dev_id);
+ *result = VK_ERROR_INITIALIZATION_FAILED;
+ return false;
+ }
+
+ // query value
+ LSTATUS ret = RegQueryValueEx(
+ hkrKey,
+ value_name,
+ NULL,
+ NULL,
+ NULL,
+ &requiredSize);
+
+ if (ret != ERROR_SUCCESS) {
+ if (ret == ERROR_FILE_NOT_FOUND) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "loaderGetDeviceRegistryEntry: Device ID(%d) Does not contain a value for \"%s\"", dev_id, value_name);
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "loaderGetDeviceRegistryEntry: DeviceID(%d) Failed to obtain %s size", dev_id, value_name);
+ }
+ goto out;
+ }
+
+ manifest_path = loader_instance_heap_alloc(inst, requiredSize, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (manifest_path == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetDeviceRegistryEntry: Failed to allocate space for DriverName.");
+ *result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ ret = RegQueryValueEx(
+ hkrKey,
+ value_name,
+ NULL,
+ &data_type,
+ (BYTE *)manifest_path,
+ &requiredSize
+ );
+
+ if (ret != ERROR_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetDeviceRegistryEntry: DeviceID(%d) Failed to obtain %s", value_name);
+
+ *result = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ if (data_type != REG_SZ && data_type != REG_MULTI_SZ) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetDeviceRegistryEntry: Invalid %s data type. Expected REG_SZ or REG_MULTI_SZ.", value_name);
+ *result = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ found = loaderAddJsonEntry(inst, reg_data, total_size, value_name, data_type, manifest_path, requiredSize, result);
+
+out:
+ if (manifest_path != NULL) {
+ loader_instance_heap_free(inst, manifest_path);
+ }
+ RegCloseKey(hkrKey);
+ return found;
+}
+
+// Find the list of registry files (names VulkanDriverName/VulkanDriverNameWow) in hkr .
+//
+// This function looks for display devices and childish software components
+// for a list of files which are added to a returned list (function return
+// value).
+// Function return is a string with a ';' separated list of filenames.
+// Function return is NULL if no valid name/value pairs are found in the key,
+// or the key is not found.
+//
+// *reg_data contains a string list of filenames as pointer.
+// When done using the returned string list, the caller should free the pointer.
+VkResult loaderGetDeviceRegistryFiles(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size,
+ LPCSTR value_name) {
+ static const wchar_t *softwareComponentGUID = L"{5c4c3332-344d-483c-8739-259e934c9cc8}";
+ static const wchar_t *displayGUID = L"{4d36e968-e325-11ce-bfc1-08002be10318}";
+ const ULONG flags = CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT;
+
+ wchar_t childGuid[MAX_GUID_STRING_LEN + 2]; // +2 for brackets {}
+ ULONG childGuidSize = sizeof(childGuid);
+
+ DEVINST devID = 0, childID = 0;
+ wchar_t *pDeviceNames = NULL;
+ ULONG deviceNamesSize = 0;
+ VkResult result = VK_SUCCESS;
+ bool found = false;
+
+ if (NULL == reg_data) {
+ result = VK_ERROR_INITIALIZATION_FAILED;
+ return result;
+ }
+
+ // if after obtaining the DeviceNameSize, new device is added start over
+ do {
+ CM_Get_Device_ID_List_SizeW(&deviceNamesSize, displayGUID, flags);
+
+ if (pDeviceNames != NULL) {
+ loader_instance_heap_free(inst, pDeviceNames);
+ }
+
+ pDeviceNames = loader_instance_heap_alloc(inst, deviceNamesSize * sizeof(wchar_t), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (pDeviceNames == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetDeviceRegistryFiles: Failed to allocate space for display device names.");
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ return result;
+ }
+ } while (CM_Get_Device_ID_ListW(displayGUID, pDeviceNames, deviceNamesSize, flags) == CR_BUFFER_SMALL);
+
+ if (pDeviceNames) {
+ for (wchar_t *deviceName = pDeviceNames; *deviceName; deviceName += wcslen(deviceName) + 1) {
+ CONFIGRET status = CM_Locate_DevNodeW(&devID, deviceName, CM_LOCATE_DEVNODE_NORMAL);
+ if (CR_SUCCESS != status) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: failed to open DevNode %ls",
+ deviceName);
+ continue;
+ }
+ ULONG ulStatus, ulProblem;
+ status = CM_Get_DevNode_Status(&ulStatus, &ulProblem, devID, 0);
+
+ if (CR_SUCCESS != status)
+ {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: failed to probe device status %ls",
+ deviceName);
+ continue;
+ }
+ if ((ulStatus & DN_HAS_PROBLEM) && (ulProblem == CM_PROB_NEED_RESTART || ulProblem == DN_NEED_RESTART)) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "loaderGetDeviceRegistryFiles: device %ls is pending reboot, skipping ...", deviceName);
+ continue;
+ }
+
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "loaderGetDeviceRegistryFiles: opening device %ls", deviceName);
+
+ if (loaderGetDeviceRegistryEntry(inst, reg_data, reg_data_size, devID, value_name, &result)) {
+ found = true;
+ continue;
+ }
+ else if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
+ break;
+ }
+
+ status = CM_Get_Child(&childID, devID, 0);
+ if (status != CR_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "loaderGetDeviceRegistryFiles: unable to open child-device error:%d", status);
+ continue;
+ }
+
+ do {
+ wchar_t buffer[MAX_DEVICE_ID_LEN];
+ CM_Get_Device_IDW(childID, buffer, MAX_DEVICE_ID_LEN, 0);
+
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "loaderGetDeviceRegistryFiles: Opening child device %d - %ls", childID, buffer);
+
+ status = CM_Get_DevNode_Registry_PropertyW(childID, CM_DRP_CLASSGUID, NULL, &childGuid, &childGuidSize, 0);
+ if (status != CR_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetDeviceRegistryFiles: unable to obtain GUID for:%d error:%d", childID, status);
+
+ result = VK_ERROR_INITIALIZATION_FAILED;
+ continue;
+ }
+
+ if (wcscmp(childGuid, softwareComponentGUID) != 0) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "loaderGetDeviceRegistryFiles: GUID for %d is not SoftwareComponent skipping", childID);
+ continue;
+ }
+
+ if (loaderGetDeviceRegistryEntry(inst, reg_data, reg_data_size, childID, value_name, &result)) {
+ found = true;
+ break; // check next-display-device
+ }
+
+ } while (CM_Get_Sibling(&childID, childID, 0) == CR_SUCCESS);
+ }
+
+ loader_instance_heap_free(inst, pDeviceNames);
+ }
+
+ if (!found && result != VK_ERROR_OUT_OF_HOST_MEMORY) {
+ result = VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ return result;
+}
+
+static char *loader_get_next_path(char *path);
+
+// Find the list of registry files (names within a key) in key "location".
+//
+// This function looks in the registry (hive = DEFAULT_VK_REGISTRY_HIVE) key as
+// given in "location"
+// for a list or name/values which are added to a returned list (function return
+// value).
+// The DWORD values within the key must be 0 or they are skipped.
+// Function return is a string with a ';' separated list of filenames.
+// Function return is NULL if no valid name/value pairs are found in the key,
+// or the key is not found.
+//
+// *reg_data contains a string list of filenames as pointer.
+// When done using the returned string list, the caller should free the pointer.
+VkResult loaderGetRegistryFiles(const struct loader_instance *inst, char *location, bool use_secondary_hive, char **reg_data,
+ PDWORD reg_data_size) {
+ // This list contains all of the allowed ICDs. This allows us to verify that a device is actually present from the vendor
+ // specified. This does disallow other vendors, but any new driver should use the device-specific registries anyway.
+ static const struct {
+ const char *filename;
+ int vendor_id;
+ } known_drivers[] = {
+#if defined(_WIN64)
+ {
+ .filename = "igvk64.json",
+ .vendor_id = 0x8086,
+ },
+ {
+ .filename = "nv-vk64.json",
+ .vendor_id = 0x10de,
+ },
+ {
+ .filename = "amd-vulkan64.json",
+ .vendor_id = 0x1002,
+ },
+ {
+ .filename = "amdvlk64.json",
+ .vendor_id = 0x1002,
+ },
+#else
+ {
+ .filename = "igvk32.json",
+ .vendor_id = 0x8086,
+ },
+ {
+ .filename = "nv-vk32.json",
+ .vendor_id = 0x10de,
+ },
+ {
+ .filename = "amd-vulkan32.json",
+ .vendor_id = 0x1002,
+ },
+ {
+ .filename = "amdvlk32.json",
+ .vendor_id = 0x1002,
+ },
+#endif
+ };
+
+ LONG rtn_value;
+ HKEY hive = DEFAULT_VK_REGISTRY_HIVE, key;
+ DWORD access_flags;
+ char name[2048];
+ char *loc = location;
+ char *next;
+ DWORD idx;
+ DWORD name_size = sizeof(name);
+ DWORD value;
+ DWORD value_size = sizeof(value);
+ VkResult result = VK_SUCCESS;
+ bool found = false;
+ IDXGIFactory1 *dxgi_factory = NULL;
+ bool is_driver = !strcmp(location, VK_DRIVERS_INFO_REGISTRY_LOC);
+
+ if (NULL == reg_data) {
+ result = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ if (is_driver) {
+ HRESULT hres = dyn_CreateDXGIFactory1(&IID_IDXGIFactory1, &dxgi_factory);
+ if (hres != S_OK) {
+ loader_log(
+ inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderGetRegistryFiles: Failed to create dxgi factory for ICD registry verification. No ICDs will be added from "
+ "legacy registry locations");
+ goto out;
+ }
+ }
+
+ while (*loc) {
+ next = loader_get_next_path(loc);
+ access_flags = KEY_QUERY_VALUE;
+ rtn_value = RegOpenKeyEx(hive, loc, 0, access_flags, &key);
+ if (ERROR_SUCCESS == rtn_value) {
+ idx = 0;
+ while ((rtn_value = RegEnumValue(key, idx++, name, &name_size, NULL, NULL, (LPBYTE)&value, &value_size)) ==
+ ERROR_SUCCESS) {
+ if (value_size == sizeof(value) && value == 0) {
+ if (NULL == *reg_data) {
+ *reg_data = loader_instance_heap_alloc(inst, *reg_data_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == *reg_data) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetRegistryFiles: Failed to allocate space for registry data for key %s", name);
+ RegCloseKey(key);
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ *reg_data[0] = '\0';
+ } else if (strlen(*reg_data) + name_size + 1 > *reg_data_size) {
+ void *new_ptr = loader_instance_heap_realloc(inst, *reg_data, *reg_data_size, *reg_data_size * 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_ptr) {
+ loader_log(
+ inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetRegistryFiles: Failed to reallocate space for registry value of size %d for key %s",
+ *reg_data_size * 2, name);
+ RegCloseKey(key);
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ *reg_data = new_ptr;
+ *reg_data_size *= 2;
+ }
+
+ // We've now found a json file. If this is an ICD, we still need to check if there is actually a device
+ // that matches this ICD
+ loader_log(
+ inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Located json file \"%s\" from registry \"%s\\%s\"", name,
+ hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR, location);
+ if (is_driver) {
+ int i;
+ for (i = 0; i < sizeof(known_drivers) / sizeof(known_drivers[0]); ++i) {
+ if (!strcmp(name + strlen(name) - strlen(known_drivers[i].filename), known_drivers[i].filename)) {
+ break;
+ }
+ }
+ if (i == sizeof(known_drivers) / sizeof(known_drivers[0])) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "Driver %s is not recognized as a known driver. It will be assumed to be active", name);
+ } else {
+ bool found_gpu = false;
+ for (int j = 0;; ++j) {
+ IDXGIAdapter1 *adapter;
+ HRESULT hres = dxgi_factory->lpVtbl->EnumAdapters1(dxgi_factory, j, &adapter);
+ if (hres == DXGI_ERROR_NOT_FOUND) {
+ break;
+ } else if (hres != S_OK) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Failed to enumerate DXGI adapters at index %d. As a result, drivers may be skipped", j);
+ continue;
+ }
+
+ DXGI_ADAPTER_DESC1 description;
+ hres = adapter->lpVtbl->GetDesc1(adapter, &description);
+ if (hres != S_OK) {
+ loader_log(
+ inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "Failed to get DXGI adapter information at index %d. As a result, drivers may be skipped", j);
+ continue;
+ }
+
+ if (description.VendorId == known_drivers[i].vendor_id) {
+ found_gpu = true;
+ break;
+ }
+ }
+
+ if (!found_gpu) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "Dropping driver %s as no corresponduing DXGI adapter was found", name);
+ continue;
+ }
+ }
+ }
+
+ if (strlen(*reg_data) == 0) {
+ // The list is emtpy. Add the first entry.
+ (void)snprintf(*reg_data, name_size + 1, "%s", name);
+ found = true;
+ } else {
+ // At this point the reg_data variable contains other JSON paths, likely from the PNP/device section
+ // of the registry that we want to have precendence over this non-device specific section of the registry.
+ // To make sure we avoid enumerating old JSON files/drivers that might be present in the non-device specific
+ // area of the registry when a newer device specific JSON file is present, do a check before adding.
+ // Find the file name, without path, of the JSON file found in the non-device specific registry location.
+ // If the same JSON file name is already found in the list, don't add it again.
+ bool foundDuplicate = false;
+ char *pLastSlashName = strrchr(name, '\\');
+ if (pLastSlashName != NULL) {
+ char *foundMatch = strstr(*reg_data, pLastSlashName + 1);
+ if (foundMatch != NULL) {
+ foundDuplicate = true;
+ }
+ }
+
+ if (foundDuplicate == false) {
+ // Add the new entry to the list.
+ (void)snprintf(*reg_data + strlen(*reg_data), name_size + 2, "%c%s", PATH_SEPARATOR, name);
+ found = true;
+ } else {
+ loader_log(
+ inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "Skipping adding of json file \"%s\" from registry \"%s\\%s\" to the list due to duplication", name,
+ hive == DEFAULT_VK_REGISTRY_HIVE ? DEFAULT_VK_REGISTRY_HIVE_STR : SECONDARY_VK_REGISTRY_HIVE_STR,
+ location);
+ }
+ }
+ }
+ name_size = sizeof(name);
+ value_size = sizeof(value);
+ }
+ RegCloseKey(key);
+ }
+
+ // Advance the location - if the next location is in the secondary hive, then reset the locations and advance the hive
+ if (use_secondary_hive && (hive == DEFAULT_VK_REGISTRY_HIVE) && (*next == '\0')) {
+ loc = location;
+ hive = SECONDARY_VK_REGISTRY_HIVE;
+ } else {
+ loc = next;
+ }
+ }
+
+ if (!found && result != VK_ERROR_OUT_OF_HOST_MEMORY) {
+ result = VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+out:
+ if (is_driver && dxgi_factory != NULL) {
+ dxgi_factory->lpVtbl->Release(dxgi_factory);
+ }
+
+ return result;
+}
+
+#endif // WIN32
+
+// Combine path elements, separating each element with the platform-specific
+// directory separator, and save the combined string to a destination buffer,
+// not exceeding the given length. Path elements are given as variable args,
+// with a NULL element terminating the list.
+//
+// \returns the total length of the combined string, not including an ASCII
+// NUL termination character. This length may exceed the available storage:
+// in this case, the written string will be truncated to avoid a buffer
+// overrun, and the return value will greater than or equal to the storage
+// size. A NULL argument may be provided as the destination buffer in order
+// to determine the required string length without actually writing a string.
+static size_t loader_platform_combine_path(char *dest, size_t len, ...) {
+ size_t required_len = 0;
+ va_list ap;
+ const char *component;
+
+ va_start(ap, len);
+
+ while ((component = va_arg(ap, const char *))) {
+ if (required_len > 0) {
+ // This path element is not the first non-empty element; prepend
+ // a directory separator if space allows
+ if (dest && required_len + 1 < len) {
+ (void)snprintf(dest + required_len, len - required_len, "%c", DIRECTORY_SYMBOL);
+ }
+ required_len++;
+ }
+
+ if (dest && required_len < len) {
+ strncpy(dest + required_len, component, len - required_len);
+ }
+ required_len += strlen(component);
+ }
+
+ va_end(ap);
+
+ // strncpy(3) won't add a NUL terminating byte in the event of truncation.
+ if (dest && required_len >= len) {
+ dest[len - 1] = '\0';
+ }
+
+ return required_len;
+}
+
+// Given string of three part form "maj.min.pat" convert to a vulkan version number.
+static uint32_t loader_make_version(char *vers_str) {
+ uint32_t vers = 0, major = 0, minor = 0, patch = 0;
+ char *vers_tok;
+
+ if (!vers_str) {
+ return vers;
+ }
+
+ vers_tok = strtok(vers_str, ".\"\n\r");
+ if (NULL != vers_tok) {
+ major = (uint16_t)atoi(vers_tok);
+ vers_tok = strtok(NULL, ".\"\n\r");
+ if (NULL != vers_tok) {
+ minor = (uint16_t)atoi(vers_tok);
+ vers_tok = strtok(NULL, ".\"\n\r");
+ if (NULL != vers_tok) {
+ patch = (uint16_t)atoi(vers_tok);
+ }
+ }
+ }
+
+ return VK_MAKE_VERSION(major, minor, patch);
+}
+
+bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2) {
+ return strcmp(op1->extensionName, op2->extensionName) == 0 ? true : false;
+}
+
+// Search the given ext_array for an extension matching the given vk_ext_prop
+bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count,
+ const VkExtensionProperties *ext_array) {
+ for (uint32_t i = 0; i < count; i++) {
+ if (compare_vk_extension_properties(vk_ext_prop, &ext_array[i])) return true;
+ }
+ return false;
+}
+
+// Search the given ext_list for an extension matching the given vk_ext_prop
+bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop, const struct loader_extension_list *ext_list) {
+ for (uint32_t i = 0; i < ext_list->count; i++) {
+ if (compare_vk_extension_properties(&ext_list->list[i], vk_ext_prop)) return true;
+ }
+ return false;
+}
+
+// Search the given ext_list for a device extension matching the given ext_prop
+bool has_vk_dev_ext_property(const VkExtensionProperties *ext_prop, const struct loader_device_extension_list *ext_list) {
+ for (uint32_t i = 0; i < ext_list->count; i++) {
+ if (compare_vk_extension_properties(&ext_list->list[i].props, ext_prop)) return true;
+ }
+ return false;
+}
+
+// Get the next unused layer property in the list. Init the property to zero.
+static struct loader_layer_properties *loaderGetNextLayerPropertySlot(const struct loader_instance *inst,
+ struct loader_layer_list *layer_list) {
+ if (layer_list->capacity == 0) {
+ layer_list->list =
+ loader_instance_heap_alloc(inst, sizeof(struct loader_layer_properties) * 64, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (layer_list->list == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderGetNextLayerPropertySlot: Out of memory can "
+ "not add any layer properties to list");
+ return NULL;
+ }
+ memset(layer_list->list, 0, sizeof(struct loader_layer_properties) * 64);
+ layer_list->capacity = sizeof(struct loader_layer_properties) * 64;
+ }
+
+ // Ensure enough room to add an entry
+ if ((layer_list->count + 1) * sizeof(struct loader_layer_properties) > layer_list->capacity) {
+ void *new_ptr = loader_instance_heap_realloc(inst, layer_list->list, layer_list->capacity, layer_list->capacity * 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_ptr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderGetNextLayerPropertySlot: realloc failed for layer list");
+ return NULL;
+ }
+ layer_list->list = new_ptr;
+ memset((uint8_t *)layer_list->list + layer_list->capacity, 0, layer_list->capacity);
+ layer_list->capacity *= 2;
+ }
+
+ layer_list->count++;
+ return &(layer_list->list[layer_list->count - 1]);
+}
+
+// Search the given layer list for a layer property matching the given layer name
+static struct loader_layer_properties *loaderFindLayerProperty(const char *name, const struct loader_layer_list *layer_list) {
+ for (uint32_t i = 0; i < layer_list->count; i++) {
+ const VkLayerProperties *item = &layer_list->list[i].info;
+ if (strcmp(name, item->layerName) == 0) return &layer_list->list[i];
+ }
+ return NULL;
+}
+
+// Search the given layer list for a layer matching the given layer name
+static bool loaderFindLayerNameInList(const char *name, const struct loader_layer_list *layer_list) {
+ if (NULL == layer_list) {
+ return false;
+ }
+ if (NULL != loaderFindLayerProperty(name, layer_list)) {
+ return true;
+ }
+ return false;
+}
+
+// Search the given meta-layer's component list for a layer matching the given layer name
+static bool loaderFindLayerNameInMetaLayer(const struct loader_instance *inst, const char *layer_name,
+ struct loader_layer_list *layer_list, struct loader_layer_properties *meta_layer_props) {
+ for (uint32_t comp_layer = 0; comp_layer < meta_layer_props->num_component_layers; comp_layer++) {
+ if (!strcmp(meta_layer_props->component_layer_names[comp_layer], layer_name)) {
+ return true;
+ }
+ struct loader_layer_properties *comp_layer_props =
+ loaderFindLayerProperty(meta_layer_props->component_layer_names[comp_layer], layer_list);
+ if (comp_layer_props->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) {
+ return loaderFindLayerNameInMetaLayer(inst, layer_name, layer_list, comp_layer_props);
+ }
+ }
+ return false;
+}
+
+// Search the override layer's blacklist for a layer matching the given layer name
+static bool loaderFindLayerNameInBlacklist(const struct loader_instance *inst, const char *layer_name,
+ struct loader_layer_list *layer_list, struct loader_layer_properties *meta_layer_props) {
+ for (uint32_t black_layer = 0; black_layer < meta_layer_props->num_blacklist_layers; ++black_layer) {
+ if (!strcmp(meta_layer_props->blacklist_layer_names[black_layer], layer_name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Remove all layer properties entries from the list
+void loaderDeleteLayerListAndProperties(const struct loader_instance *inst, struct loader_layer_list *layer_list) {
+ uint32_t i, j, k;
+ struct loader_device_extension_list *dev_ext_list;
+ struct loader_dev_ext_props *ext_props;
+ if (!layer_list) return;
+
+ for (i = 0; i < layer_list->count; i++) {
+ if (NULL != layer_list->list[i].blacklist_layer_names) {
+ loader_instance_heap_free(inst, layer_list->list[i].blacklist_layer_names);
+ layer_list->list[i].blacklist_layer_names = NULL;
+ }
+ if (NULL != layer_list->list[i].component_layer_names) {
+ loader_instance_heap_free(inst, layer_list->list[i].component_layer_names);
+ layer_list->list[i].component_layer_names = NULL;
+ }
+ if (NULL != layer_list->list[i].override_paths) {
+ loader_instance_heap_free(inst, layer_list->list[i].override_paths);
+ layer_list->list[i].override_paths = NULL;
+ }
+ loader_destroy_generic_list(inst, (struct loader_generic_list *)&layer_list->list[i].instance_extension_list);
+ dev_ext_list = &layer_list->list[i].device_extension_list;
+ if (dev_ext_list->capacity > 0 && NULL != dev_ext_list->list) {
+ for (j = 0; j < dev_ext_list->count; j++) {
+ ext_props = &dev_ext_list->list[j];
+ if (ext_props->entrypoint_count > 0) {
+ for (k = 0; k < ext_props->entrypoint_count; k++) {
+ loader_instance_heap_free(inst, ext_props->entrypoints[k]);
+ }
+ loader_instance_heap_free(inst, ext_props->entrypoints);
+ }
+ }
+ }
+ loader_destroy_generic_list(inst, (struct loader_generic_list *)dev_ext_list);
+ }
+ layer_list->count = 0;
+
+ if (layer_list->capacity > 0) {
+ layer_list->capacity = 0;
+ loader_instance_heap_free(inst, layer_list->list);
+ }
+}
+
+// Remove all layers in the layer list that are blacklisted by the override layer.
+// NOTE: This should only be called if an override layer is found and not expired.
+void loaderRemoveLayersInBlacklist(const struct loader_instance *inst, struct loader_layer_list *layer_list) {
+ struct loader_layer_properties *override_prop = loaderFindLayerProperty(VK_OVERRIDE_LAYER_NAME, layer_list);
+ if (NULL == override_prop) {
+ return;
+ }
+
+ for (int32_t j = 0; j < (int32_t)(layer_list->count); j++) {
+ struct loader_layer_properties cur_layer_prop = layer_list->list[j];
+ const char *cur_layer_name = &cur_layer_prop.info.layerName[0];
+
+ // Skip the override layer itself.
+ if (!strcmp(VK_OVERRIDE_LAYER_NAME, cur_layer_name)) {
+ continue;
+ }
+
+ // If found in the override layer's blacklist, remove it
+ if (loaderFindLayerNameInBlacklist(inst, cur_layer_name, layer_list, override_prop)) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "loaderRemoveLayersInBlacklist: Override layer is active and layer %s is in the blacklist"
+ " inside of it. Removing that layer from current layer list.",
+ cur_layer_name);
+
+ if (cur_layer_prop.type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) {
+ // Delete the component layers
+ loader_instance_heap_free(inst, cur_layer_prop.component_layer_names);
+ loader_instance_heap_free(inst, cur_layer_prop.override_paths);
+ // Never need to free the blacklist, since it can only exist in the override layer
+ }
+
+ // Remove the current invalid meta-layer from the layer list. Use memmove since we are
+ // overlapping the source and destination addresses.
+ memmove(&layer_list->list[j], &layer_list->list[j + 1],
+ sizeof(struct loader_layer_properties) * (layer_list->count - 1 - j));
+
+ // Decrement the count (because we now have one less) and decrement the loop index since we need to
+ // re-check this index.
+ layer_list->count--;
+ j--;
+
+ // Re-do the query for the override layer
+ override_prop = loaderFindLayerProperty(VK_OVERRIDE_LAYER_NAME, layer_list);
+ }
+ }
+}
+
+// Remove all layers in the layer list that are not found inside any implicit meta-layers.
+void loaderRemoveLayersNotInImplicitMetaLayers(const struct loader_instance *inst, struct loader_layer_list *layer_list) {
+ int32_t i;
+ int32_t j;
+ int32_t layer_count = (int32_t)(layer_list->count);
+
+ for (i = 0; i < layer_count; i++) {
+ layer_list->list[i].keep = false;
+ }
+
+ for (i = 0; i < layer_count; i++) {
+ struct loader_layer_properties cur_layer_prop = layer_list->list[i];
+
+ if (0 == (cur_layer_prop.type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) {
+ cur_layer_prop.keep = true;
+ } else {
+ continue;
+ }
+
+ if (cur_layer_prop.type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) {
+ for (j = 0; j < layer_count; j++) {
+ struct loader_layer_properties layer_to_check = layer_list->list[j];
+
+ if (i == j) {
+ continue;
+ }
+
+ // For all layers found in this meta layer, we want to keep them as well.
+ if (loaderFindLayerNameInMetaLayer(inst, layer_to_check.info.layerName, layer_list, &cur_layer_prop)) {
+ cur_layer_prop.keep = true;
+ }
+ }
+ }
+ }
+
+ // Remove any layers we don't want to keep (Don't use layer_count here as we need it to be
+ // dynamically updated if we delete a layer property in the list).
+ for (i = 0; i < (int32_t)(layer_list->count); i++) {
+ struct loader_layer_properties cur_layer_prop = layer_list->list[i];
+ if (!cur_layer_prop.keep) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "loaderRemoveLayersNotInImplicitMetaLayers : Implicit meta-layers are active, and layer %s is not list"
+ " inside of any. So removing layer from current layer list.",
+ cur_layer_prop.info.layerName);
+
+ if (cur_layer_prop.type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) {
+ // Delete the component layers
+ loader_instance_heap_free(inst, cur_layer_prop.component_layer_names);
+ loader_instance_heap_free(inst, cur_layer_prop.override_paths);
+ }
+
+ // Remove the current invalid meta-layer from the layer list. Use memmove since we are
+ // overlapping the source and destination addresses.
+ memmove(&layer_list->list[i], &layer_list->list[i + 1],
+ sizeof(struct loader_layer_properties) * (layer_list->count - 1 - i));
+
+ // Decrement the count (because we now have one less) and decrement the loop index since we need to
+ // re-check this index.
+ layer_list->count--;
+ i--;
+ }
+ }
+}
+
+static VkResult loader_add_instance_extensions(const struct loader_instance *inst,
+ const PFN_vkEnumerateInstanceExtensionProperties fp_get_props, const char *lib_name,
+ struct loader_extension_list *ext_list) {
+ uint32_t i, count = 0;
+ VkExtensionProperties *ext_props;
+ VkResult res = VK_SUCCESS;
+
+ if (!fp_get_props) {
+ // No EnumerateInstanceExtensionProperties defined
+ goto out;
+ }
+
+ res = fp_get_props(NULL, &count, NULL);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_instance_extensions: Error getting Instance "
+ "extension count from %s",
+ lib_name);
+ goto out;
+ }
+
+ if (count == 0) {
+ // No ExtensionProperties to report
+ goto out;
+ }
+
+ ext_props = loader_stack_alloc(count * sizeof(VkExtensionProperties));
+ if (NULL == ext_props) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ res = fp_get_props(NULL, &count, ext_props);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_instance_extensions: Error getting Instance "
+ "extensions from %s",
+ lib_name);
+ goto out;
+ }
+
+ for (i = 0; i < count; i++) {
+ char spec_version[64];
+
+ bool ext_unsupported = wsi_unsupported_instance_extension(&ext_props[i]);
+ if (!ext_unsupported) {
+ (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_VERSION_MAJOR(ext_props[i].specVersion),
+ VK_VERSION_MINOR(ext_props[i].specVersion), VK_VERSION_PATCH(ext_props[i].specVersion));
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Instance Extension: %s (%s) version %s", ext_props[i].extensionName,
+ lib_name, spec_version);
+
+ res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_instance_extensions: Failed to add %s "
+ "to Instance extension list",
+ lib_name);
+ goto out;
+ }
+ }
+ }
+
+out:
+ return res;
+}
+
+// Initialize ext_list with the physical device extensions.
+// The extension properties are passed as inputs in count and ext_props.
+static VkResult loader_init_device_extensions(const struct loader_instance *inst, struct loader_physical_device_term *phys_dev_term,
+ uint32_t count, VkExtensionProperties *ext_props,
+ struct loader_extension_list *ext_list) {
+ VkResult res;
+ uint32_t i;
+
+ res = loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, sizeof(VkExtensionProperties));
+ if (VK_SUCCESS != res) {
+ return res;
+ }
+
+ for (i = 0; i < count; i++) {
+ char spec_version[64];
+ (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_VERSION_MAJOR(ext_props[i].specVersion),
+ VK_VERSION_MINOR(ext_props[i].specVersion), VK_VERSION_PATCH(ext_props[i].specVersion));
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Device Extension: %s (%s) version %s", ext_props[i].extensionName,
+ phys_dev_term->this_icd_term->scanned_icd->lib_name, spec_version);
+ res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
+ if (res != VK_SUCCESS) return res;
+ }
+
+ return VK_SUCCESS;
+}
+
+VkResult loader_add_device_extensions(const struct loader_instance *inst,
+ PFN_vkEnumerateDeviceExtensionProperties fpEnumerateDeviceExtensionProperties,
+ VkPhysicalDevice physical_device, const char *lib_name,
+ struct loader_extension_list *ext_list) {
+ uint32_t i, count;
+ VkResult res;
+ VkExtensionProperties *ext_props;
+
+ res = fpEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL);
+ if (res == VK_SUCCESS && count > 0) {
+ ext_props = loader_stack_alloc(count * sizeof(VkExtensionProperties));
+ if (!ext_props) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_device_extensions: Failed to allocate space"
+ " for device extension properties.");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ res = fpEnumerateDeviceExtensionProperties(physical_device, NULL, &count, ext_props);
+ if (res != VK_SUCCESS) {
+ return res;
+ }
+ for (i = 0; i < count; i++) {
+ char spec_version[64];
+ (void)snprintf(spec_version, sizeof(spec_version), "%d.%d.%d", VK_VERSION_MAJOR(ext_props[i].specVersion),
+ VK_VERSION_MINOR(ext_props[i].specVersion), VK_VERSION_PATCH(ext_props[i].specVersion));
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Device Extension: %s (%s) version %s", ext_props[i].extensionName,
+ lib_name, spec_version);
+ res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
+ if (res != VK_SUCCESS) {
+ return res;
+ }
+ }
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_device_extensions: Error getting physical "
+ "device extension info count from library %s",
+ lib_name);
+ return res;
+ }
+
+ return VK_SUCCESS;
+}
+
+VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size) {
+ size_t capacity = 32 * element_size;
+ list_info->count = 0;
+ list_info->capacity = 0;
+ list_info->list = loader_instance_heap_alloc(inst, capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (list_info->list == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_init_generic_list: Failed to allocate space "
+ "for generic list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memset(list_info->list, 0, capacity);
+ list_info->capacity = capacity;
+ return VK_SUCCESS;
+}
+
+void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list) {
+ loader_instance_heap_free(inst, list->list);
+ list->count = 0;
+ list->capacity = 0;
+}
+
+// Append non-duplicate extension properties defined in props to the given ext_list.
+// Return - Vk_SUCCESS on success
+VkResult loader_add_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list,
+ uint32_t prop_list_count, const VkExtensionProperties *props) {
+ uint32_t i;
+ const VkExtensionProperties *cur_ext;
+
+ if (ext_list->list == NULL || ext_list->capacity == 0) {
+ VkResult res = loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, sizeof(VkExtensionProperties));
+ if (VK_SUCCESS != res) {
+ return res;
+ }
+ }
+
+ for (i = 0; i < prop_list_count; i++) {
+ cur_ext = &props[i];
+
+ // look for duplicates
+ if (has_vk_extension_property(cur_ext, ext_list)) {
+ continue;
+ }
+
+ // add to list at end
+ // check for enough capacity
+ if (ext_list->count * sizeof(VkExtensionProperties) >= ext_list->capacity) {
+ void *new_ptr = loader_instance_heap_realloc(inst, ext_list->list, ext_list->capacity, ext_list->capacity * 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (new_ptr == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_to_ext_list: Failed to reallocate "
+ "space for extension list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ ext_list->list = new_ptr;
+
+ // double capacity
+ ext_list->capacity *= 2;
+ }
+
+ memcpy(&ext_list->list[ext_list->count], cur_ext, sizeof(VkExtensionProperties));
+ ext_list->count++;
+ }
+ return VK_SUCCESS;
+}
+
+// Append one extension property defined in props with entrypoints defined in entries to the given
+// ext_list. Do not append if a duplicate.
+// Return - Vk_SUCCESS on success
+VkResult loader_add_to_dev_ext_list(const struct loader_instance *inst, struct loader_device_extension_list *ext_list,
+ const VkExtensionProperties *props, uint32_t entry_count, char **entrys) {
+ uint32_t idx;
+ if (ext_list->list == NULL || ext_list->capacity == 0) {
+ VkResult res = loader_init_generic_list(inst, (struct loader_generic_list *)ext_list, sizeof(struct loader_dev_ext_props));
+ if (VK_SUCCESS != res) {
+ return res;
+ }
+ }
+
+ // look for duplicates
+ if (has_vk_dev_ext_property(props, ext_list)) {
+ return VK_SUCCESS;
+ }
+
+ idx = ext_list->count;
+ // add to list at end
+ // check for enough capacity
+ if (idx * sizeof(struct loader_dev_ext_props) >= ext_list->capacity) {
+ void *new_ptr = loader_instance_heap_realloc(inst, ext_list->list, ext_list->capacity, ext_list->capacity * 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+
+ if (NULL == new_ptr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_to_dev_ext_list: Failed to reallocate space for device extension list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ ext_list->list = new_ptr;
+
+ // double capacity
+ ext_list->capacity *= 2;
+ }
+
+ memcpy(&ext_list->list[idx].props, props, sizeof(*props));
+ ext_list->list[idx].entrypoint_count = entry_count;
+ if (entry_count == 0) {
+ ext_list->list[idx].entrypoints = NULL;
+ } else {
+ ext_list->list[idx].entrypoints =
+ loader_instance_heap_alloc(inst, sizeof(char *) * entry_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (ext_list->list[idx].entrypoints == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_to_dev_ext_list: Failed to allocate space "
+ "for device extension entrypoint list in list %d",
+ idx);
+ ext_list->list[idx].entrypoint_count = 0;
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ for (uint32_t i = 0; i < entry_count; i++) {
+ ext_list->list[idx].entrypoints[i] =
+ loader_instance_heap_alloc(inst, strlen(entrys[i]) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (ext_list->list[idx].entrypoints[i] == NULL) {
+ for (uint32_t j = 0; j < i; j++) {
+ loader_instance_heap_free(inst, ext_list->list[idx].entrypoints[j]);
+ }
+ loader_instance_heap_free(inst, ext_list->list[idx].entrypoints);
+ ext_list->list[idx].entrypoint_count = 0;
+ ext_list->list[idx].entrypoints = NULL;
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_to_dev_ext_list: Failed to allocate space "
+ "for device extension entrypoint %d name",
+ i);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ strcpy(ext_list->list[idx].entrypoints[i], entrys[i]);
+ }
+ }
+ ext_list->count++;
+
+ return VK_SUCCESS;
+}
+
+// Prototypes needed.
+bool loaderAddMetaLayer(const struct loader_instance *inst, const struct loader_layer_properties *prop,
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list);
+
+// Manage lists of VkLayerProperties
+static bool loaderInitLayerList(const struct loader_instance *inst, struct loader_layer_list *list) {
+ list->capacity = 32 * sizeof(struct loader_layer_properties);
+ list->list = loader_instance_heap_alloc(inst, list->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (list->list == NULL) {
+ return false;
+ }
+ memset(list->list, 0, list->capacity);
+ list->count = 0;
+ return true;
+}
+
+// Search the given layer list for a list matching the given VkLayerProperties
+bool loaderListHasLayerProperty(const VkLayerProperties *vk_layer_prop, const struct loader_layer_list *list) {
+ for (uint32_t i = 0; i < list->count; i++) {
+ if (strcmp(vk_layer_prop->layerName, list->list[i].info.layerName) == 0) return true;
+ }
+ return false;
+}
+
+void loaderDestroyLayerList(const struct loader_instance *inst, struct loader_device *device,
+ struct loader_layer_list *layer_list) {
+ if (device) {
+ loader_device_heap_free(device, layer_list->list);
+ } else {
+ loader_instance_heap_free(inst, layer_list->list);
+ }
+ layer_list->count = 0;
+ layer_list->capacity = 0;
+}
+
+// Append non-duplicate layer properties defined in prop_list to the given layer_info list
+VkResult loaderAddLayerPropertiesToList(const struct loader_instance *inst, struct loader_layer_list *list,
+ uint32_t prop_list_count, const struct loader_layer_properties *props) {
+ uint32_t i;
+ struct loader_layer_properties *layer;
+
+ if (list->list == NULL || list->capacity == 0) {
+ if (!loaderInitLayerList(inst, list)) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ }
+
+ if (list->list == NULL) return VK_SUCCESS;
+
+ for (i = 0; i < prop_list_count; i++) {
+ layer = (struct loader_layer_properties *)&props[i];
+
+ // Look for duplicates, and skip
+ if (loaderListHasLayerProperty(&layer->info, list)) {
+ continue;
+ }
+
+ // Check for enough capacity
+ if (((list->count + 1) * sizeof(struct loader_layer_properties)) >= list->capacity) {
+ size_t new_capacity = list->capacity * 2;
+ void *new_ptr =
+ loader_instance_heap_realloc(inst, list->list, list->capacity, new_capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_ptr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderAddLayerPropertiesToList: Realloc failed for when attempting to add new layer");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ list->list = new_ptr;
+ list->capacity = new_capacity;
+ }
+
+ memcpy(&list->list[list->count], layer, sizeof(struct loader_layer_properties));
+ list->count++;
+ }
+
+ return VK_SUCCESS;
+}
+
+// Search the given search_list for any layers in the props list. Add these to the
+// output layer_list. Don't add duplicates to the output layer_list.
+static VkResult loaderAddLayerNamesToList(const struct loader_instance *inst, struct loader_layer_list *output_list,
+ struct loader_layer_list *expanded_output_list, uint32_t name_count,
+ const char *const *names, const struct loader_layer_list *source_list) {
+ struct loader_layer_properties *layer_prop;
+ VkResult err = VK_SUCCESS;
+
+ for (uint32_t i = 0; i < name_count; i++) {
+ const char *source_name = names[i];
+ layer_prop = loaderFindLayerProperty(source_name, source_list);
+ if (NULL == layer_prop) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loaderAddLayerNamesToList: Unable to find layer %s", source_name);
+ err = VK_ERROR_LAYER_NOT_PRESENT;
+ continue;
+ }
+
+ // If not a meta-layer, simply add it.
+ if (0 == (layer_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
+ if (!loaderListHasLayerProperty(&layer_prop->info, output_list)) {
+ loaderAddLayerPropertiesToList(inst, output_list, 1, layer_prop);
+ }
+ if (!loaderListHasLayerProperty(&layer_prop->info, expanded_output_list)) {
+ loaderAddLayerPropertiesToList(inst, expanded_output_list, 1, layer_prop);
+ }
+ } else {
+ if (!loaderListHasLayerProperty(&layer_prop->info, output_list) ||
+ !loaderListHasLayerProperty(&layer_prop->info, expanded_output_list)) {
+ loaderAddMetaLayer(inst, layer_prop, output_list, expanded_output_list, source_list);
+ }
+ }
+ }
+
+ return err;
+}
+
+static bool checkExpiration(const struct loader_instance *inst, const struct loader_layer_properties *prop) {
+ time_t current = time(NULL);
+ struct tm tm_current = *localtime(&current);
+
+ struct tm tm_expiration = {
+ .tm_sec = 0,
+ .tm_min = prop->expiration.minute,
+ .tm_hour = prop->expiration.hour,
+ .tm_mday = prop->expiration.day,
+ .tm_mon = prop->expiration.month - 1,
+ .tm_year = prop->expiration.year - 1900,
+ .tm_isdst = tm_current.tm_isdst,
+ // wday and yday are ignored by mktime
+ };
+ time_t expiration = mktime(&tm_expiration);
+
+ return current < expiration;
+}
+
+// Determine if the provided implicit layer should be enabled by querying the appropriate environmental variables.
+// For an implicit layer, at least a disable environment variable is required.
+bool loaderImplicitLayerIsEnabled(const struct loader_instance *inst, const struct loader_layer_properties *prop) {
+ bool enable = false;
+ char *env_value = NULL;
+
+ // If no enable_environment variable is specified, this implicit layer is always be enabled by default.
+ if (prop->enable_env_var.name[0] == 0) {
+ enable = true;
+ } else {
+ // Otherwise, only enable this layer if the enable environment variable is defined
+ env_value = loader_getenv(prop->enable_env_var.name, inst);
+ if (env_value && !strcmp(prop->enable_env_var.value, env_value)) {
+ enable = true;
+ }
+ loader_free_getenv(env_value, inst);
+ }
+
+ // The disable_environment has priority over everything else. If it is defined, the layer is always
+ // disabled.
+ env_value = loader_getenv(prop->disable_env_var.name, inst);
+ if (env_value) {
+ enable = false;
+ }
+ loader_free_getenv(env_value, inst);
+
+ // If this layer has an expiration, check it to determine if this layer has expired.
+ if (prop->has_expiration) {
+ enable = checkExpiration(inst, prop);
+ }
+
+ // Enable this layer if it is included in the override layer
+ if (inst != NULL && inst->override_layer_present) {
+ struct loader_layer_properties *override = NULL;
+ for (uint32_t i = 0; i < inst->instance_layer_list.count; ++i) {
+ if (strcmp(inst->instance_layer_list.list[i].info.layerName, VK_OVERRIDE_LAYER_NAME) == 0) {
+ override = &inst->instance_layer_list.list[i];
+ break;
+ }
+ }
+ if (override != NULL) {
+ for (uint32_t i = 0; i < override->num_component_layers; ++i) {
+ if (strcmp(override->component_layer_names[i], prop->info.layerName) == 0) {
+ enable = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return enable;
+}
+
+// Check the individual implicit layer for the enable/disable environment variable settings. Only add it after
+// every check has passed indicating it should be used.
+static void loaderAddImplicitLayer(const struct loader_instance *inst, const struct loader_layer_properties *prop,
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list) {
+ bool enable = loaderImplicitLayerIsEnabled(inst, prop);
+
+ // If the implicit layer is supposed to be enable, make sure the layer supports at least the same API version
+ // that the application is asking (i.e. layer's API >= app's API). If it's not, disable this layer.
+ if (enable) {
+ uint16_t layer_api_major_version = VK_VERSION_MAJOR(prop->info.specVersion);
+ uint16_t layer_api_minor_version = VK_VERSION_MINOR(prop->info.specVersion);
+ if (inst->app_api_major_version > layer_api_major_version ||
+ (inst->app_api_major_version == layer_api_major_version && inst->app_api_minor_version > layer_api_minor_version)) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "loader_add_implicit_layer: Disabling implicit layer %s for using an old API version %d.%d versus "
+ "application requested %d.%d",
+ prop->info.layerName, layer_api_major_version, layer_api_minor_version, inst->app_api_major_version,
+ inst->app_api_minor_version);
+ enable = false;
+ }
+ }
+
+ if (enable) {
+ if (0 == (prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
+ if (!loaderListHasLayerProperty(&prop->info, target_list)) {
+ loaderAddLayerPropertiesToList(inst, target_list, 1, prop);
+ }
+ if (NULL != expanded_target_list && !loaderListHasLayerProperty(&prop->info, expanded_target_list)) {
+ loaderAddLayerPropertiesToList(inst, expanded_target_list, 1, prop);
+ }
+ } else {
+ if (!loaderListHasLayerProperty(&prop->info, target_list) ||
+ (NULL != expanded_target_list && !loaderListHasLayerProperty(&prop->info, expanded_target_list))) {
+ loaderAddMetaLayer(inst, prop, target_list, expanded_target_list, source_list);
+ }
+ }
+ }
+}
+
+// Add the component layers of a meta-layer to the active list of layers
+bool loaderAddMetaLayer(const struct loader_instance *inst, const struct loader_layer_properties *prop,
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list) {
+ bool found = true;
+
+ // If the meta-layer isn't present in the unexpanded list, add it.
+ if (!loaderListHasLayerProperty(&prop->info, target_list)) {
+ loaderAddLayerPropertiesToList(inst, target_list, 1, prop);
+ }
+
+ // We need to add all the individual component layers
+ for (uint32_t comp_layer = 0; comp_layer < prop->num_component_layers; comp_layer++) {
+ bool found_comp = false;
+ const struct loader_layer_properties *search_prop =
+ loaderFindLayerProperty(prop->component_layer_names[comp_layer], source_list);
+ if (search_prop != NULL) {
+ found_comp = true;
+
+ // If the component layer is itself an implicit layer, we need to do the implicit layer enable
+ // checks
+ if (0 == (search_prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) {
+ loaderAddImplicitLayer(inst, search_prop, target_list, expanded_target_list, source_list);
+ } else {
+ if (0 != (search_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
+ found = loaderAddMetaLayer(inst, search_prop, target_list, expanded_target_list, source_list);
+ } else {
+ // Otherwise, just make sure it hasn't already been added to either list before we add it
+ if (!loaderListHasLayerProperty(&search_prop->info, target_list)) {
+ loaderAddLayerPropertiesToList(inst, target_list, 1, search_prop);
+ }
+ if (NULL != expanded_target_list && !loaderListHasLayerProperty(&search_prop->info, expanded_target_list)) {
+ loaderAddLayerPropertiesToList(inst, expanded_target_list, 1, search_prop);
+ }
+ }
+ }
+ }
+ if (!found_comp) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderAddMetaLayer: Failed to find layer name %s component layer "
+ "%s to activate",
+ search_prop->info.layerName, prop->component_layer_names[comp_layer]);
+ found = false;
+ }
+ }
+
+ // Add this layer to the overall target list (not the expanded one)
+ if (found && !loaderListHasLayerProperty(&prop->info, target_list)) {
+ loaderAddLayerPropertiesToList(inst, target_list, 1, prop);
+ }
+
+ return found;
+}
+
+// Search the source_list for any layer with a name that matches the given name and a type
+// that matches the given type. Add all matching layers to the target_list.
+// Do not add if found loader_layer_properties is already on the target_list.
+void loaderAddLayerNameToList(const struct loader_instance *inst, const char *name, const enum layer_type_flags type_flags,
+ const struct loader_layer_list *source_list, struct loader_layer_list *target_list,
+ struct loader_layer_list *expanded_target_list) {
+ bool found = false;
+ for (uint32_t i = 0; i < source_list->count; i++) {
+ struct loader_layer_properties *source_prop = &source_list->list[i];
+ if (0 == strcmp(source_prop->info.layerName, name) && (source_prop->type_flags & type_flags) == type_flags) {
+ // If not a meta-layer, simply add it.
+ if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
+ if (!loaderListHasLayerProperty(&source_prop->info, target_list) &&
+ VK_SUCCESS == loaderAddLayerPropertiesToList(inst, target_list, 1, source_prop)) {
+ found = true;
+ }
+ if (!loaderListHasLayerProperty(&source_prop->info, expanded_target_list) &&
+ VK_SUCCESS == loaderAddLayerPropertiesToList(inst, expanded_target_list, 1, source_prop)) {
+ found = true;
+ }
+ } else {
+ found = loaderAddMetaLayer(inst, source_prop, target_list, expanded_target_list, source_list);
+ }
+ }
+ }
+ if (!found) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "loaderAddLayerNameToList: Failed to find layer name %s to activate",
+ name);
+ }
+}
+
+static VkExtensionProperties *get_extension_property(const char *name, const struct loader_extension_list *list) {
+ for (uint32_t i = 0; i < list->count; i++) {
+ if (strcmp(name, list->list[i].extensionName) == 0) return &list->list[i];
+ }
+ return NULL;
+}
+
+static VkExtensionProperties *get_dev_extension_property(const char *name, const struct loader_device_extension_list *list) {
+ for (uint32_t i = 0; i < list->count; i++) {
+ if (strcmp(name, list->list[i].props.extensionName) == 0) return &list->list[i].props;
+ }
+ return NULL;
+}
+
+// For Instance extensions implemented within the loader (i.e. DEBUG_REPORT
+// the extension must provide two entry points for the loader to use:
+// - "trampoline" entry point - this is the address returned by GetProcAddr
+// and will always do what's necessary to support a
+// global call.
+// - "terminator" function - this function will be put at the end of the
+// instance chain and will contain the necessary logic
+// to call / process the extension for the appropriate
+// ICDs that are available.
+// There is no generic mechanism for including these functions, the references
+// must be placed into the appropriate loader entry points.
+// GetInstanceProcAddr: call extension GetInstanceProcAddr to check for GetProcAddr
+// requests
+// loader_coalesce_extensions(void) - add extension records to the list of global
+// extension available to the app.
+// instance_disp - add function pointer for terminator function
+// to this array.
+// The extension itself should be in a separate file that will be linked directly
+// with the loader.
+VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
+ struct loader_extension_list *inst_exts) {
+ struct loader_extension_list icd_exts;
+ VkResult res = VK_SUCCESS;
+ char *env_value;
+ bool filter_extensions = true;
+
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Build ICD instance extension list");
+
+ // Check if a user wants to disable the instance extension filtering behavior
+ env_value = loader_getenv("VK_LOADER_DISABLE_INST_EXT_FILTER", inst);
+ if (NULL != env_value && atoi(env_value) != 0) {
+ filter_extensions = false;
+ }
+ loader_free_getenv(env_value, inst);
+
+ // traverse scanned icd list adding non-duplicate extensions to the list
+ for (uint32_t i = 0; i < icd_tramp_list->count; i++) {
+ res = loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts, sizeof(VkExtensionProperties));
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+ res = loader_add_instance_extensions(inst, icd_tramp_list->scanned_list[i].EnumerateInstanceExtensionProperties,
+ icd_tramp_list->scanned_list[i].lib_name, &icd_exts);
+ if (VK_SUCCESS == res) {
+ if (filter_extensions) {
+ // Remove any extensions not recognized by the loader
+ for (int32_t j = 0; j < (int32_t)icd_exts.count; j++) {
+ // See if the extension is in the list of supported extensions
+ bool found = false;
+ for (uint32_t k = 0; LOADER_INSTANCE_EXTENSIONS[k] != NULL; k++) {
+ if (strcmp(icd_exts.list[j].extensionName, LOADER_INSTANCE_EXTENSIONS[k]) == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ // If it isn't in the list, remove it
+ if (!found) {
+ for (uint32_t k = j + 1; k < icd_exts.count; k++) {
+ icd_exts.list[k - 1] = icd_exts.list[k];
+ }
+ --icd_exts.count;
+ --j;
+ }
+ }
+ }
+
+ res = loader_add_to_ext_list(inst, inst_exts, icd_exts.count, icd_exts.list);
+ }
+ loader_destroy_generic_list(inst, (struct loader_generic_list *)&icd_exts);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+ };
+
+ // Traverse loader's extensions, adding non-duplicate extensions to the list
+ debug_utils_AddInstanceExtensions(inst, inst_exts);
+
+out:
+ return res;
+}
+
+struct loader_icd_term *loader_get_icd_and_device(const VkDevice device, struct loader_device **found_dev, uint32_t *icd_index) {
+ *found_dev = NULL;
+ for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
+ uint32_t index = 0;
+ for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
+ for (struct loader_device *dev = icd_term->logical_device_list; dev; dev = dev->next)
+ // Value comparison of device prevents object wrapping by layers
+ if (loader_get_dispatch(dev->icd_device) == loader_get_dispatch(device) ||
+ (dev->chain_device != VK_NULL_HANDLE &&
+ loader_get_dispatch(dev->chain_device) == loader_get_dispatch(device))) {
+ *found_dev = dev;
+ if (NULL != icd_index) {
+ *icd_index = index;
+ }
+ return icd_term;
+ }
+ index++;
+ }
+ }
+ return NULL;
+}
+
+void loader_destroy_logical_device(const struct loader_instance *inst, struct loader_device *dev,
+ const VkAllocationCallbacks *pAllocator) {
+ if (pAllocator) {
+ dev->alloc_callbacks = *pAllocator;
+ }
+ if (NULL != dev->expanded_activated_layer_list.list) {
+ loaderDeactivateLayers(inst, dev, &dev->expanded_activated_layer_list);
+ }
+ if (NULL != dev->app_activated_layer_list.list) {
+ loaderDestroyLayerList(inst, dev, &dev->app_activated_layer_list);
+ }
+ loader_device_heap_free(dev, dev);
+}
+
+struct loader_device *loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator) {
+ struct loader_device *new_dev;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator) {
+ new_dev = (struct loader_device *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(struct loader_device),
+ sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ } else {
+#endif
+ new_dev = (struct loader_device *)malloc(sizeof(struct loader_device));
+ }
+
+ if (!new_dev) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_create_logical_device: Failed to alloc struct "
+ "loader_device");
+ return NULL;
+ }
+
+ memset(new_dev, 0, sizeof(struct loader_device));
+ if (pAllocator) {
+ new_dev->alloc_callbacks = *pAllocator;
+ }
+
+ return new_dev;
+}
+
+void loader_add_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term, struct loader_device *dev) {
+ dev->next = icd_term->logical_device_list;
+ icd_term->logical_device_list = dev;
+}
+
+void loader_remove_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term,
+ struct loader_device *found_dev, const VkAllocationCallbacks *pAllocator) {
+ struct loader_device *dev, *prev_dev;
+
+ if (!icd_term || !found_dev) return;
+
+ prev_dev = NULL;
+ dev = icd_term->logical_device_list;
+ while (dev && dev != found_dev) {
+ prev_dev = dev;
+ dev = dev->next;
+ }
+
+ if (prev_dev)
+ prev_dev->next = found_dev->next;
+ else
+ icd_term->logical_device_list = found_dev->next;
+ loader_destroy_logical_device(inst, found_dev, pAllocator);
+}
+
+static void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
+ const VkAllocationCallbacks *pAllocator) {
+ ptr_inst->total_icd_count--;
+ for (struct loader_device *dev = icd_term->logical_device_list; dev;) {
+ struct loader_device *next_dev = dev->next;
+ loader_destroy_logical_device(ptr_inst, dev, pAllocator);
+ dev = next_dev;
+ }
+
+ loader_instance_heap_free(ptr_inst, icd_term);
+}
+
+static struct loader_icd_term *loader_icd_create(const struct loader_instance *inst) {
+ struct loader_icd_term *icd_term;
+
+ icd_term = loader_instance_heap_alloc(inst, sizeof(struct loader_icd_term), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (!icd_term) {
+ return NULL;
+ }
+
+ memset(icd_term, 0, sizeof(struct loader_icd_term));
+
+ return icd_term;
+}
+
+static struct loader_icd_term *loader_icd_add(struct loader_instance *ptr_inst, const struct loader_scanned_icd *scanned_icd) {
+ struct loader_icd_term *icd_term;
+
+ icd_term = loader_icd_create(ptr_inst);
+ if (!icd_term) {
+ return NULL;
+ }
+
+ icd_term->scanned_icd = scanned_icd;
+ icd_term->this_instance = ptr_inst;
+
+ // Prepend to the list
+ icd_term->next = ptr_inst->icd_terms;
+ ptr_inst->icd_terms = icd_term;
+ ptr_inst->total_icd_count++;
+
+ return icd_term;
+}
+
+// Determine the ICD interface version to use.
+// @param icd
+// @param pVersion Output parameter indicating which version to use or 0 if
+// the negotiation API is not supported by the ICD
+// @return bool indicating true if the selected interface version is supported
+// by the loader, false indicates the version is not supported
+bool loader_get_icd_interface_version(PFN_vkNegotiateLoaderICDInterfaceVersion fp_negotiate_icd_version, uint32_t *pVersion) {
+ if (fp_negotiate_icd_version == NULL) {
+ // ICD does not support the negotiation API, it supports version 0 or 1
+ // calling code must determine if it is version 0 or 1
+ *pVersion = 0;
+ } else {
+ // ICD supports the negotiation API, so call it with the loader's
+ // latest version supported
+ *pVersion = CURRENT_LOADER_ICD_INTERFACE_VERSION;
+ VkResult result = fp_negotiate_icd_version(pVersion);
+
+ if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
+ // ICD no longer supports the loader's latest interface version so
+ // fail loading the ICD
+ return false;
+ }
+ }
+
+#if MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION > 0
+ if (*pVersion < MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION) {
+ // Loader no longer supports the ICD's latest interface version so fail
+ // loading the ICD
+ return false;
+ }
+#endif
+ return true;
+}
+
+void loader_scanned_icd_clear(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list) {
+ if (0 != icd_tramp_list->capacity) {
+ for (uint32_t i = 0; i < icd_tramp_list->count; i++) {
+ loader_platform_close_library(icd_tramp_list->scanned_list[i].handle);
+ loader_instance_heap_free(inst, icd_tramp_list->scanned_list[i].lib_name);
+ }
+ loader_instance_heap_free(inst, icd_tramp_list->scanned_list);
+ icd_tramp_list->capacity = 0;
+ icd_tramp_list->count = 0;
+ icd_tramp_list->scanned_list = NULL;
+ }
+}
+
+static VkResult loader_scanned_icd_init(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list) {
+ VkResult err = VK_SUCCESS;
+ loader_scanned_icd_clear(inst, icd_tramp_list);
+ icd_tramp_list->capacity = 8 * sizeof(struct loader_scanned_icd);
+ icd_tramp_list->scanned_list = loader_instance_heap_alloc(inst, icd_tramp_list->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == icd_tramp_list->scanned_list) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_init: Realloc failed for layer list when "
+ "attempting to add new layer");
+ err = VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ return err;
+}
+
+static VkResult loader_scanned_icd_add(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
+ const char *filename, uint32_t api_version) {
+ loader_platform_dl_handle handle;
+ PFN_vkCreateInstance fp_create_inst;
+ PFN_vkEnumerateInstanceExtensionProperties fp_get_inst_ext_props;
+ PFN_vkGetInstanceProcAddr fp_get_proc_addr;
+ PFN_GetPhysicalDeviceProcAddr fp_get_phys_dev_proc_addr = NULL;
+ PFN_vkNegotiateLoaderICDInterfaceVersion fp_negotiate_icd_version;
+ struct loader_scanned_icd *new_scanned_icd;
+ uint32_t interface_vers;
+ VkResult res = VK_SUCCESS;
+
+ // TODO implement smarter opening/closing of libraries. For now this
+ // function leaves libraries open and the scanned_icd_clear closes them
+ handle = loader_platform_open_library(filename);
+ if (NULL == handle) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, loader_platform_open_library_error(filename));
+ goto out;
+ }
+
+ // Get and settle on an ICD interface version
+ fp_negotiate_icd_version = loader_platform_get_proc_address(handle, "vk_icdNegotiateLoaderICDInterfaceVersion");
+
+ if (!loader_get_icd_interface_version(fp_negotiate_icd_version, &interface_vers)) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_add: ICD %s doesn't support interface"
+ " version compatible with loader, skip this ICD.",
+ filename);
+ goto out;
+ }
+
+ fp_get_proc_addr = loader_platform_get_proc_address(handle, "vk_icdGetInstanceProcAddr");
+ if (NULL == fp_get_proc_addr) {
+ assert(interface_vers == 0);
+ // Use deprecated interface from version 0
+ fp_get_proc_addr = loader_platform_get_proc_address(handle, "vkGetInstanceProcAddr");
+ if (NULL == fp_get_proc_addr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_add: Attempt to retrieve either "
+ "\'vkGetInstanceProcAddr\' or "
+ "\'vk_icdGetInstanceProcAddr\' from ICD %s failed.",
+ filename);
+ goto out;
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_scanned_icd_add: Using deprecated ICD "
+ "interface of \'vkGetInstanceProcAddr\' instead of "
+ "\'vk_icdGetInstanceProcAddr\' for ICD %s",
+ filename);
+ }
+ fp_create_inst = loader_platform_get_proc_address(handle, "vkCreateInstance");
+ if (NULL == fp_create_inst) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_add: Failed querying "
+ "\'vkCreateInstance\' via dlsym/loadlibrary for "
+ "ICD %s",
+ filename);
+ goto out;
+ }
+ fp_get_inst_ext_props = loader_platform_get_proc_address(handle, "vkEnumerateInstanceExtensionProperties");
+ if (NULL == fp_get_inst_ext_props) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_add: Could not get \'vkEnumerate"
+ "InstanceExtensionProperties\' via dlsym/loadlibrary "
+ "for ICD %s",
+ filename);
+ goto out;
+ }
+ } else {
+ // Use newer interface version 1 or later
+ if (interface_vers == 0) {
+ interface_vers = 1;
+ }
+
+ fp_create_inst = (PFN_vkCreateInstance)fp_get_proc_addr(NULL, "vkCreateInstance");
+ if (NULL == fp_create_inst) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_add: Could not get "
+ "\'vkCreateInstance\' via \'vk_icdGetInstanceProcAddr\'"
+ " for ICD %s",
+ filename);
+ goto out;
+ }
+ fp_get_inst_ext_props =
+ (PFN_vkEnumerateInstanceExtensionProperties)fp_get_proc_addr(NULL, "vkEnumerateInstanceExtensionProperties");
+ if (NULL == fp_get_inst_ext_props) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_add: Could not get \'vkEnumerate"
+ "InstanceExtensionProperties\' via "
+ "\'vk_icdGetInstanceProcAddr\' for ICD %s",
+ filename);
+ goto out;
+ }
+ fp_get_phys_dev_proc_addr = loader_platform_get_proc_address(handle, "vk_icdGetPhysicalDeviceProcAddr");
+ }
+
+ // check for enough capacity
+ if ((icd_tramp_list->count * sizeof(struct loader_scanned_icd)) >= icd_tramp_list->capacity) {
+ void *new_ptr = loader_instance_heap_realloc(inst, icd_tramp_list->scanned_list, icd_tramp_list->capacity,
+ icd_tramp_list->capacity * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_ptr) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_scanned_icd_add: Realloc failed on icd library list for ICD %s", filename);
+ goto out;
+ }
+ icd_tramp_list->scanned_list = new_ptr;
+
+ // double capacity
+ icd_tramp_list->capacity *= 2;
+ }
+
+ new_scanned_icd = &(icd_tramp_list->scanned_list[icd_tramp_list->count]);
+ new_scanned_icd->handle = handle;
+ new_scanned_icd->api_version = api_version;
+ new_scanned_icd->GetInstanceProcAddr = fp_get_proc_addr;
+ new_scanned_icd->GetPhysicalDeviceProcAddr = fp_get_phys_dev_proc_addr;
+ new_scanned_icd->EnumerateInstanceExtensionProperties = fp_get_inst_ext_props;
+ new_scanned_icd->CreateInstance = fp_create_inst;
+ new_scanned_icd->interface_version = interface_vers;
+
+ new_scanned_icd->lib_name = (char *)loader_instance_heap_alloc(inst, strlen(filename) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_scanned_icd->lib_name) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_scanned_icd_add: Out of memory can't add ICD %s", filename);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ strcpy(new_scanned_icd->lib_name, filename);
+ icd_tramp_list->count++;
+
+out:
+
+ return res;
+}
+
+static void loader_debug_init(void) {
+ char *env, *orig;
+
+ if (g_loader_debug > 0) return;
+
+ g_loader_debug = 0;
+
+ // Parse comma-separated debug options
+ orig = env = loader_getenv("VK_LOADER_DEBUG", NULL);
+ while (env) {
+ char *p = strchr(env, ',');
+ size_t len;
+
+ if (p)
+ len = p - env;
+ else
+ len = strlen(env);
+
+ if (len > 0) {
+ if (strncmp(env, "all", len) == 0) {
+ g_loader_debug = ~0u;
+ g_loader_log_msgs = ~0u;
+ } else if (strncmp(env, "warn", len) == 0) {
+ g_loader_debug |= LOADER_WARN_BIT;
+ g_loader_log_msgs |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
+ } else if (strncmp(env, "info", len) == 0) {
+ g_loader_debug |= LOADER_INFO_BIT;
+ g_loader_log_msgs |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
+ } else if (strncmp(env, "perf", len) == 0) {
+ g_loader_debug |= LOADER_PERF_BIT;
+ g_loader_log_msgs |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
+ } else if (strncmp(env, "error", len) == 0) {
+ g_loader_debug |= LOADER_ERROR_BIT;
+ g_loader_log_msgs |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
+ } else if (strncmp(env, "debug", len) == 0) {
+ g_loader_debug |= LOADER_DEBUG_BIT;
+ g_loader_log_msgs |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
+ }
+ }
+
+ if (!p) break;
+
+ env = p + 1;
+ }
+
+ loader_free_getenv(orig, NULL);
+}
+
+void loader_initialize(void) {
+ // initialize mutexs
+ loader_platform_thread_create_mutex(&loader_lock);
+ loader_platform_thread_create_mutex(&loader_json_lock);
+
+ // initialize logging
+ loader_debug_init();
+
+ // initial cJSON to use alloc callbacks
+ cJSON_Hooks alloc_fns = {
+ .malloc_fn = loader_instance_tls_heap_alloc, .free_fn = loader_instance_tls_heap_free,
+ };
+ cJSON_InitHooks(&alloc_fns);
+
+#if defined(_WIN32)
+ // This is needed to ensure that newer APIs are available right away
+ // and not after the first call that has been statically linked
+ LoadLibrary("gdi32.dll");
+#endif
+}
+
+struct loader_data_files {
+ uint32_t count;
+ uint32_t alloc_count;
+ char **filename_list;
+};
+
+void loader_release() {
+ // release mutexs
+ loader_platform_thread_delete_mutex(&loader_lock);
+ loader_platform_thread_delete_mutex(&loader_json_lock);
+}
+
+// Get next file or dirname given a string list or registry key path
+//
+// \returns
+// A pointer to first char in the next path.
+// The next path (or NULL) in the list is returned in next_path.
+// Note: input string is modified in some cases. PASS IN A COPY!
+static char *loader_get_next_path(char *path) {
+ uint32_t len;
+ char *next;
+
+ if (path == NULL) return NULL;
+ next = strchr(path, PATH_SEPARATOR);
+ if (next == NULL) {
+ len = (uint32_t)strlen(path);
+ next = path + len;
+ } else {
+ *next = '\0';
+ next++;
+ }
+
+ return next;
+}
+
+// Given a path which is absolute or relative, expand the path if relative or
+// leave the path unmodified if absolute. The base path to prepend to relative
+// paths is given in rel_base.
+//
+// @return - A string in out_fullpath of the full absolute path
+static void loader_expand_path(const char *path, const char *rel_base, size_t out_size, char *out_fullpath) {
+ if (loader_platform_is_path_absolute(path)) {
+ // do not prepend a base to an absolute path
+ rel_base = "";
+ }
+
+ loader_platform_combine_path(out_fullpath, out_size, rel_base, path, NULL);
+}
+
+// Given a filename (file) and a list of paths (dir), try to find an existing
+// file in the paths. If filename already is a path then no searching in the given paths.
+//
+// @return - A string in out_fullpath of either the full path or file.
+static void loader_get_fullpath(const char *file, const char *dirs, size_t out_size, char *out_fullpath) {
+ if (!loader_platform_is_path(file) && *dirs) {
+ char *dirs_copy, *dir, *next_dir;
+
+ dirs_copy = loader_stack_alloc(strlen(dirs) + 1);
+ strcpy(dirs_copy, dirs);
+
+ // find if file exists after prepending paths in given list
+ for (dir = dirs_copy; *dir && (next_dir = loader_get_next_path(dir)); dir = next_dir) {
+ loader_platform_combine_path(out_fullpath, out_size, dir, file, NULL);
+ if (loader_platform_file_exists(out_fullpath)) {
+ return;
+ }
+ }
+ }
+
+ (void)snprintf(out_fullpath, out_size, "%s", file);
+}
+
+// Read a JSON file into a buffer.
+//
+// @return - A pointer to a cJSON object representing the JSON parse tree.
+// This returned buffer should be freed by caller.
+static VkResult loader_get_json(const struct loader_instance *inst, const char *filename, cJSON **json) {
+ FILE *file = NULL;
+ char *json_buf;
+ size_t len;
+ VkResult res = VK_SUCCESS;
+
+ if (NULL == json) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_get_json: Received invalid JSON file");
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ *json = NULL;
+
+ file = fopen(filename, "rb");
+ if (!file) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_get_json: Failed to open JSON file %s", filename);
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+ fseek(file, 0, SEEK_END);
+ len = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ json_buf = (char *)loader_stack_alloc(len + 1);
+ if (json_buf == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_get_json: Failed to allocate space for "
+ "JSON file %s buffer of length %d",
+ filename, len);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ if (fread(json_buf, sizeof(char), len, file) != len) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_get_json: Failed to read JSON file %s.", filename);
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+ json_buf[len] = '\0';
+
+ // Parse text from file
+ *json = cJSON_Parse(json_buf);
+ if (*json == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_get_json: Failed to parse JSON file %s, "
+ "this is usually because something ran out of "
+ "memory.",
+ filename);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+out:
+ if (NULL != file) {
+ fclose(file);
+ }
+
+ return res;
+}
+
+const char *std_validation_str = "VK_LAYER_LUNARG_standard_validation";
+
+// Adds the legacy VK_LAYER_LUNARG_standard_validation as a meta-layer if it
+// fails to find it in the list already. This is usually an indication that a
+// newer loader is being used with an older layer set.
+static bool loaderAddLegacyStandardValidationLayer(const struct loader_instance *inst,
+ struct loader_layer_list *layer_instance_list) {
+ uint32_t i;
+ bool success = true;
+ struct loader_layer_properties *props = loaderGetNextLayerPropertySlot(inst, layer_instance_list);
+ const char std_validation_names[6][VK_MAX_EXTENSION_NAME_SIZE] = {
+ "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker",
+ "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects"};
+ uint32_t layer_count = sizeof(std_validation_names) / sizeof(std_validation_names[0]);
+
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "Adding VK_LAYER_LUNARG_standard_validation using the loader legacy path. This is"
+ " not an error.");
+
+ if (NULL == props) {
+ goto out;
+ }
+
+ memset(props, 0, sizeof(struct loader_layer_properties));
+ props->type_flags = VK_LAYER_TYPE_FLAG_INSTANCE_LAYER | VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER | VK_LAYER_TYPE_FLAG_META_LAYER;
+ strncpy(props->info.description, "LunarG Standard Validation Layer", sizeof(props->info.description));
+ props->info.implementationVersion = 1;
+ strncpy(props->info.layerName, std_validation_str, sizeof(props->info.layerName));
+ props->info.specVersion = VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION);
+
+ props->component_layer_names =
+ loader_instance_heap_alloc(inst, sizeof(char[MAX_STRING_SIZE]) * layer_count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == props->component_layer_names) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "Failed to allocate space for legacy VK_LAYER_LUNARG_standard_validation"
+ " meta-layer component_layers information.");
+ success = false;
+ goto out;
+ }
+ for (i = 0; i < layer_count; i++) {
+ strncpy(props->component_layer_names[i], std_validation_names[i], MAX_STRING_SIZE - 1);
+ props->component_layer_names[i][MAX_STRING_SIZE - 1] = '\0';
+ }
+
+out:
+
+ if (!success && NULL != props && NULL != props->component_layer_names) {
+ loader_instance_heap_free(inst, props->component_layer_names);
+ props->component_layer_names = NULL;
+ }
+
+ return success;
+}
+
+// Verify that all component layers in a meta-layer are valid.
+static bool verifyMetaLayerComponentLayers(const struct loader_instance *inst, struct loader_layer_properties *prop,
+ struct loader_layer_list *instance_layers) {
+ bool success = true;
+ const uint32_t expected_major = VK_VERSION_MAJOR(prop->info.specVersion);
+ const uint32_t expected_minor = VK_VERSION_MINOR(prop->info.specVersion);
+
+ for (uint32_t comp_layer = 0; comp_layer < prop->num_component_layers; comp_layer++) {
+ if (!loaderFindLayerNameInList(prop->component_layer_names[comp_layer], instance_layers)) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "verifyMetaLayerComponentLayers: Meta-layer %s can't find component layer %s at index %d."
+ " Skipping this layer.",
+ prop->info.layerName, prop->component_layer_names[comp_layer], comp_layer);
+ }
+ success = false;
+ break;
+ } else {
+ struct loader_layer_properties *comp_prop =
+ loaderFindLayerProperty(prop->component_layer_names[comp_layer], instance_layers);
+ if (comp_prop == NULL) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "verifyMetaLayerComponentLayers: Meta-layer %s can't find property for component layer "
+ "%s at index %d. Skipping this layer.",
+ prop->info.layerName, prop->component_layer_names[comp_layer], comp_layer);
+ }
+ success = false;
+ break;
+ }
+
+ // Check the version of each layer, they need to at least match MAJOR and MINOR
+ uint32_t cur_major = VK_VERSION_MAJOR(comp_prop->info.specVersion);
+ uint32_t cur_minor = VK_VERSION_MINOR(comp_prop->info.specVersion);
+ if (cur_major != expected_major || cur_minor != expected_minor) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "verifyMetaLayerComponentLayers: Meta-layer uses API version %d.%d, but component "
+ "layer %d uses API version %d.%d. Skipping this layer.",
+ expected_major, expected_minor, comp_layer, cur_major, cur_minor);
+ }
+ success = false;
+ break;
+ }
+
+ // Make sure the layer isn't using it's own name
+ if (!strcmp(prop->info.layerName, prop->component_layer_names[comp_layer])) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "verifyMetaLayerComponentLayers: Meta-layer %s lists itself in its component layer "
+ "list at index %d. Skipping this layer.",
+ prop->info.layerName, comp_layer);
+ }
+ success = false;
+ break;
+ }
+ if (comp_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "verifyMetaLayerComponentLayers: Adding meta-layer %s which also contains meta-layer %s",
+ prop->info.layerName, comp_prop->info.layerName);
+ }
+
+ // Make sure if the layer is using a meta-layer in its component list that we also verify that.
+ if (!verifyMetaLayerComponentLayers(inst, comp_prop, instance_layers)) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Meta-layer %s component layer %s can not find all component layers."
+ " Skipping this layer.",
+ prop->info.layerName, prop->component_layer_names[comp_layer]);
+ }
+ success = false;
+ break;
+ }
+ }
+
+ // Add any instance and device extensions from component layers to this layer
+ // list, so that anyone querying extensions will only need to look at the meta-layer
+ for (uint32_t ext = 0; ext < comp_prop->instance_extension_list.count; ext++) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "Meta-layer %s component layer %s adding instance extension %s", prop->info.layerName,
+ prop->component_layer_names[comp_layer], comp_prop->instance_extension_list.list[ext].extensionName);
+ }
+ if (!has_vk_extension_property(&comp_prop->instance_extension_list.list[ext], &prop->instance_extension_list)) {
+ loader_add_to_ext_list(inst, &prop->instance_extension_list, 1, &comp_prop->instance_extension_list.list[ext]);
+ }
+ }
+
+ for (uint32_t ext = 0; ext < comp_prop->device_extension_list.count; ext++) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "Meta-layer %s component layer %s adding device extension %s", prop->info.layerName,
+ prop->component_layer_names[comp_layer],
+ comp_prop->device_extension_list.list[ext].props.extensionName);
+ }
+ if (!has_vk_dev_ext_property(&comp_prop->device_extension_list.list[ext].props, &prop->device_extension_list)) {
+ loader_add_to_dev_ext_list(inst, &prop->device_extension_list,
+ &comp_prop->device_extension_list.list[ext].props, 0, NULL);
+ }
+ }
+ }
+ }
+ if (success) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Meta-layer %s all %d component layers appear to be valid.",
+ prop->info.layerName, prop->num_component_layers);
+ }
+ return success;
+}
+
+// Verify that all meta-layers in a layer list are valid.
+static void VerifyAllMetaLayers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
+ bool *override_layer_present) {
+ *override_layer_present = false;
+ for (int32_t i = 0; i < (int32_t)instance_layers->count; i++) {
+ struct loader_layer_properties *prop = &instance_layers->list[i];
+
+ // If this is a meta-layer, make sure it is valid
+ if ((prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) && !verifyMetaLayerComponentLayers(inst, prop, instance_layers)) {
+ if (NULL != inst) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "Removing meta-layer %s from instance layer list since it appears invalid.", prop->info.layerName);
+ }
+
+ // Delete the component layers
+ loader_instance_heap_free(inst, prop->component_layer_names);
+ if (prop->blacklist_layer_names != NULL) {
+ loader_instance_heap_free(inst, prop->blacklist_layer_names);
+ }
+
+ // Remove the current invalid meta-layer from the layer list. Use memmove since we are
+ // overlapping the source and destination addresses.
+ memmove(&instance_layers->list[i], &instance_layers->list[i + 1],
+ sizeof(struct loader_layer_properties) * (instance_layers->count - 1 - i));
+
+ // Decrement the count (because we now have one less) and decrement the loop index since we need to
+ // re-check this index.
+ instance_layers->count--;
+ i--;
+ } else if (prop->is_override && loaderImplicitLayerIsEnabled(inst, prop)) {
+ *override_layer_present = true;
+ }
+ }
+}
+
+// This structure is used to store the json file version
+// in a more manageable way.
+typedef struct {
+ uint16_t major;
+ uint16_t minor;
+ uint16_t patch;
+} layer_json_version;
+
+static inline bool layer_json_supports_pre_instance_tag(const layer_json_version *layer_json) {
+ // Supported versions started in 1.1.2, so anything newer
+ return layer_json->major > 1 || layer_json->minor > 1 || (layer_json->minor == 1 && layer_json->patch > 1);
+}
+
+static VkResult loaderReadLayerJson(const struct loader_instance *inst, struct loader_layer_list *layer_instance_list,
+ cJSON *layer_node, layer_json_version version, cJSON *item, cJSON *disable_environment,
+ bool is_implicit, char *filename) {
+ char *temp;
+ char *name, *type, *library_path_str, *api_version;
+ char *implementation_version, *description;
+ cJSON *ext_item;
+ cJSON *library_path;
+ cJSON *component_layers;
+ cJSON *override_paths;
+ cJSON *blacklisted_layers;
+ VkExtensionProperties ext_prop;
+ VkResult result = VK_ERROR_INITIALIZATION_FAILED;
+ struct loader_layer_properties *props = NULL;
+ int i, j;
+
+// The following are required in the "layer" object:
+// (required) "name"
+// (required) "type"
+// (required) "library_path"
+// (required) "api_version"
+// (required) "implementation_version"
+// (required) "description"
+// (required for implicit layers) "disable_environment"
+#define GET_JSON_OBJECT(node, var) \
+ { \
+ var = cJSON_GetObjectItem(node, #var); \
+ if (var == NULL) { \
+ layer_node = layer_node->next; \
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, \
+ "Didn't find required layer object %s in manifest " \
+ "JSON file, skipping this layer", \
+ #var); \
+ goto out; \
+ } \
+ }
+#define GET_JSON_ITEM(node, var) \
+ { \
+ item = cJSON_GetObjectItem(node, #var); \
+ if (item == NULL) { \
+ layer_node = layer_node->next; \
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, \
+ "Didn't find required layer value %s in manifest JSON " \
+ "file, skipping this layer", \
+ #var); \
+ goto out; \
+ } \
+ temp = cJSON_Print(item); \
+ if (temp == NULL) { \
+ layer_node = layer_node->next; \
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, \
+ "Problem accessing layer value %s in manifest JSON " \
+ "file, skipping this layer", \
+ #var); \
+ result = VK_ERROR_OUT_OF_HOST_MEMORY; \
+ goto out; \
+ } \
+ temp[strlen(temp) - 1] = '\0'; \
+ var = loader_stack_alloc(strlen(temp) + 1); \
+ strcpy(var, &temp[1]); \
+ cJSON_Free(temp); \
+ }
+ GET_JSON_ITEM(layer_node, name)
+ GET_JSON_ITEM(layer_node, type)
+ GET_JSON_ITEM(layer_node, api_version)
+ GET_JSON_ITEM(layer_node, implementation_version)
+ GET_JSON_ITEM(layer_node, description)
+
+ // Add list entry
+ if (!strcmp(type, "DEVICE")) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "Device layers are deprecated skipping this layer");
+ layer_node = layer_node->next;
+ goto out;
+ }
+
+ // Allow either GLOBAL or INSTANCE type interchangeably to handle
+ // layers that must work with older loaders
+ if (!strcmp(type, "INSTANCE") || !strcmp(type, "GLOBAL")) {
+ if (layer_instance_list == NULL) {
+ layer_node = layer_node->next;
+ goto out;
+ }
+ props = loaderGetNextLayerPropertySlot(inst, layer_instance_list);
+ if (NULL == props) {
+ // Error already triggered in loaderGetNextLayerPropertySlot.
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ props->type_flags = VK_LAYER_TYPE_FLAG_INSTANCE_LAYER;
+ if (!is_implicit) {
+ props->type_flags |= VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER;
+ }
+ } else {
+ layer_node = layer_node->next;
+ goto out;
+ }
+
+ // Expiration date for override layer. Field starte with JSON file 1.1.2 and
+ // is completely optional. So, no check put in place.
+ if (!strcmp(name, VK_OVERRIDE_LAYER_NAME)) {
+ cJSON *expiration;
+
+ if (version.major < 1 && version.minor < 1 && version.patch < 2) {
+ loader_log(
+ inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Override layer expiration date not added until version 1.1.2. Please update JSON file version appropriately.");
+ }
+
+ props->is_override = true;
+ expiration = cJSON_GetObjectItem(layer_node, "expiration_date");
+ if (NULL != expiration) {
+ char date_copy[32];
+ uint8_t cur_item = 0;
+
+ // Get the string for the current item
+ temp = cJSON_Print(expiration);
+ if (temp == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Problem accessing layer value 'expiration_date' in manifest JSON file, skipping this layer");
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ temp[strlen(temp) - 1] = '\0';
+ strcpy(date_copy, &temp[1]);
+ cJSON_Free(temp);
+
+ if (strlen(date_copy) == 16) {
+ char *cur_start = &date_copy[0];
+ char *next_dash = strchr(date_copy, '-');
+ if (NULL != next_dash) {
+ while (cur_item < 5 && strlen(cur_start)) {
+ if (next_dash != NULL) {
+ *next_dash = '\0';
+ }
+ switch (cur_item) {
+ case 0: // Year
+ props->expiration.year = atoi(cur_start);
+ break;
+ case 1: // Month
+ props->expiration.month = atoi(cur_start);
+ break;
+ case 2: // Day
+ props->expiration.day = atoi(cur_start);
+ break;
+ case 3: // Hour
+ props->expiration.hour = atoi(cur_start);
+ break;
+ case 4: // Minute
+ props->expiration.minute = atoi(cur_start);
+ props->has_expiration = true;
+ break;
+ default: // Ignore
+ break;
+ }
+ if (next_dash != NULL) {
+ cur_start = next_dash + 1;
+ next_dash = strchr(cur_start, '-');
+ }
+ cur_item++;
+ }
+ }
+ }
+ }
+ }
+
+ // Library path no longer required unless component_layers is also not defined
+ library_path = cJSON_GetObjectItem(layer_node, "library_path");
+ component_layers = cJSON_GetObjectItem(layer_node, "component_layers");
+ if (NULL != library_path) {
+ if (NULL != component_layers) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Indicating meta-layer-specific component_layers, but also "
+ "defining layer library path. Both are not compatible, so "
+ "skipping this layer");
+ goto out;
+ }
+ props->num_component_layers = 0;
+ props->component_layer_names = NULL;
+
+ temp = cJSON_Print(library_path);
+ if (NULL == temp) {
+ layer_node = layer_node->next;
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Problem accessing layer value library_path in manifest JSON "
+ "file, skipping this layer");
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ temp[strlen(temp) - 1] = '\0';
+ library_path_str = loader_stack_alloc(strlen(temp) + 1);
+ strcpy(library_path_str, &temp[1]);
+ cJSON_Free(temp);
+
+ char *fullpath = props->lib_name;
+ char *rel_base;
+ if (NULL != library_path_str) {
+ if (loader_platform_is_path(library_path_str)) {
+ // A relative or absolute path
+ char *name_copy = loader_stack_alloc(strlen(filename) + 1);
+ strcpy(name_copy, filename);
+ rel_base = loader_platform_dirname(name_copy);
+ loader_expand_path(library_path_str, rel_base, MAX_STRING_SIZE, fullpath);
+ } else {
+// A filename which is assumed in a system directory
+#if defined(DEFAULT_VK_LAYERS_PATH)
+ loader_get_fullpath(library_path_str, DEFAULT_VK_LAYERS_PATH, MAX_STRING_SIZE, fullpath);
+#else
+ loader_get_fullpath(library_path_str, "", MAX_STRING_SIZE, fullpath);
+#endif
+ }
+ }
+ } else if (NULL != component_layers) {
+ if (version.major == 1 && (version.minor < 1 || version.patch < 1)) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Indicating meta-layer-specific component_layers, but using older "
+ "JSON file version.");
+ }
+ int count = cJSON_GetArraySize(component_layers);
+ props->num_component_layers = count;
+
+ // Allocate buffer for layer names
+ props->component_layer_names =
+ loader_instance_heap_alloc(inst, sizeof(char[MAX_STRING_SIZE]) * count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == props->component_layer_names) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // Copy the component layers into the array
+ for (i = 0; i < count; i++) {
+ cJSON *comp_layer = cJSON_GetArrayItem(component_layers, i);
+ if (NULL != comp_layer) {
+ temp = cJSON_Print(comp_layer);
+ if (NULL == temp) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ temp[strlen(temp) - 1] = '\0';
+ strncpy(props->component_layer_names[i], temp + 1, MAX_STRING_SIZE - 1);
+ props->component_layer_names[i][MAX_STRING_SIZE - 1] = '\0';
+ cJSON_Free(temp);
+ }
+ }
+
+ // This is now, officially, a meta-layer
+ props->type_flags |= VK_LAYER_TYPE_FLAG_META_LAYER;
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Encountered meta-layer %s", name);
+
+ // Make sure we set up other things so we head down the correct branches below
+ library_path_str = NULL;
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Layer missing both library_path and component_layers fields. One or the "
+ "other MUST be defined. Skipping this layer");
+ goto out;
+ }
+
+ props->num_blacklist_layers = 0;
+ props->blacklist_layer_names = NULL;
+ blacklisted_layers = cJSON_GetObjectItem(layer_node, "blacklisted_layers");
+ if (blacklisted_layers != NULL) {
+ if (strcmp(name, VK_OVERRIDE_LAYER_NAME)) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Layer %s contains a blacklist, but a blacklist can only be provided by the override metalayer. "
+ "This blacklist will be ignored.",
+ name);
+ } else {
+ props->num_blacklist_layers = cJSON_GetArraySize(blacklisted_layers);
+
+ // Allocate the blacklist array
+ props->blacklist_layer_names = loader_instance_heap_alloc(
+ inst, sizeof(char[MAX_STRING_SIZE]) * props->num_blacklist_layers, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (props->blacklist_layer_names == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // Copy the blacklisted layers into the array
+ for (i = 0; i < (int)props->num_blacklist_layers; ++i) {
+ cJSON *black_layer = cJSON_GetArrayItem(blacklisted_layers, i);
+ if (black_layer == NULL) {
+ continue;
+ }
+ temp = cJSON_Print(black_layer);
+ if (temp == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ temp[strlen(temp) - 1] = '\0';
+ strncpy(props->blacklist_layer_names[i], temp + 1, MAX_STRING_SIZE - 1);
+ props->blacklist_layer_names[i][MAX_STRING_SIZE - 1] = '\0';
+ cJSON_Free(temp);
+ }
+ }
+ }
+
+ override_paths = cJSON_GetObjectItem(layer_node, "override_paths");
+ if (NULL != override_paths) {
+ if (version.major == 1 && (version.minor < 1 || version.patch < 1)) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Indicating meta-layer-specific override paths, but using older "
+ "JSON file version.");
+ }
+ int count = cJSON_GetArraySize(override_paths);
+ props->num_override_paths = count;
+
+ // Allocate buffer for override paths
+ props->override_paths =
+ loader_instance_heap_alloc(inst, sizeof(char[MAX_STRING_SIZE]) * count, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == props->override_paths) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // Copy the override paths into the array
+ for (i = 0; i < count; i++) {
+ cJSON *override_path = cJSON_GetArrayItem(override_paths, i);
+ if (NULL != override_path) {
+ temp = cJSON_Print(override_path);
+ if (NULL == temp) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ temp[strlen(temp) - 1] = '\0';
+ strncpy(props->override_paths[i], temp + 1, MAX_STRING_SIZE - 1);
+ props->override_paths[i][MAX_STRING_SIZE - 1] = '\0';
+ cJSON_Free(temp);
+ }
+ }
+ }
+
+ if (is_implicit) {
+ GET_JSON_OBJECT(layer_node, disable_environment)
+ }
+#undef GET_JSON_ITEM
+#undef GET_JSON_OBJECT
+
+ strncpy(props->info.layerName, name, sizeof(props->info.layerName));
+ props->info.layerName[sizeof(props->info.layerName) - 1] = '\0';
+ props->info.specVersion = loader_make_version(api_version);
+ props->info.implementationVersion = atoi(implementation_version);
+ strncpy((char *)props->info.description, description, sizeof(props->info.description));
+ props->info.description[sizeof(props->info.description) - 1] = '\0';
+ if (is_implicit) {
+ if (!disable_environment || !disable_environment->child) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Didn't find required layer child value disable_environment"
+ "in manifest JSON file, skipping this layer");
+ layer_node = layer_node->next;
+ goto out;
+ }
+ strncpy(props->disable_env_var.name, disable_environment->child->string, sizeof(props->disable_env_var.name));
+ props->disable_env_var.name[sizeof(props->disable_env_var.name) - 1] = '\0';
+ strncpy(props->disable_env_var.value, disable_environment->child->valuestring, sizeof(props->disable_env_var.value));
+ props->disable_env_var.value[sizeof(props->disable_env_var.value) - 1] = '\0';
+ }
+
+// Now get all optional items and objects and put in list:
+// functions
+// instance_extensions
+// device_extensions
+// enable_environment (implicit layers only)
+#define GET_JSON_OBJECT(node, var) \
+ { var = cJSON_GetObjectItem(node, #var); }
+#define GET_JSON_ITEM(node, var) \
+ { \
+ item = cJSON_GetObjectItem(node, #var); \
+ if (item != NULL) { \
+ temp = cJSON_Print(item); \
+ if (temp != NULL) { \
+ temp[strlen(temp) - 1] = '\0'; \
+ var = loader_stack_alloc(strlen(temp) + 1); \
+ strcpy(var, &temp[1]); \
+ cJSON_Free(temp); \
+ } else { \
+ result = VK_ERROR_OUT_OF_HOST_MEMORY; \
+ goto out; \
+ } \
+ } \
+ }
+
+ cJSON *instance_extensions, *device_extensions, *functions, *enable_environment;
+ cJSON *entrypoints = NULL;
+ char *vkGetInstanceProcAddr = NULL;
+ char *vkGetDeviceProcAddr = NULL;
+ char *vkNegotiateLoaderLayerInterfaceVersion = NULL;
+ char *spec_version = NULL;
+ char **entry_array = NULL;
+
+ // Layer interface functions
+ // vkGetInstanceProcAddr
+ // vkGetDeviceProcAddr
+ // vkNegotiateLoaderLayerInterfaceVersion (starting with JSON file 1.1.0)
+ GET_JSON_OBJECT(layer_node, functions)
+ if (functions != NULL) {
+ if (version.major > 1 || version.minor >= 1) {
+ GET_JSON_ITEM(functions, vkNegotiateLoaderLayerInterfaceVersion)
+ if (vkNegotiateLoaderLayerInterfaceVersion != NULL)
+ strncpy(props->functions.str_negotiate_interface, vkNegotiateLoaderLayerInterfaceVersion,
+ sizeof(props->functions.str_negotiate_interface));
+ props->functions.str_negotiate_interface[sizeof(props->functions.str_negotiate_interface) - 1] = '\0';
+ } else {
+ props->functions.str_negotiate_interface[0] = '\0';
+ }
+ GET_JSON_ITEM(functions, vkGetInstanceProcAddr)
+ GET_JSON_ITEM(functions, vkGetDeviceProcAddr)
+ if (vkGetInstanceProcAddr != NULL) {
+ strncpy(props->functions.str_gipa, vkGetInstanceProcAddr, sizeof(props->functions.str_gipa));
+ if (version.major > 1 || version.minor >= 1) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "Layer \"%s\" using deprecated \'vkGetInstanceProcAddr\' tag which was deprecated starting with JSON "
+ "file version 1.1.0. The new vkNegotiateLayerInterfaceVersion function is preferred, though for "
+ "compatibility reasons it may be desirable to continue using the deprecated tag.",
+ name);
+ }
+ }
+ props->functions.str_gipa[sizeof(props->functions.str_gipa) - 1] = '\0';
+ if (vkGetDeviceProcAddr != NULL) {
+ strncpy(props->functions.str_gdpa, vkGetDeviceProcAddr, sizeof(props->functions.str_gdpa));
+ if (version.major > 1 || version.minor >= 1) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "Layer \"%s\" using deprecated \'vkGetDeviceProcAddr\' tag which was deprecated starting with JSON "
+ "file version 1.1.0. The new vkNegotiateLayerInterfaceVersion function is preferred, though for "
+ "compatibility reasons it may be desirable to continue using the deprecated tag.",
+ name);
+ }
+ }
+ props->functions.str_gdpa[sizeof(props->functions.str_gdpa) - 1] = '\0';
+ }
+
+ // instance_extensions
+ // array of {
+ // name
+ // spec_version
+ // }
+ GET_JSON_OBJECT(layer_node, instance_extensions)
+ if (instance_extensions != NULL) {
+ int count = cJSON_GetArraySize(instance_extensions);
+ for (i = 0; i < count; i++) {
+ ext_item = cJSON_GetArrayItem(instance_extensions, i);
+ GET_JSON_ITEM(ext_item, name)
+ if (name != NULL) {
+ strncpy(ext_prop.extensionName, name, sizeof(ext_prop.extensionName));
+ ext_prop.extensionName[sizeof(ext_prop.extensionName) - 1] = '\0';
+ }
+ GET_JSON_ITEM(ext_item, spec_version)
+ if (NULL != spec_version) {
+ ext_prop.specVersion = atoi(spec_version);
+ } else {
+ ext_prop.specVersion = 0;
+ }
+ bool ext_unsupported = wsi_unsupported_instance_extension(&ext_prop);
+ if (!ext_unsupported) {
+ loader_add_to_ext_list(inst, &props->instance_extension_list, 1, &ext_prop);
+ }
+ }
+ }
+
+ // device_extensions
+ // array of {
+ // name
+ // spec_version
+ // entrypoints
+ // }
+ GET_JSON_OBJECT(layer_node, device_extensions)
+ if (device_extensions != NULL) {
+ int count = cJSON_GetArraySize(device_extensions);
+ for (i = 0; i < count; i++) {
+ ext_item = cJSON_GetArrayItem(device_extensions, i);
+ GET_JSON_ITEM(ext_item, name)
+ GET_JSON_ITEM(ext_item, spec_version)
+ if (name != NULL) {
+ strncpy(ext_prop.extensionName, name, sizeof(ext_prop.extensionName));
+ ext_prop.extensionName[sizeof(ext_prop.extensionName) - 1] = '\0';
+ }
+ if (NULL != spec_version) {
+ ext_prop.specVersion = atoi(spec_version);
+ } else {
+ ext_prop.specVersion = 0;
+ }
+ // entrypoints = cJSON_GetObjectItem(ext_item, "entrypoints");
+ GET_JSON_OBJECT(ext_item, entrypoints)
+ int entry_count;
+ if (entrypoints == NULL) {
+ loader_add_to_dev_ext_list(inst, &props->device_extension_list, &ext_prop, 0, NULL);
+ continue;
+ }
+ entry_count = cJSON_GetArraySize(entrypoints);
+ if (entry_count) {
+ entry_array = (char **)loader_stack_alloc(sizeof(char *) * entry_count);
+ }
+ for (j = 0; j < entry_count; j++) {
+ ext_item = cJSON_GetArrayItem(entrypoints, j);
+ if (ext_item != NULL) {
+ temp = cJSON_Print(ext_item);
+ if (NULL == temp) {
+ entry_array[j] = NULL;
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ temp[strlen(temp) - 1] = '\0';
+ entry_array[j] = loader_stack_alloc(strlen(temp) + 1);
+ strcpy(entry_array[j], &temp[1]);
+ cJSON_Free(temp);
+ }
+ }
+ loader_add_to_dev_ext_list(inst, &props->device_extension_list, &ext_prop, entry_count, entry_array);
+ }
+ }
+ if (is_implicit) {
+ GET_JSON_OBJECT(layer_node, enable_environment)
+
+ // enable_environment is optional
+ if (enable_environment) {
+ strncpy(props->enable_env_var.name, enable_environment->child->string, sizeof(props->enable_env_var.name));
+ props->enable_env_var.name[sizeof(props->enable_env_var.name) - 1] = '\0';
+ strncpy(props->enable_env_var.value, enable_environment->child->valuestring, sizeof(props->enable_env_var.value));
+ props->enable_env_var.value[sizeof(props->enable_env_var.value) - 1] = '\0';
+ }
+ }
+
+ // Read in the pre-instance stuff
+ cJSON *pre_instance = cJSON_GetObjectItem(layer_node, "pre_instance_functions");
+ if (pre_instance) {
+ if (!layer_json_supports_pre_instance_tag(&version)) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "Found pre_instance_functions section in layer from \"%s\". "
+ "This section is only valid in manifest version 1.1.2 or later. The section will be ignored",
+ filename);
+ } else if (!is_implicit) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "Found pre_instance_functions section in explicit layer from "
+ "\"%s\". This section is only valid in implicit layers. The section will be ignored",
+ filename);
+ } else {
+ cJSON *inst_ext_json = cJSON_GetObjectItem(pre_instance, "vkEnumerateInstanceExtensionProperties");
+ if (inst_ext_json) {
+ char *inst_ext_name = cJSON_Print(inst_ext_json);
+ if (inst_ext_name == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ size_t len = strlen(inst_ext_name) >= MAX_STRING_SIZE ? MAX_STRING_SIZE - 3 : strlen(inst_ext_name) - 2;
+ strncpy(props->pre_instance_functions.enumerate_instance_extension_properties, inst_ext_name + 1, len);
+ props->pre_instance_functions.enumerate_instance_extension_properties[len] = '\0';
+ cJSON_Free(inst_ext_name);
+ }
+
+ cJSON *inst_layer_json = cJSON_GetObjectItem(pre_instance, "vkEnumerateInstanceLayerProperties");
+ if (inst_layer_json) {
+ char *inst_layer_name = cJSON_Print(inst_layer_json);
+ if (inst_layer_name == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ size_t len = strlen(inst_layer_name) >= MAX_STRING_SIZE ? MAX_STRING_SIZE - 3 : strlen(inst_layer_name) - 2;
+ strncpy(props->pre_instance_functions.enumerate_instance_layer_properties, inst_layer_name + 1, len);
+ props->pre_instance_functions.enumerate_instance_layer_properties[len] = '\0';
+ cJSON_Free(inst_layer_name);
+ }
+
+ cJSON *inst_version_json = cJSON_GetObjectItem(pre_instance, "vkEnumerateInstanceVersion");
+ if (inst_version_json) {
+ char *inst_version_name = cJSON_Print(inst_version_json);
+ if (inst_version_json) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ size_t len = strlen(inst_version_name) >= MAX_STRING_SIZE ? MAX_STRING_SIZE - 3 : strlen(inst_version_name) - 2;
+ strncpy(props->pre_instance_functions.enumerate_instance_version, inst_version_name + 1, len);
+ props->pre_instance_functions.enumerate_instance_version[len] = '\0';
+ cJSON_Free(inst_version_name);
+ }
+ }
+ }
+
+ result = VK_SUCCESS;
+
+out:
+#undef GET_JSON_ITEM
+#undef GET_JSON_OBJECT
+
+ if (VK_SUCCESS != result && NULL != props) {
+ if (NULL != props->blacklist_layer_names) {
+ loader_instance_heap_free(inst, props->blacklist_layer_names);
+ }
+ if (NULL != props->component_layer_names) {
+ loader_instance_heap_free(inst, props->component_layer_names);
+ }
+ if (NULL != props->override_paths) {
+ loader_instance_heap_free(inst, props->override_paths);
+ }
+ props->num_blacklist_layers = 0;
+ props->blacklist_layer_names = NULL;
+ props->num_component_layers = 0;
+ props->component_layer_names = NULL;
+ props->num_override_paths = 0;
+ props->override_paths = NULL;
+ }
+
+ return result;
+}
+
+static inline bool isValidLayerJsonVersion(const layer_json_version *layer_json) {
+ // Supported versions are: 1.0.0, 1.0.1, and 1.1.0 - 1.1.2.
+ if ((layer_json->major == 1 && layer_json->minor == 1 && layer_json->patch < 3) ||
+ (layer_json->major == 1 && layer_json->minor == 0 && layer_json->patch < 2)) {
+ return true;
+ }
+ return false;
+}
+
+static inline bool layerJsonSupportsMultipleLayers(const layer_json_version *layer_json) {
+ // Supported versions started in 1.0.1, so anything newer
+ if ((layer_json->major > 1 || layer_json->minor > 0 || layer_json->patch > 1)) {
+ return true;
+ }
+ return false;
+}
+
+// Given a cJSON struct (json) of the top level JSON object from layer manifest
+// file, add entry to the layer_list. Fill out the layer_properties in this list
+// entry from the input cJSON object.
+//
+// \returns
+// void
+// layer_list has a new entry and initialized accordingly.
+// If the json input object does not have all the required fields no entry
+// is added to the list.
+static VkResult loaderAddLayerProperties(const struct loader_instance *inst, struct loader_layer_list *layer_instance_list,
+ cJSON *json, bool is_implicit, char *filename) {
+ // The following Fields in layer manifest file that are required:
+ // - "file_format_version"
+ // - If more than one "layer" object are used, then the "layers" array is
+ // required
+ VkResult result = VK_ERROR_INITIALIZATION_FAILED;
+ cJSON *item, *layers_node, *layer_node;
+ layer_json_version json_version = {0, 0, 0};
+ char *vers_tok;
+ cJSON *disable_environment = NULL;
+ item = cJSON_GetObjectItem(json, "file_format_version");
+ if (item == NULL) {
+ goto out;
+ }
+ char *file_vers = cJSON_PrintUnformatted(item);
+ if (NULL == file_vers) {
+ goto out;
+ }
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Found manifest file %s, version %s", filename, file_vers);
+ // Get the major/minor/and patch as integers for easier comparison
+ vers_tok = strtok(file_vers, ".\"\n\r");
+ if (NULL != vers_tok) {
+ json_version.major = (uint16_t)atoi(vers_tok);
+ vers_tok = strtok(NULL, ".\"\n\r");
+ if (NULL != vers_tok) {
+ json_version.minor = (uint16_t)atoi(vers_tok);
+ vers_tok = strtok(NULL, ".\"\n\r");
+ if (NULL != vers_tok) {
+ json_version.patch = (uint16_t)atoi(vers_tok);
+ }
+ }
+ }
+
+ if (!isValidLayerJsonVersion(&json_version)) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderAddLayerProperties: %s invalid layer manifest file version %d.%d.%d. May cause errors.", filename,
+ json_version.major, json_version.minor, json_version.patch);
+ }
+ cJSON_Free(file_vers);
+
+ // If "layers" is present, read in the array of layer objects
+ layers_node = cJSON_GetObjectItem(json, "layers");
+ if (layers_node != NULL) {
+ int numItems = cJSON_GetArraySize(layers_node);
+ if (!layerJsonSupportsMultipleLayers(&json_version)) {
+ loader_log(
+ inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderAddLayerProperties: \'layers\' tag not supported until file version 1.0.1, but %s is reporting version %s",
+ filename, file_vers);
+ }
+ for (int curLayer = 0; curLayer < numItems; curLayer++) {
+ layer_node = cJSON_GetArrayItem(layers_node, curLayer);
+ if (layer_node == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderAddLayerProperties: Can not find 'layers' array element %d object in manifest JSON file %s. "
+ "Skipping this file",
+ curLayer, filename);
+ goto out;
+ }
+ result = loaderReadLayerJson(inst, layer_instance_list, layer_node, json_version, item, disable_environment,
+ is_implicit, filename);
+ }
+ } else {
+ // Otherwise, try to read in individual layers
+ layer_node = cJSON_GetObjectItem(json, "layer");
+ if (layer_node == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderAddLayerProperties: Can not find 'layer' object in manifest JSON file %s. Skipping this file.",
+ filename);
+ goto out;
+ }
+ // Loop through all "layer" objects in the file to get a count of them
+ // first.
+ uint16_t layer_count = 0;
+ cJSON *tempNode = layer_node;
+ do {
+ tempNode = tempNode->next;
+ layer_count++;
+ } while (tempNode != NULL);
+
+ // Throw a warning if we encounter multiple "layer" objects in file
+ // versions newer than 1.0.0. Having multiple objects with the same
+ // name at the same level is actually a JSON standard violation.
+ if (layer_count > 1 && layerJsonSupportsMultipleLayers(&json_version)) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderAddLayerProperties: Multiple 'layer' nodes are deprecated starting in file version \"1.0.1\". "
+ "Please use 'layers' : [] array instead in %s.",
+ filename);
+ } else {
+ do {
+ result = loaderReadLayerJson(inst, layer_instance_list, layer_node, json_version, item, disable_environment,
+ is_implicit, filename);
+ layer_node = layer_node->next;
+ } while (layer_node != NULL);
+ }
+ }
+
+out:
+
+ return result;
+}
+
+static inline size_t DetermineDataFilePathSize(const char *cur_path, size_t relative_path_size) {
+ size_t path_size = 0;
+
+ if (NULL != cur_path) {
+ // For each folder in cur_path, (detected by finding additional
+ // path separators in the string) we need to add the relative path on
+ // the end. Plus, leave an additional two slots on the end to add an
+ // additional directory slash and path separator if needed
+ path_size += strlen(cur_path) + relative_path_size + 2;
+ for (const char *x = cur_path; *x; ++x) {
+ if (*x == PATH_SEPARATOR) {
+ path_size += relative_path_size + 2;
+ }
+ }
+ }
+
+ return path_size;
+}
+
+static inline void CopyDataFilePath(const char *cur_path, const char *relative_path, size_t relative_path_size,
+ char **output_path) {
+ if (NULL != cur_path) {
+ uint32_t start = 0;
+ uint32_t stop = 0;
+ char *cur_write = *output_path;
+
+ while (cur_path[start] != '\0') {
+ while (cur_path[start] == PATH_SEPARATOR) {
+ start++;
+ }
+ stop = start;
+ while (cur_path[stop] != PATH_SEPARATOR && cur_path[stop] != '\0') {
+ stop++;
+ }
+ const size_t s = stop - start;
+ if (s) {
+ memcpy(cur_write, &cur_path[start], s);
+ cur_write += s;
+
+ // If last symbol written was not a directory symbol, add it.
+ if (*(cur_write - 1) != DIRECTORY_SYMBOL) {
+ *cur_write++ = DIRECTORY_SYMBOL;
+ }
+
+ if (relative_path_size > 0) {
+ memcpy(cur_write, relative_path, relative_path_size);
+ cur_write += relative_path_size;
+ }
+ *cur_write++ = PATH_SEPARATOR;
+ start = stop;
+ }
+ }
+ *output_path = cur_write;
+ }
+}
+
+// Check to see if there's enough space in the data file list. If not, add some.
+static inline VkResult CheckAndAdjustDataFileList(const struct loader_instance *inst, struct loader_data_files *out_files) {
+ if (out_files->count == 0) {
+ out_files->filename_list = loader_instance_heap_alloc(inst, 64 * sizeof(char *), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (NULL == out_files->filename_list) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "CheckAndAdjustDataFileList: Failed to allocate space for manifest file name list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ out_files->alloc_count = 64;
+ } else if (out_files->count == out_files->alloc_count) {
+ size_t new_size = out_files->alloc_count * sizeof(char *) * 2;
+ void *new_ptr = loader_instance_heap_realloc(inst, out_files->filename_list, out_files->alloc_count * sizeof(char *),
+ new_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (NULL == new_ptr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "CheckAndAdjustDataFileList: Failed to reallocate space for manifest file name list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ out_files->filename_list = new_ptr;
+ out_files->alloc_count *= 2;
+ }
+
+ return VK_SUCCESS;
+}
+
+// If the file found is a manifest file name, add it to the out_files manifest list.
+static VkResult AddIfManifestFile(const struct loader_instance *inst, const char *file_name, struct loader_data_files *out_files) {
+ VkResult vk_result = VK_SUCCESS;
+
+ if (NULL == file_name || NULL == out_files) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "AddIfManfistFile: Received NULL pointer");
+ vk_result = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ // Look for files ending with ".json" suffix
+ size_t name_len = strlen(file_name);
+ const char *name_suffix = file_name + name_len - 5;
+ if ((name_len < 5) || 0 != strncmp(name_suffix, ".json", 5)) {
+ // Use incomplete to indicate invalid name, but to keep going.
+ vk_result = VK_INCOMPLETE;
+ goto out;
+ }
+
+ // Check and allocate space in the manifest list if necessary
+ vk_result = CheckAndAdjustDataFileList(inst, out_files);
+ if (VK_SUCCESS != vk_result) {
+ goto out;
+ }
+
+ out_files->filename_list[out_files->count] =
+ loader_instance_heap_alloc(inst, strlen(file_name) + 1, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (out_files->filename_list[out_files->count] == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "AddIfManfistFile: Failed to allocate space for manifest file %d list",
+ out_files->count);
+ vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ strcpy(out_files->filename_list[out_files->count++], file_name);
+
+out:
+
+ return vk_result;
+}
+
+static VkResult AddDataFilesInPath(const struct loader_instance *inst, char *search_path, bool is_directory_list,
+ struct loader_data_files *out_files) {
+ VkResult vk_result = VK_SUCCESS;
+ DIR *dir_stream = NULL;
+ struct dirent *dir_entry;
+ char *cur_file;
+ char *next_file;
+ char *name;
+ char full_path[2048];
+#ifndef _WIN32
+ char temp_path[2048];
+#endif
+
+ // Now, parse the paths
+ next_file = search_path;
+ while (NULL != next_file && *next_file != '\0') {
+ name = NULL;
+ cur_file = next_file;
+ next_file = loader_get_next_path(cur_file);
+
+ // Get the next name in the list and verify it's valid
+ if (is_directory_list) {
+ dir_stream = opendir(cur_file);
+ if (NULL == dir_stream) {
+ continue;
+ }
+ while (1) {
+ dir_entry = readdir(dir_stream);
+ if (NULL == dir_entry) {
+ break;
+ }
+
+ name = &(dir_entry->d_name[0]);
+ loader_get_fullpath(name, cur_file, sizeof(full_path), full_path);
+ name = full_path;
+
+ VkResult local_res;
+ local_res = AddIfManifestFile(inst, name, out_files);
+
+ // Incomplete means this was not a valid data file.
+ if (local_res == VK_INCOMPLETE) {
+ continue;
+ } else if (local_res != VK_SUCCESS) {
+ vk_result = local_res;
+ break;
+ }
+ }
+ closedir(dir_stream);
+ if (vk_result != VK_SUCCESS) {
+ goto out;
+ }
+ } else {
+#ifdef _WIN32
+ name = cur_file;
+#else
+ // Only Linux has relative paths, make a copy of location so it isn't modified
+ size_t str_len;
+ if (NULL != next_file) {
+ str_len = next_file - cur_file + 1;
+ } else {
+ str_len = strlen(cur_file) + 1;
+ }
+ if (str_len > sizeof(temp_path)) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "AddDataFilesInPath: Path to %s too long\n", cur_file);
+ continue;
+ }
+ strcpy(temp_path, cur_file);
+ name = temp_path;
+#endif
+ loader_get_fullpath(cur_file, name, sizeof(full_path), full_path);
+ name = full_path;
+
+ VkResult local_res;
+ local_res = AddIfManifestFile(inst, name, out_files);
+
+ // Incomplete means this was not a valid data file.
+ if (local_res == VK_INCOMPLETE) {
+ continue;
+ } else if (local_res != VK_SUCCESS) {
+ vk_result = local_res;
+ break;
+ }
+ }
+ }
+
+out:
+
+ return vk_result;
+}
+
+// Look for data files in the provided paths, but first check the environment override to determine if we should use that
+// instead.
+static VkResult ReadDataFilesInSearchPaths(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
+ const char *env_override, const char *path_override, const char *relative_location,
+ bool *override_active, struct loader_data_files *out_files) {
+ VkResult vk_result = VK_SUCCESS;
+ bool is_directory_list = true;
+ bool is_icd = (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD);
+ char *override_env = NULL;
+ const char *override_path = NULL;
+ size_t search_path_size = 0;
+ char *search_path = NULL;
+ char *cur_path_ptr = NULL;
+ size_t rel_size = 0;
+#ifndef _WIN32
+ bool xdgconfig_alloc = true;
+ bool xdgdata_alloc = true;
+#endif
+
+#ifndef _WIN32
+ // Determine how much space is needed to generate the full search path
+ // for the current manifest files.
+ char *xdgconfdirs = loader_secure_getenv("XDG_CONFIG_DIRS", inst);
+ char *xdgdatadirs = loader_secure_getenv("XDG_DATA_DIRS", inst);
+ char *xdgdatahome = loader_secure_getenv("XDG_DATA_HOME", inst);
+ char *home = NULL;
+ char* home_root = NULL;
+
+ if (xdgconfdirs == NULL) {
+ xdgconfig_alloc = false;
+ }
+ if (xdgdatadirs == NULL) {
+ xdgdata_alloc = false;
+ }
+ if (xdgconfdirs == NULL || xdgconfdirs[0] == '\0') {
+ xdgconfdirs = FALLBACK_CONFIG_DIRS;
+ }
+ if (xdgdatadirs == NULL || xdgdatadirs[0] == '\0') {
+ xdgdatadirs = FALLBACK_DATA_DIRS;
+ }
+
+ // Only use HOME if XDG_DATA_HOME is not present on the system
+ if (NULL == xdgdatahome) {
+ home = loader_secure_getenv("HOME", inst);
+ if (home != NULL) {
+ home_root = loader_instance_heap_alloc(inst, strlen(home) + 14, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (home_root == NULL) {
+ vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ strcpy(home_root, home);
+ strcat(home_root, "/.local/share");
+ }
+ }
+#endif
+
+ if (path_override != NULL) {
+ override_path = path_override;
+ } else if (env_override != NULL) {
+#ifndef _WIN32
+ if (geteuid() != getuid() || getegid() != getgid()) {
+ // Don't allow setuid apps to use the env var:
+ env_override = NULL;
+ } else
+#endif
+ {
+ override_env = loader_secure_getenv(env_override, inst);
+
+ // The ICD override is actually a specific list of filenames, not directories
+ if (is_icd && NULL != override_env) {
+ is_directory_list = false;
+ }
+ override_path = override_env;
+ }
+ }
+
+ // Add two by default for NULL terminator and one path separator on end (just in case)
+ search_path_size = 2;
+
+ // If there's an override, use that (and the local folder if required) and nothing else
+ if (NULL != override_path) {
+ // Local folder and null terminator
+ search_path_size += strlen(override_path) + 1;
+ } else if (NULL == relative_location) {
+ // If there's no override, and no relative location, bail out. This is usually
+ // the case when we're on Windows and the default path is to use the registry.
+ goto out;
+ } else {
+ // Add the general search folders (with the appropriate relative folder added)
+ rel_size = strlen(relative_location);
+ if (rel_size == 0) {
+ goto out;
+ } else {
+#if defined(__APPLE__)
+ search_path_size += MAXPATHLEN;
+#endif
+#ifndef _WIN32
+ search_path_size += DetermineDataFilePathSize(xdgconfdirs, rel_size);
+ search_path_size += DetermineDataFilePathSize(xdgdatadirs, rel_size);
+ search_path_size += DetermineDataFilePathSize(SYSCONFDIR, rel_size);
+#if defined(EXTRASYSCONFDIR)
+ search_path_size += DetermineDataFilePathSize(EXTRASYSCONFDIR, rel_size);
+#endif
+ if (is_directory_list) {
+ if (!IsHighIntegrity()) {
+ search_path_size += DetermineDataFilePathSize(xdgdatahome, rel_size);
+ search_path_size += DetermineDataFilePathSize(home_root, rel_size);
+ }
+ }
+#endif
+ }
+ }
+
+ // Allocate the required space
+ search_path = loader_instance_heap_alloc(inst, search_path_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (NULL == search_path) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ReadDataFilesInSearchPaths: Failed to allocate space for search path of length %d", (uint32_t)search_path_size);
+ vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ cur_path_ptr = search_path;
+
+ // Add the remaining paths to the list
+ if (NULL != override_path) {
+ strcpy(cur_path_ptr, override_path);
+ } else {
+#ifndef _WIN32
+ if (rel_size > 0) {
+#if defined(__APPLE__)
+ // Add the bundle's Resources dir to the beginning of the search path.
+ // Looks for manifests in the bundle first, before any system directories.
+ CFBundleRef main_bundle = CFBundleGetMainBundle();
+ if (NULL != main_bundle) {
+ CFURLRef ref = CFBundleCopyResourcesDirectoryURL(main_bundle);
+ if (NULL != ref) {
+ if (CFURLGetFileSystemRepresentation(ref, TRUE, (UInt8 *)cur_path_ptr, search_path_size)) {
+ cur_path_ptr += strlen(cur_path_ptr);
+ *cur_path_ptr++ = DIRECTORY_SYMBOL;
+ memcpy(cur_path_ptr, relative_location, rel_size);
+ cur_path_ptr += rel_size;
+ *cur_path_ptr++ = PATH_SEPARATOR;
+ }
+ CFRelease(ref);
+ }
+ }
+#endif
+ CopyDataFilePath(xdgconfdirs, relative_location, rel_size, &cur_path_ptr);
+ CopyDataFilePath(SYSCONFDIR, relative_location, rel_size, &cur_path_ptr);
+#if defined(EXTRASYSCONFDIR)
+ CopyDataFilePath(EXTRASYSCONFDIR, relative_location, rel_size, &cur_path_ptr);
+#endif
+ CopyDataFilePath(xdgdatadirs, relative_location, rel_size, &cur_path_ptr);
+ if (is_directory_list) {
+ CopyDataFilePath(xdgdatahome, relative_location, rel_size, &cur_path_ptr);
+ CopyDataFilePath(home_root, relative_location, rel_size, &cur_path_ptr);
+ }
+ }
+
+ // Remove the last path separator
+ --cur_path_ptr;
+
+ assert(cur_path_ptr - search_path < (ptrdiff_t)search_path_size);
+ *cur_path_ptr = '\0';
+#endif
+ }
+
+ // Print out the paths being searched if debugging is enabled
+ if (search_path_size > 0) {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "ReadDataFilesInSearchPaths: Searching the following paths for manifest files: %s\n", search_path);
+ }
+
+ // Now, parse the paths and add any manifest files found in them.
+ vk_result = AddDataFilesInPath(inst, search_path, is_directory_list, out_files);
+
+ if (NULL != override_path) {
+ *override_active = true;
+ } else {
+ *override_active = false;
+ }
+
+out:
+
+ if (NULL != override_env) {
+ loader_free_getenv(override_env, inst);
+ }
+#ifndef _WIN32
+ if (xdgconfig_alloc) {
+ loader_free_getenv(xdgconfdirs, inst);
+ }
+ if (xdgdata_alloc) {
+ loader_free_getenv(xdgdatadirs, inst);
+ }
+ if (NULL != xdgdatahome) {
+ loader_free_getenv(xdgdatahome, inst);
+ }
+ if (NULL != home) {
+ loader_free_getenv(home, inst);
+ }
+ if (NULL != home_root) {
+ loader_instance_heap_free(inst, home_root);
+ }
+#endif
+
+ if (NULL != search_path) {
+ loader_instance_heap_free(inst, search_path);
+ }
+
+ return vk_result;
+}
+
+#ifdef _WIN32
+// Read manifest JSON files uing the Windows driver interface
+static VkResult ReadManifestsFromD3DAdapters(const struct loader_instance *inst, char **reg_data, PDWORD reg_data_size,
+ const wchar_t *value_name) {
+ VkResult result = VK_INCOMPLETE;
+ LoaderEnumAdapters2 adapters = {.adapter_count = 0, .adapters = NULL};
+ LoaderQueryRegistryInfo *full_info = NULL;
+ size_t full_info_size = 0;
+ char *json_path = NULL;
+ size_t json_path_size = 0;
+
+ PFN_LoaderEnumAdapters2 fpLoaderEnumAdapters2 =
+ (PFN_LoaderEnumAdapters2)GetProcAddress(GetModuleHandle("gdi32.dll"), "D3DKMTEnumAdapters2");
+ PFN_LoaderQueryAdapterInfo fpLoaderQueryAdapterInfo =
+ (PFN_LoaderQueryAdapterInfo)GetProcAddress(GetModuleHandle("gdi32.dll"), "D3DKMTQueryAdapterInfo");
+ if (fpLoaderEnumAdapters2 == NULL || fpLoaderQueryAdapterInfo == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // Get all of the adapters
+ NTSTATUS status = fpLoaderEnumAdapters2(&adapters);
+ if (status == STATUS_SUCCESS && adapters.adapter_count > 0) {
+ adapters.adapters = loader_instance_heap_alloc(inst, sizeof(*adapters.adapters) * adapters.adapter_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (adapters.adapters == NULL) {
+ goto out;
+ }
+ status = fpLoaderEnumAdapters2(&adapters);
+ }
+ if (status != STATUS_SUCCESS) {
+ goto out;
+ }
+
+ // If that worked, we need to get the manifest file(s) for each adapter
+ for (ULONG i = 0; i < adapters.adapter_count; ++i) {
+ // The first query should just check if the field exists and how big it is
+ LoaderQueryRegistryInfo filename_info = {
+ .query_type = LOADER_QUERY_REGISTRY_ADAPTER_KEY,
+ .query_flags =
+ {
+ .translate_path = true,
+ },
+ .value_type = REG_MULTI_SZ,
+ .physical_adapter_index = 0,
+ };
+ wcsncpy(filename_info.value_name, value_name, sizeof(filename_info.value_name) / sizeof(DWORD));
+ LoaderQueryAdapterInfo query_info = {
+ .handle = adapters.adapters[i].handle,
+ .type = LOADER_QUERY_TYPE_REGISTRY,
+ .private_data = &filename_info,
+ .private_data_size = sizeof(filename_info),
+ };
+ status = fpLoaderQueryAdapterInfo(&query_info);
+
+ // This error indicates that the type didn't match, so we'll try a REG_SZ
+ if (status != STATUS_SUCCESS) {
+ filename_info.value_type = REG_SZ;
+ status = fpLoaderQueryAdapterInfo(&query_info);
+ }
+
+ if (status != STATUS_SUCCESS || filename_info.status != LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW) {
+ continue;
+ }
+
+ while (status == STATUS_SUCCESS &&
+ ((LoaderQueryRegistryInfo *)query_info.private_data)->status == LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW) {
+ bool needs_copy = (full_info == NULL);
+ size_t full_size = sizeof(LoaderQueryRegistryInfo) + filename_info.output_value_size;
+ void *buffer =
+ loader_instance_heap_realloc(inst, full_info, full_info_size, full_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (buffer == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ full_info = buffer;
+ full_info_size = full_size;
+
+ if (needs_copy) {
+ memcpy(full_info, &filename_info, sizeof(LoaderQueryRegistryInfo));
+ }
+ query_info.private_data = full_info;
+ query_info.private_data_size = (UINT)full_info_size;
+ status = fpLoaderQueryAdapterInfo(&query_info);
+ }
+
+ if (status != STATUS_SUCCESS || full_info->status != LOADER_QUERY_REGISTRY_STATUS_SUCCESS) {
+ goto out;
+ }
+
+ // Convert the wide string to a narrow string
+ void *buffer = loader_instance_heap_realloc(inst, json_path, json_path_size, full_info->output_value_size,
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (buffer == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ json_path = buffer;
+ json_path_size = full_info->output_value_size;
+
+ // Iterate over each component string
+ for (const wchar_t *curr_path = full_info->output_string; curr_path[0] != '\0'; curr_path += wcslen(curr_path) + 1) {
+ WideCharToMultiByte(CP_UTF8, 0, curr_path, -1, json_path, (int)json_path_size, NULL, NULL);
+
+ // Add the string to the output list
+ result = VK_SUCCESS;
+ loaderAddJsonEntry(inst, reg_data, reg_data_size, (LPCTSTR)L"EnumAdapters", REG_SZ, json_path,
+ (DWORD)strlen(json_path) + 1, &result);
+ if (result != VK_SUCCESS) {
+ goto out;
+ }
+
+ // If this is a string and not a multi-string, we don't want to go throught the loop more than once
+ if (full_info->value_type == REG_SZ) {
+ break;
+ }
+ }
+ }
+
+out:
+ if (json_path != NULL) {
+ loader_instance_heap_free(inst, json_path);
+ }
+ if (full_info != NULL) {
+ loader_instance_heap_free(inst, full_info);
+ }
+ if (adapters.adapters != NULL) {
+ loader_instance_heap_free(inst, adapters.adapters);
+ }
+
+ return result;
+}
+
+// Look for data files in the registry.
+static VkResult ReadDataFilesInRegistry(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
+ bool warn_if_not_present, char *registry_location, struct loader_data_files *out_files) {
+ VkResult vk_result = VK_SUCCESS;
+ bool is_icd = (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD);
+ char *search_path = NULL;
+
+ // These calls look at the PNP/Device section of the registry.
+ VkResult regHKR_result = VK_SUCCESS;
+ DWORD reg_size = 4096;
+ if (!strncmp(registry_location, VK_DRIVERS_INFO_REGISTRY_LOC, sizeof(VK_DRIVERS_INFO_REGISTRY_LOC))) {
+ // If we're looking for drivers we need to try enumerating adapters
+ regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, &reg_size, LoaderPnpDriverRegistryWide());
+ if (regHKR_result == VK_INCOMPLETE) {
+ regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpDriverRegistry());
+ }
+ } else if (!strncmp(registry_location, VK_ELAYERS_INFO_REGISTRY_LOC, sizeof(VK_ELAYERS_INFO_REGISTRY_LOC))) {
+ regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, &reg_size, LoaderPnpELayerRegistryWide());
+ if (regHKR_result == VK_INCOMPLETE) {
+ regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpELayerRegistry());
+ }
+ } else if (!strncmp(registry_location, VK_ILAYERS_INFO_REGISTRY_LOC, sizeof(VK_ILAYERS_INFO_REGISTRY_LOC))) {
+ regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, &reg_size, LoaderPnpILayerRegistryWide());
+ if (regHKR_result == VK_INCOMPLETE) {
+ regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, &reg_size, LoaderPnpILayerRegistry());
+ }
+ }
+
+ // This call looks into the Khronos non-device specific section of the registry.
+ bool use_secondary_hive = (data_file_type == LOADER_DATA_FILE_MANIFEST_LAYER) && (!IsHighIntegrity());
+ VkResult reg_result = loaderGetRegistryFiles(inst, registry_location, use_secondary_hive, &search_path, &reg_size);
+
+ if ((VK_SUCCESS != reg_result && VK_SUCCESS != regHKR_result) || NULL == search_path) {
+ if (data_file_type == LOADER_DATA_FILE_MANIFEST_ICD) {
+ loader_log(
+ inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ReadDataFilesInRegistry: Registry lookup failed to get ICD manifest files. Possibly missing Vulkan driver?");
+ if (VK_SUCCESS == reg_result || VK_ERROR_OUT_OF_HOST_MEMORY == reg_result) {
+ vk_result = reg_result;
+ } else {
+ vk_result = regHKR_result;
+ }
+ } else {
+ if (warn_if_not_present) {
+ if (data_file_type == LOADER_DATA_FILE_MANIFEST_LAYER) {
+ // This is only a warning for layers
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "ReadDataFilesInRegistry: Registry lookup failed to get layer manifest files.");
+ } else {
+ // This is only a warning for general data files
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "ReadDataFilesInRegistry: Registry lookup failed to get data files.");
+ }
+ }
+ if (reg_result == VK_ERROR_OUT_OF_HOST_MEMORY) {
+ vk_result = reg_result;
+ } else {
+ // Return success for now since it's not critical for layers
+ vk_result = VK_SUCCESS;
+ }
+ }
+ goto out;
+ }
+
+ // Now, parse the paths and add any manifest files found in them.
+ vk_result = AddDataFilesInPath(inst, search_path, false, out_files);
+
+out:
+
+ if (NULL != search_path) {
+ loader_instance_heap_free(inst, search_path);
+ }
+
+ return vk_result;
+}
+#endif // _WIN32
+
+// Find the Vulkan library manifest files.
+//
+// This function scans the "location" or "env_override" directories/files
+// for a list of JSON manifest files. If env_override is non-NULL
+// and has a valid value. Then the location is ignored. Otherwise
+// location is used to look for manifest files. The location
+// is interpreted as Registry path on Windows and a directory path(s)
+// on Linux. "home_location" is an additional directory in the users home
+// directory to look at. It is expanded into the dir path
+// $XDG_DATA_HOME/home_location or $HOME/.local/share/home_location depending
+// on environment variables. This "home_location" is only used on Linux.
+//
+// \returns
+// VKResult
+// A string list of manifest files to be opened in out_files param.
+// List has a pointer to string for each manifest filename.
+// When done using the list in out_files, pointers should be freed.
+// Location or override string lists can be either files or directories as
+// follows:
+// | location | override
+// --------------------------------
+// Win ICD | files | files
+// Win Layer | files | dirs
+// Linux ICD | dirs | files
+// Linux Layer| dirs | dirs
+static VkResult loaderGetDataFiles(const struct loader_instance *inst, enum loader_data_files_type data_file_type,
+ bool warn_if_not_present, const char *env_override, const char *path_override,
+ char *registry_location, const char *relative_location, struct loader_data_files *out_files) {
+ VkResult res = VK_SUCCESS;
+ bool override_active = false;
+
+ // Free and init the out_files information so there's no false data left from uninitialized variables.
+ if (out_files->filename_list != NULL) {
+ for (uint32_t i = 0; i < out_files->count; i++) {
+ if (NULL != out_files->filename_list[i]) {
+ loader_instance_heap_free(inst, out_files->filename_list[i]);
+ out_files->filename_list[i] = NULL;
+ }
+ }
+ loader_instance_heap_free(inst, out_files->filename_list);
+ }
+ out_files->count = 0;
+ out_files->alloc_count = 0;
+ out_files->filename_list = NULL;
+
+ res = ReadDataFilesInSearchPaths(inst, data_file_type, env_override, path_override, relative_location, &override_active,
+ out_files);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+
+#ifdef _WIN32
+ // Read the registry if the override wasn't active.
+ if (!override_active) {
+ res = ReadDataFilesInRegistry(inst, data_file_type, warn_if_not_present, registry_location, out_files);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+ }
+#endif
+
+out:
+
+ if (VK_SUCCESS != res && NULL != out_files->filename_list) {
+ for (uint32_t remove = 0; remove < out_files->count; remove++) {
+ loader_instance_heap_free(inst, out_files->filename_list[remove]);
+ }
+ loader_instance_heap_free(inst, out_files->filename_list);
+ out_files->count = 0;
+ out_files->alloc_count = 0;
+ out_files->filename_list = NULL;
+ }
+
+ return res;
+}
+
+void loader_init_icd_lib_list() {}
+
+void loader_destroy_icd_lib_list() {}
+
+// Try to find the Vulkan ICD driver(s).
+//
+// This function scans the default system loader path(s) or path
+// specified by the \c VK_ICD_FILENAMES environment variable in
+// order to find loadable VK ICDs manifest files. From these
+// manifest files it finds the ICD libraries.
+//
+// \returns
+// Vulkan result
+// (on result == VK_SUCCESS) a list of icds that were discovered
+VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list) {
+ char *file_str;
+ uint16_t file_major_vers = 0;
+ uint16_t file_minor_vers = 0;
+ uint16_t file_patch_vers = 0;
+ char *vers_tok;
+ struct loader_data_files manifest_files;
+ VkResult res = VK_SUCCESS;
+ bool lockedMutex = false;
+ cJSON *json = NULL;
+ uint32_t num_good_icds = 0;
+
+ memset(&manifest_files, 0, sizeof(struct loader_data_files));
+
+ res = loader_scanned_icd_init(inst, icd_tramp_list);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+
+ // Get a list of manifest files for ICDs
+ res = loaderGetDataFiles(inst, LOADER_DATA_FILE_MANIFEST_ICD, true, "VK_ICD_FILENAMES", NULL, VK_DRIVERS_INFO_REGISTRY_LOC,
+ VK_DRIVERS_INFO_RELATIVE_DIR, &manifest_files);
+ if (VK_SUCCESS != res || manifest_files.count == 0) {
+ goto out;
+ }
+
+ loader_platform_thread_lock_mutex(&loader_json_lock);
+ lockedMutex = true;
+ for (uint32_t i = 0; i < manifest_files.count; i++) {
+ file_str = manifest_files.filename_list[i];
+ if (file_str == NULL) {
+ continue;
+ }
+
+ VkResult temp_res = loader_get_json(inst, file_str, &json);
+ if (NULL == json || temp_res != VK_SUCCESS) {
+ if (NULL != json) {
+ cJSON_Delete(json);
+ json = NULL;
+ }
+ // If we haven't already found an ICD, copy this result to
+ // the returned result.
+ if (num_good_icds == 0) {
+ res = temp_res;
+ }
+ if (temp_res == VK_ERROR_OUT_OF_HOST_MEMORY) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ res = temp_res;
+
+ cJSON *item, *itemICD;
+ item = cJSON_GetObjectItem(json, "file_format_version");
+ if (item == NULL) {
+ if (num_good_icds == 0) {
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ }
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: ICD JSON %s does not have a"
+ " \'file_format_version\' field. Skipping ICD JSON.",
+ file_str);
+ cJSON_Delete(json);
+ json = NULL;
+ continue;
+ }
+
+ char *file_vers = cJSON_Print(item);
+ if (NULL == file_vers) {
+ // Only reason the print can fail is if there was an allocation issue
+ if (num_good_icds == 0) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: Failed retrieving ICD JSON %s"
+ " \'file_format_version\' field. Skipping ICD JSON",
+ file_str);
+ cJSON_Delete(json);
+ json = NULL;
+ continue;
+ }
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Found ICD manifest file %s, version %s", file_str, file_vers);
+
+ // Get the major/minor/and patch as integers for easier comparison
+ vers_tok = strtok(file_vers, ".\"\n\r");
+ if (NULL != vers_tok) {
+ file_major_vers = (uint16_t)atoi(vers_tok);
+ vers_tok = strtok(NULL, ".\"\n\r");
+ if (NULL != vers_tok) {
+ file_minor_vers = (uint16_t)atoi(vers_tok);
+ vers_tok = strtok(NULL, ".\"\n\r");
+ if (NULL != vers_tok) {
+ file_patch_vers = (uint16_t)atoi(vers_tok);
+ }
+ }
+ }
+
+ if (file_major_vers != 1 || file_minor_vers != 0 || file_patch_vers > 1) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: Unexpected manifest file version "
+ "(expected 1.0.0 or 1.0.1), may cause errors");
+ }
+ cJSON_Free(file_vers);
+
+ itemICD = cJSON_GetObjectItem(json, "ICD");
+ if (itemICD != NULL) {
+ item = cJSON_GetObjectItem(itemICD, "library_path");
+ if (item != NULL) {
+ char *temp = cJSON_Print(item);
+ if (!temp || strlen(temp) == 0) {
+ if (num_good_icds == 0) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: Failed retrieving ICD JSON %s"
+ " \'library_path\' field. Skipping ICD JSON.",
+ file_str);
+ cJSON_Free(temp);
+ cJSON_Delete(json);
+ json = NULL;
+ continue;
+ }
+ // strip out extra quotes
+ temp[strlen(temp) - 1] = '\0';
+ char *library_path = loader_stack_alloc(strlen(temp) + 1);
+ if (NULL == library_path) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_icd_scan: Failed to allocate space for "
+ "ICD JSON %s \'library_path\' value. Skipping "
+ "ICD JSON.",
+ file_str);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ cJSON_Free(temp);
+ cJSON_Delete(json);
+ json = NULL;
+ goto out;
+ }
+ strcpy(library_path, &temp[1]);
+ cJSON_Free(temp);
+ if (strlen(library_path) == 0) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: ICD JSON %s \'library_path\'"
+ " field is empty. Skipping ICD JSON.",
+ file_str);
+ cJSON_Delete(json);
+ json = NULL;
+ continue;
+ }
+ char fullpath[MAX_STRING_SIZE];
+ // Print out the paths being searched if debugging is enabled
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Searching for ICD drivers named %s", library_path);
+ if (loader_platform_is_path(library_path)) {
+ // a relative or absolute path
+ char *name_copy = loader_stack_alloc(strlen(file_str) + 1);
+ char *rel_base;
+ strcpy(name_copy, file_str);
+ rel_base = loader_platform_dirname(name_copy);
+ loader_expand_path(library_path, rel_base, sizeof(fullpath), fullpath);
+ } else {
+// a filename which is assumed in a system directory
+#if defined(DEFAULT_VK_DRIVERS_PATH)
+ loader_get_fullpath(library_path, DEFAULT_VK_DRIVERS_PATH, sizeof(fullpath), fullpath);
+#else
+ loader_get_fullpath(library_path, "", sizeof(fullpath), fullpath);
+#endif
+ }
+
+ uint32_t vers = 0;
+ item = cJSON_GetObjectItem(itemICD, "api_version");
+ if (item != NULL) {
+ temp = cJSON_Print(item);
+ if (NULL == temp) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: Failed retrieving ICD JSON %s"
+ " \'api_version\' field. Skipping ICD JSON.",
+ file_str);
+
+ // Only reason the print can fail is if there was an
+ // allocation issue
+ if (num_good_icds == 0) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ cJSON_Free(temp);
+ cJSON_Delete(json);
+ json = NULL;
+ continue;
+ }
+ vers = loader_make_version(temp);
+ cJSON_Free(temp);
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: ICD JSON %s does not have an"
+ " \'api_version\' field.",
+ file_str);
+ }
+
+ res = loader_scanned_icd_add(inst, icd_tramp_list, fullpath, vers);
+ if (VK_SUCCESS != res) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_icd_scan: Failed to add ICD JSON %s. "
+ " Skipping ICD JSON.",
+ fullpath);
+ cJSON_Delete(json);
+ json = NULL;
+ continue;
+ }
+ num_good_icds++;
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: Failed to find \'library_path\' "
+ "object in ICD JSON file %s. Skipping ICD JSON.",
+ file_str);
+ }
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_icd_scan: Can not find \'ICD\' object in ICD JSON "
+ "file %s. Skipping ICD JSON",
+ file_str);
+ }
+
+ cJSON_Delete(json);
+ json = NULL;
+ }
+
+out:
+
+ if (NULL != json) {
+ cJSON_Delete(json);
+ }
+
+ if (NULL != manifest_files.filename_list) {
+ for (uint32_t i = 0; i < manifest_files.count; i++) {
+ if (NULL != manifest_files.filename_list[i]) {
+ loader_instance_heap_free(inst, manifest_files.filename_list[i]);
+ }
+ }
+ loader_instance_heap_free(inst, manifest_files.filename_list);
+ }
+ if (lockedMutex) {
+ loader_platform_thread_unlock_mutex(&loader_json_lock);
+ }
+
+ return res;
+}
+
+void loaderScanForLayers(struct loader_instance *inst, struct loader_layer_list *instance_layers) {
+ char *file_str;
+ struct loader_data_files manifest_files;
+ cJSON *json;
+ bool override_layer_valid = false;
+ char *override_paths = NULL;
+ uint32_t total_count = 0;
+
+ memset(&manifest_files, 0, sizeof(struct loader_data_files));
+
+ // Cleanup any previously scanned libraries
+ loaderDeleteLayerListAndProperties(inst, instance_layers);
+
+ loader_platform_thread_lock_mutex(&loader_json_lock);
+
+ // Get a list of manifest files for any implicit layers
+ // Pass NULL for environment variable override - implicit layers are not overridden by LAYERS_PATH_ENV
+ if (VK_SUCCESS != loaderGetDataFiles(inst, LOADER_DATA_FILE_MANIFEST_LAYER, false, NULL, NULL, VK_ILAYERS_INFO_REGISTRY_LOC,
+ VK_ILAYERS_INFO_RELATIVE_DIR, &manifest_files)) {
+ goto out;
+ }
+
+ if (manifest_files.count != 0) {
+ total_count += manifest_files.count;
+ for (uint32_t i = 0; i < manifest_files.count; i++) {
+ file_str = manifest_files.filename_list[i];
+ if (file_str == NULL) {
+ continue;
+ }
+
+ // Parse file into JSON struct
+ VkResult res = loader_get_json(inst, file_str, &json);
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ goto out;
+ } else if (VK_SUCCESS != res || NULL == json) {
+ continue;
+ }
+
+ VkResult local_res = loaderAddLayerProperties(inst, instance_layers, json, true, file_str);
+ cJSON_Delete(json);
+
+ if (VK_SUCCESS != local_res) {
+ goto out;
+ }
+ }
+ }
+
+ // Check to see if the override layer is present, and use it's override paths.
+ for (int32_t i = 0; i < (int32_t)instance_layers->count; i++) {
+ struct loader_layer_properties *prop = &instance_layers->list[i];
+ if (prop->is_override && loaderImplicitLayerIsEnabled(inst, prop) && prop->num_override_paths > 0) {
+ char *cur_write_ptr = NULL;
+ size_t override_path_size = 0;
+ for (uint32_t j = 0; j < prop->num_override_paths; j++) {
+ override_path_size += DetermineDataFilePathSize(prop->override_paths[j], 0);
+ }
+ override_paths = loader_instance_heap_alloc(inst, override_path_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (override_paths == NULL) {
+ goto out;
+ }
+ cur_write_ptr = &override_paths[0];
+ for (uint32_t j = 0; j < prop->num_override_paths; j++) {
+ CopyDataFilePath(prop->override_paths[j], NULL, 0, &cur_write_ptr);
+ }
+ // Remove the last path separator
+ --cur_write_ptr;
+ assert(cur_write_ptr - override_paths < (ptrdiff_t)override_path_size);
+ *cur_write_ptr = '\0';
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "loaderScanForLayers: Override layer has override paths set to %s",
+ override_paths);
+ }
+ }
+
+ // Get a list of manifest files for explicit layers
+ if (VK_SUCCESS != loaderGetDataFiles(inst, LOADER_DATA_FILE_MANIFEST_LAYER, true, "VK_LAYER_PATH", override_paths,
+ VK_ELAYERS_INFO_REGISTRY_LOC, VK_ELAYERS_INFO_RELATIVE_DIR, &manifest_files)) {
+ goto out;
+ }
+
+ // Make sure we have at least one layer, if not, go ahead and return
+ if (manifest_files.count == 0 && total_count == 0) {
+ goto out;
+ } else {
+ total_count += manifest_files.count;
+ for (uint32_t i = 0; i < manifest_files.count; i++) {
+ file_str = manifest_files.filename_list[i];
+ if (file_str == NULL) {
+ continue;
+ }
+
+ // Parse file into JSON struct
+ VkResult res = loader_get_json(inst, file_str, &json);
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ goto out;
+ } else if (VK_SUCCESS != res || NULL == json) {
+ continue;
+ }
+
+ VkResult local_res = loaderAddLayerProperties(inst, instance_layers, json, false, file_str);
+ cJSON_Delete(json);
+
+ // If the error is anything other than out of memory we still want to try to load the other layers
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == local_res) {
+ goto out;
+ }
+ }
+ }
+
+ // See if "VK_LAYER_LUNARG_standard_validation" already in list.
+ bool found_std_val = false;
+ for (uint32_t i = 0; i < instance_layers->count; i++) {
+ struct loader_layer_properties *props = &instance_layers->list[i];
+ if (strcmp(props->info.layerName, std_validation_str) == 0) {
+ found_std_val = true;
+ break;
+ }
+ }
+
+ // If we didn't find the VK_LAYER_LUNARG_standard_validation meta-layer in
+ // the list, then we need to add it manually. This is likely because we're
+ // dealing with a new loader, but an old layer folder.
+ if (!found_std_val && !loaderAddLegacyStandardValidationLayer(inst, instance_layers)) {
+ goto out;
+ }
+
+ // Verify any meta-layers in the list are valid and all the component layers are
+ // actually present in the available layer list
+ VerifyAllMetaLayers(inst, instance_layers, &override_layer_valid);
+
+ if (override_layer_valid) {
+ loaderRemoveLayersInBlacklist(inst, instance_layers);
+ if (NULL != inst) {
+ inst->override_layer_present = true;
+ }
+ }
+
+out:
+
+ if (NULL != override_paths) {
+ loader_instance_heap_free(inst, override_paths);
+ }
+ if (NULL != manifest_files.filename_list) {
+ for (uint32_t i = 0; i < manifest_files.count; i++) {
+ if (NULL != manifest_files.filename_list[i]) {
+ loader_instance_heap_free(inst, manifest_files.filename_list[i]);
+ }
+ }
+ loader_instance_heap_free(inst, manifest_files.filename_list);
+ }
+ loader_platform_thread_unlock_mutex(&loader_json_lock);
+}
+
+void loaderScanForImplicitLayers(struct loader_instance *inst, struct loader_layer_list *instance_layers) {
+ char *file_str;
+ struct loader_data_files manifest_files;
+ cJSON *json;
+ bool override_layer_valid = false;
+ char *override_paths = NULL;
+ bool implicit_metalayer_present = false;
+ bool have_json_lock = false;
+
+ // Before we begin anything, init manifest_files to avoid a delete of garbage memory if
+ // a failure occurs before allocating the manifest filename_list.
+ memset(&manifest_files, 0, sizeof(struct loader_data_files));
+
+ // Pass NULL for environment variable override - implicit layers are not overridden by LAYERS_PATH_ENV
+ VkResult res = loaderGetDataFiles(inst, LOADER_DATA_FILE_MANIFEST_LAYER, false, NULL, NULL, VK_ILAYERS_INFO_REGISTRY_LOC,
+ VK_ILAYERS_INFO_RELATIVE_DIR, &manifest_files);
+ if (VK_SUCCESS != res || manifest_files.count == 0) {
+ goto out;
+ }
+
+ // Cleanup any previously scanned libraries
+ loaderDeleteLayerListAndProperties(inst, instance_layers);
+
+ loader_platform_thread_lock_mutex(&loader_json_lock);
+ have_json_lock = true;
+
+ for (uint32_t i = 0; i < manifest_files.count; i++) {
+ file_str = manifest_files.filename_list[i];
+ if (file_str == NULL) {
+ continue;
+ }
+
+ // parse file into JSON struct
+ res = loader_get_json(inst, file_str, &json);
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ goto out;
+ } else if (VK_SUCCESS != res || NULL == json) {
+ continue;
+ }
+
+ res = loaderAddLayerProperties(inst, instance_layers, json, true, file_str);
+
+ loader_instance_heap_free(inst, file_str);
+ manifest_files.filename_list[i] = NULL;
+ cJSON_Delete(json);
+
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ goto out;
+ }
+ }
+
+ // Check to see if either the override layer is present, or another implicit meta-layer.
+ // Each of these may require explicit layers to be enabled at this time.
+ for (int32_t i = 0; i < (int32_t)instance_layers->count; i++) {
+ struct loader_layer_properties *prop = &instance_layers->list[i];
+ if (prop->is_override && loaderImplicitLayerIsEnabled(inst, prop)) {
+ override_layer_valid = true;
+ if (prop->num_override_paths > 0) {
+ char *cur_write_ptr = NULL;
+ size_t override_path_size = 0;
+ for (uint32_t j = 0; j < prop->num_override_paths; j++) {
+ override_path_size += DetermineDataFilePathSize(prop->override_paths[j], 0);
+ }
+ override_paths = loader_instance_heap_alloc(inst, override_path_size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (override_paths == NULL) {
+ goto out;
+ }
+ cur_write_ptr = &override_paths[0];
+ for (uint32_t j = 0; j < prop->num_override_paths; j++) {
+ CopyDataFilePath(prop->override_paths[j], NULL, 0, &cur_write_ptr);
+ }
+ // Remove the last path separator
+ --cur_write_ptr;
+ assert(cur_write_ptr - override_paths < (ptrdiff_t)override_path_size);
+ *cur_write_ptr = '\0';
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loaderScanForImplicitLayers: Override layer has override paths set to %s", override_paths);
+ }
+ } else if (!prop->is_override && prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER) {
+ implicit_metalayer_present = true;
+ }
+ }
+
+ // If either the override layer or an implicit meta-layer are present, we need to add
+ // explicit layer info as well. Not to worry, though, all explicit layers not included
+ // in the override layer will be removed below in loaderRemoveLayersInBlacklist().
+ if (override_layer_valid || implicit_metalayer_present) {
+ if (VK_SUCCESS != loaderGetDataFiles(inst, LOADER_DATA_FILE_MANIFEST_LAYER, true, "VK_LAYER_PATH", override_paths,
+ VK_ELAYERS_INFO_REGISTRY_LOC, VK_ELAYERS_INFO_RELATIVE_DIR, &manifest_files)) {
+ goto out;
+ }
+
+ for (uint32_t i = 0; i < manifest_files.count; i++) {
+ file_str = manifest_files.filename_list[i];
+ if (file_str == NULL) {
+ continue;
+ }
+
+ // parse file into JSON struct
+ res = loader_get_json(inst, file_str, &json);
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ goto out;
+ } else if (VK_SUCCESS != res || NULL == json) {
+ continue;
+ }
+
+ res = loaderAddLayerProperties(inst, instance_layers, json, true, file_str);
+
+ loader_instance_heap_free(inst, file_str);
+ cJSON_Delete(json);
+
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ goto out;
+ }
+ }
+ }
+
+ // Verify any meta-layers in the list are valid and all the component layers are
+ // actually present in the available layer list
+ VerifyAllMetaLayers(inst, instance_layers, &override_layer_valid);
+
+ if (override_layer_valid || implicit_metalayer_present) {
+ loaderRemoveLayersNotInImplicitMetaLayers(inst, instance_layers);
+ if (override_layer_valid && inst != NULL) {
+ inst->override_layer_present = true;
+ }
+ }
+
+out:
+
+ if (NULL != override_paths) {
+ loader_instance_heap_free(inst, override_paths);
+ }
+ if (NULL != manifest_files.filename_list) {
+ loader_instance_heap_free(inst, manifest_files.filename_list);
+ }
+
+ if (have_json_lock) {
+ loader_platform_thread_unlock_mutex(&loader_json_lock);
+ }
+}
+
+static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpdpa_instance_internal(VkInstance inst, const char *pName) {
+ // inst is not wrapped
+ if (inst == VK_NULL_HANDLE) {
+ return NULL;
+ }
+ VkLayerInstanceDispatchTable *disp_table = *(VkLayerInstanceDispatchTable **)inst;
+ void *addr;
+
+ if (disp_table == NULL) return NULL;
+
+ bool found_name;
+ addr = loader_lookup_instance_dispatch_table(disp_table, pName, &found_name);
+ if (found_name) {
+ return addr;
+ }
+
+ if (loader_phys_dev_ext_gpa(loader_get_instance(inst), pName, true, NULL, &addr)) return addr;
+
+ // Don't call down the chain, this would be an infinite loop
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "loader_gpdpa_instance_internal() unrecognized name %s", pName);
+ return NULL;
+}
+
+static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpdpa_instance_terminator(VkInstance inst, const char *pName) {
+ // inst is not wrapped
+ if (inst == VK_NULL_HANDLE) {
+ return NULL;
+ }
+ VkLayerInstanceDispatchTable *disp_table = *(VkLayerInstanceDispatchTable **)inst;
+ void *addr;
+
+ if (disp_table == NULL) return NULL;
+
+ bool found_name;
+ addr = loader_lookup_instance_dispatch_table(disp_table, pName, &found_name);
+ if (found_name) {
+ return addr;
+ }
+
+ // Get the terminator, but don't perform checking since it should already
+ // have been setup if we get here.
+ if (loader_phys_dev_ext_gpa(loader_get_instance(inst), pName, false, NULL, &addr)) {
+ return addr;
+ }
+
+ // Don't call down the chain, this would be an infinite loop
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "loader_gpdpa_instance_terminator() unrecognized name %s", pName);
+ return NULL;
+}
+
+static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_internal(VkInstance inst, const char *pName) {
+ if (!strcmp(pName, "vkGetInstanceProcAddr")) {
+ return (PFN_vkVoidFunction)loader_gpa_instance_internal;
+ }
+ if (!strcmp(pName, "vk_layerGetPhysicalDeviceProcAddr")) {
+ return (PFN_vkVoidFunction)loader_gpdpa_instance_terminator;
+ }
+ if (!strcmp(pName, "vkCreateInstance")) {
+ return (PFN_vkVoidFunction)terminator_CreateInstance;
+ }
+ if (!strcmp(pName, "vkCreateDevice")) {
+ return (PFN_vkVoidFunction)terminator_CreateDevice;
+ }
+
+ // inst is not wrapped
+ if (inst == VK_NULL_HANDLE) {
+ return NULL;
+ }
+ VkLayerInstanceDispatchTable *disp_table = *(VkLayerInstanceDispatchTable **)inst;
+ void *addr;
+
+ if (disp_table == NULL) return NULL;
+
+ bool found_name;
+ addr = loader_lookup_instance_dispatch_table(disp_table, pName, &found_name);
+ if (found_name) {
+ return addr;
+ }
+
+ // Don't call down the chain, this would be an infinite loop
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, "loader_gpa_instance_internal() unrecognized name %s", pName);
+ return NULL;
+}
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_device_internal(VkDevice device, const char *pName) {
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, NULL);
+
+ // Return this function if a layer above here is asking for the vkGetDeviceProcAddr.
+ // This is so we can properly intercept any device commands needing a terminator.
+ if (!strcmp(pName, "vkGetDeviceProcAddr")) {
+ return (PFN_vkVoidFunction)loader_gpa_device_internal;
+ }
+
+ // NOTE: Device Funcs needing Trampoline/Terminator.
+ // Overrides for device functions needing a trampoline and
+ // a terminator because certain device entry-points still need to go
+ // through a terminator before hitting the ICD. This could be for
+ // several reasons, but the main one is currently unwrapping an
+ // object before passing the appropriate info along to the ICD.
+ // This is why we also have to override the direct ICD call to
+ // vkGetDeviceProcAddr to intercept those calls.
+ PFN_vkVoidFunction addr = get_extension_device_proc_terminator(dev, pName);
+ if (NULL != addr) {
+ return addr;
+ }
+
+ return icd_term->dispatch.GetDeviceProcAddr(device, pName);
+}
+
+// Initialize device_ext dispatch table entry as follows:
+// If dev == NULL find all logical devices created within this instance and
+// init the entry (given by idx) in the ext dispatch table.
+// If dev != NULL only initialize the entry in the given dev's dispatch table.
+// The initialization value is gotten by calling down the device chain with
+// GDPA.
+// If GDPA returns NULL then don't initialize the dispatch table entry.
+static void loader_init_dispatch_dev_ext_entry(struct loader_instance *inst, struct loader_device *dev, uint32_t idx,
+ const char *funcName)
+
+{
+ void *gdpa_value;
+ if (dev != NULL) {
+ gdpa_value = dev->loader_dispatch.core_dispatch.GetDeviceProcAddr(dev->chain_device, funcName);
+ if (gdpa_value != NULL) dev->loader_dispatch.ext_dispatch.dev_ext[idx] = (PFN_vkDevExt)gdpa_value;
+ } else {
+ for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next) {
+ struct loader_device *ldev = icd_term->logical_device_list;
+ while (ldev) {
+ gdpa_value = ldev->loader_dispatch.core_dispatch.GetDeviceProcAddr(ldev->chain_device, funcName);
+ if (gdpa_value != NULL) ldev->loader_dispatch.ext_dispatch.dev_ext[idx] = (PFN_vkDevExt)gdpa_value;
+ ldev = ldev->next;
+ }
+ }
+ }
+}
+
+// Find all dev extension in the hash table and initialize the dispatch table
+// for dev for each of those extension entrypoints found in hash table.
+void loader_init_dispatch_dev_ext(struct loader_instance *inst, struct loader_device *dev) {
+ for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) {
+ if (inst->dev_ext_disp_hash[i].func_name != NULL)
+ loader_init_dispatch_dev_ext_entry(inst, dev, i, inst->dev_ext_disp_hash[i].func_name);
+ }
+}
+
+static bool loader_check_icds_for_dev_ext_address(struct loader_instance *inst, const char *funcName) {
+ struct loader_icd_term *icd_term;
+ icd_term = inst->icd_terms;
+ while (NULL != icd_term) {
+ if (icd_term->scanned_icd->GetInstanceProcAddr(icd_term->instance, funcName))
+ // this icd supports funcName
+ return true;
+ icd_term = icd_term->next;
+ }
+
+ return false;
+}
+
+static bool loader_check_layer_list_for_dev_ext_address(const struct loader_layer_list *const layers, const char *funcName) {
+ // Iterate over the layers.
+ for (uint32_t layer = 0; layer < layers->count; ++layer) {
+ // Iterate over the extensions.
+ const struct loader_device_extension_list *const extensions = &(layers->list[layer].device_extension_list);
+ for (uint32_t extension = 0; extension < extensions->count; ++extension) {
+ // Iterate over the entry points.
+ const struct loader_dev_ext_props *const property = &(extensions->list[extension]);
+ for (uint32_t entry = 0; entry < property->entrypoint_count; ++entry) {
+ if (strcmp(property->entrypoints[entry], funcName) == 0) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static void loader_free_dev_ext_table(struct loader_instance *inst) {
+ for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) {
+ loader_instance_heap_free(inst, inst->dev_ext_disp_hash[i].func_name);
+ loader_instance_heap_free(inst, inst->dev_ext_disp_hash[i].list.index);
+ }
+ memset(inst->dev_ext_disp_hash, 0, sizeof(inst->dev_ext_disp_hash));
+}
+
+static bool loader_add_dev_ext_table(struct loader_instance *inst, uint32_t *ptr_idx, const char *funcName) {
+ uint32_t i;
+ uint32_t idx = *ptr_idx;
+ struct loader_dispatch_hash_list *list = &inst->dev_ext_disp_hash[idx].list;
+
+ if (!inst->dev_ext_disp_hash[idx].func_name) {
+ // no entry here at this idx, so use it
+ assert(list->capacity == 0);
+ inst->dev_ext_disp_hash[idx].func_name =
+ (char *)loader_instance_heap_alloc(inst, strlen(funcName) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (inst->dev_ext_disp_hash[idx].func_name == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_dev_ext_table: Failed to allocate memory "
+ "for func_name %s",
+ funcName);
+ return false;
+ }
+ strncpy(inst->dev_ext_disp_hash[idx].func_name, funcName, strlen(funcName) + 1);
+ return true;
+ }
+
+ // check for enough capacity
+ if (list->capacity == 0) {
+ list->index = loader_instance_heap_alloc(inst, 8 * sizeof(*(list->index)), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (list->index == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_dev_ext_table: Failed to allocate memory for list index of function %s", funcName);
+ return false;
+ }
+ list->capacity = 8 * sizeof(*(list->index));
+ } else if (list->capacity < (list->count + 1) * sizeof(*(list->index))) {
+ void *new_ptr = loader_instance_heap_realloc(inst, list->index, list->capacity, list->capacity * 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_ptr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_dev_ext_table: Failed to reallocate memory for list index of function %s", funcName);
+ return false;
+ }
+ list->index = new_ptr;
+ list->capacity *= 2;
+ }
+
+ // find an unused index in the hash table and use it
+ i = (idx + 1) % MAX_NUM_UNKNOWN_EXTS;
+ do {
+ if (!inst->dev_ext_disp_hash[i].func_name) {
+ assert(inst->dev_ext_disp_hash[i].list.capacity == 0);
+ inst->dev_ext_disp_hash[i].func_name =
+ (char *)loader_instance_heap_alloc(inst, strlen(funcName) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (inst->dev_ext_disp_hash[i].func_name == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_dev_ext_table: Failed to allocate memory "
+ "for func_name %s",
+ funcName);
+ return false;
+ }
+ strncpy(inst->dev_ext_disp_hash[i].func_name, funcName, strlen(funcName) + 1);
+ list->index[list->count] = i;
+ list->count++;
+ *ptr_idx = i;
+ return true;
+ }
+ i = (i + 1) % MAX_NUM_UNKNOWN_EXTS;
+ } while (i != idx);
+
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_dev_ext_table: Could not insert into hash table; is "
+ "it full?");
+
+ return false;
+}
+
+static bool loader_name_in_dev_ext_table(struct loader_instance *inst, uint32_t *idx, const char *funcName) {
+ uint32_t alt_idx;
+ if (inst->dev_ext_disp_hash[*idx].func_name && !strcmp(inst->dev_ext_disp_hash[*idx].func_name, funcName)) return true;
+
+ // funcName wasn't at the primary spot in the hash table
+ // search the list of secondary locations (shallow search, not deep search)
+ for (uint32_t i = 0; i < inst->dev_ext_disp_hash[*idx].list.count; i++) {
+ alt_idx = inst->dev_ext_disp_hash[*idx].list.index[i];
+ if (!strcmp(inst->dev_ext_disp_hash[*idx].func_name, funcName)) {
+ *idx = alt_idx;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// This function returns generic trampoline code address for unknown entry
+// points.
+// Presumably, these unknown entry points (as given by funcName) are device
+// extension entrypoints. A hash table is used to keep a list of unknown entry
+// points and their mapping to the device extension dispatch table
+// (struct loader_dev_ext_dispatch_table).
+// \returns
+// For a given entry point string (funcName), if an existing mapping is found
+// the
+// trampoline address for that mapping is returned. Otherwise, this unknown
+// entry point
+// has not been seen yet. Next check if a layer or ICD supports it. If so then
+// a
+// new entry in the hash table is initialized and that trampoline address for
+// the new entry is returned. Null is returned if the hash table is full or
+// if no discovered layer or ICD returns a non-NULL GetProcAddr for it.
+void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName) {
+ uint32_t idx;
+ uint32_t seed = 0;
+
+ idx = murmurhash(funcName, strlen(funcName), seed) % MAX_NUM_UNKNOWN_EXTS;
+
+ if (loader_name_in_dev_ext_table(inst, &idx, funcName))
+ // found funcName already in hash
+ return loader_get_dev_ext_trampoline(idx);
+
+ // Check if funcName is supported in either ICDs or a layer library
+ if (!loader_check_icds_for_dev_ext_address(inst, funcName) &&
+ !loader_check_layer_list_for_dev_ext_address(&inst->app_activated_layer_list, funcName)) {
+ // if support found in layers continue on
+ return NULL;
+ }
+
+ if (loader_add_dev_ext_table(inst, &idx, funcName)) {
+ // successfully added new table entry
+ // init any dev dispatch table entries as needed
+ loader_init_dispatch_dev_ext_entry(inst, NULL, idx, funcName);
+ return loader_get_dev_ext_trampoline(idx);
+ }
+
+ return NULL;
+}
+
+static bool loader_check_icds_for_phys_dev_ext_address(struct loader_instance *inst, const char *funcName) {
+ struct loader_icd_term *icd_term;
+ icd_term = inst->icd_terms;
+ while (NULL != icd_term) {
+ if (icd_term->scanned_icd->interface_version >= MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION &&
+ icd_term->scanned_icd->GetPhysicalDeviceProcAddr(icd_term->instance, funcName))
+ // this icd supports funcName
+ return true;
+ icd_term = icd_term->next;
+ }
+
+ return false;
+}
+
+static bool loader_check_layer_list_for_phys_dev_ext_address(struct loader_instance *inst, const char *funcName) {
+ struct loader_layer_properties *layer_prop_list = inst->expanded_activated_layer_list.list;
+ for (uint32_t layer = 0; layer < inst->expanded_activated_layer_list.count; ++layer) {
+ // If this layer supports the vk_layerGetPhysicalDeviceProcAddr, then call
+ // it and see if it returns a valid pointer for this function name.
+ if (layer_prop_list[layer].interface_version > 1) {
+ const struct loader_layer_functions *const functions = &(layer_prop_list[layer].functions);
+ if (NULL != functions->get_physical_device_proc_addr &&
+ NULL != functions->get_physical_device_proc_addr((VkInstance)inst->instance, funcName)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static void loader_free_phys_dev_ext_table(struct loader_instance *inst) {
+ for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) {
+ loader_instance_heap_free(inst, inst->phys_dev_ext_disp_hash[i].func_name);
+ loader_instance_heap_free(inst, inst->phys_dev_ext_disp_hash[i].list.index);
+ }
+ memset(inst->phys_dev_ext_disp_hash, 0, sizeof(inst->phys_dev_ext_disp_hash));
+}
+
+static bool loader_add_phys_dev_ext_table(struct loader_instance *inst, uint32_t *ptr_idx, const char *funcName) {
+ uint32_t i;
+ uint32_t idx = *ptr_idx;
+ struct loader_dispatch_hash_list *list = &inst->phys_dev_ext_disp_hash[idx].list;
+
+ if (!inst->phys_dev_ext_disp_hash[idx].func_name) {
+ // no entry here at this idx, so use it
+ assert(list->capacity == 0);
+ inst->phys_dev_ext_disp_hash[idx].func_name =
+ (char *)loader_instance_heap_alloc(inst, strlen(funcName) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (inst->phys_dev_ext_disp_hash[idx].func_name == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_phys_dev_ext_table() can't allocate memory for "
+ "func_name");
+ return false;
+ }
+ strncpy(inst->phys_dev_ext_disp_hash[idx].func_name, funcName, strlen(funcName) + 1);
+ return true;
+ }
+
+ // check for enough capacity
+ if (list->capacity == 0) {
+ list->index = loader_instance_heap_alloc(inst, 8 * sizeof(*(list->index)), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (list->index == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_add_phys_dev_ext_table() can't allocate list memory");
+ return false;
+ }
+ list->capacity = 8 * sizeof(*(list->index));
+ } else if (list->capacity < (list->count + 1) * sizeof(*(list->index))) {
+ void *new_ptr = loader_instance_heap_realloc(inst, list->index, list->capacity, list->capacity * 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_ptr) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "loader_add_phys_dev_ext_table() can't reallocate list memory");
+ return false;
+ }
+ list->index = new_ptr;
+ list->capacity *= 2;
+ }
+
+ // find an unused index in the hash table and use it
+ i = (idx + 1) % MAX_NUM_UNKNOWN_EXTS;
+ do {
+ if (!inst->phys_dev_ext_disp_hash[i].func_name) {
+ assert(inst->phys_dev_ext_disp_hash[i].list.capacity == 0);
+ inst->phys_dev_ext_disp_hash[i].func_name =
+ (char *)loader_instance_heap_alloc(inst, strlen(funcName) + 1, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (inst->phys_dev_ext_disp_hash[i].func_name == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_dev_ext_table() can't reallocate "
+ "func_name memory");
+ return false;
+ }
+ strncpy(inst->phys_dev_ext_disp_hash[i].func_name, funcName, strlen(funcName) + 1);
+ list->index[list->count] = i;
+ list->count++;
+ *ptr_idx = i;
+ return true;
+ }
+ i = (i + 1) % MAX_NUM_UNKNOWN_EXTS;
+ } while (i != idx);
+
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_add_phys_dev_ext_table() couldn't insert into hash table; is "
+ "it full?");
+ return false;
+}
+
+static bool loader_name_in_phys_dev_ext_table(struct loader_instance *inst, uint32_t *idx, const char *funcName) {
+ uint32_t alt_idx;
+ if (inst->phys_dev_ext_disp_hash[*idx].func_name && !strcmp(inst->phys_dev_ext_disp_hash[*idx].func_name, funcName))
+ return true;
+
+ // funcName wasn't at the primary spot in the hash table
+ // search the list of secondary locations (shallow search, not deep search)
+ for (uint32_t i = 0; i < inst->phys_dev_ext_disp_hash[*idx].list.count; i++) {
+ alt_idx = inst->phys_dev_ext_disp_hash[*idx].list.index[i];
+ if (!strcmp(inst->phys_dev_ext_disp_hash[*idx].func_name, funcName)) {
+ *idx = alt_idx;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// This function returns a generic trampoline and/or terminator function
+// address for any unknown physical device extension commands. A hash
+// table is used to keep a list of unknown entry points and their
+// mapping to the physical device extension dispatch table (struct
+// loader_phys_dev_ext_dispatch_table).
+// For a given entry point string (funcName), if an existing mapping is
+// found, then the trampoline address for that mapping is returned in
+// tramp_addr (if it is not NULL) and the terminator address for that
+// mapping is returned in term_addr (if it is not NULL). Otherwise,
+// this unknown entry point has not been seen yet.
+// If it has not been seen before, and perform_checking is 'true',
+// check if a layer or and ICD supports it. If so then a new entry in
+// the hash table is initialized and the trampoline and/or terminator
+// addresses are returned.
+// Null is returned if the hash table is full or if no discovered layer or
+// ICD returns a non-NULL GetProcAddr for it.
+bool loader_phys_dev_ext_gpa(struct loader_instance *inst, const char *funcName, bool perform_checking, void **tramp_addr,
+ void **term_addr) {
+ uint32_t idx;
+ uint32_t seed = 0;
+ bool success = false;
+
+ if (inst == NULL) {
+ goto out;
+ }
+
+ if (NULL != tramp_addr) {
+ *tramp_addr = NULL;
+ }
+ if (NULL != term_addr) {
+ *term_addr = NULL;
+ }
+
+ // We should always check to see if any ICD supports it.
+ if (!loader_check_icds_for_phys_dev_ext_address(inst, funcName)) {
+ // If we're not checking layers, or we are and it's not in a layer, just
+ // return
+ if (!perform_checking || !loader_check_layer_list_for_phys_dev_ext_address(inst, funcName)) {
+ goto out;
+ }
+ }
+
+ idx = murmurhash(funcName, strlen(funcName), seed) % MAX_NUM_UNKNOWN_EXTS;
+ if (perform_checking && !loader_name_in_phys_dev_ext_table(inst, &idx, funcName)) {
+ uint32_t i;
+ bool added = false;
+
+ // Only need to add first one to get index in Instance. Others will use
+ // the same index.
+ if (!added && loader_add_phys_dev_ext_table(inst, &idx, funcName)) {
+ added = true;
+ }
+
+ // Setup the ICD function pointers
+ struct loader_icd_term *icd_term = inst->icd_terms;
+ while (NULL != icd_term) {
+ if (MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION <= icd_term->scanned_icd->interface_version &&
+ NULL != icd_term->scanned_icd->GetPhysicalDeviceProcAddr) {
+ icd_term->phys_dev_ext[idx] =
+ (PFN_PhysDevExt)icd_term->scanned_icd->GetPhysicalDeviceProcAddr(icd_term->instance, funcName);
+
+ // Make sure we set the instance dispatch to point to the
+ // loader's terminator now since we can at least handle it
+ // in one ICD.
+ inst->disp->phys_dev_ext[idx] = loader_get_phys_dev_ext_termin(idx);
+ } else {
+ icd_term->phys_dev_ext[idx] = NULL;
+ }
+
+ icd_term = icd_term->next;
+ }
+
+ // Now, search for the first layer attached and query using it to get
+ // the first entry point.
+ for (i = 0; i < inst->expanded_activated_layer_list.count; i++) {
+ struct loader_layer_properties *layer_prop = &inst->expanded_activated_layer_list.list[i];
+ if (layer_prop->interface_version > 1 && NULL != layer_prop->functions.get_physical_device_proc_addr) {
+ inst->disp->phys_dev_ext[idx] =
+ (PFN_PhysDevExt)layer_prop->functions.get_physical_device_proc_addr((VkInstance)inst->instance, funcName);
+ if (NULL != inst->disp->phys_dev_ext[idx]) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (NULL != tramp_addr) {
+ *tramp_addr = loader_get_phys_dev_ext_tramp(idx);
+ }
+
+ if (NULL != term_addr) {
+ *term_addr = loader_get_phys_dev_ext_termin(idx);
+ }
+
+ success = true;
+
+out:
+ return success;
+}
+
+struct loader_instance *loader_get_instance(const VkInstance instance) {
+ // look up the loader_instance in our list by comparing dispatch tables, as
+ // there is no guarantee the instance is still a loader_instance* after any
+ // layers which wrap the instance object.
+ const VkLayerInstanceDispatchTable *disp;
+ struct loader_instance *ptr_instance = NULL;
+ disp = loader_get_instance_layer_dispatch(instance);
+ for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
+ if (&inst->disp->layer_inst_disp == disp) {
+ ptr_instance = inst;
+ break;
+ }
+ }
+ return ptr_instance;
+}
+
+static loader_platform_dl_handle loaderOpenLayerFile(const struct loader_instance *inst, const char *chain_type,
+ struct loader_layer_properties *prop) {
+ if ((prop->lib_handle = loader_platform_open_library(prop->lib_name)) == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, loader_platform_open_library_error(prop->lib_name));
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Loading layer library %s", prop->lib_name);
+ }
+
+ return prop->lib_handle;
+}
+
+static void loaderCloseLayerFile(const struct loader_instance *inst, struct loader_layer_properties *prop) {
+ if (prop->lib_handle) {
+ loader_platform_close_library(prop->lib_handle);
+ loader_log(inst, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Unloading layer library %s", prop->lib_name);
+ prop->lib_handle = NULL;
+ }
+}
+
+void loaderDeactivateLayers(const struct loader_instance *instance, struct loader_device *device, struct loader_layer_list *list) {
+ // Delete instance list of enabled layers and close any layer libraries
+ for (uint32_t i = 0; i < list->count; i++) {
+ struct loader_layer_properties *layer_prop = &list->list[i];
+
+ loaderCloseLayerFile(instance, layer_prop);
+ }
+ loaderDestroyLayerList(instance, device, list);
+}
+
+// Go through the search_list and find any layers which match type. If layer
+// type match is found in then add it to ext_list.
+static void loaderAddImplicitLayers(const struct loader_instance *inst, struct loader_layer_list *target_list,
+ struct loader_layer_list *expanded_target_list, const struct loader_layer_list *source_list) {
+ for (uint32_t src_layer = 0; src_layer < source_list->count; src_layer++) {
+ const struct loader_layer_properties *prop = &source_list->list[src_layer];
+ if (0 == (prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) {
+ loaderAddImplicitLayer(inst, prop, target_list, expanded_target_list, source_list);
+ }
+ }
+}
+
+// Get the layer name(s) from the env_name environment variable. If layer is found in
+// search_list then add it to layer_list. But only add it to layer_list if type_flags matches.
+static void loaderAddEnvironmentLayers(struct loader_instance *inst, const enum layer_type_flags type_flags, const char *env_name,
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list) {
+ char *next, *name;
+ char *layer_env = loader_getenv(env_name, inst);
+ if (layer_env == NULL) {
+ goto out;
+ }
+ name = loader_stack_alloc(strlen(layer_env) + 1);
+ if (name == NULL) {
+ goto out;
+ }
+ strcpy(name, layer_env);
+
+ while (name && *name) {
+ next = loader_get_next_path(name);
+ loaderAddLayerNameToList(inst, name, type_flags, source_list, target_list, expanded_target_list);
+ name = next;
+ }
+
+out:
+
+ if (layer_env != NULL) {
+ loader_free_getenv(layer_env, inst);
+ }
+
+ return;
+}
+
+VkResult loaderEnableInstanceLayers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
+ const struct loader_layer_list *instance_layers) {
+ VkResult err = VK_SUCCESS;
+ uint16_t layer_api_major_version;
+ uint16_t layer_api_minor_version;
+ uint32_t i;
+ struct loader_layer_properties *prop;
+
+ assert(inst && "Cannot have null instance");
+
+ if (!loaderInitLayerList(inst, &inst->app_activated_layer_list)) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderEnableInstanceLayers: Failed to initialize application version of the layer list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ if (!loaderInitLayerList(inst, &inst->expanded_activated_layer_list)) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderEnableInstanceLayers: Failed to initialize expanded version of the layer list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ // Add any implicit layers first
+ loaderAddImplicitLayers(inst, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list, instance_layers);
+
+ // Add any layers specified via environment variable next
+ loaderAddEnvironmentLayers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, "VK_INSTANCE_LAYERS", &inst->app_activated_layer_list,
+ &inst->expanded_activated_layer_list, instance_layers);
+
+ // Add layers specified by the application
+ err = loaderAddLayerNamesToList(inst, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list,
+ pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames, instance_layers);
+
+ for (i = 0; i < inst->expanded_activated_layer_list.count; i++) {
+ // Verify that the layer api version is at least that of the application's request, if not, throw a warning since
+ // undefined behavior could occur.
+ prop = inst->expanded_activated_layer_list.list + i;
+ layer_api_major_version = VK_VERSION_MAJOR(prop->info.specVersion);
+ layer_api_minor_version = VK_VERSION_MINOR(prop->info.specVersion);
+ if (inst->app_api_major_version > layer_api_major_version ||
+ (inst->app_api_major_version == layer_api_major_version && inst->app_api_minor_version > layer_api_minor_version)) {
+ loader_log(inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "loader_add_to_layer_list: Explicit layer %s is using an old API version %" PRIu16 ".%" PRIu16
+ " versus application requested %" PRIu16 ".%" PRIu16,
+ prop->info.layerName, layer_api_major_version, layer_api_minor_version, inst->app_api_major_version,
+ inst->app_api_minor_version);
+ }
+ }
+
+ return err;
+}
+
+// Determine the layer interface version to use.
+bool loaderGetLayerInterfaceVersion(PFN_vkNegotiateLoaderLayerInterfaceVersion fp_negotiate_layer_version,
+ VkNegotiateLayerInterface *interface_struct) {
+ memset(interface_struct, 0, sizeof(VkNegotiateLayerInterface));
+ interface_struct->sType = LAYER_NEGOTIATE_INTERFACE_STRUCT;
+ interface_struct->loaderLayerInterfaceVersion = 1;
+ interface_struct->pNext = NULL;
+
+ if (fp_negotiate_layer_version != NULL) {
+ // Layer supports the negotiation API, so call it with the loader's
+ // latest version supported
+ interface_struct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
+ VkResult result = fp_negotiate_layer_version(interface_struct);
+
+ if (result != VK_SUCCESS) {
+ // Layer no longer supports the loader's latest interface version so
+ // fail loading the Layer
+ return false;
+ }
+ }
+
+ if (interface_struct->loaderLayerInterfaceVersion < MIN_SUPPORTED_LOADER_LAYER_INTERFACE_VERSION) {
+ // Loader no longer supports the layer's latest interface version so
+ // fail loading the layer
+ return false;
+ }
+
+ return true;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL loader_layer_create_device(VkInstance instance, VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
+ PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA) {
+ VkResult res;
+ VkPhysicalDevice internal_device = VK_NULL_HANDLE;
+ struct loader_device *dev = NULL;
+ struct loader_instance *inst = NULL;
+
+ assert(pCreateInfo->queueCreateInfoCount >= 1);
+
+ if (instance != NULL) {
+ inst = loader_get_instance(instance);
+ internal_device = physicalDevice;
+ } else {
+ struct loader_physical_device_tramp *phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
+ internal_device = phys_dev->phys_dev;
+ inst = (struct loader_instance *)phys_dev->this_instance;
+ }
+
+ // Get the physical device (ICD) extensions
+ struct loader_extension_list icd_exts;
+ icd_exts.list = NULL;
+ res = loader_init_generic_list(inst, (struct loader_generic_list *)&icd_exts, sizeof(VkExtensionProperties));
+ if (VK_SUCCESS != res) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice: Failed to create ICD extension list");
+ goto out;
+ }
+
+ PFN_vkEnumerateDeviceExtensionProperties enumDeviceExtensionProperties = NULL;
+ if (layerGIPA != NULL) {
+ enumDeviceExtensionProperties =
+ (PFN_vkEnumerateDeviceExtensionProperties)layerGIPA(instance, "vkEnumerateDeviceExtensionProperties");
+ } else {
+ enumDeviceExtensionProperties = inst->disp->layer_inst_disp.EnumerateDeviceExtensionProperties;
+ }
+ res = loader_add_device_extensions(inst, enumDeviceExtensionProperties, internal_device, "Unknown", &icd_exts);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice: Failed to add extensions to list");
+ goto out;
+ }
+
+ // Make sure requested extensions to be enabled are supported
+ res = loader_validate_device_extensions(inst, &inst->expanded_activated_layer_list, &icd_exts, pCreateInfo);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice: Failed to validate extensions in list");
+ goto out;
+ }
+
+ dev = loader_create_logical_device(inst, pAllocator);
+ if (dev == NULL) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // Copy the application enabled instance layer list into the device
+ if (NULL != inst->app_activated_layer_list.list) {
+ dev->app_activated_layer_list.capacity = inst->app_activated_layer_list.capacity;
+ dev->app_activated_layer_list.count = inst->app_activated_layer_list.count;
+ dev->app_activated_layer_list.list =
+ loader_device_heap_alloc(dev, inst->app_activated_layer_list.capacity, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ if (dev->app_activated_layer_list.list == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkCreateDevice: Failed to allocate application activated layer list of size %d.",
+ inst->app_activated_layer_list.capacity);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memcpy(dev->app_activated_layer_list.list, inst->app_activated_layer_list.list,
+ sizeof(*dev->app_activated_layer_list.list) * dev->app_activated_layer_list.count);
+ } else {
+ dev->app_activated_layer_list.capacity = 0;
+ dev->app_activated_layer_list.count = 0;
+ dev->app_activated_layer_list.list = NULL;
+ }
+
+ // Copy the expanded enabled instance layer list into the device
+ if (NULL != inst->expanded_activated_layer_list.list) {
+ dev->expanded_activated_layer_list.capacity = inst->expanded_activated_layer_list.capacity;
+ dev->expanded_activated_layer_list.count = inst->expanded_activated_layer_list.count;
+ dev->expanded_activated_layer_list.list =
+ loader_device_heap_alloc(dev, inst->expanded_activated_layer_list.capacity, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ if (dev->expanded_activated_layer_list.list == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkCreateDevice: Failed to allocate expanded activated layer list of size %d.",
+ inst->expanded_activated_layer_list.capacity);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memcpy(dev->expanded_activated_layer_list.list, inst->expanded_activated_layer_list.list,
+ sizeof(*dev->expanded_activated_layer_list.list) * dev->expanded_activated_layer_list.count);
+ } else {
+ dev->expanded_activated_layer_list.capacity = 0;
+ dev->expanded_activated_layer_list.count = 0;
+ dev->expanded_activated_layer_list.list = NULL;
+ }
+
+ res = loader_create_device_chain(internal_device, pCreateInfo, pAllocator, inst, dev, layerGIPA, nextGDPA);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice: Failed to create device chain.");
+ goto out;
+ }
+
+ *pDevice = dev->chain_device;
+
+ // Initialize any device extension dispatch entry's from the instance list
+ loader_init_dispatch_dev_ext(inst, dev);
+
+ // Initialize WSI device extensions as part of core dispatch since loader
+ // has dedicated trampoline code for these
+ loader_init_device_extension_dispatch_table(&dev->loader_dispatch, inst->disp->layer_inst_disp.GetInstanceProcAddr,
+ dev->loader_dispatch.core_dispatch.GetDeviceProcAddr, inst->instance, *pDevice);
+
+out:
+
+ // Failure cleanup
+ if (VK_SUCCESS != res) {
+ if (NULL != dev) {
+ loader_destroy_logical_device(inst, dev, pAllocator);
+ }
+ }
+
+ if (NULL != icd_exts.list) {
+ loader_destroy_generic_list(inst, (struct loader_generic_list *)&icd_exts);
+ }
+ return res;
+}
+
+VKAPI_ATTR void VKAPI_CALL loader_layer_destroy_device(VkDevice device, const VkAllocationCallbacks *pAllocator,
+ PFN_vkDestroyDevice destroyFunction) {
+ struct loader_device *dev;
+
+ if (device == VK_NULL_HANDLE) {
+ return;
+ }
+
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, NULL);
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ destroyFunction(device, pAllocator);
+ dev->chain_device = NULL;
+ dev->icd_device = NULL;
+ loader_remove_logical_device(inst, icd_term, dev, pAllocator);
+}
+
+// Given the list of layers to activate in the loader_instance
+// structure. This function will add a VkLayerInstanceCreateInfo
+// structure to the VkInstanceCreateInfo.pNext pointer.
+// Each activated layer will have it's own VkLayerInstanceLink
+// structure that tells the layer what Get*ProcAddr to call to
+// get function pointers to the next layer down.
+// Once the chain info has been created this function will
+// execute the CreateInstance call chain. Each layer will
+// then have an opportunity in it's CreateInstance function
+// to setup it's dispatch table when the lower layer returns
+// successfully.
+// Each layer can wrap or not-wrap the returned VkInstance object
+// as it sees fit.
+// The instance chain is terminated by a loader function
+// that will call CreateInstance on all available ICD's and
+// cache those VkInstance objects for future use.
+VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
+ struct loader_instance *inst, VkInstance *created_instance) {
+ uint32_t activated_layers = 0;
+ VkLayerInstanceCreateInfo chain_info;
+ VkLayerInstanceLink *layer_instance_link_info = NULL;
+ VkInstanceCreateInfo loader_create_info;
+ VkResult res;
+
+ PFN_vkGetInstanceProcAddr next_gipa = loader_gpa_instance_internal;
+ PFN_vkGetInstanceProcAddr cur_gipa = loader_gpa_instance_internal;
+ PFN_vkGetDeviceProcAddr cur_gdpa = loader_gpa_device_internal;
+ PFN_GetPhysicalDeviceProcAddr next_gpdpa = loader_gpdpa_instance_internal;
+ PFN_GetPhysicalDeviceProcAddr cur_gpdpa = loader_gpdpa_instance_internal;
+
+ memcpy(&loader_create_info, pCreateInfo, sizeof(VkInstanceCreateInfo));
+
+ if (inst->expanded_activated_layer_list.count > 0) {
+ chain_info.u.pLayerInfo = NULL;
+ chain_info.pNext = pCreateInfo->pNext;
+ chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ chain_info.function = VK_LAYER_LINK_INFO;
+ loader_create_info.pNext = &chain_info;
+
+ layer_instance_link_info = loader_stack_alloc(sizeof(VkLayerInstanceLink) * inst->expanded_activated_layer_list.count);
+ if (!layer_instance_link_info) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_create_instance_chain: Failed to alloc Instance"
+ " objects for layer");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ // Create instance chain of enabled layers
+ for (int32_t i = inst->expanded_activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &inst->expanded_activated_layer_list.list[i];
+ loader_platform_dl_handle lib_handle;
+
+ lib_handle = loaderOpenLayerFile(inst, "instance", layer_prop);
+ if (!lib_handle) {
+ continue;
+ }
+
+ if (NULL == layer_prop->functions.negotiate_layer_interface) {
+ PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_interface = NULL;
+ bool functions_in_interface = false;
+ if (strlen(layer_prop->functions.str_negotiate_interface) == 0) {
+ negotiate_interface = (PFN_vkNegotiateLoaderLayerInterfaceVersion)loader_platform_get_proc_address(
+ lib_handle, "vkNegotiateLoaderLayerInterfaceVersion");
+ } else {
+ negotiate_interface = (PFN_vkNegotiateLoaderLayerInterfaceVersion)loader_platform_get_proc_address(
+ lib_handle, layer_prop->functions.str_negotiate_interface);
+ }
+
+ // If we can negotiate an interface version, then we can also
+ // get everything we need from the one function call, so try
+ // that first, and see if we can get all the function pointers
+ // necessary from that one call.
+ if (NULL != negotiate_interface) {
+ layer_prop->functions.negotiate_layer_interface = negotiate_interface;
+
+ VkNegotiateLayerInterface interface_struct;
+
+ if (loaderGetLayerInterfaceVersion(negotiate_interface, &interface_struct)) {
+ // Go ahead and set the properties version to the
+ // correct value.
+ layer_prop->interface_version = interface_struct.loaderLayerInterfaceVersion;
+
+ // If the interface is 2 or newer, we have access to the
+ // new GetPhysicalDeviceProcAddr function, so grab it,
+ // and the other necessary functions, from the
+ // structure.
+ if (interface_struct.loaderLayerInterfaceVersion > 1) {
+ cur_gipa = interface_struct.pfnGetInstanceProcAddr;
+ cur_gdpa = interface_struct.pfnGetDeviceProcAddr;
+ cur_gpdpa = interface_struct.pfnGetPhysicalDeviceProcAddr;
+ if (cur_gipa != NULL) {
+ // We've set the functions, so make sure we
+ // don't do the unnecessary calls later.
+ functions_in_interface = true;
+ }
+ }
+ }
+ }
+
+ if (!functions_in_interface) {
+ if ((cur_gipa = layer_prop->functions.get_instance_proc_addr) == NULL) {
+ if (strlen(layer_prop->functions.str_gipa) == 0) {
+ cur_gipa =
+ (PFN_vkGetInstanceProcAddr)loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
+ layer_prop->functions.get_instance_proc_addr = cur_gipa;
+ } else {
+ cur_gipa = (PFN_vkGetInstanceProcAddr)loader_platform_get_proc_address(lib_handle,
+ layer_prop->functions.str_gipa);
+ }
+
+ if (NULL == cur_gipa) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_create_instance_chain: Failed to"
+ " find \'vkGetInstanceProcAddr\' in "
+ "layer %s",
+ layer_prop->lib_name);
+ continue;
+ }
+ }
+ }
+ }
+
+ layer_instance_link_info[activated_layers].pNext = chain_info.u.pLayerInfo;
+ layer_instance_link_info[activated_layers].pfnNextGetInstanceProcAddr = next_gipa;
+ layer_instance_link_info[activated_layers].pfnNextGetPhysicalDeviceProcAddr = next_gpdpa;
+ next_gipa = cur_gipa;
+ if (layer_prop->interface_version > 1 && cur_gpdpa != NULL) {
+ layer_prop->functions.get_physical_device_proc_addr = cur_gpdpa;
+ next_gpdpa = cur_gpdpa;
+ }
+ if (layer_prop->interface_version > 1 && cur_gipa != NULL) {
+ layer_prop->functions.get_instance_proc_addr = cur_gipa;
+ }
+ if (layer_prop->interface_version > 1 && cur_gdpa != NULL) {
+ layer_prop->functions.get_device_proc_addr = cur_gdpa;
+ }
+
+ chain_info.u.pLayerInfo = &layer_instance_link_info[activated_layers];
+
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Insert instance layer %s (%s)", layer_prop->info.layerName,
+ layer_prop->lib_name);
+
+ activated_layers++;
+ }
+ }
+
+ PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)next_gipa(*created_instance, "vkCreateInstance");
+ if (fpCreateInstance) {
+ VkLayerInstanceCreateInfo create_info_disp;
+
+ create_info_disp.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ create_info_disp.function = VK_LOADER_DATA_CALLBACK;
+
+ create_info_disp.u.pfnSetInstanceLoaderData = vkSetInstanceDispatch;
+
+ create_info_disp.pNext = loader_create_info.pNext;
+ loader_create_info.pNext = &create_info_disp;
+
+ VkLayerInstanceCreateInfo create_info_disp2;
+
+ create_info_disp2.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
+ create_info_disp2.function = VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK;
+
+ create_info_disp2.u.layerDevice.pfnLayerCreateDevice = loader_layer_create_device;
+ create_info_disp2.u.layerDevice.pfnLayerDestroyDevice = loader_layer_destroy_device;
+
+ create_info_disp2.pNext = loader_create_info.pNext;
+ loader_create_info.pNext = &create_info_disp2;
+
+ res = fpCreateInstance(&loader_create_info, pAllocator, created_instance);
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_create_instance_chain: Failed to find "
+ "\'vkCreateInstance\'");
+ // Couldn't find CreateInstance function!
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ if (res == VK_SUCCESS) {
+ loader_init_instance_core_dispatch_table(&inst->disp->layer_inst_disp, next_gipa, *created_instance);
+ inst->instance = *created_instance;
+ }
+
+ return res;
+}
+
+void loaderActivateInstanceLayerExtensions(struct loader_instance *inst, VkInstance created_inst) {
+ loader_init_instance_extension_dispatch_table(&inst->disp->layer_inst_disp, inst->disp->layer_inst_disp.GetInstanceProcAddr,
+ created_inst);
+}
+
+VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, const struct loader_instance *inst,
+ struct loader_device *dev, PFN_vkGetInstanceProcAddr callingLayer,
+ PFN_vkGetDeviceProcAddr *layerNextGDPA) {
+ uint32_t activated_layers = 0;
+ VkLayerDeviceLink *layer_device_link_info;
+ VkLayerDeviceCreateInfo chain_info;
+ VkDeviceCreateInfo loader_create_info;
+ VkResult res;
+
+ PFN_vkGetDeviceProcAddr fpGDPA = NULL, nextGDPA = loader_gpa_device_internal;
+ PFN_vkGetInstanceProcAddr fpGIPA = NULL, nextGIPA = loader_gpa_instance_internal;
+
+ memcpy(&loader_create_info, pCreateInfo, sizeof(VkDeviceCreateInfo));
+
+ // Before we continue, we need to find out if the KHR_device_group extension is in the enabled list. If it is, we then
+ // need to look for the corresponding VkDeviceGroupDeviceCreateInfoKHR struct in the device list. This is because we
+ // need to replace all the incoming physical device values (which are really loader trampoline physical device values)
+ // with the layer/ICD version.
+ {
+ VkBaseOutStructure *pNext = (VkBaseOutStructure *)loader_create_info.pNext;
+ VkBaseOutStructure *pPrev = (VkBaseOutStructure *)&loader_create_info;
+ while (NULL != pNext) {
+ if (VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO == pNext->sType) {
+ VkDeviceGroupDeviceCreateInfoKHR *cur_struct = (VkDeviceGroupDeviceCreateInfoKHR *)pNext;
+ if (0 < cur_struct->physicalDeviceCount && NULL != cur_struct->pPhysicalDevices) {
+ VkDeviceGroupDeviceCreateInfoKHR *temp_struct = loader_stack_alloc(sizeof(VkDeviceGroupDeviceCreateInfoKHR));
+ VkPhysicalDevice *phys_dev_array = NULL;
+ if (NULL == temp_struct) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memcpy(temp_struct, cur_struct, sizeof(VkDeviceGroupDeviceCreateInfoKHR));
+ phys_dev_array = loader_stack_alloc(sizeof(VkPhysicalDevice) * cur_struct->physicalDeviceCount);
+ if (NULL == phys_dev_array) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ // Before calling down, replace the incoming physical device values (which are really loader trampoline
+ // physical devices) with the next layer (or possibly even the terminator) physical device values.
+ struct loader_physical_device_tramp *cur_tramp;
+ for (uint32_t phys_dev = 0; phys_dev < cur_struct->physicalDeviceCount; phys_dev++) {
+ cur_tramp = (struct loader_physical_device_tramp *)cur_struct->pPhysicalDevices[phys_dev];
+ phys_dev_array[phys_dev] = cur_tramp->phys_dev;
+ }
+ temp_struct->pPhysicalDevices = phys_dev_array;
+
+ // Replace the old struct in the pNext chain with this one.
+ pPrev->pNext = (VkBaseOutStructure *)temp_struct;
+ pNext = (VkBaseOutStructure *)temp_struct;
+ }
+ break;
+ }
+
+ pPrev = pNext;
+ pNext = pNext->pNext;
+ }
+ }
+
+ layer_device_link_info = loader_stack_alloc(sizeof(VkLayerDeviceLink) * dev->expanded_activated_layer_list.count);
+ if (!layer_device_link_info) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_create_device_chain: Failed to alloc Device objects"
+ " for layer. Skipping Layer.");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ if (dev->expanded_activated_layer_list.count > 0) {
+ chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ chain_info.function = VK_LAYER_LINK_INFO;
+ chain_info.u.pLayerInfo = NULL;
+ chain_info.pNext = loader_create_info.pNext;
+ loader_create_info.pNext = &chain_info;
+
+ bool done = false;
+
+ // Create instance chain of enabled layers
+ for (int32_t i = dev->expanded_activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &dev->expanded_activated_layer_list.list[i];
+ loader_platform_dl_handle lib_handle;
+
+ lib_handle = loaderOpenLayerFile(inst, "device", layer_prop);
+ if (!lib_handle || done) {
+ continue;
+ }
+
+ // The Get*ProcAddr pointers will already be filled in if they were received from either the json file or the
+ // version negotiation
+ if ((fpGIPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
+ if (strlen(layer_prop->functions.str_gipa) == 0) {
+ fpGIPA = (PFN_vkGetInstanceProcAddr)loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
+ layer_prop->functions.get_instance_proc_addr = fpGIPA;
+ } else
+ fpGIPA =
+ (PFN_vkGetInstanceProcAddr)loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
+ if (!fpGIPA) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_create_device_chain: Failed to find "
+ "\'vkGetInstanceProcAddr\' in layer %s. Skipping"
+ " layer.",
+ layer_prop->lib_name);
+ continue;
+ }
+ }
+
+ if (fpGIPA == callingLayer) {
+ if (layerNextGDPA != NULL) {
+ *layerNextGDPA = nextGDPA;
+ }
+ done = true;
+ continue;
+ }
+
+ if ((fpGDPA = layer_prop->functions.get_device_proc_addr) == NULL) {
+ if (strlen(layer_prop->functions.str_gdpa) == 0) {
+ fpGDPA = (PFN_vkGetDeviceProcAddr)loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr");
+ layer_prop->functions.get_device_proc_addr = fpGDPA;
+ } else
+ fpGDPA =
+ (PFN_vkGetDeviceProcAddr)loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa);
+ if (!fpGDPA) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Failed to find vkGetDeviceProcAddr in layer %s",
+ layer_prop->lib_name);
+ continue;
+ }
+ }
+
+ layer_device_link_info[activated_layers].pNext = chain_info.u.pLayerInfo;
+ layer_device_link_info[activated_layers].pfnNextGetInstanceProcAddr = nextGIPA;
+ layer_device_link_info[activated_layers].pfnNextGetDeviceProcAddr = nextGDPA;
+ chain_info.u.pLayerInfo = &layer_device_link_info[activated_layers];
+ nextGIPA = fpGIPA;
+ nextGDPA = fpGDPA;
+
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0, "Inserted device layer %s (%s)", layer_prop->info.layerName,
+ layer_prop->lib_name);
+
+ activated_layers++;
+ }
+ }
+
+ VkDevice created_device = (VkDevice)dev;
+ PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)nextGIPA(inst->instance, "vkCreateDevice");
+ if (fpCreateDevice) {
+ VkLayerDeviceCreateInfo create_info_disp;
+
+ create_info_disp.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
+ create_info_disp.function = VK_LOADER_DATA_CALLBACK;
+
+ create_info_disp.u.pfnSetDeviceLoaderData = vkSetDeviceDispatch;
+
+ create_info_disp.pNext = loader_create_info.pNext;
+ loader_create_info.pNext = &create_info_disp;
+ res = fpCreateDevice(pd, &loader_create_info, pAllocator, &created_device);
+ if (res != VK_SUCCESS) {
+ return res;
+ }
+ dev->chain_device = created_device;
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_create_device_chain: Failed to find \'vkCreateDevice\' "
+ "in layers or ICD");
+ // Couldn't find CreateDevice function!
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // Initialize device dispatch table
+ loader_init_device_dispatch_table(&dev->loader_dispatch, nextGDPA, dev->chain_device);
+
+ return res;
+}
+
+VkResult loaderValidateLayers(const struct loader_instance *inst, const uint32_t layer_count,
+ const char *const *ppEnabledLayerNames, const struct loader_layer_list *list) {
+ struct loader_layer_properties *prop;
+
+ for (uint32_t i = 0; i < layer_count; i++) {
+ VkStringErrorFlags result = vk_string_validate(MaxLoaderStringLength, ppEnabledLayerNames[i]);
+ if (result != VK_STRING_ERROR_NONE) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderValidateLayers: Device ppEnabledLayerNames "
+ "contains string that is too long or is badly formed");
+ return VK_ERROR_LAYER_NOT_PRESENT;
+ }
+
+ prop = loaderFindLayerProperty(ppEnabledLayerNames[i], list);
+ if (NULL == prop) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loaderValidateLayers: Layer %d does not exist in the list of available layers", i);
+ return VK_ERROR_LAYER_NOT_PRESENT;
+ }
+ }
+ return VK_SUCCESS;
+}
+
+VkResult loader_validate_instance_extensions(struct loader_instance *inst, const struct loader_extension_list *icd_exts,
+ const struct loader_layer_list *instance_layers,
+ const VkInstanceCreateInfo *pCreateInfo) {
+ VkExtensionProperties *extension_prop;
+ char *env_value;
+ bool check_if_known = true;
+ VkResult res = VK_SUCCESS;
+
+ struct loader_layer_list active_layers;
+ struct loader_layer_list expanded_layers;
+ memset(&active_layers, 0, sizeof(active_layers));
+ memset(&expanded_layers, 0, sizeof(expanded_layers));
+ if (!loaderInitLayerList(inst, &active_layers)) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ if (!loaderInitLayerList(inst, &expanded_layers)) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // Build the lists of active layers (including metalayers) and expanded layers (with metalayers resolved to their components)
+ loaderAddImplicitLayers(inst, &active_layers, &expanded_layers, instance_layers);
+ loaderAddEnvironmentLayers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, ENABLED_LAYERS_ENV, &active_layers, &expanded_layers,
+ instance_layers);
+ res = loaderAddLayerNamesToList(inst, &active_layers, &expanded_layers, pCreateInfo->enabledLayerCount,
+ pCreateInfo->ppEnabledLayerNames, instance_layers);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+
+ for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+ VkStringErrorFlags result = vk_string_validate(MaxLoaderStringLength, pCreateInfo->ppEnabledExtensionNames[i]);
+ if (result != VK_STRING_ERROR_NONE) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_validate_instance_extensions: Instance ppEnabledExtensionNames contains "
+ "string that is too long or is badly formed");
+ res = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ // Check if a user wants to disable the instance extension filtering behavior
+ env_value = loader_getenv("VK_LOADER_DISABLE_INST_EXT_FILTER", inst);
+ if (NULL != env_value && atoi(env_value) != 0) {
+ check_if_known = false;
+ }
+ loader_free_getenv(env_value, inst);
+
+ if (check_if_known) {
+ // See if the extension is in the list of supported extensions
+ bool found = false;
+ for (uint32_t j = 0; LOADER_INSTANCE_EXTENSIONS[j] != NULL; j++) {
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], LOADER_INSTANCE_EXTENSIONS[j]) == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ // If it isn't in the list, return an error
+ if (!found) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_validate_instance_extensions: Extension %s not found in list of known instance extensions.",
+ pCreateInfo->ppEnabledExtensionNames[i]);
+ res = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+ }
+
+ extension_prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[i], icd_exts);
+
+ if (extension_prop) {
+ continue;
+ }
+
+ extension_prop = NULL;
+
+ // Not in global list, search layer extension lists
+ struct loader_layer_properties *layer_prop = NULL;
+ for (uint32_t j = 0; NULL == extension_prop && j < expanded_layers.count; ++j) {
+ extension_prop =
+ get_extension_property(pCreateInfo->ppEnabledExtensionNames[i], &expanded_layers.list[j].instance_extension_list);
+ if (extension_prop) {
+ // Found the extension in one of the layers enabled by the app.
+ break;
+ }
+
+ layer_prop = loaderFindLayerProperty(expanded_layers.list[j].info.layerName, instance_layers);
+ if (NULL == layer_prop) {
+ // Should NOT get here, loaderValidateLayers should have already filtered this case out.
+ continue;
+ }
+ }
+
+ if (!extension_prop) {
+ // Didn't find extension name in any of the global layers, error out
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_validate_instance_extensions: Instance extension %s not supported by available ICDs or enabled "
+ "layers.",
+ pCreateInfo->ppEnabledExtensionNames[i]);
+ res = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+ }
+
+out:
+ loaderDestroyLayerList(inst, NULL, &active_layers);
+ loaderDestroyLayerList(inst, NULL, &expanded_layers);
+ return res;
+}
+
+VkResult loader_validate_device_extensions(struct loader_instance *this_instance,
+ const struct loader_layer_list *activated_device_layers,
+ const struct loader_extension_list *icd_exts, const VkDeviceCreateInfo *pCreateInfo) {
+ VkExtensionProperties *extension_prop;
+ struct loader_layer_properties *layer_prop;
+
+ for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+ VkStringErrorFlags result = vk_string_validate(MaxLoaderStringLength, pCreateInfo->ppEnabledExtensionNames[i]);
+ if (result != VK_STRING_ERROR_NONE) {
+ loader_log(this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_validate_device_extensions: Device ppEnabledExtensionNames contains "
+ "string that is too long or is badly formed");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ const char *extension_name = pCreateInfo->ppEnabledExtensionNames[i];
+ extension_prop = get_extension_property(extension_name, icd_exts);
+
+ if (extension_prop) {
+ continue;
+ }
+
+ // Not in global list, search activated layer extension lists
+ for (uint32_t j = 0; j < activated_device_layers->count; j++) {
+ layer_prop = &activated_device_layers->list[j];
+
+ extension_prop = get_dev_extension_property(extension_name, &layer_prop->device_extension_list);
+ if (extension_prop) {
+ // Found the extension in one of the layers enabled by the app.
+ break;
+ }
+ }
+
+ if (!extension_prop) {
+ // Didn't find extension name in any of the device layers, error out
+ loader_log(this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_validate_device_extensions: Device extension %s not supported by selected physical device "
+ "or enabled layers.",
+ pCreateInfo->ppEnabledExtensionNames[i]);
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+ }
+ return VK_SUCCESS;
+}
+
+// Terminator functions for the Instance chain
+// All named terminator_<Vulakn API name>
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
+ struct loader_icd_term *icd_term;
+ VkExtensionProperties *prop;
+ char **filtered_extension_names = NULL;
+ VkInstanceCreateInfo icd_create_info;
+ VkResult res = VK_SUCCESS;
+ bool one_icd_successful = false;
+
+ struct loader_instance *ptr_instance = (struct loader_instance *)*pInstance;
+ memcpy(&icd_create_info, pCreateInfo, sizeof(icd_create_info));
+
+ icd_create_info.enabledLayerCount = 0;
+ icd_create_info.ppEnabledLayerNames = NULL;
+
+ // NOTE: Need to filter the extensions to only those supported by the ICD.
+ // No ICD will advertise support for layers. An ICD library could
+ // support a layer, but it would be independent of the actual ICD,
+ // just in the same library.
+ filtered_extension_names = loader_stack_alloc(pCreateInfo->enabledExtensionCount * sizeof(char *));
+ if (!filtered_extension_names) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "terminator_CreateInstance: Failed create extension name array for %d extensions",
+ pCreateInfo->enabledExtensionCount);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ icd_create_info.ppEnabledExtensionNames = (const char *const *)filtered_extension_names;
+
+ for (uint32_t i = 0; i < ptr_instance->icd_tramp_list.count; i++) {
+ icd_term = loader_icd_add(ptr_instance, &ptr_instance->icd_tramp_list.scanned_list[i]);
+ if (NULL == icd_term) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "terminator_CreateInstance: Failed to add ICD %d to ICD trampoline list.", i);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // If any error happens after here, we need to remove the ICD from the list,
+ // because we've already added it, but haven't validated it
+
+ // Make sure that we reset the pApplicationInfo so we don't get an old pointer
+ icd_create_info.pApplicationInfo = pCreateInfo->pApplicationInfo;
+ icd_create_info.enabledExtensionCount = 0;
+ struct loader_extension_list icd_exts;
+
+ loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "Build ICD instance extension list");
+ // traverse scanned icd list adding non-duplicate extensions to the list
+ res = loader_init_generic_list(ptr_instance, (struct loader_generic_list *)&icd_exts, sizeof(VkExtensionProperties));
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ // If out of memory, bail immediately.
+ goto out;
+ } else if (VK_SUCCESS != res) {
+ // Something bad happened with this ICD, so free it and try the
+ // next.
+ ptr_instance->icd_terms = icd_term->next;
+ icd_term->next = NULL;
+ loader_icd_destroy(ptr_instance, icd_term, pAllocator);
+ continue;
+ }
+
+ res = loader_add_instance_extensions(ptr_instance, icd_term->scanned_icd->EnumerateInstanceExtensionProperties,
+ icd_term->scanned_icd->lib_name, &icd_exts);
+ if (VK_SUCCESS != res) {
+ loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&icd_exts);
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
+ // If out of memory, bail immediately.
+ goto out;
+ } else {
+ // Something bad happened with this ICD, so free it and try the next.
+ ptr_instance->icd_terms = icd_term->next;
+ icd_term->next = NULL;
+ loader_icd_destroy(ptr_instance, icd_term, pAllocator);
+ continue;
+ }
+ }
+
+ for (uint32_t j = 0; j < pCreateInfo->enabledExtensionCount; j++) {
+ prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[j], &icd_exts);
+ if (prop) {
+ filtered_extension_names[icd_create_info.enabledExtensionCount] = (char *)pCreateInfo->ppEnabledExtensionNames[j];
+ icd_create_info.enabledExtensionCount++;
+ }
+ }
+
+ loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&icd_exts);
+
+ // Get the driver version from vkEnumerateInstanceVersion
+ uint32_t icd_version = VK_API_VERSION_1_0;
+ VkResult icd_result = VK_SUCCESS;
+ if (icd_term->scanned_icd->api_version >= VK_API_VERSION_1_1) {
+ PFN_vkEnumerateInstanceVersion icd_enumerate_instance_version = (PFN_vkEnumerateInstanceVersion)
+ icd_term->scanned_icd->GetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
+ if (icd_enumerate_instance_version != NULL) {
+ icd_result = icd_enumerate_instance_version(&icd_version);
+ if (icd_result != VK_SUCCESS) {
+ icd_version = VK_API_VERSION_1_0;
+ loader_log(ptr_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0, "terminator_CreateInstance: ICD \"%s\" "
+ "vkEnumerateInstanceVersion returned error. The ICD will be treated as a 1.0 ICD",
+ icd_term->scanned_icd->lib_name);
+ }
+ }
+ }
+
+ // Create an instance, substituting the version to 1.0 if necessary
+ VkApplicationInfo icd_app_info;
+ uint32_t icd_version_nopatch = VK_MAKE_VERSION(VK_VERSION_MAJOR(icd_version), VK_VERSION_MINOR(icd_version), 0);
+ uint32_t requested_version = pCreateInfo == NULL || pCreateInfo->pApplicationInfo == NULL ? VK_API_VERSION_1_0 : pCreateInfo->pApplicationInfo->apiVersion;
+ if ((requested_version != 0) && (icd_version_nopatch == VK_API_VERSION_1_0)) {
+ if (icd_create_info.pApplicationInfo == NULL) {
+ memset(&icd_app_info, 0, sizeof(icd_app_info));
+ } else {
+ memcpy(&icd_app_info, icd_create_info.pApplicationInfo, sizeof(icd_app_info));
+ }
+ icd_app_info.apiVersion = icd_version;
+ icd_create_info.pApplicationInfo = &icd_app_info;
+ }
+ icd_result = ptr_instance->icd_tramp_list.scanned_list[i].CreateInstance(&icd_create_info, pAllocator, &(icd_term->instance));
+ if (VK_ERROR_OUT_OF_HOST_MEMORY == icd_result) {
+ // If out of memory, bail immediately.
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ } else if (VK_SUCCESS != icd_result) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "terminator_CreateInstance: Failed to CreateInstance in "
+ "ICD %d. Skipping ICD.",
+ i);
+ ptr_instance->icd_terms = icd_term->next;
+ icd_term->next = NULL;
+ loader_icd_destroy(ptr_instance, icd_term, pAllocator);
+ continue;
+ }
+
+ if (!loader_icd_init_entries(icd_term, icd_term->instance,
+ ptr_instance->icd_tramp_list.scanned_list[i].GetInstanceProcAddr)) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "terminator_CreateInstance: Failed to CreateInstance and find "
+ "entrypoints with ICD. Skipping ICD.");
+ ptr_instance->icd_terms = icd_term->next;
+ icd_term->next = NULL;
+ loader_icd_destroy(ptr_instance, icd_term, pAllocator);
+ continue;
+ }
+
+ // If we made it this far, at least one ICD was successful
+ one_icd_successful = true;
+ }
+
+ // If no ICDs were added to instance list and res is unchanged from it's initial value, the loader was unable to
+ // find a suitable ICD.
+ if (VK_SUCCESS == res && (ptr_instance->icd_terms == NULL || !one_icd_successful)) {
+ res = VK_ERROR_INCOMPATIBLE_DRIVER;
+ }
+
+out:
+
+ if (VK_SUCCESS != res) {
+ while (NULL != ptr_instance->icd_terms) {
+ icd_term = ptr_instance->icd_terms;
+ ptr_instance->icd_terms = icd_term->next;
+ if (NULL != icd_term->instance) {
+ icd_term->dispatch.DestroyInstance(icd_term->instance, pAllocator);
+ }
+ loader_icd_destroy(ptr_instance, icd_term, pAllocator);
+ }
+ }
+
+ return res;
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
+ struct loader_instance *ptr_instance = loader_instance(instance);
+ if (NULL == ptr_instance) {
+ return;
+ }
+ struct loader_icd_term *icd_terms = ptr_instance->icd_terms;
+ struct loader_icd_term *next_icd_term;
+
+ // Remove this instance from the list of instances:
+ struct loader_instance *prev = NULL;
+ struct loader_instance *next = loader.instances;
+ while (next != NULL) {
+ if (next == ptr_instance) {
+ // Remove this instance from the list:
+ if (prev)
+ prev->next = next->next;
+ else
+ loader.instances = next->next;
+ break;
+ }
+ prev = next;
+ next = next->next;
+ }
+
+ while (NULL != icd_terms) {
+ if (icd_terms->instance) {
+ icd_terms->dispatch.DestroyInstance(icd_terms->instance, pAllocator);
+ }
+ next_icd_term = icd_terms->next;
+ icd_terms->instance = VK_NULL_HANDLE;
+ loader_icd_destroy(ptr_instance, icd_terms, pAllocator);
+
+ icd_terms = next_icd_term;
+ }
+
+ loaderDeleteLayerListAndProperties(ptr_instance, &ptr_instance->instance_layer_list);
+ loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_tramp_list);
+ loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list);
+ if (NULL != ptr_instance->phys_devs_term) {
+ for (uint32_t i = 0; i < ptr_instance->phys_dev_count_term; i++) {
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_term[i]);
+ }
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_term);
+ }
+ if (NULL != ptr_instance->phys_dev_groups_term) {
+ for (uint32_t i = 0; i < ptr_instance->phys_dev_group_count_term; i++) {
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_dev_groups_term[i]);
+ }
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_dev_groups_term);
+ }
+ loader_free_dev_ext_table(ptr_instance);
+ loader_free_phys_dev_ext_table(ptr_instance);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
+ VkResult res = VK_SUCCESS;
+ struct loader_physical_device_term *phys_dev_term;
+ phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ struct loader_device *dev = (struct loader_device *)*pDevice;
+ PFN_vkCreateDevice fpCreateDevice = icd_term->dispatch.CreateDevice;
+ struct loader_extension_list icd_exts;
+
+ VkBaseOutStructure *caller_dgci_container = NULL;
+ VkDeviceGroupDeviceCreateInfoKHR *caller_dgci = NULL;
+
+ dev->phys_dev_term = phys_dev_term;
+
+ icd_exts.list = NULL;
+
+ if (fpCreateDevice == NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "terminator_CreateDevice: No vkCreateDevice command exposed "
+ "by ICD %s",
+ icd_term->scanned_icd->lib_name);
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ VkDeviceCreateInfo localCreateInfo;
+ memcpy(&localCreateInfo, pCreateInfo, sizeof(localCreateInfo));
+
+ // NOTE: Need to filter the extensions to only those supported by the ICD.
+ // No ICD will advertise support for layers. An ICD library could support a layer,
+ // but it would be independent of the actual ICD, just in the same library.
+ char **filtered_extension_names = NULL;
+ if (0 < pCreateInfo->enabledExtensionCount) {
+ filtered_extension_names = loader_stack_alloc(pCreateInfo->enabledExtensionCount * sizeof(char *));
+ if (NULL == filtered_extension_names) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "terminator_CreateDevice: Failed to create extension name "
+ "storage for %d extensions",
+ pCreateInfo->enabledExtensionCount);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ }
+
+ localCreateInfo.enabledLayerCount = 0;
+ localCreateInfo.ppEnabledLayerNames = NULL;
+
+ localCreateInfo.enabledExtensionCount = 0;
+ localCreateInfo.ppEnabledExtensionNames = (const char *const *)filtered_extension_names;
+
+ // Get the physical device (ICD) extensions
+ res = loader_init_generic_list(icd_term->this_instance, (struct loader_generic_list *)&icd_exts, sizeof(VkExtensionProperties));
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+
+ res = loader_add_device_extensions(icd_term->this_instance, icd_term->dispatch.EnumerateDeviceExtensionProperties,
+ phys_dev_term->phys_dev, icd_term->scanned_icd->lib_name, &icd_exts);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+
+ for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+ const char *extension_name = pCreateInfo->ppEnabledExtensionNames[i];
+ VkExtensionProperties *prop = get_extension_property(extension_name, &icd_exts);
+ if (prop) {
+ filtered_extension_names[localCreateInfo.enabledExtensionCount] = (char *)extension_name;
+ localCreateInfo.enabledExtensionCount++;
+ } else {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_DEBUG_BIT_EXT, 0,
+ "vkCreateDevice extension %s not available for "
+ "devices associated with ICD %s",
+ extension_name, icd_term->scanned_icd->lib_name);
+ }
+ }
+
+ // Before we continue, If KHX_device_group is the list of enabled and viable extensions, then we then need to look for the
+ // corresponding VkDeviceGroupDeviceCreateInfo struct in the device list and replace all the physical device values (which
+ // are really loader physical device terminator values) with the ICD versions.
+ //if (icd_term->this_instance->enabled_known_extensions.khr_device_group_creation == 1) {
+ {
+ VkBaseOutStructure *pNext = (VkBaseOutStructure *)localCreateInfo.pNext;
+ VkBaseOutStructure *pPrev = (VkBaseOutStructure *)&localCreateInfo;
+ while (NULL != pNext) {
+ if (VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO == pNext->sType) {
+ VkDeviceGroupDeviceCreateInfo *cur_struct = (VkDeviceGroupDeviceCreateInfo *)pNext;
+ if (0 < cur_struct->physicalDeviceCount && NULL != cur_struct->pPhysicalDevices) {
+ VkDeviceGroupDeviceCreateInfo *temp_struct = loader_stack_alloc(sizeof(VkDeviceGroupDeviceCreateInfo));
+ VkPhysicalDevice *phys_dev_array = NULL;
+ if (NULL == temp_struct) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memcpy(temp_struct, cur_struct, sizeof(VkDeviceGroupDeviceCreateInfo));
+ phys_dev_array = loader_stack_alloc(sizeof(VkPhysicalDevice) * cur_struct->physicalDeviceCount);
+ if (NULL == phys_dev_array) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ // Before calling down, replace the incoming physical device values (which are really loader terminator
+ // physical devices) with the ICDs physical device values.
+ struct loader_physical_device_term *cur_term;
+ for (uint32_t phys_dev = 0; phys_dev < cur_struct->physicalDeviceCount; phys_dev++) {
+ cur_term = (struct loader_physical_device_term *)cur_struct->pPhysicalDevices[phys_dev];
+ phys_dev_array[phys_dev] = cur_term->phys_dev;
+ }
+ temp_struct->pPhysicalDevices = phys_dev_array;
+
+ // Keep track of pointers to restore pNext chain before returning
+ caller_dgci_container = pPrev;
+ caller_dgci = cur_struct;
+
+ // Replace the old struct in the pNext chain with this one.
+ pPrev->pNext = (VkBaseOutStructure *)temp_struct;
+ pNext = (VkBaseOutStructure *)temp_struct;
+ }
+ break;
+ }
+
+ pPrev = pNext;
+ pNext = pNext->pNext;
+ }
+ }
+
+ // Handle loader emulation for structs that are not supported by the ICD:
+ // Presently, the emulation leaves the pNext chain alone. This means that the ICD will receive items in the chain which
+ // are not recognized by the ICD. If this causes the ICD to fail, then the items would have to be removed here. The current
+ // implementation does not remove them because copying the pNext chain would be impossible if the loader does not recognize
+ // the any of the struct types, as the loader would not know the size to allocate and copy.
+ //if (icd_term->dispatch.GetPhysicalDeviceFeatures2 == NULL && icd_term->dispatch.GetPhysicalDeviceFeatures2KHR == NULL) {
+ {
+ const void *pNext = localCreateInfo.pNext;
+ while (pNext != NULL) {
+ switch (*(VkStructureType *)pNext) {
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {
+ const VkPhysicalDeviceFeatures2KHR *features = pNext;
+
+ if (icd_term->dispatch.GetPhysicalDeviceFeatures2 == NULL && icd_term->dispatch.GetPhysicalDeviceFeatures2KHR == NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkCreateDevice: Emulating handling of VkPhysicalDeviceFeatures2 in pNext chain for ICD \"%s\"",
+ icd_term->scanned_icd->lib_name);
+
+ // Verify that VK_KHR_get_physical_device_properties2 is enabled
+ if (icd_term->this_instance->enabled_known_extensions.khr_get_physical_device_properties2) {
+ localCreateInfo.pEnabledFeatures = &features->features;
+ }
+ }
+
+ // Leave this item in the pNext chain for now
+
+ pNext = features->pNext;
+ break;
+ }
+
+ case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO: {
+ const VkDeviceGroupDeviceCreateInfoKHR *group_info = pNext;
+
+ if (icd_term->dispatch.EnumeratePhysicalDeviceGroups == NULL && icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHR == NULL) {
+ loader_log(
+ icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkCreateDevice: Emulating handling of VkPhysicalDeviceGroupProperties in pNext chain for ICD \"%s\"",
+ icd_term->scanned_icd->lib_name);
+
+ // The group must contain only this one device, since physical device groups aren't actually supported
+ if (group_info->physicalDeviceCount != 1) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkCreateDevice: Emulation failed to create device from device group info");
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+ }
+
+ // Nothing needs to be done here because we're leaving the item in the pNext chain and because the spec states
+ // that the physicalDevice argument must be included in the device group, and we've already checked that it is
+
+ pNext = group_info->pNext;
+ break;
+ }
+
+ // Multiview properties are also allowed, but since VK_KHX_multiview is a device extension, we'll just let the ICD
+ // handle that error when the user enables the extension here
+ default: {
+ const VkBaseInStructure *header = pNext;
+ pNext = header->pNext;
+ break;
+ }
+ }
+ }
+ }
+
+ // Every extension that has a loader-defined terminator needs to be marked as enabled or disabled so that we know whether or
+ // not to return that terminator when vkGetDeviceProcAddr is called
+ for (uint32_t i = 0; i < localCreateInfo.enabledExtensionCount; ++i) {
+ if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
+ dev->extensions.khr_swapchain_enabled = true;
+ } else if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME)) {
+ dev->extensions.khr_display_swapchain_enabled = true;
+ } else if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], VK_KHR_DEVICE_GROUP_EXTENSION_NAME)) {
+ dev->extensions.khr_device_group_enabled = true;
+ } else if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
+ dev->extensions.ext_debug_marker_enabled = true;
+ } else if (!strcmp(localCreateInfo.ppEnabledExtensionNames[i], "VK_EXT_full_screen_exclusive")) {
+ dev->extensions.ext_full_screen_exclusive_enabled = true;
+ }
+ }
+ dev->extensions.ext_debug_utils_enabled = icd_term->this_instance->enabled_known_extensions.ext_debug_utils;
+
+ if (!dev->extensions.khr_device_group_enabled) {
+ VkPhysicalDeviceProperties properties;
+ icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &properties);
+ if (properties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) {
+ dev->extensions.khr_device_group_enabled = true;
+ }
+ }
+
+ res = fpCreateDevice(phys_dev_term->phys_dev, &localCreateInfo, pAllocator, &dev->icd_device);
+ if (res != VK_SUCCESS) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "terminator_CreateDevice: Failed in ICD %s vkCreateDevice"
+ "call",
+ icd_term->scanned_icd->lib_name);
+ goto out;
+ }
+
+ *pDevice = dev->icd_device;
+ loader_add_logical_device(icd_term->this_instance, icd_term, dev);
+
+ // Init dispatch pointer in new device object
+ loader_init_dispatch(*pDevice, &dev->loader_dispatch);
+
+out:
+ if (NULL != icd_exts.list) {
+ loader_destroy_generic_list(icd_term->this_instance, (struct loader_generic_list *)&icd_exts);
+ }
+
+ // Restore pNext pointer to old VkDeviceGroupDeviceCreateInfoKHX
+ // in the chain to maintain consistency for the caller.
+ if (caller_dgci_container != NULL) {
+ caller_dgci_container->pNext = (VkBaseOutStructure *)caller_dgci;
+ }
+
+ return res;
+}
+
+VkResult setupLoaderTrampPhysDevs(VkInstance instance) {
+ VkResult res = VK_SUCCESS;
+ VkPhysicalDevice *local_phys_devs = NULL;
+ struct loader_instance *inst;
+ uint32_t total_count = 0;
+ struct loader_physical_device_tramp **new_phys_devs = NULL;
+
+ inst = loader_get_instance(instance);
+ if (NULL == inst) {
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ // Query how many GPUs there
+ res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(instance, &total_count, NULL);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevs: Failed during dispatch call "
+ "of \'vkEnumeratePhysicalDevices\' to lower layers or "
+ "loader to get count.");
+ goto out;
+ }
+
+ // Really use what the total GPU count is since Optimus and other layers may mess
+ // the count up.
+ total_count = inst->total_gpu_count;
+
+ // Create an array for the new physical devices, which will be stored
+ // in the instance for the trampoline code.
+ new_phys_devs = (struct loader_physical_device_tramp **)loader_instance_heap_alloc(
+ inst, total_count * sizeof(struct loader_physical_device_tramp *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_devs) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevs: Failed to allocate new physical device"
+ " array of size %d",
+ total_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(new_phys_devs, 0, total_count * sizeof(struct loader_physical_device_tramp *));
+
+ // Create a temporary array (on the stack) to keep track of the
+ // returned VkPhysicalDevice values.
+ local_phys_devs = loader_stack_alloc(sizeof(VkPhysicalDevice) * total_count);
+ if (NULL == local_phys_devs) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevs: Failed to allocate local "
+ "physical device array of size %d",
+ total_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(local_phys_devs, 0, sizeof(VkPhysicalDevice) * total_count);
+
+ res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(instance, &total_count, local_phys_devs);
+ if (VK_SUCCESS != res) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevs: Failed during dispatch call "
+ "of \'vkEnumeratePhysicalDevices\' to lower layers or "
+ "loader to get content.");
+ goto out;
+ }
+
+ // Copy or create everything to fill the new array of physical devices
+ for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
+ // Check if this physical device is already in the old buffer
+ for (uint32_t old_idx = 0; old_idx < inst->phys_dev_count_tramp; old_idx++) {
+ if (local_phys_devs[new_idx] == inst->phys_devs_tramp[old_idx]->phys_dev) {
+ new_phys_devs[new_idx] = inst->phys_devs_tramp[old_idx];
+ break;
+ }
+ }
+
+ // If this physical device isn't in the old buffer, create it
+ if (NULL == new_phys_devs[new_idx]) {
+ new_phys_devs[new_idx] = (struct loader_physical_device_tramp *)loader_instance_heap_alloc(
+ inst, sizeof(struct loader_physical_device_tramp), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_devs[new_idx]) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevs: Failed to allocate "
+ "physical device trampoline object %d",
+ new_idx);
+ total_count = new_idx;
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ // Initialize the new physicalDevice object
+ loader_set_dispatch((void *)new_phys_devs[new_idx], inst->disp);
+ new_phys_devs[new_idx]->this_instance = inst;
+ new_phys_devs[new_idx]->phys_dev = local_phys_devs[new_idx];
+ }
+ }
+
+out:
+
+ if (VK_SUCCESS != res) {
+ if (NULL != new_phys_devs) {
+ for (uint32_t i = 0; i < total_count; i++) {
+ loader_instance_heap_free(inst, new_phys_devs[i]);
+ }
+ loader_instance_heap_free(inst, new_phys_devs);
+ }
+ total_count = 0;
+ } else {
+ // Free everything that didn't carry over to the new array of
+ // physical devices
+ if (NULL != inst->phys_devs_tramp) {
+ for (uint32_t i = 0; i < inst->phys_dev_count_tramp; i++) {
+ bool found = false;
+ for (uint32_t j = 0; j < total_count; j++) {
+ if (inst->phys_devs_tramp[i] == new_phys_devs[j]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ loader_instance_heap_free(inst, inst->phys_devs_tramp[i]);
+ }
+ }
+ loader_instance_heap_free(inst, inst->phys_devs_tramp);
+ }
+
+ // Swap in the new physical device list
+ inst->phys_dev_count_tramp = total_count;
+ inst->phys_devs_tramp = new_phys_devs;
+ }
+
+ return res;
+}
+
+VkResult setupLoaderTermPhysDevs(struct loader_instance *inst) {
+ VkResult res = VK_SUCCESS;
+ struct loader_icd_term *icd_term;
+ struct loader_phys_dev_per_icd *icd_phys_dev_array = NULL;
+ struct loader_physical_device_term **new_phys_devs = NULL;
+
+ inst->total_gpu_count = 0;
+
+ // Allocate something to store the physical device characteristics
+ // that we read from each ICD.
+ icd_phys_dev_array =
+ (struct loader_phys_dev_per_icd *)loader_stack_alloc(sizeof(struct loader_phys_dev_per_icd) * inst->total_icd_count);
+ if (NULL == icd_phys_dev_array) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevs: Failed to allocate temporary "
+ "ICD Physical device info array of size %d",
+ inst->total_gpu_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(icd_phys_dev_array, 0, sizeof(struct loader_phys_dev_per_icd) * inst->total_icd_count);
+ icd_term = inst->icd_terms;
+
+ // For each ICD, query the number of physical devices, and then get an
+ // internal value for those physical devices.
+ for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
+ res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &icd_phys_dev_array[icd_idx].count, NULL);
+ if (VK_SUCCESS != res) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevs: Call to "
+ "ICD %d's \'vkEnumeratePhysicalDevices\' failed with"
+ " error 0x%08x",
+ icd_idx, res);
+ goto out;
+ }
+
+ icd_phys_dev_array[icd_idx].phys_devs =
+ (VkPhysicalDevice *)loader_stack_alloc(icd_phys_dev_array[icd_idx].count * sizeof(VkPhysicalDevice));
+ if (NULL == icd_phys_dev_array[icd_idx].phys_devs) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevs: Failed to allocate temporary "
+ "ICD Physical device array for ICD %d of size %d",
+ icd_idx, inst->total_gpu_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &(icd_phys_dev_array[icd_idx].count),
+ icd_phys_dev_array[icd_idx].phys_devs);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+ inst->total_gpu_count += icd_phys_dev_array[icd_idx].count;
+ icd_phys_dev_array[icd_idx].this_icd_term = icd_term;
+ }
+
+ if (0 == inst->total_gpu_count) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevs: Failed to detect any valid"
+ " GPUs in the current config");
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ new_phys_devs = loader_instance_heap_alloc(inst, sizeof(struct loader_physical_device_term *) * inst->total_gpu_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_devs) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevs: Failed to allocate new physical"
+ " device array of size %d",
+ inst->total_gpu_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(new_phys_devs, 0, sizeof(struct loader_physical_device_term *) * inst->total_gpu_count);
+
+ // Copy or create everything to fill the new array of physical devices
+ uint32_t idx = 0;
+ for (uint32_t icd_idx = 0; icd_idx < inst->total_icd_count; icd_idx++) {
+ for (uint32_t pd_idx = 0; pd_idx < icd_phys_dev_array[icd_idx].count; pd_idx++) {
+ // Check if this physical device is already in the old buffer
+ if (NULL != inst->phys_devs_term) {
+ for (uint32_t old_idx = 0; old_idx < inst->phys_dev_count_term; old_idx++) {
+ if (icd_phys_dev_array[icd_idx].phys_devs[pd_idx] == inst->phys_devs_term[old_idx]->phys_dev) {
+ new_phys_devs[idx] = inst->phys_devs_term[old_idx];
+ break;
+ }
+ }
+ }
+ // If this physical device isn't in the old buffer, then we
+ // need to create it.
+ if (NULL == new_phys_devs[idx]) {
+ new_phys_devs[idx] = loader_instance_heap_alloc(inst, sizeof(struct loader_physical_device_term),
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_devs[idx]) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevs: Failed to allocate "
+ "physical device terminator object %d",
+ idx);
+ inst->total_gpu_count = idx;
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ loader_set_dispatch((void *)new_phys_devs[idx], inst->disp);
+ new_phys_devs[idx]->this_icd_term = icd_phys_dev_array[icd_idx].this_icd_term;
+ new_phys_devs[idx]->icd_index = (uint8_t)(icd_idx);
+ new_phys_devs[idx]->phys_dev = icd_phys_dev_array[icd_idx].phys_devs[pd_idx];
+ }
+ idx++;
+ }
+ }
+
+out:
+
+ if (VK_SUCCESS != res) {
+ if (NULL != new_phys_devs) {
+ // We've encountered an error, so we should free the new buffers.
+ for (uint32_t i = 0; i < inst->total_gpu_count; i++) {
+ loader_instance_heap_free(inst, new_phys_devs[i]);
+ }
+ loader_instance_heap_free(inst, new_phys_devs);
+ }
+ inst->total_gpu_count = 0;
+ } else {
+ // Free everything that didn't carry over to the new array of
+ // physical devices. Everything else will have been copied over
+ // to the new array.
+ if (NULL != inst->phys_devs_term) {
+ for (uint32_t cur_pd = 0; cur_pd < inst->phys_dev_count_term; cur_pd++) {
+ bool found = false;
+ for (uint32_t new_pd_idx = 0; new_pd_idx < inst->total_gpu_count; new_pd_idx++) {
+ if (inst->phys_devs_term[cur_pd] == new_phys_devs[new_pd_idx]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ loader_instance_heap_free(inst, inst->phys_devs_term[cur_pd]);
+ }
+ }
+ loader_instance_heap_free(inst, inst->phys_devs_term);
+ }
+
+ // Swap out old and new devices list
+ inst->phys_dev_count_term = inst->total_gpu_count;
+ inst->phys_devs_term = new_phys_devs;
+ }
+
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
+ VkPhysicalDevice *pPhysicalDevices) {
+ struct loader_instance *inst = (struct loader_instance *)instance;
+ VkResult res = VK_SUCCESS;
+
+ // Always call the setup loader terminator physical devices because they may
+ // have changed at any point.
+ res = setupLoaderTermPhysDevs(inst);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+
+ uint32_t copy_count = inst->total_gpu_count;
+ if (NULL != pPhysicalDevices) {
+ if (copy_count > *pPhysicalDeviceCount) {
+ copy_count = *pPhysicalDeviceCount;
+ res = VK_INCOMPLETE;
+ }
+
+ for (uint32_t i = 0; i < copy_count; i++) {
+ pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_term[i];
+ }
+ }
+
+ *pPhysicalDeviceCount = copy_count;
+
+out:
+
+ return res;
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL != icd_term->dispatch.GetPhysicalDeviceProperties) {
+ icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, pProperties);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
+ uint32_t *pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL != icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties) {
+ icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, pProperties);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL != icd_term->dispatch.GetPhysicalDeviceMemoryProperties) {
+ icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, pProperties);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures *pFeatures) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL != icd_term->dispatch.GetPhysicalDeviceFeatures) {
+ icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, pFeatures);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+ VkFormatProperties *pFormatInfo) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL != icd_term->dispatch.GetPhysicalDeviceFormatProperties) {
+ icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, pFormatInfo);
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+ VkImageType type, VkImageTiling tiling,
+ VkImageUsageFlags usage, VkImageCreateFlags flags,
+ VkImageFormatProperties *pImageFormatProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceImageFormatProperties) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "Encountered the vkEnumerateDeviceLayerProperties "
+ "terminator. This means a layer improperly continued.");
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(phys_dev_term->phys_dev, format, type, tiling, usage, flags,
+ pImageFormatProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+ VkImageType type, VkSampleCountFlagBits samples,
+ VkImageUsageFlags usage, VkImageTiling tiling,
+ uint32_t *pNumProperties,
+ VkSparseImageFormatProperties *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL != icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties) {
+ icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(phys_dev_term->phys_dev, format, type, samples, usage,
+ tiling, pNumProperties, pProperties);
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
+ const char *pLayerName, uint32_t *pPropertyCount,
+ VkExtensionProperties *pProperties) {
+ struct loader_physical_device_term *phys_dev_term;
+
+ struct loader_layer_list implicit_layer_list = {0};
+ struct loader_extension_list all_exts = {0};
+ struct loader_extension_list icd_exts = {0};
+
+ // Any layer or trampoline wrapping should be removed at this point in time can just cast to the expected
+ // type for VkPhysicalDevice.
+ phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+
+ // if we got here with a non-empty pLayerName, look up the extensions
+ // from the json
+ if (pLayerName != NULL && strlen(pLayerName) > 0) {
+ uint32_t count;
+ uint32_t copy_size;
+ const struct loader_instance *inst = phys_dev_term->this_icd_term->this_instance;
+ struct loader_device_extension_list *dev_ext_list = NULL;
+ struct loader_device_extension_list local_ext_list;
+ memset(&local_ext_list, 0, sizeof(local_ext_list));
+ if (vk_string_validate(MaxLoaderStringLength, pLayerName) == VK_STRING_ERROR_NONE) {
+ for (uint32_t i = 0; i < inst->instance_layer_list.count; i++) {
+ struct loader_layer_properties *props = &inst->instance_layer_list.list[i];
+ if (strcmp(props->info.layerName, pLayerName) == 0) {
+ dev_ext_list = &props->device_extension_list;
+ }
+ }
+
+ count = (dev_ext_list == NULL) ? 0 : dev_ext_list->count;
+ if (pProperties == NULL) {
+ *pPropertyCount = count;
+ loader_destroy_generic_list(inst, (struct loader_generic_list *)&local_ext_list);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_SUCCESS;
+ }
+
+ copy_size = *pPropertyCount < count ? *pPropertyCount : count;
+ for (uint32_t i = 0; i < copy_size; i++) {
+ memcpy(&pProperties[i], &dev_ext_list->list[i].props, sizeof(VkExtensionProperties));
+ }
+ *pPropertyCount = copy_size;
+
+ loader_destroy_generic_list(inst, (struct loader_generic_list *)&local_ext_list);
+ if (copy_size < count) {
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_INCOMPLETE;
+ }
+ } else {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkEnumerateDeviceExtensionProperties: pLayerName "
+ "is too long or is badly formed");
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ return VK_SUCCESS;
+ }
+
+ // This case is during the call down the instance chain with pLayerName == NULL
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ uint32_t icd_ext_count = *pPropertyCount;
+ VkResult res;
+
+ // Get the available device extensions
+ res = icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL, &icd_ext_count, pProperties);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+
+ if (!loaderInitLayerList(icd_term->this_instance, &implicit_layer_list)) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ loaderAddImplicitLayers(icd_term->this_instance, &implicit_layer_list, NULL, &icd_term->this_instance->instance_layer_list);
+ // We need to determine which implicit layers are active, and then add their extensions. This can't be cached as
+ // it depends on results of environment variables (which can change).
+ if (pProperties != NULL) {
+ // Initialize dev_extension list within the physicalDevice object
+ res = loader_init_device_extensions(icd_term->this_instance, phys_dev_term, icd_ext_count, pProperties, &icd_exts);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+
+ // We need to determine which implicit layers are active, and then add their extensions. This can't be cached as
+ // it depends on results of environment variables (which can change).
+ res = loader_add_to_ext_list(icd_term->this_instance, &all_exts, icd_exts.count, icd_exts.list);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+
+ loaderAddImplicitLayers(icd_term->this_instance, &implicit_layer_list, NULL, &icd_term->this_instance->instance_layer_list);
+
+ for (uint32_t i = 0; i < implicit_layer_list.count; i++) {
+ for (uint32_t j = 0; j < implicit_layer_list.list[i].device_extension_list.count; j++) {
+ res = loader_add_to_ext_list(icd_term->this_instance, &all_exts, 1,
+ &implicit_layer_list.list[i].device_extension_list.list[j].props);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+ }
+ }
+ uint32_t capacity = *pPropertyCount;
+ VkExtensionProperties *props = pProperties;
+
+ for (uint32_t i = 0; i < all_exts.count && i < capacity; i++) {
+ props[i] = all_exts.list[i];
+ }
+
+ // Wasn't enough space for the extensions, we did partial copy now return VK_INCOMPLETE
+ if (capacity < all_exts.count) {
+ res = VK_INCOMPLETE;
+ } else {
+ *pPropertyCount = all_exts.count;
+ }
+ } else {
+ // Just return the count; need to add in the count of implicit layer extensions
+ // don't worry about duplicates being added in the count
+ *pPropertyCount = icd_ext_count;
+
+ for (uint32_t i = 0; i < implicit_layer_list.count; i++) {
+ *pPropertyCount += implicit_layer_list.list[i].device_extension_list.count;
+ }
+ res = VK_SUCCESS;
+ }
+
+out:
+
+ if (NULL != implicit_layer_list.list) {
+ loader_destroy_generic_list(icd_term->this_instance, (struct loader_generic_list *)&implicit_layer_list);
+ }
+ if (NULL != all_exts.list) {
+ loader_destroy_generic_list(icd_term->this_instance, (struct loader_generic_list *)&all_exts);
+ }
+ if (NULL != icd_exts.list) {
+ loader_destroy_generic_list(icd_term->this_instance, (struct loader_generic_list *)&icd_exts);
+ }
+
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
+ VkLayerProperties *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "Encountered the vkEnumerateDeviceLayerProperties "
+ "terminator. This means a layer improperly continued.");
+ // Should never get here this call isn't dispatched down the chain
+ return VK_ERROR_INITIALIZATION_FAILED;
+}
+
+VkStringErrorFlags vk_string_validate(const int max_length, const char *utf8) {
+ VkStringErrorFlags result = VK_STRING_ERROR_NONE;
+ int num_char_bytes = 0;
+ int i, j;
+
+ for (i = 0; i <= max_length; i++) {
+ if (utf8[i] == 0) {
+ break;
+ } else if (i == max_length) {
+ result |= VK_STRING_ERROR_LENGTH;
+ break;
+ } else if ((utf8[i] >= 0x20) && (utf8[i] < 0x7f)) {
+ num_char_bytes = 0;
+ } else if ((utf8[i] & UTF8_ONE_BYTE_MASK) == UTF8_ONE_BYTE_CODE) {
+ num_char_bytes = 1;
+ } else if ((utf8[i] & UTF8_TWO_BYTE_MASK) == UTF8_TWO_BYTE_CODE) {
+ num_char_bytes = 2;
+ } else if ((utf8[i] & UTF8_THREE_BYTE_MASK) == UTF8_THREE_BYTE_CODE) {
+ num_char_bytes = 3;
+ } else {
+ result = VK_STRING_ERROR_BAD_DATA;
+ }
+
+ // Validate the following num_char_bytes of data
+ for (j = 0; (j < num_char_bytes) && (i < max_length); j++) {
+ if (++i == max_length) {
+ result |= VK_STRING_ERROR_LENGTH;
+ break;
+ }
+ if ((utf8[i] & UTF8_DATA_BYTE_MASK) != UTF8_DATA_BYTE_CODE) {
+ result |= VK_STRING_ERROR_BAD_DATA;
+ }
+ }
+ }
+ return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+terminator_EnumerateInstanceVersion(const VkEnumerateInstanceVersionChain *chain, uint32_t* pApiVersion) {
+ // NOTE: The Vulkan WG doesn't want us checking pApiVersion for NULL, but instead
+ // prefers us crashing.
+ *pApiVersion = VK_MAKE_VERSION(loader_major_version, loader_minor_version, VK_HEADER_VERSION);
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+terminator_EnumerateInstanceExtensionProperties(const VkEnumerateInstanceExtensionPropertiesChain *chain, const char *pLayerName,
+ uint32_t *pPropertyCount, VkExtensionProperties *pProperties) {
+ struct loader_extension_list *global_ext_list = NULL;
+ struct loader_layer_list instance_layers;
+ struct loader_extension_list local_ext_list;
+ struct loader_icd_tramp_list icd_tramp_list;
+ uint32_t copy_size;
+ VkResult res = VK_SUCCESS;
+
+ // tls_instance = NULL;
+ memset(&local_ext_list, 0, sizeof(local_ext_list));
+ memset(&instance_layers, 0, sizeof(instance_layers));
+
+ // Get layer libraries if needed
+ if (pLayerName && strlen(pLayerName) != 0) {
+ if (vk_string_validate(MaxLoaderStringLength, pLayerName) != VK_STRING_ERROR_NONE) {
+ assert(VK_FALSE &&
+ "vkEnumerateInstanceExtensionProperties: "
+ "pLayerName is too long or is badly formed");
+ res = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ loaderScanForLayers(NULL, &instance_layers);
+ for (uint32_t i = 0; i < instance_layers.count; i++) {
+ struct loader_layer_properties *props = &instance_layers.list[i];
+ if (strcmp(props->info.layerName, pLayerName) == 0) {
+ global_ext_list = &props->instance_extension_list;
+ break;
+ }
+ }
+ } else {
+ // Scan/discover all ICD libraries
+ memset(&icd_tramp_list, 0, sizeof(icd_tramp_list));
+ res = loader_icd_scan(NULL, &icd_tramp_list);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+ // Get extensions from all ICD's, merge so no duplicates
+ res = loader_get_icd_loader_instance_extensions(NULL, &icd_tramp_list, &local_ext_list);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+ loader_scanned_icd_clear(NULL, &icd_tramp_list);
+
+ // Append enabled implicit layers.
+ loaderScanForImplicitLayers(NULL, &instance_layers);
+ for (uint32_t i = 0; i < instance_layers.count; i++) {
+ if (!loaderImplicitLayerIsEnabled(NULL, &instance_layers.list[i])) {
+ continue;
+ }
+ struct loader_extension_list *ext_list = &instance_layers.list[i].instance_extension_list;
+ loader_add_to_ext_list(NULL, &local_ext_list, ext_list->count, ext_list->list);
+ }
+
+ global_ext_list = &local_ext_list;
+ }
+
+ if (global_ext_list == NULL) {
+ res = VK_ERROR_LAYER_NOT_PRESENT;
+ goto out;
+ }
+
+ if (pProperties == NULL) {
+ *pPropertyCount = global_ext_list->count;
+ goto out;
+ }
+
+ copy_size = *pPropertyCount < global_ext_list->count ? *pPropertyCount : global_ext_list->count;
+ for (uint32_t i = 0; i < copy_size; i++) {
+ memcpy(&pProperties[i], &global_ext_list->list[i], sizeof(VkExtensionProperties));
+ }
+ *pPropertyCount = copy_size;
+
+ if (copy_size < global_ext_list->count) {
+ res = VK_INCOMPLETE;
+ goto out;
+ }
+
+out:
+
+ loader_destroy_generic_list(NULL, (struct loader_generic_list *)&local_ext_list);
+ loaderDeleteLayerListAndProperties(NULL, &instance_layers);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceLayerProperties(const VkEnumerateInstanceLayerPropertiesChain *chain,
+ uint32_t *pPropertyCount,
+ VkLayerProperties *pProperties) {
+ VkResult result = VK_SUCCESS;
+ struct loader_layer_list instance_layer_list;
+ tls_instance = NULL;
+
+ LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
+
+ uint32_t copy_size;
+
+ // Get layer libraries
+ memset(&instance_layer_list, 0, sizeof(instance_layer_list));
+ loaderScanForLayers(NULL, &instance_layer_list);
+
+ if (pProperties == NULL) {
+ *pPropertyCount = instance_layer_list.count;
+ goto out;
+ }
+
+ copy_size = (*pPropertyCount < instance_layer_list.count) ? *pPropertyCount : instance_layer_list.count;
+ for (uint32_t i = 0; i < copy_size; i++) {
+ memcpy(&pProperties[i], &instance_layer_list.list[i].info, sizeof(VkLayerProperties));
+ }
+
+ *pPropertyCount = copy_size;
+
+ if (copy_size < instance_layer_list.count) {
+ result = VK_INCOMPLETE;
+ goto out;
+ }
+
+out:
+
+ loaderDeleteLayerListAndProperties(NULL, &instance_layer_list);
+ return result;
+}
+
+#if defined(_WIN32) && defined(LOADER_DYNAMIC_LIB)
+BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
+ switch (reason) {
+ case DLL_PROCESS_ATTACH:
+ loader_initialize();
+ break;
+ case DLL_PROCESS_DETACH:
+ if (NULL == reserved) {
+ loader_release();
+ }
+ break;
+ default:
+ // Do nothing
+ break;
+ }
+ return TRUE;
+}
+#elif !defined(_WIN32)
+__attribute__((constructor)) void loader_init_library() { loader_initialize(); }
+
+__attribute__((destructor)) void loader_free_library() { loader_release(); }
+#endif
+
+// ---- Vulkan Core 1.1 terminators
+
+VkResult setupLoaderTermPhysDevGroups(struct loader_instance *inst) {
+ VkResult res = VK_SUCCESS;
+ struct loader_icd_term *icd_term;
+ uint32_t total_count = 0;
+ uint32_t cur_icd_group_count = 0;
+ VkPhysicalDeviceGroupPropertiesKHR **new_phys_dev_groups = NULL;
+ VkPhysicalDeviceGroupPropertiesKHR *local_phys_dev_groups = NULL;
+ PFN_vkEnumeratePhysicalDeviceGroups fpEnumeratePhysicalDeviceGroups = NULL;
+
+ if (0 == inst->phys_dev_count_term) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Loader failed to setup physical "
+ "device terminator info before calling \'EnumeratePhysicalDeviceGroups\'.");
+ assert(false);
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ // For each ICD, query the number of physical device groups, and then get an
+ // internal value for those physical devices.
+ icd_term = inst->icd_terms;
+ for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ if (inst->enabled_known_extensions.khr_device_group_creation) {
+ fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHR;
+ } else {
+ fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroups;
+ }
+
+ cur_icd_group_count = 0;
+ if (NULL == fpEnumeratePhysicalDeviceGroups) {
+ // Treat each ICD's GPU as it's own group if the extension isn't supported
+ res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &cur_icd_group_count, NULL);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
+ "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
+ icd_idx);
+ goto out;
+ }
+ } else {
+ // Query the actual group info
+ res = fpEnumeratePhysicalDeviceGroups(icd_term->instance, &cur_icd_group_count, NULL);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
+ "\'EnumeratePhysicalDeviceGroups\' to ICD %d to get count.",
+ icd_idx);
+ goto out;
+ }
+ }
+ total_count += cur_icd_group_count;
+ }
+
+ // Create an array for the new physical device groups, which will be stored
+ // in the instance for the Terminator code.
+ new_phys_dev_groups = (VkPhysicalDeviceGroupProperties **)loader_instance_heap_alloc(
+ inst, total_count * sizeof(VkPhysicalDeviceGroupProperties *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_dev_groups) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed to allocate new physical device"
+ " group array of size %d",
+ total_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupProperties *));
+
+ // Create a temporary array (on the stack) to keep track of the
+ // returned VkPhysicalDevice values.
+ local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupProperties) * total_count);
+ if (NULL == local_phys_dev_groups) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed to allocate local "
+ "physical device group array of size %d",
+ total_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ // Initialize the memory to something valid
+ memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupProperties) * total_count);
+ for (uint32_t group = 0; group < total_count; group++) {
+ local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR;
+ local_phys_dev_groups[group].pNext = NULL;
+ local_phys_dev_groups[group].subsetAllocation = false;
+ }
+
+ cur_icd_group_count = 0;
+ icd_term = inst->icd_terms;
+ for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
+ uint32_t count_this_time = total_count - cur_icd_group_count;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ if (inst->enabled_known_extensions.khr_device_group_creation) {
+ fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHR;
+ } else {
+ fpEnumeratePhysicalDeviceGroups = icd_term->dispatch.EnumeratePhysicalDeviceGroups;
+ }
+
+ if (NULL == fpEnumeratePhysicalDeviceGroups) {
+ VkPhysicalDevice* phys_dev_array = loader_stack_alloc(sizeof(VkPhysicalDevice) * count_this_time);
+ if (NULL == phys_dev_array) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed to allocate local "
+ "physical device array of size %d",
+ count_this_time);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ res = icd_term->dispatch.EnumeratePhysicalDevices(icd_term->instance, &count_this_time, phys_dev_array);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
+ "\'EnumeratePhysicalDevices\' to ICD %d to get plain phys dev count.",
+ icd_idx);
+ goto out;
+ }
+
+ // Add each GPU as it's own group
+ for (uint32_t indiv_gpu = 0; indiv_gpu < count_this_time; indiv_gpu++) {
+ local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDeviceCount = 1;
+ local_phys_dev_groups[indiv_gpu + cur_icd_group_count].physicalDevices[0] = phys_dev_array[indiv_gpu];
+ }
+
+ } else {
+ res = fpEnumeratePhysicalDeviceGroups(icd_term->instance, &count_this_time, &local_phys_dev_groups[cur_icd_group_count]);
+ if (VK_SUCCESS != res) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed during dispatch call of "
+ "\'EnumeratePhysicalDeviceGroups\' to ICD %d to get content.",
+ icd_idx);
+ goto out;
+ }
+ }
+
+ cur_icd_group_count += count_this_time;
+ }
+
+ // Replace all the physical device IDs with the proper loader values
+ for (uint32_t group = 0; group < total_count; group++) {
+ for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
+ bool found = false;
+ for (uint32_t term_gpu = 0; term_gpu < inst->phys_dev_count_term; term_gpu++) {
+ if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_term[term_gpu]->phys_dev) {
+ local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_term[term_gpu];
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed to find GPU %d in group %d"
+ " returned by \'EnumeratePhysicalDeviceGroups\' in list returned"
+ " by \'EnumeratePhysicalDevices\'", group_gpu, group);
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+ }
+ }
+
+ // Copy or create everything to fill the new array of physical device groups
+ for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
+ // Check if this physical device group with the same contents is already in the old buffer
+ for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_term; old_idx++) {
+ if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_term[old_idx]->physicalDeviceCount) {
+ bool found_all_gpus = true;
+ for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_term[old_idx]->physicalDeviceCount; old_gpu++) {
+ bool found_gpu = false;
+ for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
+ if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_term[old_idx]->physicalDevices[old_gpu]) {
+ found_gpu = true;
+ break;
+ }
+ }
+
+ if (!found_gpu) {
+ found_all_gpus = false;
+ break;
+ }
+ }
+ if (!found_all_gpus) {
+ continue;
+ } else {
+ new_phys_dev_groups[new_idx] = inst->phys_dev_groups_term[old_idx];
+ break;
+ }
+ }
+ }
+
+ // If this physical device group isn't in the old buffer, create it
+ if (NULL == new_phys_dev_groups[new_idx]) {
+ new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHR *)loader_instance_heap_alloc(
+ inst, sizeof(VkPhysicalDeviceGroupPropertiesKHR), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_dev_groups[new_idx]) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTermPhysDevGroups: Failed to allocate "
+ "physical device group Terminator object %d",
+ new_idx);
+ total_count = new_idx;
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
+ sizeof(VkPhysicalDeviceGroupPropertiesKHR));
+ }
+ }
+
+out:
+
+ if (VK_SUCCESS != res) {
+ if (NULL != new_phys_dev_groups) {
+ for (uint32_t i = 0; i < total_count; i++) {
+ loader_instance_heap_free(inst, new_phys_dev_groups[i]);
+ }
+ loader_instance_heap_free(inst, new_phys_dev_groups);
+ }
+ total_count = 0;
+ } else {
+ // Free everything that didn't carry over to the new array of
+ // physical device groups
+ if (NULL != inst->phys_dev_groups_term) {
+ for (uint32_t i = 0; i < inst->phys_dev_group_count_term; i++) {
+ bool found = false;
+ for (uint32_t j = 0; j < total_count; j++) {
+ if (inst->phys_dev_groups_term[i] == new_phys_dev_groups[j]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ loader_instance_heap_free(inst, inst->phys_dev_groups_term[i]);
+ }
+ }
+ loader_instance_heap_free(inst, inst->phys_dev_groups_term);
+ }
+
+ // Swap in the new physical device group list
+ inst->phys_dev_group_count_term = total_count;
+ inst->phys_dev_groups_term = new_phys_dev_groups;
+ }
+
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
+ VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
+ struct loader_instance *inst = (struct loader_instance *)instance;
+ VkResult res = VK_SUCCESS;
+
+ // Always call the setup loader terminator physical device groups because they may
+ // have changed at any point.
+ res = setupLoaderTermPhysDevGroups(inst);
+ if (VK_SUCCESS != res) {
+ goto out;
+ }
+
+ uint32_t copy_count = inst->phys_dev_group_count_term;
+ if (NULL != pPhysicalDeviceGroupProperties) {
+ if (copy_count > *pPhysicalDeviceGroupCount) {
+ copy_count = *pPhysicalDeviceGroupCount;
+ res = VK_INCOMPLETE;
+ }
+
+ for (uint32_t i = 0; i < copy_count; i++) {
+ memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_term[i],
+ sizeof(VkPhysicalDeviceGroupPropertiesKHR));
+ }
+ }
+
+ *pPhysicalDeviceGroupCount = copy_count;
+
+out:
+
+ return res;
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures2 *pFeatures) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceFeatures2 fpGetPhysicalDeviceFeatures2 = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2KHR;
+ } else {
+ fpGetPhysicalDeviceFeatures2 = icd_term->dispatch.GetPhysicalDeviceFeatures2;
+ }
+
+ if (fpGetPhysicalDeviceFeatures2 != NULL || !inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceFeatures2(phys_dev_term->phys_dev, pFeatures);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceFeatures2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFeatures",
+ icd_term->scanned_icd->lib_name);
+
+ // Write to the VkPhysicalDeviceFeatures2 struct
+ icd_term->dispatch.GetPhysicalDeviceFeatures(phys_dev_term->phys_dev, &pFeatures->features);
+
+ const VkBaseInStructure *pNext = pFeatures->pNext;
+ while (pNext != NULL) {
+ switch (pNext->sType) {
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
+ // Skip the check if VK_KHR_multiview is enabled because it's a device extension
+ // Write to the VkPhysicalDeviceMultiviewFeaturesKHR struct
+ VkPhysicalDeviceMultiviewFeaturesKHR *multiview_features = (VkPhysicalDeviceMultiviewFeaturesKHR *)pNext;
+ multiview_features->multiview = VK_FALSE;
+ multiview_features->multiviewGeometryShader = VK_FALSE;
+ multiview_features->multiviewTessellationShader = VK_FALSE;
+
+ pNext = multiview_features->pNext;
+ break;
+ }
+ default: {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceFeatures2: Emulation found unrecognized structure type in pFeatures->pNext - "
+ "this struct will be ignored");
+
+ pNext = pNext->pNext;
+ break;
+ }
+ }
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties2 *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceProperties2 fpGetPhysicalDeviceProperties2 = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2KHR;
+ } else {
+ fpGetPhysicalDeviceProperties2 = icd_term->dispatch.GetPhysicalDeviceProperties2;
+ }
+
+ if (fpGetPhysicalDeviceProperties2 != NULL || !inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceProperties2(phys_dev_term->phys_dev, pProperties);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceProperties",
+ icd_term->scanned_icd->lib_name);
+
+ // Write to the VkPhysicalDeviceProperties2 struct
+ icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pProperties->properties);
+
+ const VkBaseInStructure *pNext = pProperties->pNext;
+ while (pNext != NULL) {
+ switch (pNext->sType) {
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
+ VkPhysicalDeviceIDPropertiesKHR *id_properties = (VkPhysicalDeviceIDPropertiesKHR *)pNext;
+
+ // Verify that "VK_KHR_external_memory_capabilities" is enabled
+ if (icd_term->this_instance->enabled_known_extensions.khr_external_memory_capabilities) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceProperties2: Emulation cannot generate unique IDs for struct "
+ "VkPhysicalDeviceIDProperties - setting IDs to zero instead");
+
+ // Write to the VkPhysicalDeviceIDPropertiesKHR struct
+ memset(id_properties->deviceUUID, 0, VK_UUID_SIZE);
+ memset(id_properties->driverUUID, 0, VK_UUID_SIZE);
+ id_properties->deviceLUIDValid = VK_FALSE;
+ }
+
+ pNext = id_properties->pNext;
+ break;
+ }
+ default: {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in "
+ "pProperties->pNext - this struct will be ignored");
+
+ pNext = pNext->pNext;
+ break;
+ }
+ }
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
+ VkFormatProperties2 *pFormatProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceFormatProperties2 fpGetPhysicalDeviceFormatProperties2 = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2KHR;
+ } else {
+ fpGetPhysicalDeviceFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceFormatProperties2;
+ }
+
+ if (fpGetPhysicalDeviceFormatProperties2 != NULL || !inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceFormatProperties2(phys_dev_term->phys_dev, format, pFormatProperties);
+ } else {
+ // Emulate the call
+ loader_log(
+ icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceFormatProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceFormatProperties",
+ icd_term->scanned_icd->lib_name);
+
+ // Write to the VkFormatProperties2 struct
+ icd_term->dispatch.GetPhysicalDeviceFormatProperties(phys_dev_term->phys_dev, format, &pFormatProperties->formatProperties);
+
+ if (pFormatProperties->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceFormatProperties2: Emulation found unrecognized structure type in "
+ "pFormatProperties->pNext - this struct will be ignored");
+ }
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
+ VkImageFormatProperties2KHR *pImageFormatProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceImageFormatProperties2 fpGetPhysicalDeviceImageFormatProperties2 = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2KHR;
+ } else {
+ fpGetPhysicalDeviceImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceImageFormatProperties2;
+ }
+
+ if (fpGetPhysicalDeviceImageFormatProperties2 != NULL || !inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ // Pass the call to the driver
+ return fpGetPhysicalDeviceImageFormatProperties2(phys_dev_term->phys_dev, pImageFormatInfo, pImageFormatProperties);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceImageFormatProperties2: Emulating call in ICD \"%s\" using "
+ "vkGetPhysicalDeviceImageFormatProperties",
+ icd_term->scanned_icd->lib_name);
+
+ // If there is more info in either pNext, then this is unsupported
+ if (pImageFormatInfo->pNext != NULL || pImageFormatProperties->pNext != NULL) {
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
+ }
+
+ // Write to the VkImageFormatProperties2KHR struct
+ return icd_term->dispatch.GetPhysicalDeviceImageFormatProperties(
+ phys_dev_term->phys_dev, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling,
+ pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2(
+ VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR *pQueueFamilyProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2 fpGetPhysicalDeviceQueueFamilyProperties2 = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2KHR;
+ } else {
+ fpGetPhysicalDeviceQueueFamilyProperties2 = icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties2;
+ }
+
+ if (fpGetPhysicalDeviceQueueFamilyProperties2 != NULL || !inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceQueueFamilyProperties2(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceQueueFamilyProperties2: Emulating call in ICD \"%s\" using "
+ "vkGetPhysicalDeviceQueueFamilyProperties",
+ icd_term->scanned_icd->lib_name);
+
+ if (pQueueFamilyProperties == NULL || *pQueueFamilyPropertyCount == 0) {
+ // Write to pQueueFamilyPropertyCount
+ icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount, NULL);
+ } else {
+ // Allocate a temporary array for the output of the old function
+ VkQueueFamilyProperties *properties = loader_stack_alloc(*pQueueFamilyPropertyCount * sizeof(VkQueueFamilyProperties));
+ if (properties == NULL) {
+ *pQueueFamilyPropertyCount = 0;
+ loader_log(
+ icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkGetPhysicalDeviceQueueFamilyProperties2: Out of memory - Failed to allocate array for loader emulation.");
+ return;
+ }
+
+ icd_term->dispatch.GetPhysicalDeviceQueueFamilyProperties(phys_dev_term->phys_dev, pQueueFamilyPropertyCount,
+ properties);
+ for (uint32_t i = 0; i < *pQueueFamilyPropertyCount; ++i) {
+ // Write to the VkQueueFamilyProperties2KHR struct
+ memcpy(&pQueueFamilyProperties[i].queueFamilyProperties, &properties[i], sizeof(VkQueueFamilyProperties));
+
+ if (pQueueFamilyProperties[i].pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceQueueFamilyProperties2: Emulation found unrecognized structure type in "
+ "pQueueFamilyProperties[%d].pNext - this struct will be ignored",
+ i);
+ }
+ }
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2(
+ VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceMemoryProperties2 fpGetPhysicalDeviceMemoryProperties2 = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2KHR;
+ } else {
+ fpGetPhysicalDeviceMemoryProperties2 = icd_term->dispatch.GetPhysicalDeviceMemoryProperties2;
+ }
+
+ if (fpGetPhysicalDeviceMemoryProperties2 != NULL || !inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceMemoryProperties2(phys_dev_term->phys_dev, pMemoryProperties);
+ } else {
+ // Emulate the call
+ loader_log(
+ icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceMemoryProperties2: Emulating call in ICD \"%s\" using vkGetPhysicalDeviceMemoryProperties",
+ icd_term->scanned_icd->lib_name);
+
+ // Write to the VkPhysicalDeviceMemoryProperties2 struct
+ icd_term->dispatch.GetPhysicalDeviceMemoryProperties(phys_dev_term->phys_dev, &pMemoryProperties->memoryProperties);
+
+ if (pMemoryProperties->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceMemoryProperties2: Emulation found unrecognized structure type in "
+ "pMemoryProperties->pNext - this struct will be ignored");
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR *pFormatInfo, uint32_t *pPropertyCount,
+ VkSparseImageFormatProperties2KHR *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 fpGetPhysicalDeviceSparseImageFormatProperties2 = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2KHR;
+ } else {
+ fpGetPhysicalDeviceSparseImageFormatProperties2 = icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties2;
+ }
+
+ if (fpGetPhysicalDeviceSparseImageFormatProperties2 != NULL || !inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceSparseImageFormatProperties2(phys_dev_term->phys_dev, pFormatInfo, pPropertyCount, pProperties);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulating call in ICD \"%s\" using "
+ "vkGetPhysicalDeviceSparseImageFormatProperties",
+ icd_term->scanned_icd->lib_name);
+
+ if (pFormatInfo->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulation found unrecognized structure type in "
+ "pFormatInfo->pNext - this struct will be ignored");
+ }
+
+ if (pProperties == NULL || *pPropertyCount == 0) {
+ // Write to pPropertyCount
+ icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
+ phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
+ pFormatInfo->tiling, pPropertyCount, NULL);
+ } else {
+ // Allocate a temporary array for the output of the old function
+ VkSparseImageFormatProperties *properties =
+ loader_stack_alloc(*pPropertyCount * sizeof(VkSparseImageMemoryRequirements));
+ if (properties == NULL) {
+ *pPropertyCount = 0;
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSparseImageFormatProperties2: Out of memory - Failed to allocate array for "
+ "loader emulation.");
+ return;
+ }
+
+ icd_term->dispatch.GetPhysicalDeviceSparseImageFormatProperties(
+ phys_dev_term->phys_dev, pFormatInfo->format, pFormatInfo->type, pFormatInfo->samples, pFormatInfo->usage,
+ pFormatInfo->tiling, pPropertyCount, properties);
+ for (uint32_t i = 0; i < *pPropertyCount; ++i) {
+ // Write to the VkSparseImageFormatProperties2KHR struct
+ memcpy(&pProperties[i].properties, &properties[i], sizeof(VkSparseImageFormatProperties));
+
+ if (pProperties[i].pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceSparseImageFormatProperties2: Emulation found unrecognized structure type in "
+ "pProperties[%d].pNext - this struct will be ignored",
+ i);
+ }
+ }
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalBufferProperties(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
+ VkExternalBufferProperties *pExternalBufferProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceExternalBufferProperties fpGetPhysicalDeviceExternalBufferProperties = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_external_memory_capabilities) {
+ fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferPropertiesKHR;
+ } else {
+ fpGetPhysicalDeviceExternalBufferProperties = icd_term->dispatch.GetPhysicalDeviceExternalBufferProperties;
+ }
+
+ if (fpGetPhysicalDeviceExternalBufferProperties || !inst->enabled_known_extensions.khr_external_memory_capabilities) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceExternalBufferProperties(phys_dev_term->phys_dev, pExternalBufferInfo, pExternalBufferProperties);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalBufferProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
+
+ if (pExternalBufferInfo->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalBufferProperties: Emulation found unrecognized structure type in "
+ "pExternalBufferInfo->pNext - this struct will be ignored");
+ }
+
+ // Fill in everything being unsupported
+ memset(&pExternalBufferProperties->externalMemoryProperties, 0, sizeof(VkExternalMemoryPropertiesKHR));
+
+ if (pExternalBufferProperties->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalBufferProperties: Emulation found unrecognized structure type in "
+ "pExternalBufferProperties->pNext - this struct will be ignored");
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalSemaphoreProperties(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
+ VkExternalSemaphoreProperties *pExternalSemaphoreProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceExternalSemaphoreProperties fpGetPhysicalDeviceExternalSemaphoreProperties = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_external_semaphore_capabilities) {
+ fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphorePropertiesKHR;
+ } else {
+ fpGetPhysicalDeviceExternalSemaphoreProperties = icd_term->dispatch.GetPhysicalDeviceExternalSemaphoreProperties;
+ }
+
+ if (fpGetPhysicalDeviceExternalSemaphoreProperties != NULL || !inst->enabled_known_extensions.khr_external_semaphore_capabilities) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceExternalSemaphoreProperties(phys_dev_term->phys_dev, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulating call in ICD \"%s\"",
+ icd_term->scanned_icd->lib_name);
+
+ if (pExternalSemaphoreInfo->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulation found unrecognized structure type in "
+ "pExternalSemaphoreInfo->pNext - this struct will be ignored");
+ }
+
+ // Fill in everything being unsupported
+ pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
+ pExternalSemaphoreProperties->compatibleHandleTypes = 0;
+ pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
+
+ if (pExternalSemaphoreProperties->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalSemaphoreProperties: Emulation found unrecognized structure type in "
+ "pExternalSemaphoreProperties->pNext - this struct will be ignored");
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalFenceProperties(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
+ VkExternalFenceProperties *pExternalFenceProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ const struct loader_instance *inst = icd_term->this_instance;
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ PFN_vkGetPhysicalDeviceExternalFenceProperties fpGetPhysicalDeviceExternalFenceProperties = NULL;
+ if (inst != NULL && inst->enabled_known_extensions.khr_external_fence_capabilities) {
+ fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFencePropertiesKHR;
+ } else {
+ fpGetPhysicalDeviceExternalFenceProperties = icd_term->dispatch.GetPhysicalDeviceExternalFenceProperties;
+ }
+
+ if (fpGetPhysicalDeviceExternalFenceProperties != NULL || !inst->enabled_known_extensions.khr_external_fence_capabilities) {
+ // Pass the call to the driver
+ fpGetPhysicalDeviceExternalFenceProperties(phys_dev_term->phys_dev, pExternalFenceInfo, pExternalFenceProperties);
+ } else {
+ // Emulate the call
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalFenceProperties: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
+
+ if (pExternalFenceInfo->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalFenceProperties: Emulation found unrecognized structure type in "
+ "pExternalFenceInfo->pNext - this struct will be ignored");
+ }
+
+ // Fill in everything being unsupported
+ pExternalFenceProperties->exportFromImportedHandleTypes = 0;
+ pExternalFenceProperties->compatibleHandleTypes = 0;
+ pExternalFenceProperties->externalFenceFeatures = 0;
+
+ if (pExternalFenceProperties->pNext != NULL) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "vkGetPhysicalDeviceExternalFenceProperties: Emulation found unrecognized structure type in "
+ "pExternalFenceProperties->pNext - this struct will be ignored");
+ }
+ }
+}
diff --git a/thirdparty/vulkan/loader/loader.h b/thirdparty/vulkan/loader/loader.h
new file mode 100644
index 0000000000..8d6b4c454a
--- /dev/null
+++ b/thirdparty/vulkan/loader/loader.h
@@ -0,0 +1,532 @@
+/*
+ *
+ * Copyright (c) 2014-2019 The Khronos Group Inc.
+ * Copyright (c) 2014-2019 Valve Corporation
+ * Copyright (c) 2014-2019 LunarG, Inc.
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Chia-I Wu <olvaffe@gmail.com>
+ * Author: Chia-I Wu <olv@lunarg.com>
+ * Author: Mark Lobodzinski <mark@LunarG.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ *
+ */
+
+#ifndef LOADER_H
+#define LOADER_H
+
+#include <vulkan/vulkan.h>
+#include "vk_loader_platform.h"
+#include "vk_loader_layer.h"
+#include <vulkan/vk_layer.h>
+#include <vulkan/vk_icd.h>
+#include <assert.h>
+#include "vk_layer_dispatch_table.h"
+#include "vk_loader_extensions.h"
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define LOADER_EXPORT __attribute__((visibility("default")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
+#define LOADER_EXPORT __attribute__((visibility("default")))
+#else
+#define LOADER_EXPORT
+#endif
+
+// A debug option to disable allocators at compile time to investigate future issues.
+#define DEBUG_DISABLE_APP_ALLOCATORS 0
+
+#define MAX_STRING_SIZE 1024
+
+// This is defined in vk_layer.h, but if there's problems we need to create the define
+// here.
+#ifndef MAX_NUM_UNKNOWN_EXTS
+#define MAX_NUM_UNKNOWN_EXTS 250
+#endif
+
+enum layer_type_flags {
+ VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1, // If not set, indicates Device layer
+ VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2, // If not set, indicates Implicit layer
+ VK_LAYER_TYPE_FLAG_META_LAYER = 0x4, // If not set, indicates standard layer
+};
+
+typedef enum VkStringErrorFlagBits {
+ VK_STRING_ERROR_NONE = 0x00000000,
+ VK_STRING_ERROR_LENGTH = 0x00000001,
+ VK_STRING_ERROR_BAD_DATA = 0x00000002,
+} VkStringErrorFlagBits;
+typedef VkFlags VkStringErrorFlags;
+
+static const int MaxLoaderStringLength = 256;
+static const char UTF8_ONE_BYTE_CODE = 0xC0;
+static const char UTF8_ONE_BYTE_MASK = 0xE0;
+static const char UTF8_TWO_BYTE_CODE = 0xE0;
+static const char UTF8_TWO_BYTE_MASK = 0xF0;
+static const char UTF8_THREE_BYTE_CODE = 0xF0;
+static const char UTF8_THREE_BYTE_MASK = 0xF8;
+static const char UTF8_DATA_BYTE_CODE = 0x80;
+static const char UTF8_DATA_BYTE_MASK = 0xC0;
+
+// form of all dynamic lists/arrays
+// only the list element should be changed
+struct loader_generic_list {
+ size_t capacity;
+ uint32_t count;
+ void *list;
+};
+
+struct loader_extension_list {
+ size_t capacity;
+ uint32_t count;
+ VkExtensionProperties *list;
+};
+
+struct loader_dev_ext_props {
+ VkExtensionProperties props;
+ uint32_t entrypoint_count;
+ char **entrypoints;
+};
+
+struct loader_device_extension_list {
+ size_t capacity;
+ uint32_t count;
+ struct loader_dev_ext_props *list;
+};
+
+struct loader_name_value {
+ char name[MAX_STRING_SIZE];
+ char value[MAX_STRING_SIZE];
+};
+
+struct loader_layer_functions {
+ char str_gipa[MAX_STRING_SIZE];
+ char str_gdpa[MAX_STRING_SIZE];
+ char str_negotiate_interface[MAX_STRING_SIZE];
+ PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface;
+ PFN_vkGetInstanceProcAddr get_instance_proc_addr;
+ PFN_vkGetDeviceProcAddr get_device_proc_addr;
+ PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr;
+};
+
+struct loader_override_expiration {
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hour;
+ uint8_t minute;
+};
+
+struct loader_layer_properties {
+ VkLayerProperties info;
+ enum layer_type_flags type_flags;
+ uint32_t interface_version; // PFN_vkNegotiateLoaderLayerInterfaceVersion
+ char lib_name[MAX_STRING_SIZE];
+ loader_platform_dl_handle lib_handle;
+ struct loader_layer_functions functions;
+ struct loader_extension_list instance_extension_list;
+ struct loader_device_extension_list device_extension_list;
+ struct loader_name_value disable_env_var;
+ struct loader_name_value enable_env_var;
+ uint32_t num_component_layers;
+ char (*component_layer_names)[MAX_STRING_SIZE];
+ struct {
+ char enumerate_instance_extension_properties[MAX_STRING_SIZE];
+ char enumerate_instance_layer_properties[MAX_STRING_SIZE];
+ char enumerate_instance_version[MAX_STRING_SIZE];
+ } pre_instance_functions;
+ uint32_t num_override_paths;
+ char (*override_paths)[MAX_STRING_SIZE];
+ bool is_override;
+ bool has_expiration;
+ struct loader_override_expiration expiration;
+ bool keep;
+ uint32_t num_blacklist_layers;
+ char (*blacklist_layer_names)[MAX_STRING_SIZE];
+};
+
+struct loader_layer_list {
+ size_t capacity;
+ uint32_t count;
+ struct loader_layer_properties *list;
+};
+
+struct loader_dispatch_hash_list {
+ size_t capacity;
+ uint32_t count;
+ uint32_t *index; // index into the dev_ext dispatch table
+};
+
+// loader_dispatch_hash_entry and loader_dev_ext_dispatch_table.dev_ext have
+// one to one correspondence; one loader_dispatch_hash_entry for one dev_ext
+// dispatch entry.
+// Also have a one to one correspondence with functions in dev_ext_trampoline.c
+struct loader_dispatch_hash_entry {
+ char *func_name;
+ struct loader_dispatch_hash_list list; // to handle hashing collisions
+};
+
+typedef VkResult(VKAPI_PTR *PFN_vkDevExt)(VkDevice device);
+struct loader_dev_ext_dispatch_table {
+ PFN_vkDevExt dev_ext[MAX_NUM_UNKNOWN_EXTS];
+};
+
+struct loader_dev_dispatch_table {
+ VkLayerDispatchTable core_dispatch;
+ struct loader_dev_ext_dispatch_table ext_dispatch;
+};
+
+// per CreateDevice structure
+struct loader_device {
+ struct loader_dev_dispatch_table loader_dispatch;
+ VkDevice chain_device; // device object from the dispatch chain
+ VkDevice icd_device; // device object from the icd
+ struct loader_physical_device_term *phys_dev_term;
+
+ // List of activated layers.
+ // app_ is the version based on exactly what the application asked for.
+ // This is what must be returned to the application on Enumerate calls.
+ // expanded_ is the version based on expanding meta-layers into their
+ // individual component layers. This is what is used internally.
+ struct loader_layer_list app_activated_layer_list;
+ struct loader_layer_list expanded_activated_layer_list;
+
+ VkAllocationCallbacks alloc_callbacks;
+
+ // List of activated device extensions that have terminators implemented in the loader
+ struct {
+ bool khr_swapchain_enabled;
+ bool khr_display_swapchain_enabled;
+ bool khr_device_group_enabled;
+ bool ext_debug_marker_enabled;
+ bool ext_debug_utils_enabled;
+ bool ext_full_screen_exclusive_enabled;
+ } extensions;
+
+ struct loader_device *next;
+};
+
+// Per ICD information
+
+// Per ICD structure
+struct loader_icd_term {
+ // pointers to find other structs
+ const struct loader_scanned_icd *scanned_icd;
+ const struct loader_instance *this_instance;
+ struct loader_device *logical_device_list;
+ VkInstance instance; // instance object from the icd
+ struct loader_icd_term_dispatch dispatch;
+
+ struct loader_icd_term *next;
+
+ PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
+};
+
+// Per ICD library structure
+struct loader_icd_tramp_list {
+ size_t capacity;
+ uint32_t count;
+ struct loader_scanned_icd *scanned_list;
+};
+
+struct loader_instance_dispatch_table {
+ VkLayerInstanceDispatchTable layer_inst_disp; // must be first entry in structure
+
+ // Physical device functions unknown to the loader
+ PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
+};
+
+// Per instance structure
+struct loader_instance {
+ struct loader_instance_dispatch_table *disp; // must be first entry in structure
+
+ // Vulkan API version the app is intending to use.
+ uint16_t app_api_major_version;
+ uint16_t app_api_minor_version;
+
+ // We need to manually track physical devices over time. If the user
+ // re-queries the information, we don't want to delete old data or
+ // create new data unless necessary.
+ uint32_t total_gpu_count;
+ uint32_t phys_dev_count_term;
+ struct loader_physical_device_term **phys_devs_term;
+ uint32_t phys_dev_count_tramp;
+ struct loader_physical_device_tramp **phys_devs_tramp;
+
+ // We also need to manually track physical device groups, but we don't need
+ // loader specific structures since we have that content in the physical
+ // device stored internal to the public structures.
+ uint32_t phys_dev_group_count_term;
+ struct VkPhysicalDeviceGroupProperties **phys_dev_groups_term;
+ uint32_t phys_dev_group_count_tramp;
+ struct VkPhysicalDeviceGroupProperties **phys_dev_groups_tramp;
+
+ struct loader_instance *next;
+
+ uint32_t total_icd_count;
+ struct loader_icd_term *icd_terms;
+ struct loader_icd_tramp_list icd_tramp_list;
+
+ struct loader_dispatch_hash_entry dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS];
+ struct loader_dispatch_hash_entry phys_dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS];
+
+ struct loader_msg_callback_map_entry *icd_msg_callback_map;
+
+ struct loader_layer_list instance_layer_list;
+ bool override_layer_present;
+
+ // List of activated layers.
+ // app_ is the version based on exactly what the application asked for.
+ // This is what must be returned to the application on Enumerate calls.
+ // expanded_ is the version based on expanding meta-layers into their
+ // individual component layers. This is what is used internally.
+ struct loader_layer_list app_activated_layer_list;
+ struct loader_layer_list expanded_activated_layer_list;
+
+ VkInstance instance; // layers/ICD instance returned to trampoline
+
+ struct loader_extension_list ext_list; // icds and loaders extensions
+ union loader_instance_extension_enables enabled_known_extensions;
+
+ VkLayerDbgFunctionNode *DbgFunctionHead;
+ uint32_t num_tmp_report_callbacks;
+ VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos;
+ VkDebugReportCallbackEXT *tmp_report_callbacks;
+ uint32_t num_tmp_messengers;
+ VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos;
+ VkDebugUtilsMessengerEXT *tmp_messengers;
+
+ VkAllocationCallbacks alloc_callbacks;
+
+ bool wsi_surface_enabled;
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ bool wsi_win32_surface_enabled;
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ bool wsi_wayland_surface_enabled;
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ bool wsi_xcb_surface_enabled;
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ bool wsi_xlib_surface_enabled;
+#endif
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ bool wsi_android_surface_enabled;
+#endif
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ bool wsi_macos_surface_enabled;
+#endif
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ bool wsi_ios_surface_enabled;
+#endif
+ bool wsi_headless_surface_enabled;
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+ bool wsi_metal_surface_enabled;
+#endif
+ bool wsi_display_enabled;
+ bool wsi_display_props2_enabled;
+};
+
+// VkPhysicalDevice requires special treatment by loader. Firstly, terminator
+// code must be able to get the struct loader_icd_term to call into the proper
+// driver (multiple ICD/gpu case). This can be accomplished by wrapping the
+// created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices().
+// Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice
+// in trampoline code. This implies, that the loader trampoline code must also
+// wrap the VkPhysicalDevice object in trampoline code. Thus, loader has to
+// wrap the VkPhysicalDevice created object twice. In trampoline code it can't
+// rely on the terminator object wrapping since a layer may also wrap. Since
+// trampoline code wraps the VkPhysicalDevice this means all loader trampoline
+// code that passes a VkPhysicalDevice should unwrap it.
+
+// Per enumerated PhysicalDevice structure, used to wrap in trampoline code and
+// also same structure used to wrap in terminator code
+struct loader_physical_device_tramp {
+ struct loader_instance_dispatch_table *disp; // must be first entry in structure
+ struct loader_instance *this_instance;
+ VkPhysicalDevice phys_dev; // object from layers/loader terminator
+};
+
+// Per enumerated PhysicalDevice structure, used to wrap in terminator code
+struct loader_physical_device_term {
+ struct loader_instance_dispatch_table *disp; // must be first entry in structure
+ struct loader_icd_term *this_icd_term;
+ uint8_t icd_index;
+ VkPhysicalDevice phys_dev; // object from ICD
+};
+
+struct loader_struct {
+ struct loader_instance *instances;
+};
+
+struct loader_scanned_icd {
+ char *lib_name;
+ loader_platform_dl_handle handle;
+ uint32_t api_version;
+ uint32_t interface_version;
+ PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
+ PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
+ PFN_vkCreateInstance CreateInstance;
+ PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
+};
+
+static inline struct loader_instance *loader_instance(VkInstance instance) { return (struct loader_instance *)instance; }
+
+static inline VkPhysicalDevice loader_unwrap_physical_device(VkPhysicalDevice physicalDevice) {
+ struct loader_physical_device_tramp *phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
+ return phys_dev->phys_dev;
+}
+
+static inline void loader_set_dispatch(void *obj, const void *data) { *((const void **)obj) = data; }
+
+static inline VkLayerDispatchTable *loader_get_dispatch(const void *obj) { return *((VkLayerDispatchTable **)obj); }
+
+static inline struct loader_dev_dispatch_table *loader_get_dev_dispatch(const void *obj) {
+ return *((struct loader_dev_dispatch_table **)obj);
+}
+
+static inline VkLayerInstanceDispatchTable *loader_get_instance_layer_dispatch(const void *obj) {
+ return *((VkLayerInstanceDispatchTable **)obj);
+}
+
+static inline struct loader_instance_dispatch_table *loader_get_instance_dispatch(const void *obj) {
+ return *((struct loader_instance_dispatch_table **)obj);
+}
+
+static inline void loader_init_dispatch(void *obj, const void *data) {
+#ifdef DEBUG
+ assert(valid_loader_magic_value(obj) &&
+ "Incompatible ICD, first dword must be initialized to "
+ "ICD_LOADER_MAGIC. See loader/README.md for details.");
+#endif
+
+ loader_set_dispatch(obj, data);
+}
+
+// Global variables used across files
+extern struct loader_struct loader;
+extern THREAD_LOCAL_DECL struct loader_instance *tls_instance;
+#if defined(_WIN32) && !defined(LOADER_DYNAMIC_LIB)
+extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init);
+#endif
+extern loader_platform_thread_mutex loader_lock;
+extern loader_platform_thread_mutex loader_json_lock;
+
+struct loader_msg_callback_map_entry {
+ VkDebugReportCallbackEXT icd_obj;
+ VkDebugReportCallbackEXT loader_obj;
+};
+
+// Helper function definitions
+void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocationScope);
+void loader_instance_heap_free(const struct loader_instance *instance, void *pMemory);
+void *loader_instance_heap_realloc(const struct loader_instance *instance, void *pMemory, size_t orig_size, size_t size,
+ VkSystemAllocationScope alloc_scope);
+void *loader_instance_tls_heap_alloc(size_t size);
+void loader_instance_tls_heap_free(void *pMemory);
+void *loader_device_heap_alloc(const struct loader_device *device, size_t size, VkSystemAllocationScope allocationScope);
+void loader_device_heap_free(const struct loader_device *device, void *pMemory);
+void *loader_device_heap_realloc(const struct loader_device *device, void *pMemory, size_t orig_size, size_t size,
+ VkSystemAllocationScope alloc_scope);
+
+void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code, const char *format, ...);
+
+bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2);
+
+VkResult loaderValidateLayers(const struct loader_instance *inst, const uint32_t layer_count,
+ const char *const *ppEnabledLayerNames, const struct loader_layer_list *list);
+
+VkResult loader_validate_instance_extensions(struct loader_instance *inst, const struct loader_extension_list *icd_exts,
+ const struct loader_layer_list *instance_layer,
+ const VkInstanceCreateInfo *pCreateInfo);
+
+void loader_initialize(void);
+bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count,
+ const VkExtensionProperties *ext_array);
+bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop, const struct loader_extension_list *ext_list);
+
+VkResult loader_add_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list,
+ uint32_t prop_list_count, const VkExtensionProperties *props);
+VkResult loader_add_to_dev_ext_list(const struct loader_instance *inst, struct loader_device_extension_list *ext_list,
+ const VkExtensionProperties *props, uint32_t entry_count, char **entrys);
+VkResult loader_add_device_extensions(const struct loader_instance *inst,
+ PFN_vkEnumerateDeviceExtensionProperties fpEnumerateDeviceExtensionProperties,
+ VkPhysicalDevice physical_device, const char *lib_name,
+ struct loader_extension_list *ext_list);
+VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size);
+void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list);
+void loaderDestroyLayerList(const struct loader_instance *inst, struct loader_device *device, struct loader_layer_list *layer_list);
+void loaderDeleteLayerListAndProperties(const struct loader_instance *inst, struct loader_layer_list *layer_list);
+void loaderAddLayerNameToList(const struct loader_instance *inst, const char *name, const enum layer_type_flags type_flags,
+ const struct loader_layer_list *source_list, struct loader_layer_list *target_list,
+ struct loader_layer_list *expanded_target_list);
+void loader_scanned_icd_clear(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
+VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
+void loaderScanForLayers(struct loader_instance *inst, struct loader_layer_list *instance_layers);
+void loaderScanForImplicitLayers(struct loader_instance *inst, struct loader_layer_list *instance_layers);
+bool loaderImplicitLayerIsEnabled(const struct loader_instance *inst, const struct loader_layer_properties *prop);
+VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
+ struct loader_extension_list *inst_exts);
+struct loader_icd_term *loader_get_icd_and_device(const VkDevice device, struct loader_device **found_dev, uint32_t *icd_index);
+void loader_init_dispatch_dev_ext(struct loader_instance *inst, struct loader_device *dev);
+void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
+void *loader_get_dev_ext_trampoline(uint32_t index);
+bool loader_phys_dev_ext_gpa(struct loader_instance *inst, const char *funcName, bool perform_checking, void **tramp_addr,
+ void **term_addr);
+void *loader_get_phys_dev_ext_tramp(uint32_t index);
+void *loader_get_phys_dev_ext_termin(uint32_t index);
+struct loader_instance *loader_get_instance(const VkInstance instance);
+void loaderDeactivateLayers(const struct loader_instance *instance, struct loader_device *device, struct loader_layer_list *list);
+struct loader_device *loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator);
+void loader_add_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term,
+ struct loader_device *found_dev);
+void loader_remove_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term,
+ struct loader_device *found_dev, const VkAllocationCallbacks *pAllocator);
+// NOTE: Outside of loader, this entry-point is only provided for error
+// cleanup.
+void loader_destroy_logical_device(const struct loader_instance *inst, struct loader_device *dev,
+ const VkAllocationCallbacks *pAllocator);
+
+VkResult loaderEnableInstanceLayers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
+ const struct loader_layer_list *instance_layers);
+
+VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
+ struct loader_instance *inst, VkInstance *created_instance);
+
+void loaderActivateInstanceLayerExtensions(struct loader_instance *inst, VkInstance created_inst);
+
+VKAPI_ATTR VkResult VKAPI_CALL loader_layer_create_device(VkInstance instance, VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
+ PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA);
+VKAPI_ATTR void VKAPI_CALL loader_layer_destroy_device(VkDevice device, const VkAllocationCallbacks *pAllocator,
+ PFN_vkDestroyDevice destroyFunction);
+
+VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, const struct loader_instance *inst,
+ struct loader_device *dev, PFN_vkGetInstanceProcAddr callingLayer,
+ PFN_vkGetDeviceProcAddr *layerNextGDPA);
+
+VkResult loader_validate_device_extensions(struct loader_instance *this_instance,
+ const struct loader_layer_list *activated_device_layers,
+ const struct loader_extension_list *icd_exts, const VkDeviceCreateInfo *pCreateInfo);
+
+VkResult setupLoaderTrampPhysDevs(VkInstance instance);
+VkResult setupLoaderTermPhysDevs(struct loader_instance *inst);
+
+VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
+
+#endif // LOADER_H
diff --git a/thirdparty/vulkan/loader/murmurhash.c b/thirdparty/vulkan/loader/murmurhash.c
new file mode 100644
index 0000000000..40f0d5e975
--- /dev/null
+++ b/thirdparty/vulkan/loader/murmurhash.c
@@ -0,0 +1,98 @@
+
+/**
+ * `murmurhash.h' - murmurhash
+ *
+ * copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include "murmurhash.h"
+
+uint32_t murmurhash(const char *key, size_t len, uint32_t seed) {
+ uint32_t c1 = 0xcc9e2d51;
+ uint32_t c2 = 0x1b873593;
+ uint32_t r1 = 15;
+ uint32_t r2 = 13;
+ uint32_t m = 5;
+ uint32_t n = 0xe6546b64;
+ uint32_t h = 0;
+ uint32_t k = 0;
+ uint8_t *d = (uint8_t *)key; // 32 bit extract from `key'
+ const uint32_t *chunks = NULL;
+ const uint8_t *tail = NULL; // tail - last 8 bytes
+ int i = 0;
+ int l = (int)len / 4; // chunk length
+
+ h = seed;
+
+ chunks = (const uint32_t *)(d + l * 4); // body
+ tail = (const uint8_t *)(d + l * 4); // last 8 byte chunk of `key'
+
+ // for each 4 byte chunk of `key'
+ for (i = -l; i != 0; ++i) {
+ // next 4 byte chunk of `key'
+ k = chunks[i];
+
+ // encode next 4 byte chunk of `key'
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+
+ // append to hash
+ h ^= k;
+ h = (h << r2) | (h >> (32 - r2));
+ h = h * m + n;
+ }
+
+ k = 0;
+
+ // remainder
+ switch (len & 3) { // `len % 4'
+ case 3:
+ k ^= (tail[2] << 16);
+ // fall through
+ case 2:
+ k ^= (tail[1] << 8);
+ // fall through
+ case 1:
+ k ^= tail[0];
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+ h ^= k;
+ }
+
+ h ^= len;
+
+ h ^= (h >> 16);
+ h *= 0x85ebca6b;
+ h ^= (h >> 13);
+ h *= 0xc2b2ae35;
+ h ^= (h >> 16);
+
+ return h;
+}
diff --git a/thirdparty/vulkan/loader/murmurhash.h b/thirdparty/vulkan/loader/murmurhash.h
new file mode 100644
index 0000000000..775532e8b8
--- /dev/null
+++ b/thirdparty/vulkan/loader/murmurhash.h
@@ -0,0 +1,52 @@
+
+/**
+ * `murmurhash.h' - murmurhash
+ *
+ * copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and/or associated documentation files (the "Materials"), to
+ * deal in the Materials without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Materials, and to permit persons to whom the Materials are
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included in
+ * all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
+ * USE OR OTHER DEALINGS IN THE MATERIALS.
+ */
+
+#ifndef MURMURHASH_H
+#define MURMURHASH_H 1
+
+#include <stdint.h>
+
+#define MURMURHASH_VERSION "0.0.3"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns a murmur hash of `key' based on `seed'
+ * using the MurmurHash3 algorithm
+ */
+
+uint32_t murmurhash(const char *key, size_t len, uint32_t seed);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/vulkan/loader/phys_dev_ext.c b/thirdparty/vulkan/loader/phys_dev_ext.c
new file mode 100644
index 0000000000..91e0ef8f67
--- /dev/null
+++ b/thirdparty/vulkan/loader/phys_dev_ext.c
@@ -0,0 +1,1056 @@
+/*
+ *
+ * Copyright (c) 2016-17 The Khronos Group Inc.
+ * Copyright (c) 2016-17 Valve Corporation
+ * Copyright (c) 2016-17 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Young <marky@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ *
+ */
+
+// This code is used to enable generic instance extensions which use a physical device
+// as the first parameter. If the extension is already known by the loader, it will
+// not use this code, but instead use the more direct route. However, if it is
+// unknown to the loader, it will use this code. Technically, this is not trampoline
+// code since we don't want to optimize it out.
+
+#include "vk_loader_platform.h"
+#include "loader.h"
+
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC optimize(3) // force gcc to use tail-calls
+#endif
+
+// Declarations for the trampoline
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp0(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp1(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp2(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp3(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp4(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp5(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp6(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp7(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp8(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp9(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp10(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp11(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp12(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp13(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp14(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp15(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp16(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp17(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp18(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp19(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp20(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp21(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp22(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp23(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp24(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp25(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp26(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp27(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp28(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp29(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp30(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp31(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp32(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp33(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp34(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp35(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp36(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp37(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp38(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp39(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp40(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp41(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp42(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp43(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp44(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp45(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp46(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp47(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp48(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp49(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp50(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp51(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp52(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp53(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp54(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp55(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp56(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp57(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp58(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp59(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp60(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp61(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp62(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp63(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp64(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp65(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp66(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp67(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp68(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp69(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp70(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp71(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp72(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp73(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp74(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp75(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp76(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp77(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp78(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp79(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp80(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp81(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp82(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp83(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp84(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp85(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp86(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp87(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp88(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp89(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp90(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp91(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp92(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp93(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp94(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp95(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp96(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp97(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp98(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp99(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp100(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp101(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp102(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp103(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp104(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp105(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp106(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp107(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp108(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp109(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp110(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp111(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp112(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp113(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp114(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp115(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp116(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp117(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp118(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp119(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp120(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp121(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp122(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp123(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp124(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp125(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp126(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp127(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp128(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp129(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp130(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp131(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp132(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp133(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp134(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp135(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp136(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp137(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp138(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp139(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp140(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp141(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp142(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp143(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp144(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp145(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp146(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp147(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp148(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp149(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp150(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp151(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp152(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp153(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp154(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp155(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp156(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp157(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp158(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp159(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp160(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp161(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp162(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp163(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp164(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp165(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp166(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp167(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp168(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp169(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp170(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp171(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp172(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp173(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp174(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp175(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp176(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp177(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp178(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp179(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp180(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp181(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp182(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp183(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp184(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp185(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp186(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp187(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp188(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp189(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp190(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp191(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp192(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp193(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp194(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp195(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp196(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp197(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp198(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp199(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp200(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp201(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp202(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp203(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp204(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp205(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp206(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp207(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp208(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp209(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp210(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp211(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp212(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp213(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp214(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp215(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp216(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp217(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp218(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp219(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp220(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp221(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp222(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp223(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp224(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp225(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp226(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp227(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp228(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp229(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp230(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp231(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp232(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp233(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp234(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp235(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp236(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp237(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp238(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp239(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp240(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp241(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp242(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp243(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp244(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp245(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp246(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp247(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp248(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp249(VkPhysicalDevice);
+
+// Disable clang-format for lists of macros
+// clang-format off
+
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin0(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin1(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin2(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin3(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin4(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin5(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin6(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin7(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin8(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin9(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin10(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin11(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin12(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin13(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin14(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin15(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin16(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin17(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin18(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin19(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin20(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin21(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin22(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin23(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin24(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin25(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin26(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin27(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin28(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin29(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin30(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin31(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin32(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin33(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin34(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin35(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin36(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin37(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin38(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin39(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin40(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin41(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin42(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin43(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin44(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin45(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin46(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin47(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin48(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin49(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin50(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin51(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin52(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin53(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin54(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin55(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin56(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin57(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin58(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin59(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin60(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin61(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin62(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin63(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin64(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin65(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin66(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin67(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin68(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin69(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin70(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin71(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin72(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin73(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin74(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin75(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin76(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin77(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin78(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin79(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin80(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin81(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin82(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin83(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin84(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin85(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin86(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin87(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin88(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin89(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin90(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin91(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin92(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin93(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin94(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin95(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin96(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin97(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin98(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin99(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin100(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin101(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin102(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin103(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin104(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin105(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin106(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin107(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin108(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin109(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin110(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin111(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin112(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin113(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin114(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin115(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin116(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin117(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin118(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin119(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin120(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin121(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin122(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin123(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin124(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin125(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin126(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin127(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin128(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin129(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin130(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin131(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin132(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin133(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin134(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin135(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin136(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin137(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin138(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin139(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin140(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin141(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin142(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin143(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin144(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin145(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin146(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin147(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin148(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin149(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin150(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin151(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin152(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin153(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin154(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin155(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin156(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin157(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin158(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin159(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin160(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin161(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin162(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin163(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin164(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin165(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin166(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin167(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin168(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin169(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin170(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin171(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin172(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin173(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin174(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin175(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin176(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin177(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin178(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin179(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin180(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin181(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin182(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin183(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin184(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin185(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin186(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin187(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin188(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin189(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin190(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin191(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin192(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin193(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin194(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin195(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin196(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin197(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin198(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin199(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin200(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin201(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin202(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin203(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin204(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin205(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin206(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin207(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin208(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin209(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin210(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin211(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin212(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin213(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin214(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin215(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin216(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin217(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin218(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin219(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin220(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin221(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin222(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin223(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin224(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin225(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin226(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin227(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin228(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin229(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin230(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin231(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin232(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin233(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin234(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin235(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin236(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin237(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin238(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin239(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin240(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin241(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin242(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin243(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin244(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin245(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin246(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin247(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin248(VkPhysicalDevice);
+VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin249(VkPhysicalDevice);
+
+
+void *loader_get_phys_dev_ext_tramp(uint32_t index) {
+ switch (index) {
+#define TRAMP_CASE_HANDLE(num) case num: return vkPhysDevExtTramp##num
+ TRAMP_CASE_HANDLE(0);
+ TRAMP_CASE_HANDLE(1);
+ TRAMP_CASE_HANDLE(2);
+ TRAMP_CASE_HANDLE(3);
+ TRAMP_CASE_HANDLE(4);
+ TRAMP_CASE_HANDLE(5);
+ TRAMP_CASE_HANDLE(6);
+ TRAMP_CASE_HANDLE(7);
+ TRAMP_CASE_HANDLE(8);
+ TRAMP_CASE_HANDLE(9);
+ TRAMP_CASE_HANDLE(10);
+ TRAMP_CASE_HANDLE(11);
+ TRAMP_CASE_HANDLE(12);
+ TRAMP_CASE_HANDLE(13);
+ TRAMP_CASE_HANDLE(14);
+ TRAMP_CASE_HANDLE(15);
+ TRAMP_CASE_HANDLE(16);
+ TRAMP_CASE_HANDLE(17);
+ TRAMP_CASE_HANDLE(18);
+ TRAMP_CASE_HANDLE(19);
+ TRAMP_CASE_HANDLE(20);
+ TRAMP_CASE_HANDLE(21);
+ TRAMP_CASE_HANDLE(22);
+ TRAMP_CASE_HANDLE(23);
+ TRAMP_CASE_HANDLE(24);
+ TRAMP_CASE_HANDLE(25);
+ TRAMP_CASE_HANDLE(26);
+ TRAMP_CASE_HANDLE(27);
+ TRAMP_CASE_HANDLE(28);
+ TRAMP_CASE_HANDLE(29);
+ TRAMP_CASE_HANDLE(30);
+ TRAMP_CASE_HANDLE(31);
+ TRAMP_CASE_HANDLE(32);
+ TRAMP_CASE_HANDLE(33);
+ TRAMP_CASE_HANDLE(34);
+ TRAMP_CASE_HANDLE(35);
+ TRAMP_CASE_HANDLE(36);
+ TRAMP_CASE_HANDLE(37);
+ TRAMP_CASE_HANDLE(38);
+ TRAMP_CASE_HANDLE(39);
+ TRAMP_CASE_HANDLE(40);
+ TRAMP_CASE_HANDLE(41);
+ TRAMP_CASE_HANDLE(42);
+ TRAMP_CASE_HANDLE(43);
+ TRAMP_CASE_HANDLE(44);
+ TRAMP_CASE_HANDLE(45);
+ TRAMP_CASE_HANDLE(46);
+ TRAMP_CASE_HANDLE(47);
+ TRAMP_CASE_HANDLE(48);
+ TRAMP_CASE_HANDLE(49);
+ TRAMP_CASE_HANDLE(50);
+ TRAMP_CASE_HANDLE(51);
+ TRAMP_CASE_HANDLE(52);
+ TRAMP_CASE_HANDLE(53);
+ TRAMP_CASE_HANDLE(54);
+ TRAMP_CASE_HANDLE(55);
+ TRAMP_CASE_HANDLE(56);
+ TRAMP_CASE_HANDLE(57);
+ TRAMP_CASE_HANDLE(58);
+ TRAMP_CASE_HANDLE(59);
+ TRAMP_CASE_HANDLE(60);
+ TRAMP_CASE_HANDLE(61);
+ TRAMP_CASE_HANDLE(62);
+ TRAMP_CASE_HANDLE(63);
+ TRAMP_CASE_HANDLE(64);
+ TRAMP_CASE_HANDLE(65);
+ TRAMP_CASE_HANDLE(66);
+ TRAMP_CASE_HANDLE(67);
+ TRAMP_CASE_HANDLE(68);
+ TRAMP_CASE_HANDLE(69);
+ TRAMP_CASE_HANDLE(70);
+ TRAMP_CASE_HANDLE(71);
+ TRAMP_CASE_HANDLE(72);
+ TRAMP_CASE_HANDLE(73);
+ TRAMP_CASE_HANDLE(74);
+ TRAMP_CASE_HANDLE(75);
+ TRAMP_CASE_HANDLE(76);
+ TRAMP_CASE_HANDLE(77);
+ TRAMP_CASE_HANDLE(78);
+ TRAMP_CASE_HANDLE(79);
+ TRAMP_CASE_HANDLE(80);
+ TRAMP_CASE_HANDLE(81);
+ TRAMP_CASE_HANDLE(82);
+ TRAMP_CASE_HANDLE(83);
+ TRAMP_CASE_HANDLE(84);
+ TRAMP_CASE_HANDLE(85);
+ TRAMP_CASE_HANDLE(86);
+ TRAMP_CASE_HANDLE(87);
+ TRAMP_CASE_HANDLE(88);
+ TRAMP_CASE_HANDLE(89);
+ TRAMP_CASE_HANDLE(90);
+ TRAMP_CASE_HANDLE(91);
+ TRAMP_CASE_HANDLE(92);
+ TRAMP_CASE_HANDLE(93);
+ TRAMP_CASE_HANDLE(94);
+ TRAMP_CASE_HANDLE(95);
+ TRAMP_CASE_HANDLE(96);
+ TRAMP_CASE_HANDLE(97);
+ TRAMP_CASE_HANDLE(98);
+ TRAMP_CASE_HANDLE(99);
+ TRAMP_CASE_HANDLE(100);
+ TRAMP_CASE_HANDLE(101);
+ TRAMP_CASE_HANDLE(102);
+ TRAMP_CASE_HANDLE(103);
+ TRAMP_CASE_HANDLE(104);
+ TRAMP_CASE_HANDLE(105);
+ TRAMP_CASE_HANDLE(106);
+ TRAMP_CASE_HANDLE(107);
+ TRAMP_CASE_HANDLE(108);
+ TRAMP_CASE_HANDLE(109);
+ TRAMP_CASE_HANDLE(110);
+ TRAMP_CASE_HANDLE(111);
+ TRAMP_CASE_HANDLE(112);
+ TRAMP_CASE_HANDLE(113);
+ TRAMP_CASE_HANDLE(114);
+ TRAMP_CASE_HANDLE(115);
+ TRAMP_CASE_HANDLE(116);
+ TRAMP_CASE_HANDLE(117);
+ TRAMP_CASE_HANDLE(118);
+ TRAMP_CASE_HANDLE(119);
+ TRAMP_CASE_HANDLE(120);
+ TRAMP_CASE_HANDLE(121);
+ TRAMP_CASE_HANDLE(122);
+ TRAMP_CASE_HANDLE(123);
+ TRAMP_CASE_HANDLE(124);
+ TRAMP_CASE_HANDLE(125);
+ TRAMP_CASE_HANDLE(126);
+ TRAMP_CASE_HANDLE(127);
+ TRAMP_CASE_HANDLE(128);
+ TRAMP_CASE_HANDLE(129);
+ TRAMP_CASE_HANDLE(130);
+ TRAMP_CASE_HANDLE(131);
+ TRAMP_CASE_HANDLE(132);
+ TRAMP_CASE_HANDLE(133);
+ TRAMP_CASE_HANDLE(134);
+ TRAMP_CASE_HANDLE(135);
+ TRAMP_CASE_HANDLE(136);
+ TRAMP_CASE_HANDLE(137);
+ TRAMP_CASE_HANDLE(138);
+ TRAMP_CASE_HANDLE(139);
+ TRAMP_CASE_HANDLE(140);
+ TRAMP_CASE_HANDLE(141);
+ TRAMP_CASE_HANDLE(142);
+ TRAMP_CASE_HANDLE(143);
+ TRAMP_CASE_HANDLE(144);
+ TRAMP_CASE_HANDLE(145);
+ TRAMP_CASE_HANDLE(146);
+ TRAMP_CASE_HANDLE(147);
+ TRAMP_CASE_HANDLE(148);
+ TRAMP_CASE_HANDLE(149);
+ TRAMP_CASE_HANDLE(150);
+ TRAMP_CASE_HANDLE(151);
+ TRAMP_CASE_HANDLE(152);
+ TRAMP_CASE_HANDLE(153);
+ TRAMP_CASE_HANDLE(154);
+ TRAMP_CASE_HANDLE(155);
+ TRAMP_CASE_HANDLE(156);
+ TRAMP_CASE_HANDLE(157);
+ TRAMP_CASE_HANDLE(158);
+ TRAMP_CASE_HANDLE(159);
+ TRAMP_CASE_HANDLE(160);
+ TRAMP_CASE_HANDLE(161);
+ TRAMP_CASE_HANDLE(162);
+ TRAMP_CASE_HANDLE(163);
+ TRAMP_CASE_HANDLE(164);
+ TRAMP_CASE_HANDLE(165);
+ TRAMP_CASE_HANDLE(166);
+ TRAMP_CASE_HANDLE(167);
+ TRAMP_CASE_HANDLE(168);
+ TRAMP_CASE_HANDLE(169);
+ TRAMP_CASE_HANDLE(170);
+ TRAMP_CASE_HANDLE(171);
+ TRAMP_CASE_HANDLE(172);
+ TRAMP_CASE_HANDLE(173);
+ TRAMP_CASE_HANDLE(174);
+ TRAMP_CASE_HANDLE(175);
+ TRAMP_CASE_HANDLE(176);
+ TRAMP_CASE_HANDLE(177);
+ TRAMP_CASE_HANDLE(178);
+ TRAMP_CASE_HANDLE(179);
+ TRAMP_CASE_HANDLE(180);
+ TRAMP_CASE_HANDLE(181);
+ TRAMP_CASE_HANDLE(182);
+ TRAMP_CASE_HANDLE(183);
+ TRAMP_CASE_HANDLE(184);
+ TRAMP_CASE_HANDLE(185);
+ TRAMP_CASE_HANDLE(186);
+ TRAMP_CASE_HANDLE(187);
+ TRAMP_CASE_HANDLE(188);
+ TRAMP_CASE_HANDLE(189);
+ TRAMP_CASE_HANDLE(190);
+ TRAMP_CASE_HANDLE(191);
+ TRAMP_CASE_HANDLE(192);
+ TRAMP_CASE_HANDLE(193);
+ TRAMP_CASE_HANDLE(194);
+ TRAMP_CASE_HANDLE(195);
+ TRAMP_CASE_HANDLE(196);
+ TRAMP_CASE_HANDLE(197);
+ TRAMP_CASE_HANDLE(198);
+ TRAMP_CASE_HANDLE(199);
+ TRAMP_CASE_HANDLE(200);
+ TRAMP_CASE_HANDLE(201);
+ TRAMP_CASE_HANDLE(202);
+ TRAMP_CASE_HANDLE(203);
+ TRAMP_CASE_HANDLE(204);
+ TRAMP_CASE_HANDLE(205);
+ TRAMP_CASE_HANDLE(206);
+ TRAMP_CASE_HANDLE(207);
+ TRAMP_CASE_HANDLE(208);
+ TRAMP_CASE_HANDLE(209);
+ TRAMP_CASE_HANDLE(210);
+ TRAMP_CASE_HANDLE(211);
+ TRAMP_CASE_HANDLE(212);
+ TRAMP_CASE_HANDLE(213);
+ TRAMP_CASE_HANDLE(214);
+ TRAMP_CASE_HANDLE(215);
+ TRAMP_CASE_HANDLE(216);
+ TRAMP_CASE_HANDLE(217);
+ TRAMP_CASE_HANDLE(218);
+ TRAMP_CASE_HANDLE(219);
+ TRAMP_CASE_HANDLE(220);
+ TRAMP_CASE_HANDLE(221);
+ TRAMP_CASE_HANDLE(222);
+ TRAMP_CASE_HANDLE(223);
+ TRAMP_CASE_HANDLE(224);
+ TRAMP_CASE_HANDLE(225);
+ TRAMP_CASE_HANDLE(226);
+ TRAMP_CASE_HANDLE(227);
+ TRAMP_CASE_HANDLE(228);
+ TRAMP_CASE_HANDLE(229);
+ TRAMP_CASE_HANDLE(230);
+ TRAMP_CASE_HANDLE(231);
+ TRAMP_CASE_HANDLE(232);
+ TRAMP_CASE_HANDLE(233);
+ TRAMP_CASE_HANDLE(234);
+ TRAMP_CASE_HANDLE(235);
+ TRAMP_CASE_HANDLE(236);
+ TRAMP_CASE_HANDLE(237);
+ TRAMP_CASE_HANDLE(238);
+ TRAMP_CASE_HANDLE(239);
+ TRAMP_CASE_HANDLE(240);
+ TRAMP_CASE_HANDLE(241);
+ TRAMP_CASE_HANDLE(242);
+ TRAMP_CASE_HANDLE(243);
+ TRAMP_CASE_HANDLE(244);
+ TRAMP_CASE_HANDLE(245);
+ TRAMP_CASE_HANDLE(246);
+ TRAMP_CASE_HANDLE(247);
+ TRAMP_CASE_HANDLE(248);
+ TRAMP_CASE_HANDLE(249);
+ }
+ return NULL;
+}
+
+void *loader_get_phys_dev_ext_termin(uint32_t index) {
+ switch (index) {
+#define TERM_CASE_HANDLE(num) case num: return vkPhysDevExtTermin##num
+ TERM_CASE_HANDLE(0);
+ TERM_CASE_HANDLE(1);
+ TERM_CASE_HANDLE(2);
+ TERM_CASE_HANDLE(3);
+ TERM_CASE_HANDLE(4);
+ TERM_CASE_HANDLE(5);
+ TERM_CASE_HANDLE(6);
+ TERM_CASE_HANDLE(7);
+ TERM_CASE_HANDLE(8);
+ TERM_CASE_HANDLE(9);
+ TERM_CASE_HANDLE(10);
+ TERM_CASE_HANDLE(11);
+ TERM_CASE_HANDLE(12);
+ TERM_CASE_HANDLE(13);
+ TERM_CASE_HANDLE(14);
+ TERM_CASE_HANDLE(15);
+ TERM_CASE_HANDLE(16);
+ TERM_CASE_HANDLE(17);
+ TERM_CASE_HANDLE(18);
+ TERM_CASE_HANDLE(19);
+ TERM_CASE_HANDLE(20);
+ TERM_CASE_HANDLE(21);
+ TERM_CASE_HANDLE(22);
+ TERM_CASE_HANDLE(23);
+ TERM_CASE_HANDLE(24);
+ TERM_CASE_HANDLE(25);
+ TERM_CASE_HANDLE(26);
+ TERM_CASE_HANDLE(27);
+ TERM_CASE_HANDLE(28);
+ TERM_CASE_HANDLE(29);
+ TERM_CASE_HANDLE(30);
+ TERM_CASE_HANDLE(31);
+ TERM_CASE_HANDLE(32);
+ TERM_CASE_HANDLE(33);
+ TERM_CASE_HANDLE(34);
+ TERM_CASE_HANDLE(35);
+ TERM_CASE_HANDLE(36);
+ TERM_CASE_HANDLE(37);
+ TERM_CASE_HANDLE(38);
+ TERM_CASE_HANDLE(39);
+ TERM_CASE_HANDLE(40);
+ TERM_CASE_HANDLE(41);
+ TERM_CASE_HANDLE(42);
+ TERM_CASE_HANDLE(43);
+ TERM_CASE_HANDLE(44);
+ TERM_CASE_HANDLE(45);
+ TERM_CASE_HANDLE(46);
+ TERM_CASE_HANDLE(47);
+ TERM_CASE_HANDLE(48);
+ TERM_CASE_HANDLE(49);
+ TERM_CASE_HANDLE(50);
+ TERM_CASE_HANDLE(51);
+ TERM_CASE_HANDLE(52);
+ TERM_CASE_HANDLE(53);
+ TERM_CASE_HANDLE(54);
+ TERM_CASE_HANDLE(55);
+ TERM_CASE_HANDLE(56);
+ TERM_CASE_HANDLE(57);
+ TERM_CASE_HANDLE(58);
+ TERM_CASE_HANDLE(59);
+ TERM_CASE_HANDLE(60);
+ TERM_CASE_HANDLE(61);
+ TERM_CASE_HANDLE(62);
+ TERM_CASE_HANDLE(63);
+ TERM_CASE_HANDLE(64);
+ TERM_CASE_HANDLE(65);
+ TERM_CASE_HANDLE(66);
+ TERM_CASE_HANDLE(67);
+ TERM_CASE_HANDLE(68);
+ TERM_CASE_HANDLE(69);
+ TERM_CASE_HANDLE(70);
+ TERM_CASE_HANDLE(71);
+ TERM_CASE_HANDLE(72);
+ TERM_CASE_HANDLE(73);
+ TERM_CASE_HANDLE(74);
+ TERM_CASE_HANDLE(75);
+ TERM_CASE_HANDLE(76);
+ TERM_CASE_HANDLE(77);
+ TERM_CASE_HANDLE(78);
+ TERM_CASE_HANDLE(79);
+ TERM_CASE_HANDLE(80);
+ TERM_CASE_HANDLE(81);
+ TERM_CASE_HANDLE(82);
+ TERM_CASE_HANDLE(83);
+ TERM_CASE_HANDLE(84);
+ TERM_CASE_HANDLE(85);
+ TERM_CASE_HANDLE(86);
+ TERM_CASE_HANDLE(87);
+ TERM_CASE_HANDLE(88);
+ TERM_CASE_HANDLE(89);
+ TERM_CASE_HANDLE(90);
+ TERM_CASE_HANDLE(91);
+ TERM_CASE_HANDLE(92);
+ TERM_CASE_HANDLE(93);
+ TERM_CASE_HANDLE(94);
+ TERM_CASE_HANDLE(95);
+ TERM_CASE_HANDLE(96);
+ TERM_CASE_HANDLE(97);
+ TERM_CASE_HANDLE(98);
+ TERM_CASE_HANDLE(99);
+ TERM_CASE_HANDLE(100);
+ TERM_CASE_HANDLE(101);
+ TERM_CASE_HANDLE(102);
+ TERM_CASE_HANDLE(103);
+ TERM_CASE_HANDLE(104);
+ TERM_CASE_HANDLE(105);
+ TERM_CASE_HANDLE(106);
+ TERM_CASE_HANDLE(107);
+ TERM_CASE_HANDLE(108);
+ TERM_CASE_HANDLE(109);
+ TERM_CASE_HANDLE(110);
+ TERM_CASE_HANDLE(111);
+ TERM_CASE_HANDLE(112);
+ TERM_CASE_HANDLE(113);
+ TERM_CASE_HANDLE(114);
+ TERM_CASE_HANDLE(115);
+ TERM_CASE_HANDLE(116);
+ TERM_CASE_HANDLE(117);
+ TERM_CASE_HANDLE(118);
+ TERM_CASE_HANDLE(119);
+ TERM_CASE_HANDLE(120);
+ TERM_CASE_HANDLE(121);
+ TERM_CASE_HANDLE(122);
+ TERM_CASE_HANDLE(123);
+ TERM_CASE_HANDLE(124);
+ TERM_CASE_HANDLE(125);
+ TERM_CASE_HANDLE(126);
+ TERM_CASE_HANDLE(127);
+ TERM_CASE_HANDLE(128);
+ TERM_CASE_HANDLE(129);
+ TERM_CASE_HANDLE(130);
+ TERM_CASE_HANDLE(131);
+ TERM_CASE_HANDLE(132);
+ TERM_CASE_HANDLE(133);
+ TERM_CASE_HANDLE(134);
+ TERM_CASE_HANDLE(135);
+ TERM_CASE_HANDLE(136);
+ TERM_CASE_HANDLE(137);
+ TERM_CASE_HANDLE(138);
+ TERM_CASE_HANDLE(139);
+ TERM_CASE_HANDLE(140);
+ TERM_CASE_HANDLE(141);
+ TERM_CASE_HANDLE(142);
+ TERM_CASE_HANDLE(143);
+ TERM_CASE_HANDLE(144);
+ TERM_CASE_HANDLE(145);
+ TERM_CASE_HANDLE(146);
+ TERM_CASE_HANDLE(147);
+ TERM_CASE_HANDLE(148);
+ TERM_CASE_HANDLE(149);
+ TERM_CASE_HANDLE(150);
+ TERM_CASE_HANDLE(151);
+ TERM_CASE_HANDLE(152);
+ TERM_CASE_HANDLE(153);
+ TERM_CASE_HANDLE(154);
+ TERM_CASE_HANDLE(155);
+ TERM_CASE_HANDLE(156);
+ TERM_CASE_HANDLE(157);
+ TERM_CASE_HANDLE(158);
+ TERM_CASE_HANDLE(159);
+ TERM_CASE_HANDLE(160);
+ TERM_CASE_HANDLE(161);
+ TERM_CASE_HANDLE(162);
+ TERM_CASE_HANDLE(163);
+ TERM_CASE_HANDLE(164);
+ TERM_CASE_HANDLE(165);
+ TERM_CASE_HANDLE(166);
+ TERM_CASE_HANDLE(167);
+ TERM_CASE_HANDLE(168);
+ TERM_CASE_HANDLE(169);
+ TERM_CASE_HANDLE(170);
+ TERM_CASE_HANDLE(171);
+ TERM_CASE_HANDLE(172);
+ TERM_CASE_HANDLE(173);
+ TERM_CASE_HANDLE(174);
+ TERM_CASE_HANDLE(175);
+ TERM_CASE_HANDLE(176);
+ TERM_CASE_HANDLE(177);
+ TERM_CASE_HANDLE(178);
+ TERM_CASE_HANDLE(179);
+ TERM_CASE_HANDLE(180);
+ TERM_CASE_HANDLE(181);
+ TERM_CASE_HANDLE(182);
+ TERM_CASE_HANDLE(183);
+ TERM_CASE_HANDLE(184);
+ TERM_CASE_HANDLE(185);
+ TERM_CASE_HANDLE(186);
+ TERM_CASE_HANDLE(187);
+ TERM_CASE_HANDLE(188);
+ TERM_CASE_HANDLE(189);
+ TERM_CASE_HANDLE(190);
+ TERM_CASE_HANDLE(191);
+ TERM_CASE_HANDLE(192);
+ TERM_CASE_HANDLE(193);
+ TERM_CASE_HANDLE(194);
+ TERM_CASE_HANDLE(195);
+ TERM_CASE_HANDLE(196);
+ TERM_CASE_HANDLE(197);
+ TERM_CASE_HANDLE(198);
+ TERM_CASE_HANDLE(199);
+ TERM_CASE_HANDLE(200);
+ TERM_CASE_HANDLE(201);
+ TERM_CASE_HANDLE(202);
+ TERM_CASE_HANDLE(203);
+ TERM_CASE_HANDLE(204);
+ TERM_CASE_HANDLE(205);
+ TERM_CASE_HANDLE(206);
+ TERM_CASE_HANDLE(207);
+ TERM_CASE_HANDLE(208);
+ TERM_CASE_HANDLE(209);
+ TERM_CASE_HANDLE(210);
+ TERM_CASE_HANDLE(211);
+ TERM_CASE_HANDLE(212);
+ TERM_CASE_HANDLE(213);
+ TERM_CASE_HANDLE(214);
+ TERM_CASE_HANDLE(215);
+ TERM_CASE_HANDLE(216);
+ TERM_CASE_HANDLE(217);
+ TERM_CASE_HANDLE(218);
+ TERM_CASE_HANDLE(219);
+ TERM_CASE_HANDLE(220);
+ TERM_CASE_HANDLE(221);
+ TERM_CASE_HANDLE(222);
+ TERM_CASE_HANDLE(223);
+ TERM_CASE_HANDLE(224);
+ TERM_CASE_HANDLE(225);
+ TERM_CASE_HANDLE(226);
+ TERM_CASE_HANDLE(227);
+ TERM_CASE_HANDLE(228);
+ TERM_CASE_HANDLE(229);
+ TERM_CASE_HANDLE(230);
+ TERM_CASE_HANDLE(231);
+ TERM_CASE_HANDLE(232);
+ TERM_CASE_HANDLE(233);
+ TERM_CASE_HANDLE(234);
+ TERM_CASE_HANDLE(235);
+ TERM_CASE_HANDLE(236);
+ TERM_CASE_HANDLE(237);
+ TERM_CASE_HANDLE(238);
+ TERM_CASE_HANDLE(239);
+ TERM_CASE_HANDLE(240);
+ TERM_CASE_HANDLE(241);
+ TERM_CASE_HANDLE(242);
+ TERM_CASE_HANDLE(243);
+ TERM_CASE_HANDLE(244);
+ TERM_CASE_HANDLE(245);
+ TERM_CASE_HANDLE(246);
+ TERM_CASE_HANDLE(247);
+ TERM_CASE_HANDLE(248);
+ TERM_CASE_HANDLE(249);
+ }
+ return NULL;
+}
diff --git a/thirdparty/vulkan/loader/trampoline.c b/thirdparty/vulkan/loader/trampoline.c
new file mode 100644
index 0000000000..52eea968e8
--- /dev/null
+++ b/thirdparty/vulkan/loader/trampoline.c
@@ -0,0 +1,2480 @@
+/*
+ *
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ * Copyright (C) 2015 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Courtney Goeltzenleuchter <courtney@lunarg.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Tony Barbour <tony@LunarG.com>
+ * Author: Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "vk_loader_platform.h"
+#include "loader.h"
+#include "debug_utils.h"
+#include "wsi.h"
+#include "vk_loader_extensions.h"
+#include "gpa_helper.h"
+
+
+// Trampoline entrypoints are in this file for core Vulkan commands
+
+// Get an instance level or global level entry point address.
+// @param instance
+// @param pName
+// @return
+// If instance == NULL returns a global level functions only
+// If instance is valid returns a trampoline entry point for all dispatchable Vulkan
+// functions both core and extensions.
+LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName) {
+ void *addr;
+
+ addr = globalGetProcAddr(pName);
+ if (instance == VK_NULL_HANDLE || addr != NULL) {
+ return addr;
+ }
+
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (ptr_instance == NULL) return NULL;
+ // Return trampoline code for non-global entrypoints including any extensions.
+ // Device extensions are returned if a layer or ICD supports the extension.
+ // Instance extensions are returned if the extension is enabled and the
+ // loader or someone else supports the extension
+ return trampolineGetProcAddr(ptr_instance, pName);
+}
+
+// Get a device level or global level entry point address.
+// @param device
+// @param pName
+// @return
+// If device is valid, returns a device relative entry point for device level
+// entry points both core and extensions.
+// Device relative means call down the device chain.
+LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char *pName) {
+ void *addr;
+
+ // For entrypoints that loader must handle (ie non-dispatchable or create object)
+ // make sure the loader entrypoint is returned
+ addr = loader_non_passthrough_gdpa(pName);
+ if (addr) {
+ return addr;
+ }
+
+ // Although CreateDevice is on device chain it's dispatchable object isn't
+ // a VkDevice or child of VkDevice so return NULL.
+ if (!strcmp(pName, "CreateDevice")) return NULL;
+
+ // Return the dispatch table entrypoint for the fastest case
+ const VkLayerDispatchTable *disp_table = *(VkLayerDispatchTable **)device;
+ if (disp_table == NULL) return NULL;
+
+ addr = loader_lookup_device_dispatch_table(disp_table, pName);
+ if (addr) return addr;
+
+ if (disp_table->GetDeviceProcAddr == NULL) return NULL;
+ return disp_table->GetDeviceProcAddr(device, pName);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName,
+ uint32_t *pPropertyCount,
+ VkExtensionProperties *pProperties) {
+ tls_instance = NULL;
+ LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
+
+ // We know we need to call at least the terminator
+ VkResult res = VK_SUCCESS;
+ VkEnumerateInstanceExtensionPropertiesChain chain_tail = {
+ .header =
+ {
+ .type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES,
+ .version = VK_CURRENT_CHAIN_VERSION,
+ .size = sizeof(chain_tail),
+ },
+ .pfnNextLayer = &terminator_EnumerateInstanceExtensionProperties,
+ .pNextLink = NULL,
+ };
+ VkEnumerateInstanceExtensionPropertiesChain *chain_head = &chain_tail;
+
+ // Get the implicit layers
+ struct loader_layer_list layers;
+ memset(&layers, 0, sizeof(layers));
+ loaderScanForImplicitLayers(NULL, &layers);
+
+ // We'll need to save the dl handles so we can close them later
+ loader_platform_dl_handle *libs = malloc(sizeof(loader_platform_dl_handle) * layers.count);
+ if (libs == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ size_t lib_count = 0;
+
+ // Prepend layers onto the chain if they implment this entry point
+ for (uint32_t i = 0; i < layers.count; ++i) {
+ if (!loaderImplicitLayerIsEnabled(NULL, layers.list + i) ||
+ layers.list[i].pre_instance_functions.enumerate_instance_extension_properties[0] == '\0') {
+ continue;
+ }
+
+ loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
+ libs[lib_count++] = layer_lib;
+ void *pfn = loader_platform_get_proc_address(layer_lib,
+ layers.list[i].pre_instance_functions.enumerate_instance_extension_properties);
+ if (pfn == NULL) {
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"", __FUNCTION__,
+ layers.list[i].pre_instance_functions.enumerate_instance_extension_properties, layers.list[i].lib_name);
+ continue;
+ }
+
+ VkEnumerateInstanceExtensionPropertiesChain *chain_link = malloc(sizeof(VkEnumerateInstanceExtensionPropertiesChain));
+ if (chain_link == NULL) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ break;
+ }
+
+ chain_link->header.type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES;
+ chain_link->header.version = VK_CURRENT_CHAIN_VERSION;
+ chain_link->header.size = sizeof(*chain_link);
+ chain_link->pfnNextLayer = pfn;
+ chain_link->pNextLink = chain_head;
+
+ chain_head = chain_link;
+ }
+
+ // Call down the chain
+ if (res == VK_SUCCESS) {
+ res = chain_head->pfnNextLayer(chain_head->pNextLink, pLayerName, pPropertyCount, pProperties);
+ }
+
+ // Free up the layers
+ loaderDeleteLayerListAndProperties(NULL, &layers);
+
+ // Tear down the chain
+ while (chain_head != &chain_tail) {
+ VkEnumerateInstanceExtensionPropertiesChain *holder = chain_head;
+ chain_head = (VkEnumerateInstanceExtensionPropertiesChain *)chain_head->pNextLink;
+ free(holder);
+ }
+
+ // Close the dl handles
+ for (size_t i = 0; i < lib_count; ++i) {
+ loader_platform_close_library(libs[i]);
+ }
+ free(libs);
+
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
+ VkLayerProperties *pProperties) {
+ tls_instance = NULL;
+ LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
+
+ // We know we need to call at least the terminator
+ VkResult res = VK_SUCCESS;
+ VkEnumerateInstanceLayerPropertiesChain chain_tail = {
+ .header =
+ {
+ .type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES,
+ .version = VK_CURRENT_CHAIN_VERSION,
+ .size = sizeof(chain_tail),
+ },
+ .pfnNextLayer = &terminator_EnumerateInstanceLayerProperties,
+ .pNextLink = NULL,
+ };
+ VkEnumerateInstanceLayerPropertiesChain *chain_head = &chain_tail;
+
+ // Get the implicit layers
+ struct loader_layer_list layers;
+ memset(&layers, 0, sizeof(layers));
+ loaderScanForImplicitLayers(NULL, &layers);
+
+ // We'll need to save the dl handles so we can close them later
+ loader_platform_dl_handle *libs = malloc(sizeof(loader_platform_dl_handle) * layers.count);
+ if (libs == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ size_t lib_count = 0;
+
+ // Prepend layers onto the chain if they implment this entry point
+ for (uint32_t i = 0; i < layers.count; ++i) {
+ if (!loaderImplicitLayerIsEnabled(NULL, layers.list + i) ||
+ layers.list[i].pre_instance_functions.enumerate_instance_layer_properties[0] == '\0') {
+ continue;
+ }
+
+ loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
+ libs[lib_count++] = layer_lib;
+ void *pfn =
+ loader_platform_get_proc_address(layer_lib, layers.list[i].pre_instance_functions.enumerate_instance_layer_properties);
+ if (pfn == NULL) {
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"", __FUNCTION__,
+ layers.list[i].pre_instance_functions.enumerate_instance_layer_properties, layers.list[i].lib_name);
+ continue;
+ }
+
+ VkEnumerateInstanceLayerPropertiesChain *chain_link = malloc(sizeof(VkEnumerateInstanceLayerPropertiesChain));
+ if (chain_link == NULL) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ break;
+ }
+
+ chain_link->header.type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES;
+ chain_link->header.version = VK_CURRENT_CHAIN_VERSION;
+ chain_link->header.size = sizeof(*chain_link);
+ chain_link->pfnNextLayer = pfn;
+ chain_link->pNextLink = chain_head;
+
+ chain_head = chain_link;
+ }
+
+ // Call down the chain
+ if (res == VK_SUCCESS) {
+ res = chain_head->pfnNextLayer(chain_head->pNextLink, pPropertyCount, pProperties);
+ }
+
+ // Free up the layers
+ loaderDeleteLayerListAndProperties(NULL, &layers);
+
+ // Tear down the chain
+ while (chain_head != &chain_tail) {
+ VkEnumerateInstanceLayerPropertiesChain *holder = chain_head;
+ chain_head = (VkEnumerateInstanceLayerPropertiesChain *)chain_head->pNextLink;
+ free(holder);
+ }
+
+ // Close the dl handles
+ for (size_t i = 0; i < lib_count; ++i) {
+ loader_platform_close_library(libs[i]);
+ }
+ free(libs);
+
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t* pApiVersion) {
+
+ tls_instance = NULL;
+ LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
+
+ // We know we need to call at least the terminator
+ VkResult res = VK_SUCCESS;
+ VkEnumerateInstanceVersionChain chain_tail = {
+ .header =
+ {
+ .type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION,
+ .version = VK_CURRENT_CHAIN_VERSION,
+ .size = sizeof(chain_tail),
+ },
+ .pfnNextLayer = &terminator_EnumerateInstanceVersion,
+ .pNextLink = NULL,
+ };
+ VkEnumerateInstanceVersionChain *chain_head = &chain_tail;
+
+ // Get the implicit layers
+ struct loader_layer_list layers;
+ memset(&layers, 0, sizeof(layers));
+ loaderScanForImplicitLayers(NULL, &layers);
+
+ // We'll need to save the dl handles so we can close them later
+ loader_platform_dl_handle *libs = malloc(sizeof(loader_platform_dl_handle) * layers.count);
+ if (libs == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ size_t lib_count = 0;
+
+ // Prepend layers onto the chain if they implment this entry point
+ for (uint32_t i = 0; i < layers.count; ++i) {
+ if (!loaderImplicitLayerIsEnabled(NULL, layers.list + i) ||
+ layers.list[i].pre_instance_functions.enumerate_instance_version[0] == '\0') {
+ continue;
+ }
+
+ loader_platform_dl_handle layer_lib = loader_platform_open_library(layers.list[i].lib_name);
+ libs[lib_count++] = layer_lib;
+ void *pfn = loader_platform_get_proc_address(layer_lib,
+ layers.list[i].pre_instance_functions.enumerate_instance_version);
+ if (pfn == NULL) {
+ loader_log(NULL, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+ "%s: Unable to resolve symbol \"%s\" in implicit layer library \"%s\"", __FUNCTION__,
+ layers.list[i].pre_instance_functions.enumerate_instance_version, layers.list[i].lib_name);
+ continue;
+ }
+
+ VkEnumerateInstanceVersionChain *chain_link = malloc(sizeof(VkEnumerateInstanceVersionChain));
+ if (chain_link == NULL) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ break;
+ }
+
+ chain_link->header.type = VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION;
+ chain_link->header.version = VK_CURRENT_CHAIN_VERSION;
+ chain_link->header.size = sizeof(*chain_link);
+ chain_link->pfnNextLayer = pfn;
+ chain_link->pNextLink = chain_head;
+
+ chain_head = chain_link;
+ }
+
+ // Call down the chain
+ if (res == VK_SUCCESS) {
+ res = chain_head->pfnNextLayer(chain_head->pNextLink, pApiVersion);
+ }
+
+ // Free up the layers
+ loaderDeleteLayerListAndProperties(NULL, &layers);
+
+ // Tear down the chain
+ while (chain_head != &chain_tail) {
+ VkEnumerateInstanceVersionChain *holder = chain_head;
+ chain_head = (VkEnumerateInstanceVersionChain *)chain_head->pNextLink;
+ free(holder);
+ }
+
+ // Close the dl handles
+ for (size_t i = 0; i < lib_count; ++i) {
+ loader_platform_close_library(libs[i]);
+ }
+ free(libs);
+
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
+ struct loader_instance *ptr_instance = NULL;
+ VkInstance created_instance = VK_NULL_HANDLE;
+ bool loaderLocked = false;
+ VkResult res = VK_ERROR_INITIALIZATION_FAILED;
+
+ LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
+
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+ {
+#else
+ if (pAllocator) {
+ ptr_instance = (struct loader_instance *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(struct loader_instance),
+ sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ } else {
+#endif
+ ptr_instance = (struct loader_instance *)malloc(sizeof(struct loader_instance));
+ }
+
+ VkInstanceCreateInfo ici = *pCreateInfo;
+
+ if (ptr_instance == NULL) {
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ tls_instance = ptr_instance;
+ loader_platform_thread_lock_mutex(&loader_lock);
+ loaderLocked = true;
+ memset(ptr_instance, 0, sizeof(struct loader_instance));
+ if (pAllocator) {
+ ptr_instance->alloc_callbacks = *pAllocator;
+ }
+
+ // Save the application version
+ if (NULL == pCreateInfo || NULL == pCreateInfo->pApplicationInfo || 0 == pCreateInfo->pApplicationInfo->apiVersion)
+{
+ ptr_instance->app_api_major_version = 1;
+ ptr_instance->app_api_minor_version = 0;
+ } else {
+ ptr_instance->app_api_major_version = VK_VERSION_MAJOR(pCreateInfo->pApplicationInfo->apiVersion);
+ ptr_instance->app_api_minor_version = VK_VERSION_MINOR(pCreateInfo->pApplicationInfo->apiVersion);
+ }
+
+ // Look for one or more VK_EXT_debug_report or VK_EXT_debug_utils create info structures
+ // and setup a callback(s) for each one found.
+ ptr_instance->num_tmp_report_callbacks = 0;
+ ptr_instance->tmp_report_create_infos = NULL;
+ ptr_instance->tmp_report_callbacks = NULL;
+ ptr_instance->num_tmp_messengers = 0;
+ ptr_instance->tmp_messenger_create_infos = NULL;
+ ptr_instance->tmp_messengers = NULL;
+
+ // Handle cases of VK_EXT_debug_utils
+ if (util_CopyDebugUtilsMessengerCreateInfos(pCreateInfo->pNext, pAllocator, &ptr_instance->num_tmp_messengers,
+ &ptr_instance->tmp_messenger_create_infos, &ptr_instance->tmp_messengers)) {
+ // One or more were found, but allocation failed. Therefore, clean up and fail this function:
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ } else if (ptr_instance->num_tmp_messengers > 0) {
+ // Setup the temporary messenger(s) here to catch early issues:
+ if (util_CreateDebugUtilsMessengers(ptr_instance, pAllocator, ptr_instance->num_tmp_messengers,
+ ptr_instance->tmp_messenger_create_infos, ptr_instance->tmp_messengers)) {
+ // Failure of setting up one or more of the messenger. Therefore, clean up and fail this function:
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ }
+
+ // Handle cases of VK_EXT_debug_report
+ if (util_CopyDebugReportCreateInfos(pCreateInfo->pNext, pAllocator, &ptr_instance->num_tmp_report_callbacks,
+ &ptr_instance->tmp_report_create_infos, &ptr_instance->tmp_report_callbacks)) {
+ // One or more were found, but allocation failed. Therefore, clean up and fail this function:
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ } else if (ptr_instance->num_tmp_report_callbacks > 0) {
+ // Setup the temporary callback(s) here to catch early issues:
+ if (util_CreateDebugReportCallbacks(ptr_instance, pAllocator, ptr_instance->num_tmp_report_callbacks,
+ ptr_instance->tmp_report_create_infos, ptr_instance->tmp_report_callbacks)) {
+ // Failure of setting up one or more of the callback. Therefore, clean up and fail this function:
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ }
+
+ // Due to implicit layers need to get layer list even if
+ // enabledLayerCount == 0 and VK_INSTANCE_LAYERS is unset. For now always
+ // get layer list via loaderScanForLayers().
+ memset(&ptr_instance->instance_layer_list, 0, sizeof(ptr_instance->instance_layer_list));
+ loaderScanForLayers(ptr_instance, &ptr_instance->instance_layer_list);
+
+ // Validate the app requested layers to be enabled
+ if (pCreateInfo->enabledLayerCount > 0) {
+ res = loaderValidateLayers(ptr_instance, pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames,
+ &ptr_instance->instance_layer_list);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+ }
+
+ // Scan/discover all ICD libraries
+ memset(&ptr_instance->icd_tramp_list, 0, sizeof(ptr_instance->icd_tramp_list));
+ res = loader_icd_scan(ptr_instance, &ptr_instance->icd_tramp_list);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+
+ // Get extensions from all ICD's, merge so no duplicates, then validate
+ res = loader_get_icd_loader_instance_extensions(ptr_instance, &ptr_instance->icd_tramp_list, &ptr_instance->ext_list);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+ res = loader_validate_instance_extensions(ptr_instance, &ptr_instance->ext_list, &ptr_instance->instance_layer_list, &ici);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+
+ ptr_instance->disp = loader_instance_heap_alloc(ptr_instance, sizeof(struct loader_instance_dispatch_table),
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (ptr_instance->disp == NULL) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkCreateInstance: Failed to allocate Loader's full Instance dispatch table.");
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memcpy(&ptr_instance->disp->layer_inst_disp, &instance_disp, sizeof(instance_disp));
+
+ ptr_instance->next = loader.instances;
+ loader.instances = ptr_instance;
+
+ // Activate any layers on instance chain
+ res = loaderEnableInstanceLayers(ptr_instance, &ici, &ptr_instance->instance_layer_list);
+ if (res != VK_SUCCESS) {
+ goto out;
+ }
+
+ created_instance = (VkInstance)ptr_instance;
+ res = loader_create_instance_chain(&ici, pAllocator, ptr_instance, &created_instance);
+
+ if (res == VK_SUCCESS) {
+ memset(ptr_instance->enabled_known_extensions.padding, 0, sizeof(uint64_t) * 4);
+
+ wsi_create_instance(ptr_instance, &ici);
+ debug_utils_CreateInstance(ptr_instance, &ici);
+ extensions_create_instance(ptr_instance, &ici);
+
+ *pInstance = created_instance;
+
+ // Finally have the layers in place and everyone has seen
+ // the CreateInstance command go by. This allows the layer's
+ // GetInstanceProcAddr functions to return valid extension functions
+ // if enabled.
+ loaderActivateInstanceLayerExtensions(ptr_instance, *pInstance);
+ }
+
+out:
+
+ if (NULL != ptr_instance) {
+ if (res != VK_SUCCESS) {
+ if (NULL != ptr_instance->next) {
+ loader.instances = ptr_instance->next;
+ }
+ if (NULL != ptr_instance->disp) {
+ loader_instance_heap_free(ptr_instance, ptr_instance->disp);
+ }
+ if (ptr_instance->num_tmp_report_callbacks > 0) {
+ // Remove temporary VK_EXT_debug_report items
+ util_DestroyDebugReportCallbacks(ptr_instance, pAllocator, ptr_instance->num_tmp_report_callbacks,
+ ptr_instance->tmp_report_callbacks);
+ util_FreeDebugReportCreateInfos(pAllocator, ptr_instance->tmp_report_create_infos,
+ ptr_instance->tmp_report_callbacks);
+ }
+ if (ptr_instance->num_tmp_messengers > 0) {
+ // Remove temporary VK_EXT_debug_utils items
+ util_DestroyDebugUtilsMessengers(ptr_instance, pAllocator, ptr_instance->num_tmp_messengers,
+ ptr_instance->tmp_messengers);
+ util_FreeDebugUtilsMessengerCreateInfos(pAllocator, ptr_instance->tmp_messenger_create_infos,
+ ptr_instance->tmp_messengers);
+ }
+
+ if (NULL != ptr_instance->expanded_activated_layer_list.list) {
+ loaderDeactivateLayers(ptr_instance, NULL, &ptr_instance->expanded_activated_layer_list);
+ }
+ if (NULL != ptr_instance->app_activated_layer_list.list) {
+ loaderDestroyLayerList(ptr_instance, NULL, &ptr_instance->app_activated_layer_list);
+ }
+
+ loaderDeleteLayerListAndProperties(ptr_instance, &ptr_instance->instance_layer_list);
+ loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_tramp_list);
+ loader_destroy_generic_list(ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list);
+
+ loader_instance_heap_free(ptr_instance, ptr_instance);
+ } else {
+ // Remove temporary VK_EXT_debug_report or VK_EXT_debug_utils items
+ util_DestroyDebugUtilsMessengers(ptr_instance, pAllocator, ptr_instance->num_tmp_messengers,
+ ptr_instance->tmp_messengers);
+ util_DestroyDebugReportCallbacks(ptr_instance, pAllocator, ptr_instance->num_tmp_report_callbacks,
+ ptr_instance->tmp_report_callbacks);
+ }
+
+ if (loaderLocked) {
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ }
+ }
+
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
+ const VkLayerInstanceDispatchTable *disp;
+ struct loader_instance *ptr_instance = NULL;
+ bool callback_setup = false;
+ bool messenger_setup = false;
+
+ if (instance == VK_NULL_HANDLE) {
+ return;
+ }
+
+ disp = loader_get_instance_layer_dispatch(instance);
+
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ ptr_instance = loader_get_instance(instance);
+
+ if (pAllocator) {
+ ptr_instance->alloc_callbacks = *pAllocator;
+ }
+
+ if (ptr_instance->num_tmp_messengers > 0) {
+ // Setup the temporary VK_EXT_debug_utils messenger(s) here to catch cleanup issues:
+ if (!util_CreateDebugUtilsMessengers(ptr_instance, pAllocator, ptr_instance->num_tmp_messengers,
+ ptr_instance->tmp_messenger_create_infos, ptr_instance->tmp_messengers)) {
+ messenger_setup = true;
+ }
+ }
+
+ if (ptr_instance->num_tmp_report_callbacks > 0) {
+ // Setup the temporary VK_EXT_debug_report callback(s) here to catch cleanup issues:
+ if (!util_CreateDebugReportCallbacks(ptr_instance, pAllocator, ptr_instance->num_tmp_report_callbacks,
+ ptr_instance->tmp_report_create_infos, ptr_instance->tmp_report_callbacks)) {
+ callback_setup = true;
+ }
+ }
+
+ disp->DestroyInstance(instance, pAllocator);
+
+ if (NULL != ptr_instance->expanded_activated_layer_list.list) {
+ loaderDeactivateLayers(ptr_instance, NULL, &ptr_instance->expanded_activated_layer_list);
+ }
+ if (NULL != ptr_instance->app_activated_layer_list.list) {
+ loaderDestroyLayerList(ptr_instance, NULL, &ptr_instance->app_activated_layer_list);
+ }
+
+ if (ptr_instance->phys_devs_tramp) {
+ for (uint32_t i = 0; i < ptr_instance->phys_dev_count_tramp; i++) {
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_tramp[i]);
+ }
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_tramp);
+ }
+
+ if (ptr_instance->phys_dev_groups_tramp) {
+ for (uint32_t i = 0; i < ptr_instance->phys_dev_group_count_tramp; i++) {
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_dev_groups_tramp[i]);
+ }
+ loader_instance_heap_free(ptr_instance, ptr_instance->phys_dev_groups_tramp);
+ }
+
+ if (messenger_setup) {
+ util_DestroyDebugUtilsMessengers(ptr_instance, pAllocator, ptr_instance->num_tmp_messengers, ptr_instance->tmp_messengers);
+ util_FreeDebugUtilsMessengerCreateInfos(pAllocator, ptr_instance->tmp_messenger_create_infos, ptr_instance->tmp_messengers);
+ }
+
+ if (callback_setup) {
+ util_DestroyDebugReportCallbacks(ptr_instance, pAllocator, ptr_instance->num_tmp_report_callbacks,
+ ptr_instance->tmp_report_callbacks);
+ util_FreeDebugReportCreateInfos(pAllocator, ptr_instance->tmp_report_create_infos, ptr_instance->tmp_report_callbacks);
+ }
+ loader_instance_heap_free(ptr_instance, ptr_instance->disp);
+ loader_instance_heap_free(ptr_instance, ptr_instance);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
+ VkPhysicalDevice *pPhysicalDevices) {
+ VkResult res = VK_SUCCESS;
+ uint32_t count;
+ uint32_t i;
+ struct loader_instance *inst;
+
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ inst = loader_get_instance(instance);
+ if (NULL == inst) {
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ if (NULL == pPhysicalDeviceCount) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkEnumeratePhysicalDevices: Received NULL pointer for physical device count return value.");
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ // Setup the trampoline loader physical devices. This will actually
+ // call down and setup the terminator loader physical devices during the
+ // process.
+ VkResult setup_res = setupLoaderTrampPhysDevs(instance);
+ if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) {
+ res = setup_res;
+ goto out;
+ }
+
+ count = inst->phys_dev_count_tramp;
+
+ // Wrap the PhysDev object for loader usage, return wrapped objects
+ if (NULL != pPhysicalDevices) {
+ if (inst->phys_dev_count_tramp > *pPhysicalDeviceCount) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkEnumeratePhysicalDevices: Trimming device count down"
+ " by application request from %d to %d physical devices",
+ inst->phys_dev_count_tramp, *pPhysicalDeviceCount);
+ count = *pPhysicalDeviceCount;
+ res = VK_INCOMPLETE;
+ }
+ for (i = 0; i < count; i++) {
+ pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_tramp[i];
+ }
+ }
+
+ *pPhysicalDeviceCount = count;
+
+out:
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures *pFeatures) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ disp->GetPhysicalDeviceFeatures(unwrapped_phys_dev, pFeatures);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
+ VkFormatProperties *pFormatInfo) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_pd = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ disp->GetPhysicalDeviceFormatProperties(unwrapped_pd, format, pFormatInfo);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(
+ VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage,
+ VkImageCreateFlags flags, VkImageFormatProperties *pImageFormatProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceImageFormatProperties(unwrapped_phys_dev, format, type, tiling, usage, flags,
+ pImageFormatProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties *pProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ disp->GetPhysicalDeviceProperties(unwrapped_phys_dev, pProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
+ uint32_t *pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties *pQueueProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ disp->GetPhysicalDeviceQueueFamilyProperties(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ disp->GetPhysicalDeviceMemoryProperties(unwrapped_phys_dev, pMemoryProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
+ loader_platform_thread_lock_mutex(&loader_lock);
+ VkResult res = loader_layer_create_device(NULL, physicalDevice, pCreateInfo, pAllocator, pDevice, NULL, NULL);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ if (device == VK_NULL_HANDLE) {
+ return;
+ }
+ disp = loader_get_dispatch(device);
+
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ loader_layer_destroy_device(device, pAllocator, disp->DestroyDevice);
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
+ const char *pLayerName, uint32_t *pPropertyCount,
+ VkExtensionProperties *pProperties) {
+ VkResult res = VK_SUCCESS;
+ struct loader_physical_device_tramp *phys_dev;
+ const VkLayerInstanceDispatchTable *disp;
+ phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
+
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ // always pass this call down the instance chain which will terminate
+ // in the ICD. This allows layers to filter the extensions coming back
+ // up the chain. In the terminator we look up layer extensions from the
+ // manifest file if it wasn't provided by the layer itself.
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ res = disp->EnumerateDeviceExtensionProperties(phys_dev->phys_dev, pLayerName, pPropertyCount, pProperties);
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkLayerProperties *pProperties) {
+ uint32_t copy_size;
+ struct loader_physical_device_tramp *phys_dev;
+ struct loader_layer_list *enabled_layers, layers_list;
+ memset(&layers_list, 0, sizeof(layers_list));
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ // Don't dispatch this call down the instance chain, want all device layers
+ // enumerated and instance chain may not contain all device layers
+ // TODO re-evaluate the above statement we maybe able to start calling
+ // down the chain
+
+ phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
+ const struct loader_instance *inst = phys_dev->this_instance;
+
+ uint32_t count = inst->app_activated_layer_list.count;
+ if (count == 0 || pProperties == NULL) {
+ *pPropertyCount = count;
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_SUCCESS;
+ }
+ enabled_layers = (struct loader_layer_list *)&inst->app_activated_layer_list;
+
+ copy_size = (*pPropertyCount < count) ? *pPropertyCount : count;
+ for (uint32_t i = 0; i < copy_size; i++) {
+ memcpy(&pProperties[i], &(enabled_layers->list[i].info), sizeof(VkLayerProperties));
+ }
+ *pPropertyCount = copy_size;
+
+ if (copy_size < count) {
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_INCOMPLETE;
+ }
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_SUCCESS;
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex, uint32_t queueIndex,
+ VkQueue *pQueue) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
+ loader_set_dispatch(*pQueue, disp);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits,
+ VkFence fence) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(queue);
+
+ return disp->QueueSubmit(queue, submitCount, pSubmits, fence);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(queue);
+
+ return disp->QueueWaitIdle(queue);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(VkDevice device) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->DeviceWaitIdle(device);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkFreeMemory(VkDevice device, VkDeviceMemory mem,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->FreeMemory(device, mem, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset,
+ VkDeviceSize size, VkFlags flags, void **ppData) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->MapMemory(device, mem, offset, size, flags, ppData);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(VkDevice device, VkDeviceMemory mem) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->UnmapMemory(device, mem);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+ const VkMappedMemoryRange *pMemoryRanges) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->FlushMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memoryRangeCount,
+ const VkMappedMemoryRange *pMemoryRanges) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->InvalidateMappedMemoryRanges(device, memoryRangeCount, pMemoryRanges);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory,
+ VkDeviceSize *pCommittedMemoryInBytes) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->GetDeviceMemoryCommitment(device, memory, pCommittedMemoryInBytes);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
+ VkDeviceSize offset) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->BindBufferMemory(device, buffer, mem, offset);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
+ VkDeviceSize offset) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->BindImageMemory(device, image, mem, offset);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
+ VkMemoryRequirements *pMemoryRequirements) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(VkDevice device, VkImage image,
+ VkMemoryRequirements *pMemoryRequirements) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->GetImageMemoryRequirements(device, image, pMemoryRequirements);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
+vkGetImageSparseMemoryRequirements(VkDevice device, VkImage image, uint32_t *pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements *pSparseMemoryRequirements) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->GetImageSparseMemoryRequirements(device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(
+ VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage,
+ VkImageTiling tiling, uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+
+ disp->GetPhysicalDeviceSparseImageFormatProperties(unwrapped_phys_dev, format, type, samples, usage, tiling, pPropertyCount,
+ pProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
+ const VkBindSparseInfo *pBindInfo, VkFence fence) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(queue);
+
+ return disp->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateFence(device, pCreateInfo, pAllocator, pFence);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyFence(device, fence, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->ResetFences(device, fenceCount, pFences);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(VkDevice device, VkFence fence) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->GetFenceStatus(device, fence);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences,
+ VkBool32 waitAll, uint64_t timeout) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(VkDevice device, VkSemaphore semaphore,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroySemaphore(device, semaphore, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyEvent(device, event, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus(VkDevice device, VkEvent event) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->GetEventStatus(device, event);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->SetEvent(device, event);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent(VkDevice device, VkEvent event) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->ResetEvent(device, event);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyQueryPool(device, queryPool, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery,
+ uint32_t queryCount, size_t dataSize, void *pData,
+ VkDeviceSize stride, VkQueryResultFlags flags) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(VkDevice device, VkBuffer buffer,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyBuffer(device, buffer, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkBufferView *pView) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateBufferView(device, pCreateInfo, pAllocator, pView);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(VkDevice device, VkBufferView bufferView,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyBufferView(device, bufferView, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateImage(device, pCreateInfo, pAllocator, pImage);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyImage(device, image, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(VkDevice device, VkImage image,
+ const VkImageSubresource *pSubresource,
+ VkSubresourceLayout *pLayout) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->GetImageSubresourceLayout(device, image, pSubresource, pLayout);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkImageView *pView) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateImageView(device, pCreateInfo, pAllocator, pView);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyImageView(device, imageView, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkShaderModule *pShader) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateShaderModule(device, pCreateInfo, pAllocator, pShader);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyShaderModule(device, shaderModule, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkPipelineCache *pPipelineCache) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyPipelineCache(device, pipelineCache, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache,
+ size_t *pDataSize, void *pData) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache,
+ uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo *pCreateInfos,
+ const VkAllocationCallbacks *pAllocator,
+ VkPipeline *pPipelines) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkComputePipelineCreateInfo *pCreateInfos,
+ const VkAllocationCallbacks *pAllocator,
+ VkPipeline *pPipelines) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyPipeline(device, pipeline, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkPipelineLayout *pPipelineLayout) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateSampler(device, pCreateInfo, pAllocator, pSampler);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroySampler(device, sampler, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDescriptorSetLayout *pSetLayout) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDescriptorPool *pDescriptorPool) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyDescriptorPool(device, descriptorPool, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
+ VkDescriptorPoolResetFlags flags) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->ResetDescriptorPool(device, descriptorPool, flags);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(VkDevice device,
+ const VkDescriptorSetAllocateInfo *pAllocateInfo,
+ VkDescriptorSet *pDescriptorSets) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
+ uint32_t descriptorSetCount,
+ const VkDescriptorSet *pDescriptorSets) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->FreeDescriptorSets(device, descriptorPool, descriptorSetCount, pDescriptorSets);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet *pDescriptorWrites,
+ uint32_t descriptorCopyCount,
+ const VkCopyDescriptorSet *pDescriptorCopies) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkFramebuffer *pFramebuffer) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyFramebuffer(device, framebuffer, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkRenderPass *pRenderPass) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyRenderPass(device, renderPass, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass,
+ VkExtent2D *pGranularity) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->GetRenderAreaGranularity(device, renderPass, pGranularity);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkCommandPool *pCommandPool) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->DestroyCommandPool(device, commandPool, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(VkDevice device, VkCommandPool commandPool,
+ VkCommandPoolResetFlags flags) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ return disp->ResetCommandPool(device, commandPool, flags);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device,
+ const VkCommandBufferAllocateInfo *pAllocateInfo,
+ VkCommandBuffer *pCommandBuffers) {
+ const VkLayerDispatchTable *disp;
+ VkResult res;
+
+ disp = loader_get_dispatch(device);
+
+ res = disp->AllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers);
+ if (res == VK_SUCCESS) {
+ for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) {
+ if (pCommandBuffers[i]) {
+ loader_init_dispatch(pCommandBuffers[i], disp);
+ }
+ }
+ }
+
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
+ uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(device);
+
+ disp->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo *pBeginInfo) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ return disp->BeginCommandBuffer(commandBuffer, pBeginInfo);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(VkCommandBuffer commandBuffer) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ return disp->EndCommandBuffer(commandBuffer);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ return disp->ResetCommandBuffer(commandBuffer, flags);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
+ VkPipeline pipeline) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
+ uint32_t viewportCount, const VkViewport *pViewports) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
+ uint32_t scissorCount, const VkRect2D *pScissors) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetLineWidth(commandBuffer, lineWidth);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor,
+ float depthBiasClamp, float depthBiasSlopeFactor) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetBlendConstants(commandBuffer, blendConstants);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds,
+ float maxDepthBounds) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+ uint32_t compareMask) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+ uint32_t writeMask) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask,
+ uint32_t reference) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetStencilReference(commandBuffer, faceMask, reference);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout,
+ uint32_t firstSet, uint32_t descriptorSetCount,
+ const VkDescriptorSet *pDescriptorSets,
+ uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets,
+ dynamicOffsetCount, pDynamicOffsets);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+ VkIndexType indexType) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
+ uint32_t bindingCount, const VkBuffer *pBuffers,
+ const VkDeviceSize *pOffsets) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
+ uint32_t firstVertex, uint32_t firstInstance) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
+ uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset,
+ uint32_t firstInstance) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+ uint32_t drawCount, uint32_t stride) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdDrawIndirect(commandBuffer, buffer, offset, drawCount, stride);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
+ VkDeviceSize offset, uint32_t drawCount, uint32_t stride) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, drawCount, stride);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdDispatch(commandBuffer, x, y, z);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
+ VkDeviceSize offset) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdDispatchIndirect(commandBuffer, buffer, offset);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
+ uint32_t regionCount, const VkBufferCopy *pRegions) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
+ VkImageLayout srcImageLayout, VkImage dstImage,
+ VkImageLayout dstImageLayout, uint32_t regionCount,
+ const VkImageCopy *pRegions) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
+ VkImageLayout srcImageLayout, VkImage dstImage,
+ VkImageLayout dstImageLayout, uint32_t regionCount,
+ const VkImageBlit *pRegions, VkFilter filter) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage,
+ VkImageLayout dstImageLayout, uint32_t regionCount,
+ const VkBufferImageCopy *pRegions) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
+ VkImageLayout srcImageLayout, VkBuffer dstBuffer,
+ uint32_t regionCount, const VkBufferImageCopy *pRegions) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
+ VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset,
+ VkDeviceSize size, uint32_t data) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
+ VkImageLayout imageLayout, const VkClearColorValue *pColor,
+ uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
+ VkImageLayout imageLayout,
+ const VkClearDepthStencilValue *pDepthStencil,
+ uint32_t rangeCount, const VkImageSubresourceRange *pRanges) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
+ const VkClearAttachment *pAttachments, uint32_t rectCount,
+ const VkClearRect *pRects) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
+ VkImageLayout srcImageLayout, VkImage dstImage,
+ VkImageLayout dstImageLayout, uint32_t regionCount,
+ const VkImageResolve *pRegions) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event,
+ VkPipelineStageFlags stageMask) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdSetEvent(commandBuffer, event, stageMask);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event,
+ VkPipelineStageFlags stageMask) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdResetEvent(commandBuffer, event, stageMask);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
+ VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask,
+ uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier *pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier *pImageMemoryBarriers) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask, memoryBarrierCount, pMemoryBarriers,
+ bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(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) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers,
+ bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot,
+ VkFlags flags) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdBeginQuery(commandBuffer, queryPool, slot, flags);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdEndQuery(commandBuffer, queryPool, slot);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+ uint32_t firstQuery, uint32_t queryCount) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage,
+ VkQueryPool queryPool, uint32_t slot) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
+ uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer,
+ VkDeviceSize dstOffset, VkDeviceSize stride, VkFlags flags) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
+ VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size,
+ const void *pValues) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo *pRenderPassBegin,
+ VkSubpassContents contents) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdNextSubpass(commandBuffer, contents);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(VkCommandBuffer commandBuffer) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdEndRenderPass(commandBuffer);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount,
+ const VkCommandBuffer *pCommandBuffers) {
+ const VkLayerDispatchTable *disp;
+
+ disp = loader_get_dispatch(commandBuffer);
+
+ disp->CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers);
+}
+
+// ---- Vulkan core 1.1 trampolines
+
+VkResult setupLoaderTrampPhysDevGroups(VkInstance instance) {
+ VkResult res = VK_SUCCESS;
+ struct loader_instance *inst;
+ uint32_t total_count = 0;
+ VkPhysicalDeviceGroupPropertiesKHR **new_phys_dev_groups = NULL;
+ VkPhysicalDeviceGroupPropertiesKHR *local_phys_dev_groups = NULL;
+ PFN_vkEnumeratePhysicalDeviceGroups fpEnumeratePhysicalDeviceGroups = NULL;
+
+ inst = loader_get_instance(instance);
+ if (NULL == inst) {
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ // Get the function pointer to use to call into the ICD. This could be the core or KHR version
+ if (inst->enabled_known_extensions.khr_device_group_creation) {
+ fpEnumeratePhysicalDeviceGroups = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHR;
+ } else {
+ fpEnumeratePhysicalDeviceGroups = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups;
+ }
+
+ // Setup the trampoline loader physical devices. This will actually
+ // call down and setup the terminator loader physical devices during the
+ // process.
+ VkResult setup_res = setupLoaderTrampPhysDevs(instance);
+ if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) {
+ res = setup_res;
+ goto out;
+ }
+
+ // Query how many physical device groups there
+ res = fpEnumeratePhysicalDeviceGroups(instance, &total_count, NULL);
+ if (res != VK_SUCCESS) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
+ "\'EnumeratePhysicalDeviceGroupsKHR\' to lower layers or "
+ "loader to get count.");
+ goto out;
+ }
+
+ // Create an array for the new physical device groups, which will be stored
+ // in the instance for the trampoline code.
+ new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHR **)loader_instance_heap_alloc(
+ inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHR *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_dev_groups) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevGroups: Failed to allocate new physical device"
+ " group array of size %d",
+ total_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHR *));
+
+ // Create a temporary array (on the stack) to keep track of the
+ // returned VkPhysicalDevice values.
+ local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHR) * total_count);
+ if (NULL == local_phys_dev_groups) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevGroups: Failed to allocate local "
+ "physical device group array of size %d",
+ total_count);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ // Initialize the memory to something valid
+ memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHR) * total_count);
+ for (uint32_t group = 0; group < total_count; group++) {
+ local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR;
+ local_phys_dev_groups[group].pNext = NULL;
+ local_phys_dev_groups[group].subsetAllocation = false;
+ }
+
+ // Call down and get the content
+ fpEnumeratePhysicalDeviceGroups(instance, &total_count, local_phys_dev_groups);
+ if (VK_SUCCESS != res) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
+ "\'EnumeratePhysicalDeviceGroupsKHR\' to lower layers or "
+ "loader to get content.");
+ goto out;
+ }
+
+ // Replace all the physical device IDs with the proper loader values
+ for (uint32_t group = 0; group < total_count; group++) {
+ for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
+ bool found = false;
+ for (uint32_t tramp_gpu = 0; tramp_gpu < inst->phys_dev_count_tramp; tramp_gpu++) {
+ if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_tramp[tramp_gpu]->phys_dev) {
+ local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_tramp[tramp_gpu];
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevGroups: Failed to find GPU %d in group %d"
+ " returned by \'EnumeratePhysicalDeviceGroupsKHR\' in list returned"
+ " by \'EnumeratePhysicalDevices\'", group_gpu, group);
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+ }
+ }
+
+ // Copy or create everything to fill the new array of physical device groups
+ for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
+ // Check if this physical device group with the same contents is already in the old buffer
+ for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_tramp; old_idx++) {
+ if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount) {
+ bool found_all_gpus = true;
+ for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount; old_gpu++) {
+ bool found_gpu = false;
+ for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
+ if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] == inst->phys_dev_groups_tramp[old_idx]->physicalDevices[old_gpu]) {
+ found_gpu = true;
+ break;
+ }
+ }
+
+ if (!found_gpu) {
+ found_all_gpus = false;
+ break;
+ }
+ }
+ if (!found_all_gpus) {
+ continue;
+ } else {
+ new_phys_dev_groups[new_idx] = inst->phys_dev_groups_tramp[old_idx];
+ break;
+ }
+ }
+ }
+
+ // If this physical device group isn't in the old buffer, create it
+ if (NULL == new_phys_dev_groups[new_idx]) {
+ new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHR *)loader_instance_heap_alloc(
+ inst, sizeof(VkPhysicalDeviceGroupPropertiesKHR), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (NULL == new_phys_dev_groups[new_idx]) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "setupLoaderTrampPhysDevGroups: Failed to allocate "
+ "physical device group trampoline object %d",
+ new_idx);
+ total_count = new_idx;
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx],
+ sizeof(VkPhysicalDeviceGroupPropertiesKHR));
+ }
+ }
+
+out:
+
+ if (VK_SUCCESS != res) {
+ if (NULL != new_phys_dev_groups) {
+ for (uint32_t i = 0; i < total_count; i++) {
+ loader_instance_heap_free(inst, new_phys_dev_groups[i]);
+ }
+ loader_instance_heap_free(inst, new_phys_dev_groups);
+ }
+ total_count = 0;
+ } else {
+ // Free everything that didn't carry over to the new array of
+ // physical device groups
+ if (NULL != inst->phys_dev_groups_tramp) {
+ for (uint32_t i = 0; i < inst->phys_dev_group_count_tramp; i++) {
+ bool found = false;
+ for (uint32_t j = 0; j < total_count; j++) {
+ if (inst->phys_dev_groups_tramp[i] == new_phys_dev_groups[j]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ loader_instance_heap_free(inst, inst->phys_dev_groups_tramp[i]);
+ }
+ }
+ loader_instance_heap_free(inst, inst->phys_dev_groups_tramp);
+ }
+
+ // Swap in the new physical device group list
+ inst->phys_dev_group_count_tramp = total_count;
+ inst->phys_dev_groups_tramp = new_phys_dev_groups;
+ }
+
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(
+ VkInstance instance, uint32_t *pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
+ VkResult res = VK_SUCCESS;
+ uint32_t count;
+ uint32_t i;
+ struct loader_instance *inst = NULL;
+
+ loader_platform_thread_lock_mutex(&loader_lock);
+
+ inst = loader_get_instance(instance);
+ if (NULL == inst) {
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ if (NULL == pPhysicalDeviceGroupCount) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkEnumeratePhysicalDeviceGroupsKHR: Received NULL pointer for physical "
+ "device group count return value.");
+ res = VK_ERROR_INITIALIZATION_FAILED;
+ goto out;
+ }
+
+ VkResult setup_res = setupLoaderTrampPhysDevGroups(instance);
+ if (VK_SUCCESS != setup_res) {
+ res = setup_res;
+ goto out;
+ }
+
+ count = inst->phys_dev_group_count_tramp;
+
+ // Wrap the PhysDev object for loader usage, return wrapped objects
+ if (NULL != pPhysicalDeviceGroupProperties) {
+ if (inst->phys_dev_group_count_tramp > *pPhysicalDeviceGroupCount) {
+ loader_log(inst, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkEnumeratePhysicalDeviceGroupsKHR: Trimming device group count down"
+ " by application request from %d to %d physical device groups",
+ inst->phys_dev_group_count_tramp, *pPhysicalDeviceGroupCount);
+ count = *pPhysicalDeviceGroupCount;
+ res = VK_INCOMPLETE;
+ }
+ for (i = 0; i < count; i++) {
+ memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_tramp[i],
+ sizeof(VkPhysicalDeviceGroupPropertiesKHR));
+ }
+ }
+
+ *pPhysicalDeviceGroupCount = count;
+
+out:
+
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 *pFeatures) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ disp->GetPhysicalDeviceFeatures2KHR(unwrapped_phys_dev, pFeatures);
+ } else {
+ disp->GetPhysicalDeviceFeatures2(unwrapped_phys_dev, pFeatures);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties2 *pProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ disp->GetPhysicalDeviceProperties2KHR(unwrapped_phys_dev, pProperties);
+ } else {
+ disp->GetPhysicalDeviceProperties2(unwrapped_phys_dev, pProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
+ VkFormatProperties2 *pFormatProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ disp->GetPhysicalDeviceFormatProperties2KHR(unwrapped_phys_dev, format, pFormatProperties);
+ } else {
+ disp->GetPhysicalDeviceFormatProperties2(unwrapped_phys_dev, format, pFormatProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
+ VkImageFormatProperties2 *pImageFormatProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ return disp->GetPhysicalDeviceImageFormatProperties2KHR(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
+ } else {
+ return disp->GetPhysicalDeviceImageFormatProperties2(unwrapped_phys_dev, pImageFormatInfo, pImageFormatProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
+ uint32_t *pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2 *pQueueFamilyProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ disp->GetPhysicalDeviceQueueFamilyProperties2KHR(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
+ } else {
+ disp->GetPhysicalDeviceQueueFamilyProperties2(unwrapped_phys_dev, pQueueFamilyPropertyCount, pQueueFamilyProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ disp->GetPhysicalDeviceMemoryProperties2KHR(unwrapped_phys_dev, pMemoryProperties);
+ } else {
+ disp->GetPhysicalDeviceMemoryProperties2(unwrapped_phys_dev, pMemoryProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, uint32_t *pPropertyCount,
+ VkSparseImageFormatProperties2 *pProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_get_physical_device_properties2) {
+ disp->GetPhysicalDeviceSparseImageFormatProperties2KHR(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
+ } else {
+ disp->GetPhysicalDeviceSparseImageFormatProperties2(unwrapped_phys_dev, pFormatInfo, pPropertyCount, pProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
+ VkExternalBufferProperties *pExternalBufferProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_external_memory_capabilities){
+ disp->GetPhysicalDeviceExternalBufferPropertiesKHR(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
+ } else {
+ disp->GetPhysicalDeviceExternalBufferProperties(unwrapped_phys_dev, pExternalBufferInfo, pExternalBufferProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfoKHR *pExternalSemaphoreInfo,
+ VkExternalSemaphoreProperties *pExternalSemaphoreProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_external_semaphore_capabilities) {
+ disp->GetPhysicalDeviceExternalSemaphorePropertiesKHR(unwrapped_phys_dev, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
+ } else {
+ disp->GetPhysicalDeviceExternalSemaphoreProperties(unwrapped_phys_dev, pExternalSemaphoreInfo, pExternalSemaphoreProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties(
+ VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
+ VkExternalFenceProperties *pExternalFenceProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(physicalDevice);
+ const struct loader_instance *inst = ((struct loader_physical_device_tramp*) physicalDevice)->this_instance;
+
+ if (inst != NULL && inst->enabled_known_extensions.khr_external_fence_capabilities) {
+ disp->GetPhysicalDeviceExternalFencePropertiesKHR(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
+ } else {
+ disp->GetPhysicalDeviceExternalFenceProperties(unwrapped_phys_dev, pExternalFenceInfo, pExternalFenceProperties);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindBufferMemoryInfo* pBindInfos) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->BindBufferMemory2(device, bindInfoCount, pBindInfos);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->BindImageMemory2(device, bindInfoCount, pBindInfos);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures(
+ VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask(
+ VkCommandBuffer commandBuffer,
+ uint32_t deviceMask) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetDeviceMask(commandBuffer, deviceMask);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase(
+ VkCommandBuffer commandBuffer,
+ uint32_t baseGroupX,
+ uint32_t baseGroupY,
+ uint32_t baseGroupZ,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetImageMemoryRequirements2(device, pInfo, pMemoryRequirements);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2(
+ VkDevice device,
+ const VkBufferMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2(
+ VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolTrimFlags flags) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->TrimCommandPool(device, commandPool, flags);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *pQueueInfo, VkQueue *pQueue) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetDeviceQueue2(device, pQueueInfo, pQueue);
+ if (*pQueue != VK_NULL_HANDLE)
+ {
+ loader_set_dispatch(*pQueue, disp);
+ }
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion(
+ VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSamplerYcbcrConversion* pYcbcrConversion) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion(
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ VkDescriptorSetLayoutSupport* pSupport) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
+vkCreateDescriptorUpdateTemplate(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate(VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
+}
+
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate(VkDevice device, VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void *pData) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->UpdateDescriptorSetWithTemplate(device, descriptorSet, descriptorUpdateTemplate, pData);
+}
diff --git a/thirdparty/vulkan/loader/unknown_ext_chain.c b/thirdparty/vulkan/loader/unknown_ext_chain.c
new file mode 100644
index 0000000000..1c8560dd61
--- /dev/null
+++ b/thirdparty/vulkan/loader/unknown_ext_chain.c
@@ -0,0 +1,819 @@
+/*
+ * Copyright (c) 2017 The Khronos Group Inc.
+ * Copyright (c) 2017 Valve Corporation
+ * Copyright (c) 2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author Jon Ashburn <jon@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ */
+
+ // This code is used to pass on physical device extensions through the call chain. It must do this without creating a stack frame,
+ // because the actual parameters of the call are not known. Since the first parameter is known to be a VkPhysicalDevice, it can
+// unwrap the physical device, overwriting the wrapped device, and then jump to the next function in the call chain. This code
+// attempts to accomplish this by relying on tail-call optimizations, but there is no guarantee that this will work. As a result,
+// this code is only compiled on systems where an assembly alternative has not been written.
+
+ #include "vk_loader_platform.h"
+ #include "loader.h"
+
+ #if defined(__GNUC__) && !defined(__clang__)
+ #pragma GCC optimize(3) // force gcc to use tail-calls
+ #endif
+
+ // Trampoline function macro for unknown physical device extension command.
+ #define PhysDevExtTramp(num) \
+ VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTramp##num(VkPhysicalDevice physical_device) { \
+ const struct loader_instance_dispatch_table *disp; \
+ disp = loader_get_instance_dispatch(physical_device); \
+ disp->phys_dev_ext[num](loader_unwrap_physical_device(physical_device)); \
+ }
+
+// Terminator function macro for unknown physical device extension command.
+#define PhysDevExtTermin(num) \
+ VKAPI_ATTR void VKAPI_CALL vkPhysDevExtTermin##num(VkPhysicalDevice physical_device) { \
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physical_device; \
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term; \
+ struct loader_instance *inst = (struct loader_instance *)icd_term->this_instance; \
+ if (NULL == icd_term->phys_dev_ext[num]) { \
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "Extension %s not supported for this physical device", \
+ inst->phys_dev_ext_disp_hash[num].func_name); \
+ } \
+ icd_term->phys_dev_ext[num](phys_dev_term->phys_dev); \
+ }
+
+// Trampoline function macro for unknown physical device extension command.
+#define DevExtTramp(num) \
+ VKAPI_ATTR void VKAPI_CALL vkdev_ext##num(VkDevice device) { \
+ const struct loader_dev_dispatch_table *disp; \
+ disp = loader_get_dev_dispatch(device); \
+ disp->ext_dispatch.dev_ext[num](device); \
+ }
+
+
+// Instantiations of the trampoline
+PhysDevExtTramp(0)
+PhysDevExtTramp(1)
+PhysDevExtTramp(2)
+PhysDevExtTramp(3)
+PhysDevExtTramp(4)
+PhysDevExtTramp(5)
+PhysDevExtTramp(6)
+PhysDevExtTramp(7)
+PhysDevExtTramp(8)
+PhysDevExtTramp(9)
+PhysDevExtTramp(10)
+PhysDevExtTramp(11)
+PhysDevExtTramp(12)
+PhysDevExtTramp(13)
+PhysDevExtTramp(14)
+PhysDevExtTramp(15)
+PhysDevExtTramp(16)
+PhysDevExtTramp(17)
+PhysDevExtTramp(18)
+PhysDevExtTramp(19)
+PhysDevExtTramp(20)
+PhysDevExtTramp(21)
+PhysDevExtTramp(22)
+PhysDevExtTramp(23)
+PhysDevExtTramp(24)
+PhysDevExtTramp(25)
+PhysDevExtTramp(26)
+PhysDevExtTramp(27)
+PhysDevExtTramp(28)
+PhysDevExtTramp(29)
+PhysDevExtTramp(30)
+PhysDevExtTramp(31)
+PhysDevExtTramp(32)
+PhysDevExtTramp(33)
+PhysDevExtTramp(34)
+PhysDevExtTramp(35)
+PhysDevExtTramp(36)
+PhysDevExtTramp(37)
+PhysDevExtTramp(38)
+PhysDevExtTramp(39)
+PhysDevExtTramp(40)
+PhysDevExtTramp(41)
+PhysDevExtTramp(42)
+PhysDevExtTramp(43)
+PhysDevExtTramp(44)
+PhysDevExtTramp(45)
+PhysDevExtTramp(46)
+PhysDevExtTramp(47)
+PhysDevExtTramp(48)
+PhysDevExtTramp(49)
+PhysDevExtTramp(50)
+PhysDevExtTramp(51)
+PhysDevExtTramp(52)
+PhysDevExtTramp(53)
+PhysDevExtTramp(54)
+PhysDevExtTramp(55)
+PhysDevExtTramp(56)
+PhysDevExtTramp(57)
+PhysDevExtTramp(58)
+PhysDevExtTramp(59)
+PhysDevExtTramp(60)
+PhysDevExtTramp(61)
+PhysDevExtTramp(62)
+PhysDevExtTramp(63)
+PhysDevExtTramp(64)
+PhysDevExtTramp(65)
+PhysDevExtTramp(66)
+PhysDevExtTramp(67)
+PhysDevExtTramp(68)
+PhysDevExtTramp(69)
+PhysDevExtTramp(70)
+PhysDevExtTramp(71)
+PhysDevExtTramp(72)
+PhysDevExtTramp(73)
+PhysDevExtTramp(74)
+PhysDevExtTramp(75)
+PhysDevExtTramp(76)
+PhysDevExtTramp(77)
+PhysDevExtTramp(78)
+PhysDevExtTramp(79)
+PhysDevExtTramp(80)
+PhysDevExtTramp(81)
+PhysDevExtTramp(82)
+PhysDevExtTramp(83)
+PhysDevExtTramp(84)
+PhysDevExtTramp(85)
+PhysDevExtTramp(86)
+PhysDevExtTramp(87)
+PhysDevExtTramp(88)
+PhysDevExtTramp(89)
+PhysDevExtTramp(90)
+PhysDevExtTramp(91)
+PhysDevExtTramp(92)
+PhysDevExtTramp(93)
+PhysDevExtTramp(94)
+PhysDevExtTramp(95)
+PhysDevExtTramp(96)
+PhysDevExtTramp(97)
+PhysDevExtTramp(98)
+PhysDevExtTramp(99)
+PhysDevExtTramp(100)
+PhysDevExtTramp(101)
+PhysDevExtTramp(102)
+PhysDevExtTramp(103)
+PhysDevExtTramp(104)
+PhysDevExtTramp(105)
+PhysDevExtTramp(106)
+PhysDevExtTramp(107)
+PhysDevExtTramp(108)
+PhysDevExtTramp(109)
+PhysDevExtTramp(110)
+PhysDevExtTramp(111)
+PhysDevExtTramp(112)
+PhysDevExtTramp(113)
+PhysDevExtTramp(114)
+PhysDevExtTramp(115)
+PhysDevExtTramp(116)
+PhysDevExtTramp(117)
+PhysDevExtTramp(118)
+PhysDevExtTramp(119)
+PhysDevExtTramp(120)
+PhysDevExtTramp(121)
+PhysDevExtTramp(122)
+PhysDevExtTramp(123)
+PhysDevExtTramp(124)
+PhysDevExtTramp(125)
+PhysDevExtTramp(126)
+PhysDevExtTramp(127)
+PhysDevExtTramp(128)
+PhysDevExtTramp(129)
+PhysDevExtTramp(130)
+PhysDevExtTramp(131)
+PhysDevExtTramp(132)
+PhysDevExtTramp(133)
+PhysDevExtTramp(134)
+PhysDevExtTramp(135)
+PhysDevExtTramp(136)
+PhysDevExtTramp(137)
+PhysDevExtTramp(138)
+PhysDevExtTramp(139)
+PhysDevExtTramp(140)
+PhysDevExtTramp(141)
+PhysDevExtTramp(142)
+PhysDevExtTramp(143)
+PhysDevExtTramp(144)
+PhysDevExtTramp(145)
+PhysDevExtTramp(146)
+PhysDevExtTramp(147)
+PhysDevExtTramp(148)
+PhysDevExtTramp(149)
+PhysDevExtTramp(150)
+PhysDevExtTramp(151)
+PhysDevExtTramp(152)
+PhysDevExtTramp(153)
+PhysDevExtTramp(154)
+PhysDevExtTramp(155)
+PhysDevExtTramp(156)
+PhysDevExtTramp(157)
+PhysDevExtTramp(158)
+PhysDevExtTramp(159)
+PhysDevExtTramp(160)
+PhysDevExtTramp(161)
+PhysDevExtTramp(162)
+PhysDevExtTramp(163)
+PhysDevExtTramp(164)
+PhysDevExtTramp(165)
+PhysDevExtTramp(166)
+PhysDevExtTramp(167)
+PhysDevExtTramp(168)
+PhysDevExtTramp(169)
+PhysDevExtTramp(170)
+PhysDevExtTramp(171)
+PhysDevExtTramp(172)
+PhysDevExtTramp(173)
+PhysDevExtTramp(174)
+PhysDevExtTramp(175)
+PhysDevExtTramp(176)
+PhysDevExtTramp(177)
+PhysDevExtTramp(178)
+PhysDevExtTramp(179)
+PhysDevExtTramp(180)
+PhysDevExtTramp(181)
+PhysDevExtTramp(182)
+PhysDevExtTramp(183)
+PhysDevExtTramp(184)
+PhysDevExtTramp(185)
+PhysDevExtTramp(186)
+PhysDevExtTramp(187)
+PhysDevExtTramp(188)
+PhysDevExtTramp(189)
+PhysDevExtTramp(190)
+PhysDevExtTramp(191)
+PhysDevExtTramp(192)
+PhysDevExtTramp(193)
+PhysDevExtTramp(194)
+PhysDevExtTramp(195)
+PhysDevExtTramp(196)
+PhysDevExtTramp(197)
+PhysDevExtTramp(198)
+PhysDevExtTramp(199)
+PhysDevExtTramp(200)
+PhysDevExtTramp(201)
+PhysDevExtTramp(202)
+PhysDevExtTramp(203)
+PhysDevExtTramp(204)
+PhysDevExtTramp(205)
+PhysDevExtTramp(206)
+PhysDevExtTramp(207)
+PhysDevExtTramp(208)
+PhysDevExtTramp(209)
+PhysDevExtTramp(210)
+PhysDevExtTramp(211)
+PhysDevExtTramp(212)
+PhysDevExtTramp(213)
+PhysDevExtTramp(214)
+PhysDevExtTramp(215)
+PhysDevExtTramp(216)
+PhysDevExtTramp(217)
+PhysDevExtTramp(218)
+PhysDevExtTramp(219)
+PhysDevExtTramp(220)
+PhysDevExtTramp(221)
+PhysDevExtTramp(222)
+PhysDevExtTramp(223)
+PhysDevExtTramp(224)
+PhysDevExtTramp(225)
+PhysDevExtTramp(226)
+PhysDevExtTramp(227)
+PhysDevExtTramp(228)
+PhysDevExtTramp(229)
+PhysDevExtTramp(230)
+PhysDevExtTramp(231)
+PhysDevExtTramp(232)
+PhysDevExtTramp(233)
+PhysDevExtTramp(234)
+PhysDevExtTramp(235)
+PhysDevExtTramp(236)
+PhysDevExtTramp(237)
+PhysDevExtTramp(238)
+PhysDevExtTramp(239)
+PhysDevExtTramp(240)
+PhysDevExtTramp(241)
+PhysDevExtTramp(242)
+PhysDevExtTramp(243)
+PhysDevExtTramp(244)
+PhysDevExtTramp(245)
+PhysDevExtTramp(246)
+PhysDevExtTramp(247)
+PhysDevExtTramp(248)
+PhysDevExtTramp(249)
+
+// Instantiations of the terminator
+PhysDevExtTermin(0)
+PhysDevExtTermin(1)
+PhysDevExtTermin(2)
+PhysDevExtTermin(3)
+PhysDevExtTermin(4)
+PhysDevExtTermin(5)
+PhysDevExtTermin(6)
+PhysDevExtTermin(7)
+PhysDevExtTermin(8)
+PhysDevExtTermin(9)
+PhysDevExtTermin(10)
+PhysDevExtTermin(11)
+PhysDevExtTermin(12)
+PhysDevExtTermin(13)
+PhysDevExtTermin(14)
+PhysDevExtTermin(15)
+PhysDevExtTermin(16)
+PhysDevExtTermin(17)
+PhysDevExtTermin(18)
+PhysDevExtTermin(19)
+PhysDevExtTermin(20)
+PhysDevExtTermin(21)
+PhysDevExtTermin(22)
+PhysDevExtTermin(23)
+PhysDevExtTermin(24)
+PhysDevExtTermin(25)
+PhysDevExtTermin(26)
+PhysDevExtTermin(27)
+PhysDevExtTermin(28)
+PhysDevExtTermin(29)
+PhysDevExtTermin(30)
+PhysDevExtTermin(31)
+PhysDevExtTermin(32)
+PhysDevExtTermin(33)
+PhysDevExtTermin(34)
+PhysDevExtTermin(35)
+PhysDevExtTermin(36)
+PhysDevExtTermin(37)
+PhysDevExtTermin(38)
+PhysDevExtTermin(39)
+PhysDevExtTermin(40)
+PhysDevExtTermin(41)
+PhysDevExtTermin(42)
+PhysDevExtTermin(43)
+PhysDevExtTermin(44)
+PhysDevExtTermin(45)
+PhysDevExtTermin(46)
+PhysDevExtTermin(47)
+PhysDevExtTermin(48)
+PhysDevExtTermin(49)
+PhysDevExtTermin(50)
+PhysDevExtTermin(51)
+PhysDevExtTermin(52)
+PhysDevExtTermin(53)
+PhysDevExtTermin(54)
+PhysDevExtTermin(55)
+PhysDevExtTermin(56)
+PhysDevExtTermin(57)
+PhysDevExtTermin(58)
+PhysDevExtTermin(59)
+PhysDevExtTermin(60)
+PhysDevExtTermin(61)
+PhysDevExtTermin(62)
+PhysDevExtTermin(63)
+PhysDevExtTermin(64)
+PhysDevExtTermin(65)
+PhysDevExtTermin(66)
+PhysDevExtTermin(67)
+PhysDevExtTermin(68)
+PhysDevExtTermin(69)
+PhysDevExtTermin(70)
+PhysDevExtTermin(71)
+PhysDevExtTermin(72)
+PhysDevExtTermin(73)
+PhysDevExtTermin(74)
+PhysDevExtTermin(75)
+PhysDevExtTermin(76)
+PhysDevExtTermin(77)
+PhysDevExtTermin(78)
+PhysDevExtTermin(79)
+PhysDevExtTermin(80)
+PhysDevExtTermin(81)
+PhysDevExtTermin(82)
+PhysDevExtTermin(83)
+PhysDevExtTermin(84)
+PhysDevExtTermin(85)
+PhysDevExtTermin(86)
+PhysDevExtTermin(87)
+PhysDevExtTermin(88)
+PhysDevExtTermin(89)
+PhysDevExtTermin(90)
+PhysDevExtTermin(91)
+PhysDevExtTermin(92)
+PhysDevExtTermin(93)
+PhysDevExtTermin(94)
+PhysDevExtTermin(95)
+PhysDevExtTermin(96)
+PhysDevExtTermin(97)
+PhysDevExtTermin(98)
+PhysDevExtTermin(99)
+PhysDevExtTermin(100)
+PhysDevExtTermin(101)
+PhysDevExtTermin(102)
+PhysDevExtTermin(103)
+PhysDevExtTermin(104)
+PhysDevExtTermin(105)
+PhysDevExtTermin(106)
+PhysDevExtTermin(107)
+PhysDevExtTermin(108)
+PhysDevExtTermin(109)
+PhysDevExtTermin(110)
+PhysDevExtTermin(111)
+PhysDevExtTermin(112)
+PhysDevExtTermin(113)
+PhysDevExtTermin(114)
+PhysDevExtTermin(115)
+PhysDevExtTermin(116)
+PhysDevExtTermin(117)
+PhysDevExtTermin(118)
+PhysDevExtTermin(119)
+PhysDevExtTermin(120)
+PhysDevExtTermin(121)
+PhysDevExtTermin(122)
+PhysDevExtTermin(123)
+PhysDevExtTermin(124)
+PhysDevExtTermin(125)
+PhysDevExtTermin(126)
+PhysDevExtTermin(127)
+PhysDevExtTermin(128)
+PhysDevExtTermin(129)
+PhysDevExtTermin(130)
+PhysDevExtTermin(131)
+PhysDevExtTermin(132)
+PhysDevExtTermin(133)
+PhysDevExtTermin(134)
+PhysDevExtTermin(135)
+PhysDevExtTermin(136)
+PhysDevExtTermin(137)
+PhysDevExtTermin(138)
+PhysDevExtTermin(139)
+PhysDevExtTermin(140)
+PhysDevExtTermin(141)
+PhysDevExtTermin(142)
+PhysDevExtTermin(143)
+PhysDevExtTermin(144)
+PhysDevExtTermin(145)
+PhysDevExtTermin(146)
+PhysDevExtTermin(147)
+PhysDevExtTermin(148)
+PhysDevExtTermin(149)
+PhysDevExtTermin(150)
+PhysDevExtTermin(151)
+PhysDevExtTermin(152)
+PhysDevExtTermin(153)
+PhysDevExtTermin(154)
+PhysDevExtTermin(155)
+PhysDevExtTermin(156)
+PhysDevExtTermin(157)
+PhysDevExtTermin(158)
+PhysDevExtTermin(159)
+PhysDevExtTermin(160)
+PhysDevExtTermin(161)
+PhysDevExtTermin(162)
+PhysDevExtTermin(163)
+PhysDevExtTermin(164)
+PhysDevExtTermin(165)
+PhysDevExtTermin(166)
+PhysDevExtTermin(167)
+PhysDevExtTermin(168)
+PhysDevExtTermin(169)
+PhysDevExtTermin(170)
+PhysDevExtTermin(171)
+PhysDevExtTermin(172)
+PhysDevExtTermin(173)
+PhysDevExtTermin(174)
+PhysDevExtTermin(175)
+PhysDevExtTermin(176)
+PhysDevExtTermin(177)
+PhysDevExtTermin(178)
+PhysDevExtTermin(179)
+PhysDevExtTermin(180)
+PhysDevExtTermin(181)
+PhysDevExtTermin(182)
+PhysDevExtTermin(183)
+PhysDevExtTermin(184)
+PhysDevExtTermin(185)
+PhysDevExtTermin(186)
+PhysDevExtTermin(187)
+PhysDevExtTermin(188)
+PhysDevExtTermin(189)
+PhysDevExtTermin(190)
+PhysDevExtTermin(191)
+PhysDevExtTermin(192)
+PhysDevExtTermin(193)
+PhysDevExtTermin(194)
+PhysDevExtTermin(195)
+PhysDevExtTermin(196)
+PhysDevExtTermin(197)
+PhysDevExtTermin(198)
+PhysDevExtTermin(199)
+PhysDevExtTermin(200)
+PhysDevExtTermin(201)
+PhysDevExtTermin(202)
+PhysDevExtTermin(203)
+PhysDevExtTermin(204)
+PhysDevExtTermin(205)
+PhysDevExtTermin(206)
+PhysDevExtTermin(207)
+PhysDevExtTermin(208)
+PhysDevExtTermin(209)
+PhysDevExtTermin(210)
+PhysDevExtTermin(211)
+PhysDevExtTermin(212)
+PhysDevExtTermin(213)
+PhysDevExtTermin(214)
+PhysDevExtTermin(215)
+PhysDevExtTermin(216)
+PhysDevExtTermin(217)
+PhysDevExtTermin(218)
+PhysDevExtTermin(219)
+PhysDevExtTermin(220)
+PhysDevExtTermin(221)
+PhysDevExtTermin(222)
+PhysDevExtTermin(223)
+PhysDevExtTermin(224)
+PhysDevExtTermin(225)
+PhysDevExtTermin(226)
+PhysDevExtTermin(227)
+PhysDevExtTermin(228)
+PhysDevExtTermin(229)
+PhysDevExtTermin(230)
+PhysDevExtTermin(231)
+PhysDevExtTermin(232)
+PhysDevExtTermin(233)
+PhysDevExtTermin(234)
+PhysDevExtTermin(235)
+PhysDevExtTermin(236)
+PhysDevExtTermin(237)
+PhysDevExtTermin(238)
+PhysDevExtTermin(239)
+PhysDevExtTermin(240)
+PhysDevExtTermin(241)
+PhysDevExtTermin(242)
+PhysDevExtTermin(243)
+PhysDevExtTermin(244)
+PhysDevExtTermin(245)
+PhysDevExtTermin(246)
+PhysDevExtTermin(247)
+PhysDevExtTermin(248)
+PhysDevExtTermin(249)
+
+// Instantiations of the device trampoline
+DevExtTramp(0)
+DevExtTramp(1)
+DevExtTramp(2)
+DevExtTramp(3)
+DevExtTramp(4)
+DevExtTramp(5)
+DevExtTramp(6)
+DevExtTramp(7)
+DevExtTramp(8)
+DevExtTramp(9)
+DevExtTramp(10)
+DevExtTramp(11)
+DevExtTramp(12)
+DevExtTramp(13)
+DevExtTramp(14)
+DevExtTramp(15)
+DevExtTramp(16)
+DevExtTramp(17)
+DevExtTramp(18)
+DevExtTramp(19)
+DevExtTramp(20)
+DevExtTramp(21)
+DevExtTramp(22)
+DevExtTramp(23)
+DevExtTramp(24)
+DevExtTramp(25)
+DevExtTramp(26)
+DevExtTramp(27)
+DevExtTramp(28)
+DevExtTramp(29)
+DevExtTramp(30)
+DevExtTramp(31)
+DevExtTramp(32)
+DevExtTramp(33)
+DevExtTramp(34)
+DevExtTramp(35)
+DevExtTramp(36)
+DevExtTramp(37)
+DevExtTramp(38)
+DevExtTramp(39)
+DevExtTramp(40)
+DevExtTramp(41)
+DevExtTramp(42)
+DevExtTramp(43)
+DevExtTramp(44)
+DevExtTramp(45)
+DevExtTramp(46)
+DevExtTramp(47)
+DevExtTramp(48)
+DevExtTramp(49)
+DevExtTramp(50)
+DevExtTramp(51)
+DevExtTramp(52)
+DevExtTramp(53)
+DevExtTramp(54)
+DevExtTramp(55)
+DevExtTramp(56)
+DevExtTramp(57)
+DevExtTramp(58)
+DevExtTramp(59)
+DevExtTramp(60)
+DevExtTramp(61)
+DevExtTramp(62)
+DevExtTramp(63)
+DevExtTramp(64)
+DevExtTramp(65)
+DevExtTramp(66)
+DevExtTramp(67)
+DevExtTramp(68)
+DevExtTramp(69)
+DevExtTramp(70)
+DevExtTramp(71)
+DevExtTramp(72)
+DevExtTramp(73)
+DevExtTramp(74)
+DevExtTramp(75)
+DevExtTramp(76)
+DevExtTramp(77)
+DevExtTramp(78)
+DevExtTramp(79)
+DevExtTramp(80)
+DevExtTramp(81)
+DevExtTramp(82)
+DevExtTramp(83)
+DevExtTramp(84)
+DevExtTramp(85)
+DevExtTramp(86)
+DevExtTramp(87)
+DevExtTramp(88)
+DevExtTramp(89)
+DevExtTramp(90)
+DevExtTramp(91)
+DevExtTramp(92)
+DevExtTramp(93)
+DevExtTramp(94)
+DevExtTramp(95)
+DevExtTramp(96)
+DevExtTramp(97)
+DevExtTramp(98)
+DevExtTramp(99)
+DevExtTramp(100)
+DevExtTramp(101)
+DevExtTramp(102)
+DevExtTramp(103)
+DevExtTramp(104)
+DevExtTramp(105)
+DevExtTramp(106)
+DevExtTramp(107)
+DevExtTramp(108)
+DevExtTramp(109)
+DevExtTramp(110)
+DevExtTramp(111)
+DevExtTramp(112)
+DevExtTramp(113)
+DevExtTramp(114)
+DevExtTramp(115)
+DevExtTramp(116)
+DevExtTramp(117)
+DevExtTramp(118)
+DevExtTramp(119)
+DevExtTramp(120)
+DevExtTramp(121)
+DevExtTramp(122)
+DevExtTramp(123)
+DevExtTramp(124)
+DevExtTramp(125)
+DevExtTramp(126)
+DevExtTramp(127)
+DevExtTramp(128)
+DevExtTramp(129)
+DevExtTramp(130)
+DevExtTramp(131)
+DevExtTramp(132)
+DevExtTramp(133)
+DevExtTramp(134)
+DevExtTramp(135)
+DevExtTramp(136)
+DevExtTramp(137)
+DevExtTramp(138)
+DevExtTramp(139)
+DevExtTramp(140)
+DevExtTramp(141)
+DevExtTramp(142)
+DevExtTramp(143)
+DevExtTramp(144)
+DevExtTramp(145)
+DevExtTramp(146)
+DevExtTramp(147)
+DevExtTramp(148)
+DevExtTramp(149)
+DevExtTramp(150)
+DevExtTramp(151)
+DevExtTramp(152)
+DevExtTramp(153)
+DevExtTramp(154)
+DevExtTramp(155)
+DevExtTramp(156)
+DevExtTramp(157)
+DevExtTramp(158)
+DevExtTramp(159)
+DevExtTramp(160)
+DevExtTramp(161)
+DevExtTramp(162)
+DevExtTramp(163)
+DevExtTramp(164)
+DevExtTramp(165)
+DevExtTramp(166)
+DevExtTramp(167)
+DevExtTramp(168)
+DevExtTramp(169)
+DevExtTramp(170)
+DevExtTramp(171)
+DevExtTramp(172)
+DevExtTramp(173)
+DevExtTramp(174)
+DevExtTramp(175)
+DevExtTramp(176)
+DevExtTramp(177)
+DevExtTramp(178)
+DevExtTramp(179)
+DevExtTramp(180)
+DevExtTramp(181)
+DevExtTramp(182)
+DevExtTramp(183)
+DevExtTramp(184)
+DevExtTramp(185)
+DevExtTramp(186)
+DevExtTramp(187)
+DevExtTramp(188)
+DevExtTramp(189)
+DevExtTramp(190)
+DevExtTramp(191)
+DevExtTramp(192)
+DevExtTramp(193)
+DevExtTramp(194)
+DevExtTramp(195)
+DevExtTramp(196)
+DevExtTramp(197)
+DevExtTramp(198)
+DevExtTramp(199)
+DevExtTramp(200)
+DevExtTramp(201)
+DevExtTramp(202)
+DevExtTramp(203)
+DevExtTramp(204)
+DevExtTramp(205)
+DevExtTramp(206)
+DevExtTramp(207)
+DevExtTramp(208)
+DevExtTramp(209)
+DevExtTramp(210)
+DevExtTramp(211)
+DevExtTramp(212)
+DevExtTramp(213)
+DevExtTramp(214)
+DevExtTramp(215)
+DevExtTramp(216)
+DevExtTramp(217)
+DevExtTramp(218)
+DevExtTramp(219)
+DevExtTramp(220)
+DevExtTramp(221)
+DevExtTramp(222)
+DevExtTramp(223)
+DevExtTramp(224)
+DevExtTramp(225)
+DevExtTramp(226)
+DevExtTramp(227)
+DevExtTramp(228)
+DevExtTramp(229)
+DevExtTramp(230)
+DevExtTramp(231)
+DevExtTramp(232)
+DevExtTramp(233)
+DevExtTramp(234)
+DevExtTramp(235)
+DevExtTramp(236)
+DevExtTramp(237)
+DevExtTramp(238)
+DevExtTramp(239)
+DevExtTramp(240)
+DevExtTramp(241)
+DevExtTramp(242)
+DevExtTramp(243)
+DevExtTramp(244)
+DevExtTramp(245)
+DevExtTramp(246)
+DevExtTramp(247)
+DevExtTramp(248)
+DevExtTramp(249)
diff --git a/thirdparty/vulkan/loader/unknown_ext_chain_gas.S b/thirdparty/vulkan/loader/unknown_ext_chain_gas.S
new file mode 100644
index 0000000000..f847e1407d
--- /dev/null
+++ b/thirdparty/vulkan/loader/unknown_ext_chain_gas.S
@@ -0,0 +1,885 @@
+#
+# Copyright (c) 2017 The Khronos Group Inc.
+# Copyright (c) 2017 Valve Corporation
+# Copyright (c) 2017 LunarG, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Author: Lenny Komow <lenny@lunarg.com>
+#
+
+# This code is used to pass on device (including physical device) extensions through the call chain. It must do this without
+# creating a stack frame, because the actual parameters of the call are not known. Since the first parameter is known to be a
+# VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then
+# jump to the next function in the call chain
+
+#ifdef HAVE_CET_H
+#include <cet.h>
+#else
+#define _CET_ENDBR
+#endif
+
+.intel_syntax noprefix
+.include "gen_defines.asm"
+
+.ifdef X86_64
+
+.macro PhysDevExtTramp num
+.global vkPhysDevExtTramp\num
+vkPhysDevExtTramp\num:
+ _CET_ENDBR
+ mov rax, [rdi]
+ mov rdi, [rdi + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP]
+ jmp [rax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num))]
+.endm
+
+.macro PhysDevExtTermin num
+.global vkPhysDevExtTermin\num
+vkPhysDevExtTermin\num:
+ _CET_ENDBR
+ mov rax, [rdi + ICD_TERM_OFFSET_PHYS_DEV_TERM] # Store the loader_icd_term* in rax
+ cmp qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL
+ je terminError\num # Go to the error section if it is NULL
+ mov rdi, [rdi + PHYS_DEV_OFFSET_PHYS_DEV_TERM] # Load the unwrapped VkPhysicalDevice into the first arg
+ jmp [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))] # Jump to the next function in the chain
+terminError\num:
+ sub rsp, 56 # Create the stack frame
+ mov rdi, [rax + INSTANCE_OFFSET_ICD_TERM] # Load the loader_instance into rdi (first arg)
+ mov r8, [rdi + (HASH_OFFSET_INSTANCE + (HASH_SIZE * \num) + FUNC_NAME_OFFSET_HASH)] # Load the func name into r8 (fifth arg)
+ lea rcx, termin_error_string@GOTPCREL # Load the error string into rcx (fourth arg)
+ xor edx, edx # Set rdx to zero (third arg)
+ lea esi, [rdx + VK_DEBUG_REPORT_ERROR_BIT_EXT] # Write the error logging bit to rsi (second arg)
+ call loader_log # Log the error message before we crash
+ add rsp, 56 # Clean up the stack frame
+ mov rax, 0
+ jmp rax # Crash intentionally by jumping to address zero
+.endm
+
+.macro DevExtTramp num
+.global vkdev_ext\num
+vkdev_ext\num:
+ _CET_ENDBR
+ mov rax, [rdi] # Dereference the handle to get the dispatch table
+ jmp [rax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))] # Jump to the appropriate call chain
+.endm
+
+.else
+
+.macro PhysDevExtTramp num
+.global vkPhysDevExtTramp\num
+vkPhysDevExtTramp\num:
+ _CET_ENDBR
+ mov eax, [esp + 4] # Load the wrapped VkPhysicalDevice into eax
+ mov ecx, [eax + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] # Load the unwrapped VkPhysicalDevice into ecx
+ mov [esp + 4], ecx # Overwrite the wrapped VkPhysicalDevice with the unwrapped one (on the stack)
+ mov eax, [eax] # Dereference the wrapped VkPhysicalDevice to get the dispatch table in eax
+ jmp [eax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * \num))] # Dereference the wrapped VkPhysicalDevice to get the dispatch table in eax
+.endm
+
+.macro PhysDevExtTermin num
+.global vkPhysDevExtTermin\num
+vkPhysDevExtTermin\num:
+ _CET_ENDBR
+ mov ecx, [esp + 4] # Move the wrapped VkPhysicalDevice into ecx
+ mov eax, [ecx + ICD_TERM_OFFSET_PHYS_DEV_TERM] # Store the loader_icd_term* in eax
+ cmp dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))], 0 # Check if the next function in the chain is NULL
+ je terminError\num # Go to the error section if it is NULL
+ mov ecx, [ecx + PHYS_DEV_OFFSET_PHYS_DEV_TERM] # Unwrap the VkPhysicalDevice in ecx
+ mov [esp + 4], ecx # Copy the unwrapped VkPhysicalDevice into the first arg
+ jmp [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * \num))] # Jump to the next function in the chain
+terminError\num:
+ mov eax, [eax + INSTANCE_OFFSET_ICD_TERM] # Load the loader_instance into eax
+ push [eax + (HASH_OFFSET_INSTANCE + (HASH_SIZE * \num) + FUNC_NAME_OFFSET_HASH)] # Push the func name (fifth arg)
+ push offset termin_error_string@GOT # Push the error string (fourth arg)
+ push 0 # Push zero (third arg)
+ push VK_DEBUG_REPORT_ERROR_BIT_EXT # Push the error logging bit (second arg)
+ push eax # Push the loader_instance (first arg)
+ call loader_log # Log the error message before we crash
+ add esp, 20 # Clean up the args
+ mov eax, 0
+ jmp eax # Crash intentionally by jumping to address zero
+.endm
+
+.macro DevExtTramp num
+.global vkdev_ext\num
+vkdev_ext\num:
+ _CET_ENDBR
+ mov eax, [esp + 4] # Dereference the handle to get the dispatch table
+ jmp [eax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * \num))] # Jump to the appropriate call chain
+.endm
+
+.endif
+
+#if defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
+
+.data
+
+termin_error_string:
+.string "Extension %s not supported for this physical device"
+
+.text
+
+ PhysDevExtTramp 0
+ PhysDevExtTramp 1
+ PhysDevExtTramp 2
+ PhysDevExtTramp 3
+ PhysDevExtTramp 4
+ PhysDevExtTramp 5
+ PhysDevExtTramp 6
+ PhysDevExtTramp 7
+ PhysDevExtTramp 8
+ PhysDevExtTramp 9
+ PhysDevExtTramp 10
+ PhysDevExtTramp 11
+ PhysDevExtTramp 12
+ PhysDevExtTramp 13
+ PhysDevExtTramp 14
+ PhysDevExtTramp 15
+ PhysDevExtTramp 16
+ PhysDevExtTramp 17
+ PhysDevExtTramp 18
+ PhysDevExtTramp 19
+ PhysDevExtTramp 20
+ PhysDevExtTramp 21
+ PhysDevExtTramp 22
+ PhysDevExtTramp 23
+ PhysDevExtTramp 24
+ PhysDevExtTramp 25
+ PhysDevExtTramp 26
+ PhysDevExtTramp 27
+ PhysDevExtTramp 28
+ PhysDevExtTramp 29
+ PhysDevExtTramp 30
+ PhysDevExtTramp 31
+ PhysDevExtTramp 32
+ PhysDevExtTramp 33
+ PhysDevExtTramp 34
+ PhysDevExtTramp 35
+ PhysDevExtTramp 36
+ PhysDevExtTramp 37
+ PhysDevExtTramp 38
+ PhysDevExtTramp 39
+ PhysDevExtTramp 40
+ PhysDevExtTramp 41
+ PhysDevExtTramp 42
+ PhysDevExtTramp 43
+ PhysDevExtTramp 44
+ PhysDevExtTramp 45
+ PhysDevExtTramp 46
+ PhysDevExtTramp 47
+ PhysDevExtTramp 48
+ PhysDevExtTramp 49
+ PhysDevExtTramp 50
+ PhysDevExtTramp 51
+ PhysDevExtTramp 52
+ PhysDevExtTramp 53
+ PhysDevExtTramp 54
+ PhysDevExtTramp 55
+ PhysDevExtTramp 56
+ PhysDevExtTramp 57
+ PhysDevExtTramp 58
+ PhysDevExtTramp 59
+ PhysDevExtTramp 60
+ PhysDevExtTramp 61
+ PhysDevExtTramp 62
+ PhysDevExtTramp 63
+ PhysDevExtTramp 64
+ PhysDevExtTramp 65
+ PhysDevExtTramp 66
+ PhysDevExtTramp 67
+ PhysDevExtTramp 68
+ PhysDevExtTramp 69
+ PhysDevExtTramp 70
+ PhysDevExtTramp 71
+ PhysDevExtTramp 72
+ PhysDevExtTramp 73
+ PhysDevExtTramp 74
+ PhysDevExtTramp 75
+ PhysDevExtTramp 76
+ PhysDevExtTramp 77
+ PhysDevExtTramp 78
+ PhysDevExtTramp 79
+ PhysDevExtTramp 80
+ PhysDevExtTramp 81
+ PhysDevExtTramp 82
+ PhysDevExtTramp 83
+ PhysDevExtTramp 84
+ PhysDevExtTramp 85
+ PhysDevExtTramp 86
+ PhysDevExtTramp 87
+ PhysDevExtTramp 88
+ PhysDevExtTramp 89
+ PhysDevExtTramp 90
+ PhysDevExtTramp 91
+ PhysDevExtTramp 92
+ PhysDevExtTramp 93
+ PhysDevExtTramp 94
+ PhysDevExtTramp 95
+ PhysDevExtTramp 96
+ PhysDevExtTramp 97
+ PhysDevExtTramp 98
+ PhysDevExtTramp 99
+ PhysDevExtTramp 100
+ PhysDevExtTramp 101
+ PhysDevExtTramp 102
+ PhysDevExtTramp 103
+ PhysDevExtTramp 104
+ PhysDevExtTramp 105
+ PhysDevExtTramp 106
+ PhysDevExtTramp 107
+ PhysDevExtTramp 108
+ PhysDevExtTramp 109
+ PhysDevExtTramp 110
+ PhysDevExtTramp 111
+ PhysDevExtTramp 112
+ PhysDevExtTramp 113
+ PhysDevExtTramp 114
+ PhysDevExtTramp 115
+ PhysDevExtTramp 116
+ PhysDevExtTramp 117
+ PhysDevExtTramp 118
+ PhysDevExtTramp 119
+ PhysDevExtTramp 120
+ PhysDevExtTramp 121
+ PhysDevExtTramp 122
+ PhysDevExtTramp 123
+ PhysDevExtTramp 124
+ PhysDevExtTramp 125
+ PhysDevExtTramp 126
+ PhysDevExtTramp 127
+ PhysDevExtTramp 128
+ PhysDevExtTramp 129
+ PhysDevExtTramp 130
+ PhysDevExtTramp 131
+ PhysDevExtTramp 132
+ PhysDevExtTramp 133
+ PhysDevExtTramp 134
+ PhysDevExtTramp 135
+ PhysDevExtTramp 136
+ PhysDevExtTramp 137
+ PhysDevExtTramp 138
+ PhysDevExtTramp 139
+ PhysDevExtTramp 140
+ PhysDevExtTramp 141
+ PhysDevExtTramp 142
+ PhysDevExtTramp 143
+ PhysDevExtTramp 144
+ PhysDevExtTramp 145
+ PhysDevExtTramp 146
+ PhysDevExtTramp 147
+ PhysDevExtTramp 148
+ PhysDevExtTramp 149
+ PhysDevExtTramp 150
+ PhysDevExtTramp 151
+ PhysDevExtTramp 152
+ PhysDevExtTramp 153
+ PhysDevExtTramp 154
+ PhysDevExtTramp 155
+ PhysDevExtTramp 156
+ PhysDevExtTramp 157
+ PhysDevExtTramp 158
+ PhysDevExtTramp 159
+ PhysDevExtTramp 160
+ PhysDevExtTramp 161
+ PhysDevExtTramp 162
+ PhysDevExtTramp 163
+ PhysDevExtTramp 164
+ PhysDevExtTramp 165
+ PhysDevExtTramp 166
+ PhysDevExtTramp 167
+ PhysDevExtTramp 168
+ PhysDevExtTramp 169
+ PhysDevExtTramp 170
+ PhysDevExtTramp 171
+ PhysDevExtTramp 172
+ PhysDevExtTramp 173
+ PhysDevExtTramp 174
+ PhysDevExtTramp 175
+ PhysDevExtTramp 176
+ PhysDevExtTramp 177
+ PhysDevExtTramp 178
+ PhysDevExtTramp 179
+ PhysDevExtTramp 180
+ PhysDevExtTramp 181
+ PhysDevExtTramp 182
+ PhysDevExtTramp 183
+ PhysDevExtTramp 184
+ PhysDevExtTramp 185
+ PhysDevExtTramp 186
+ PhysDevExtTramp 187
+ PhysDevExtTramp 188
+ PhysDevExtTramp 189
+ PhysDevExtTramp 190
+ PhysDevExtTramp 191
+ PhysDevExtTramp 192
+ PhysDevExtTramp 193
+ PhysDevExtTramp 194
+ PhysDevExtTramp 195
+ PhysDevExtTramp 196
+ PhysDevExtTramp 197
+ PhysDevExtTramp 198
+ PhysDevExtTramp 199
+ PhysDevExtTramp 200
+ PhysDevExtTramp 201
+ PhysDevExtTramp 202
+ PhysDevExtTramp 203
+ PhysDevExtTramp 204
+ PhysDevExtTramp 205
+ PhysDevExtTramp 206
+ PhysDevExtTramp 207
+ PhysDevExtTramp 208
+ PhysDevExtTramp 209
+ PhysDevExtTramp 210
+ PhysDevExtTramp 211
+ PhysDevExtTramp 212
+ PhysDevExtTramp 213
+ PhysDevExtTramp 214
+ PhysDevExtTramp 215
+ PhysDevExtTramp 216
+ PhysDevExtTramp 217
+ PhysDevExtTramp 218
+ PhysDevExtTramp 219
+ PhysDevExtTramp 220
+ PhysDevExtTramp 221
+ PhysDevExtTramp 222
+ PhysDevExtTramp 223
+ PhysDevExtTramp 224
+ PhysDevExtTramp 225
+ PhysDevExtTramp 226
+ PhysDevExtTramp 227
+ PhysDevExtTramp 228
+ PhysDevExtTramp 229
+ PhysDevExtTramp 230
+ PhysDevExtTramp 231
+ PhysDevExtTramp 232
+ PhysDevExtTramp 233
+ PhysDevExtTramp 234
+ PhysDevExtTramp 235
+ PhysDevExtTramp 236
+ PhysDevExtTramp 237
+ PhysDevExtTramp 238
+ PhysDevExtTramp 239
+ PhysDevExtTramp 240
+ PhysDevExtTramp 241
+ PhysDevExtTramp 242
+ PhysDevExtTramp 243
+ PhysDevExtTramp 244
+ PhysDevExtTramp 245
+ PhysDevExtTramp 246
+ PhysDevExtTramp 247
+ PhysDevExtTramp 248
+ PhysDevExtTramp 249
+
+ PhysDevExtTermin 0
+ PhysDevExtTermin 1
+ PhysDevExtTermin 2
+ PhysDevExtTermin 3
+ PhysDevExtTermin 4
+ PhysDevExtTermin 5
+ PhysDevExtTermin 6
+ PhysDevExtTermin 7
+ PhysDevExtTermin 8
+ PhysDevExtTermin 9
+ PhysDevExtTermin 10
+ PhysDevExtTermin 11
+ PhysDevExtTermin 12
+ PhysDevExtTermin 13
+ PhysDevExtTermin 14
+ PhysDevExtTermin 15
+ PhysDevExtTermin 16
+ PhysDevExtTermin 17
+ PhysDevExtTermin 18
+ PhysDevExtTermin 19
+ PhysDevExtTermin 20
+ PhysDevExtTermin 21
+ PhysDevExtTermin 22
+ PhysDevExtTermin 23
+ PhysDevExtTermin 24
+ PhysDevExtTermin 25
+ PhysDevExtTermin 26
+ PhysDevExtTermin 27
+ PhysDevExtTermin 28
+ PhysDevExtTermin 29
+ PhysDevExtTermin 30
+ PhysDevExtTermin 31
+ PhysDevExtTermin 32
+ PhysDevExtTermin 33
+ PhysDevExtTermin 34
+ PhysDevExtTermin 35
+ PhysDevExtTermin 36
+ PhysDevExtTermin 37
+ PhysDevExtTermin 38
+ PhysDevExtTermin 39
+ PhysDevExtTermin 40
+ PhysDevExtTermin 41
+ PhysDevExtTermin 42
+ PhysDevExtTermin 43
+ PhysDevExtTermin 44
+ PhysDevExtTermin 45
+ PhysDevExtTermin 46
+ PhysDevExtTermin 47
+ PhysDevExtTermin 48
+ PhysDevExtTermin 49
+ PhysDevExtTermin 50
+ PhysDevExtTermin 51
+ PhysDevExtTermin 52
+ PhysDevExtTermin 53
+ PhysDevExtTermin 54
+ PhysDevExtTermin 55
+ PhysDevExtTermin 56
+ PhysDevExtTermin 57
+ PhysDevExtTermin 58
+ PhysDevExtTermin 59
+ PhysDevExtTermin 60
+ PhysDevExtTermin 61
+ PhysDevExtTermin 62
+ PhysDevExtTermin 63
+ PhysDevExtTermin 64
+ PhysDevExtTermin 65
+ PhysDevExtTermin 66
+ PhysDevExtTermin 67
+ PhysDevExtTermin 68
+ PhysDevExtTermin 69
+ PhysDevExtTermin 70
+ PhysDevExtTermin 71
+ PhysDevExtTermin 72
+ PhysDevExtTermin 73
+ PhysDevExtTermin 74
+ PhysDevExtTermin 75
+ PhysDevExtTermin 76
+ PhysDevExtTermin 77
+ PhysDevExtTermin 78
+ PhysDevExtTermin 79
+ PhysDevExtTermin 80
+ PhysDevExtTermin 81
+ PhysDevExtTermin 82
+ PhysDevExtTermin 83
+ PhysDevExtTermin 84
+ PhysDevExtTermin 85
+ PhysDevExtTermin 86
+ PhysDevExtTermin 87
+ PhysDevExtTermin 88
+ PhysDevExtTermin 89
+ PhysDevExtTermin 90
+ PhysDevExtTermin 91
+ PhysDevExtTermin 92
+ PhysDevExtTermin 93
+ PhysDevExtTermin 94
+ PhysDevExtTermin 95
+ PhysDevExtTermin 96
+ PhysDevExtTermin 97
+ PhysDevExtTermin 98
+ PhysDevExtTermin 99
+ PhysDevExtTermin 100
+ PhysDevExtTermin 101
+ PhysDevExtTermin 102
+ PhysDevExtTermin 103
+ PhysDevExtTermin 104
+ PhysDevExtTermin 105
+ PhysDevExtTermin 106
+ PhysDevExtTermin 107
+ PhysDevExtTermin 108
+ PhysDevExtTermin 109
+ PhysDevExtTermin 110
+ PhysDevExtTermin 111
+ PhysDevExtTermin 112
+ PhysDevExtTermin 113
+ PhysDevExtTermin 114
+ PhysDevExtTermin 115
+ PhysDevExtTermin 116
+ PhysDevExtTermin 117
+ PhysDevExtTermin 118
+ PhysDevExtTermin 119
+ PhysDevExtTermin 120
+ PhysDevExtTermin 121
+ PhysDevExtTermin 122
+ PhysDevExtTermin 123
+ PhysDevExtTermin 124
+ PhysDevExtTermin 125
+ PhysDevExtTermin 126
+ PhysDevExtTermin 127
+ PhysDevExtTermin 128
+ PhysDevExtTermin 129
+ PhysDevExtTermin 130
+ PhysDevExtTermin 131
+ PhysDevExtTermin 132
+ PhysDevExtTermin 133
+ PhysDevExtTermin 134
+ PhysDevExtTermin 135
+ PhysDevExtTermin 136
+ PhysDevExtTermin 137
+ PhysDevExtTermin 138
+ PhysDevExtTermin 139
+ PhysDevExtTermin 140
+ PhysDevExtTermin 141
+ PhysDevExtTermin 142
+ PhysDevExtTermin 143
+ PhysDevExtTermin 144
+ PhysDevExtTermin 145
+ PhysDevExtTermin 146
+ PhysDevExtTermin 147
+ PhysDevExtTermin 148
+ PhysDevExtTermin 149
+ PhysDevExtTermin 150
+ PhysDevExtTermin 151
+ PhysDevExtTermin 152
+ PhysDevExtTermin 153
+ PhysDevExtTermin 154
+ PhysDevExtTermin 155
+ PhysDevExtTermin 156
+ PhysDevExtTermin 157
+ PhysDevExtTermin 158
+ PhysDevExtTermin 159
+ PhysDevExtTermin 160
+ PhysDevExtTermin 161
+ PhysDevExtTermin 162
+ PhysDevExtTermin 163
+ PhysDevExtTermin 164
+ PhysDevExtTermin 165
+ PhysDevExtTermin 166
+ PhysDevExtTermin 167
+ PhysDevExtTermin 168
+ PhysDevExtTermin 169
+ PhysDevExtTermin 170
+ PhysDevExtTermin 171
+ PhysDevExtTermin 172
+ PhysDevExtTermin 173
+ PhysDevExtTermin 174
+ PhysDevExtTermin 175
+ PhysDevExtTermin 176
+ PhysDevExtTermin 177
+ PhysDevExtTermin 178
+ PhysDevExtTermin 179
+ PhysDevExtTermin 180
+ PhysDevExtTermin 181
+ PhysDevExtTermin 182
+ PhysDevExtTermin 183
+ PhysDevExtTermin 184
+ PhysDevExtTermin 185
+ PhysDevExtTermin 186
+ PhysDevExtTermin 187
+ PhysDevExtTermin 188
+ PhysDevExtTermin 189
+ PhysDevExtTermin 190
+ PhysDevExtTermin 191
+ PhysDevExtTermin 192
+ PhysDevExtTermin 193
+ PhysDevExtTermin 194
+ PhysDevExtTermin 195
+ PhysDevExtTermin 196
+ PhysDevExtTermin 197
+ PhysDevExtTermin 198
+ PhysDevExtTermin 199
+ PhysDevExtTermin 200
+ PhysDevExtTermin 201
+ PhysDevExtTermin 202
+ PhysDevExtTermin 203
+ PhysDevExtTermin 204
+ PhysDevExtTermin 205
+ PhysDevExtTermin 206
+ PhysDevExtTermin 207
+ PhysDevExtTermin 208
+ PhysDevExtTermin 209
+ PhysDevExtTermin 210
+ PhysDevExtTermin 211
+ PhysDevExtTermin 212
+ PhysDevExtTermin 213
+ PhysDevExtTermin 214
+ PhysDevExtTermin 215
+ PhysDevExtTermin 216
+ PhysDevExtTermin 217
+ PhysDevExtTermin 218
+ PhysDevExtTermin 219
+ PhysDevExtTermin 220
+ PhysDevExtTermin 221
+ PhysDevExtTermin 222
+ PhysDevExtTermin 223
+ PhysDevExtTermin 224
+ PhysDevExtTermin 225
+ PhysDevExtTermin 226
+ PhysDevExtTermin 227
+ PhysDevExtTermin 228
+ PhysDevExtTermin 229
+ PhysDevExtTermin 230
+ PhysDevExtTermin 231
+ PhysDevExtTermin 232
+ PhysDevExtTermin 233
+ PhysDevExtTermin 234
+ PhysDevExtTermin 235
+ PhysDevExtTermin 236
+ PhysDevExtTermin 237
+ PhysDevExtTermin 238
+ PhysDevExtTermin 239
+ PhysDevExtTermin 240
+ PhysDevExtTermin 241
+ PhysDevExtTermin 242
+ PhysDevExtTermin 243
+ PhysDevExtTermin 244
+ PhysDevExtTermin 245
+ PhysDevExtTermin 246
+ PhysDevExtTermin 247
+ PhysDevExtTermin 248
+ PhysDevExtTermin 249
+
+ DevExtTramp 0
+ DevExtTramp 1
+ DevExtTramp 2
+ DevExtTramp 3
+ DevExtTramp 4
+ DevExtTramp 5
+ DevExtTramp 6
+ DevExtTramp 7
+ DevExtTramp 8
+ DevExtTramp 9
+ DevExtTramp 10
+ DevExtTramp 11
+ DevExtTramp 12
+ DevExtTramp 13
+ DevExtTramp 14
+ DevExtTramp 15
+ DevExtTramp 16
+ DevExtTramp 17
+ DevExtTramp 18
+ DevExtTramp 19
+ DevExtTramp 20
+ DevExtTramp 21
+ DevExtTramp 22
+ DevExtTramp 23
+ DevExtTramp 24
+ DevExtTramp 25
+ DevExtTramp 26
+ DevExtTramp 27
+ DevExtTramp 28
+ DevExtTramp 29
+ DevExtTramp 30
+ DevExtTramp 31
+ DevExtTramp 32
+ DevExtTramp 33
+ DevExtTramp 34
+ DevExtTramp 35
+ DevExtTramp 36
+ DevExtTramp 37
+ DevExtTramp 38
+ DevExtTramp 39
+ DevExtTramp 40
+ DevExtTramp 41
+ DevExtTramp 42
+ DevExtTramp 43
+ DevExtTramp 44
+ DevExtTramp 45
+ DevExtTramp 46
+ DevExtTramp 47
+ DevExtTramp 48
+ DevExtTramp 49
+ DevExtTramp 50
+ DevExtTramp 51
+ DevExtTramp 52
+ DevExtTramp 53
+ DevExtTramp 54
+ DevExtTramp 55
+ DevExtTramp 56
+ DevExtTramp 57
+ DevExtTramp 58
+ DevExtTramp 59
+ DevExtTramp 60
+ DevExtTramp 61
+ DevExtTramp 62
+ DevExtTramp 63
+ DevExtTramp 64
+ DevExtTramp 65
+ DevExtTramp 66
+ DevExtTramp 67
+ DevExtTramp 68
+ DevExtTramp 69
+ DevExtTramp 70
+ DevExtTramp 71
+ DevExtTramp 72
+ DevExtTramp 73
+ DevExtTramp 74
+ DevExtTramp 75
+ DevExtTramp 76
+ DevExtTramp 77
+ DevExtTramp 78
+ DevExtTramp 79
+ DevExtTramp 80
+ DevExtTramp 81
+ DevExtTramp 82
+ DevExtTramp 83
+ DevExtTramp 84
+ DevExtTramp 85
+ DevExtTramp 86
+ DevExtTramp 87
+ DevExtTramp 88
+ DevExtTramp 89
+ DevExtTramp 90
+ DevExtTramp 91
+ DevExtTramp 92
+ DevExtTramp 93
+ DevExtTramp 94
+ DevExtTramp 95
+ DevExtTramp 96
+ DevExtTramp 97
+ DevExtTramp 98
+ DevExtTramp 99
+ DevExtTramp 100
+ DevExtTramp 101
+ DevExtTramp 102
+ DevExtTramp 103
+ DevExtTramp 104
+ DevExtTramp 105
+ DevExtTramp 106
+ DevExtTramp 107
+ DevExtTramp 108
+ DevExtTramp 109
+ DevExtTramp 110
+ DevExtTramp 111
+ DevExtTramp 112
+ DevExtTramp 113
+ DevExtTramp 114
+ DevExtTramp 115
+ DevExtTramp 116
+ DevExtTramp 117
+ DevExtTramp 118
+ DevExtTramp 119
+ DevExtTramp 120
+ DevExtTramp 121
+ DevExtTramp 122
+ DevExtTramp 123
+ DevExtTramp 124
+ DevExtTramp 125
+ DevExtTramp 126
+ DevExtTramp 127
+ DevExtTramp 128
+ DevExtTramp 129
+ DevExtTramp 130
+ DevExtTramp 131
+ DevExtTramp 132
+ DevExtTramp 133
+ DevExtTramp 134
+ DevExtTramp 135
+ DevExtTramp 136
+ DevExtTramp 137
+ DevExtTramp 138
+ DevExtTramp 139
+ DevExtTramp 140
+ DevExtTramp 141
+ DevExtTramp 142
+ DevExtTramp 143
+ DevExtTramp 144
+ DevExtTramp 145
+ DevExtTramp 146
+ DevExtTramp 147
+ DevExtTramp 148
+ DevExtTramp 149
+ DevExtTramp 150
+ DevExtTramp 151
+ DevExtTramp 152
+ DevExtTramp 153
+ DevExtTramp 154
+ DevExtTramp 155
+ DevExtTramp 156
+ DevExtTramp 157
+ DevExtTramp 158
+ DevExtTramp 159
+ DevExtTramp 160
+ DevExtTramp 161
+ DevExtTramp 162
+ DevExtTramp 163
+ DevExtTramp 164
+ DevExtTramp 165
+ DevExtTramp 166
+ DevExtTramp 167
+ DevExtTramp 168
+ DevExtTramp 169
+ DevExtTramp 170
+ DevExtTramp 171
+ DevExtTramp 172
+ DevExtTramp 173
+ DevExtTramp 174
+ DevExtTramp 175
+ DevExtTramp 176
+ DevExtTramp 177
+ DevExtTramp 178
+ DevExtTramp 179
+ DevExtTramp 180
+ DevExtTramp 181
+ DevExtTramp 182
+ DevExtTramp 183
+ DevExtTramp 184
+ DevExtTramp 185
+ DevExtTramp 186
+ DevExtTramp 187
+ DevExtTramp 188
+ DevExtTramp 189
+ DevExtTramp 190
+ DevExtTramp 191
+ DevExtTramp 192
+ DevExtTramp 193
+ DevExtTramp 194
+ DevExtTramp 195
+ DevExtTramp 196
+ DevExtTramp 197
+ DevExtTramp 198
+ DevExtTramp 199
+ DevExtTramp 200
+ DevExtTramp 201
+ DevExtTramp 202
+ DevExtTramp 203
+ DevExtTramp 204
+ DevExtTramp 205
+ DevExtTramp 206
+ DevExtTramp 207
+ DevExtTramp 208
+ DevExtTramp 209
+ DevExtTramp 210
+ DevExtTramp 211
+ DevExtTramp 212
+ DevExtTramp 213
+ DevExtTramp 214
+ DevExtTramp 215
+ DevExtTramp 216
+ DevExtTramp 217
+ DevExtTramp 218
+ DevExtTramp 219
+ DevExtTramp 220
+ DevExtTramp 221
+ DevExtTramp 222
+ DevExtTramp 223
+ DevExtTramp 224
+ DevExtTramp 225
+ DevExtTramp 226
+ DevExtTramp 227
+ DevExtTramp 228
+ DevExtTramp 229
+ DevExtTramp 230
+ DevExtTramp 231
+ DevExtTramp 232
+ DevExtTramp 233
+ DevExtTramp 234
+ DevExtTramp 235
+ DevExtTramp 236
+ DevExtTramp 237
+ DevExtTramp 238
+ DevExtTramp 239
+ DevExtTramp 240
+ DevExtTramp 241
+ DevExtTramp 242
+ DevExtTramp 243
+ DevExtTramp 244
+ DevExtTramp 245
+ DevExtTramp 246
+ DevExtTramp 247
+ DevExtTramp 248
+ DevExtTramp 249
diff --git a/thirdparty/vulkan/loader/unknown_ext_chain_masm.asm b/thirdparty/vulkan/loader/unknown_ext_chain_masm.asm
new file mode 100644
index 0000000000..34bc7c2fc7
--- /dev/null
+++ b/thirdparty/vulkan/loader/unknown_ext_chain_masm.asm
@@ -0,0 +1,883 @@
+;
+; Copyright (c) 2017 The Khronos Group Inc.
+; Copyright (c) 2017 Valve Corporation
+; Copyright (c) 2017 LunarG, Inc.
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+; http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+;
+; Author: Lenny Komow <lenny@lunarg.com>
+;
+
+; This code is used to pass on device (including physical device) extensions through the call chain. It must do this without
+; creating a stack frame, because the actual parameters of the call are not known. Since the first parameter is known to be a
+; VkPhysicalDevice or a dispatchable object it can unwrap the object, possibly overwriting the wrapped physical device, and then
+; jump to the next function in the call chain
+
+; Codegen defines a number of values, chiefly offsets of members within structs and sizes of data types within gen_defines.asm.
+; Struct member offsets are defined in the format "XX_OFFSET_YY" where XX indicates the member within the struct and YY indicates
+; the struct type that it is a member of. Data type sizes are defined in the format "XX_SIZE" where XX indicates the data type.
+INCLUDE gen_defines.asm
+
+; 64-bit values and macro
+IFDEF rax
+
+PhysDevExtTramp macro num:req
+public vkPhysDevExtTramp&num&
+vkPhysDevExtTramp&num&:
+ mov rax, qword ptr [rcx] ; Dereference the wrapped VkPhysicalDevice to get the dispatch table in rax
+ mov rcx, qword ptr [rcx + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into rcx
+ jmp qword ptr [rax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * num))] ; Jump to the next function in the chain, preserving the args in other registers
+endm
+
+PhysDevExtTermin macro num
+public vkPhysDevExtTermin&num&
+vkPhysDevExtTermin&num&:
+ mov rax, qword ptr [rcx + ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Store the loader_icd_term* in rax
+ cmp qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))], 0 ; Check if the next function in the chain is NULL
+ je terminError&num& ; Go to the error section if it is NULL
+ mov rcx, qword ptr [rcx + PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Load the unwrapped VkPhysicalDevice into the first arg
+ jmp qword ptr [rax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))] ; Jump to the next function in the chain
+terminError&num&:
+ sub rsp, 56 ; Create the stack frame
+ mov rcx, qword ptr [rax + INSTANCE_OFFSET_ICD_TERM] ; Load the loader_instance into rcx (first arg)
+ mov rax, qword ptr [rcx + (HASH_OFFSET_INSTANCE + (HASH_SIZE * num) + FUNC_NAME_OFFSET_HASH)] ; Load the func name into rax
+ lea r9, termin_error_string ; Load the error string into r9 (fourth arg)
+ xor r8d, r8d ; Set r8 to zero (third arg)
+ mov qword ptr [rsp + 32], rax ; Move the func name onto the stack (fifth arg)
+ lea edx, [r8 + VK_DEBUG_REPORT_ERROR_BIT_EXT] ; Write the error logging bit to rdx (second arg)
+ call loader_log ; Log the error message before we crash
+ add rsp, 56 ; Clean up the stack frame
+ mov rax, 0
+ jmp rax ; Crash intentionally by jumping to address zero
+endm
+
+DevExtTramp macro num
+public vkdev_ext&num&
+vkdev_ext&num&:
+ mov rax, qword ptr [rcx] ; Dereference the handle to get the dispatch table
+ jmp qword ptr [rax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * num))] ; Jump to the appropriate call chain
+endm
+
+; 32-bit values and macro
+ELSE
+
+PhysDevExtTramp macro num
+public _vkPhysDevExtTramp&num&@4
+_vkPhysDevExtTramp&num&@4:
+ mov eax, dword ptr [esp + 4] ; Load the wrapped VkPhysicalDevice into eax
+ mov ecx, [eax + PHYS_DEV_OFFSET_PHYS_DEV_TRAMP] ; Load the unwrapped VkPhysicalDevice into ecx
+ mov [esp + 4], ecx ; Overwrite the wrapped VkPhysicalDevice with the unwrapped one (on the stack)
+ mov eax, [eax] ; Dereference the wrapped VkPhysicalDevice to get the dispatch table in eax
+ jmp dword ptr [eax + (PHYS_DEV_OFFSET_INST_DISPATCH + (PTR_SIZE * num))] ; Jump to the next function in the chain, preserving the args on the stack
+endm
+
+PhysDevExtTermin macro num
+public _vkPhysDevExtTermin&num&@4
+_vkPhysDevExtTermin&num&@4:
+ mov ecx, dword ptr [esp + 4] ; Move the wrapped VkPhysicalDevice into ecx
+ mov eax, dword ptr [ecx + ICD_TERM_OFFSET_PHYS_DEV_TERM] ; Store the loader_icd_term* in eax
+ cmp dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))], 0 ; Check if the next function in the chain is NULL
+ je terminError&num& ; Go to the error section if it is NULL
+ mov ecx, dword ptr [ecx + PHYS_DEV_OFFSET_PHYS_DEV_TERM] ; Unwrap the VkPhysicalDevice in ecx
+ mov dword ptr [esp + 4], ecx ; Copy the unwrapped VkPhysicalDevice into the first arg
+ jmp dword ptr [eax + (DISPATCH_OFFSET_ICD_TERM + (PTR_SIZE * num))] ; Jump to the next function in the chain
+terminError&num&:
+ mov eax, dword ptr [eax + INSTANCE_OFFSET_ICD_TERM] ; Load the loader_instance into eax
+ push dword ptr [eax + (HASH_OFFSET_INSTANCE + (HASH_SIZE * num) + FUNC_NAME_OFFSET_HASH)] ; Push the func name (fifth arg)
+ push offset termin_error_string ; Push the error string (fourth arg)
+ push 0 ; Push zero (third arg)
+ push VK_DEBUG_REPORT_ERROR_BIT_EXT ; Push the error logging bit (second arg)
+ push eax ; Push the loader_instance (first arg)
+ call _loader_log ; Log the error message before we crash
+ add esp, 20 ; Clean up the args
+ mov eax, 0
+ jmp eax ; Crash intentionally by jumping to address zero
+endm
+
+DevExtTramp macro num
+public _vkdev_ext&num&@4
+_vkdev_ext&num&@4:
+ mov eax, dword ptr [esp + 4] ; Dereference the handle to get the dispatch table
+ jmp dword ptr [eax + (EXT_OFFSET_DEVICE_DISPATCH + (PTR_SIZE * num))] ; Jump to the appropriate call chain
+endm
+
+; This is also needed for 32-bit only
+.model flat
+
+ENDIF
+
+.const
+ termin_error_string db 'Extension %s not supported for this physical device', 0
+
+.code
+
+IFDEF rax
+extrn loader_log:near
+ELSE
+extrn _loader_log:near
+ENDIF
+
+ PhysDevExtTramp 0
+ PhysDevExtTramp 1
+ PhysDevExtTramp 2
+ PhysDevExtTramp 3
+ PhysDevExtTramp 4
+ PhysDevExtTramp 5
+ PhysDevExtTramp 6
+ PhysDevExtTramp 7
+ PhysDevExtTramp 8
+ PhysDevExtTramp 9
+ PhysDevExtTramp 10
+ PhysDevExtTramp 11
+ PhysDevExtTramp 12
+ PhysDevExtTramp 13
+ PhysDevExtTramp 14
+ PhysDevExtTramp 15
+ PhysDevExtTramp 16
+ PhysDevExtTramp 17
+ PhysDevExtTramp 18
+ PhysDevExtTramp 19
+ PhysDevExtTramp 20
+ PhysDevExtTramp 21
+ PhysDevExtTramp 22
+ PhysDevExtTramp 23
+ PhysDevExtTramp 24
+ PhysDevExtTramp 25
+ PhysDevExtTramp 26
+ PhysDevExtTramp 27
+ PhysDevExtTramp 28
+ PhysDevExtTramp 29
+ PhysDevExtTramp 30
+ PhysDevExtTramp 31
+ PhysDevExtTramp 32
+ PhysDevExtTramp 33
+ PhysDevExtTramp 34
+ PhysDevExtTramp 35
+ PhysDevExtTramp 36
+ PhysDevExtTramp 37
+ PhysDevExtTramp 38
+ PhysDevExtTramp 39
+ PhysDevExtTramp 40
+ PhysDevExtTramp 41
+ PhysDevExtTramp 42
+ PhysDevExtTramp 43
+ PhysDevExtTramp 44
+ PhysDevExtTramp 45
+ PhysDevExtTramp 46
+ PhysDevExtTramp 47
+ PhysDevExtTramp 48
+ PhysDevExtTramp 49
+ PhysDevExtTramp 50
+ PhysDevExtTramp 51
+ PhysDevExtTramp 52
+ PhysDevExtTramp 53
+ PhysDevExtTramp 54
+ PhysDevExtTramp 55
+ PhysDevExtTramp 56
+ PhysDevExtTramp 57
+ PhysDevExtTramp 58
+ PhysDevExtTramp 59
+ PhysDevExtTramp 60
+ PhysDevExtTramp 61
+ PhysDevExtTramp 62
+ PhysDevExtTramp 63
+ PhysDevExtTramp 64
+ PhysDevExtTramp 65
+ PhysDevExtTramp 66
+ PhysDevExtTramp 67
+ PhysDevExtTramp 68
+ PhysDevExtTramp 69
+ PhysDevExtTramp 70
+ PhysDevExtTramp 71
+ PhysDevExtTramp 72
+ PhysDevExtTramp 73
+ PhysDevExtTramp 74
+ PhysDevExtTramp 75
+ PhysDevExtTramp 76
+ PhysDevExtTramp 77
+ PhysDevExtTramp 78
+ PhysDevExtTramp 79
+ PhysDevExtTramp 80
+ PhysDevExtTramp 81
+ PhysDevExtTramp 82
+ PhysDevExtTramp 83
+ PhysDevExtTramp 84
+ PhysDevExtTramp 85
+ PhysDevExtTramp 86
+ PhysDevExtTramp 87
+ PhysDevExtTramp 88
+ PhysDevExtTramp 89
+ PhysDevExtTramp 90
+ PhysDevExtTramp 91
+ PhysDevExtTramp 92
+ PhysDevExtTramp 93
+ PhysDevExtTramp 94
+ PhysDevExtTramp 95
+ PhysDevExtTramp 96
+ PhysDevExtTramp 97
+ PhysDevExtTramp 98
+ PhysDevExtTramp 99
+ PhysDevExtTramp 100
+ PhysDevExtTramp 101
+ PhysDevExtTramp 102
+ PhysDevExtTramp 103
+ PhysDevExtTramp 104
+ PhysDevExtTramp 105
+ PhysDevExtTramp 106
+ PhysDevExtTramp 107
+ PhysDevExtTramp 108
+ PhysDevExtTramp 109
+ PhysDevExtTramp 110
+ PhysDevExtTramp 111
+ PhysDevExtTramp 112
+ PhysDevExtTramp 113
+ PhysDevExtTramp 114
+ PhysDevExtTramp 115
+ PhysDevExtTramp 116
+ PhysDevExtTramp 117
+ PhysDevExtTramp 118
+ PhysDevExtTramp 119
+ PhysDevExtTramp 120
+ PhysDevExtTramp 121
+ PhysDevExtTramp 122
+ PhysDevExtTramp 123
+ PhysDevExtTramp 124
+ PhysDevExtTramp 125
+ PhysDevExtTramp 126
+ PhysDevExtTramp 127
+ PhysDevExtTramp 128
+ PhysDevExtTramp 129
+ PhysDevExtTramp 130
+ PhysDevExtTramp 131
+ PhysDevExtTramp 132
+ PhysDevExtTramp 133
+ PhysDevExtTramp 134
+ PhysDevExtTramp 135
+ PhysDevExtTramp 136
+ PhysDevExtTramp 137
+ PhysDevExtTramp 138
+ PhysDevExtTramp 139
+ PhysDevExtTramp 140
+ PhysDevExtTramp 141
+ PhysDevExtTramp 142
+ PhysDevExtTramp 143
+ PhysDevExtTramp 144
+ PhysDevExtTramp 145
+ PhysDevExtTramp 146
+ PhysDevExtTramp 147
+ PhysDevExtTramp 148
+ PhysDevExtTramp 149
+ PhysDevExtTramp 150
+ PhysDevExtTramp 151
+ PhysDevExtTramp 152
+ PhysDevExtTramp 153
+ PhysDevExtTramp 154
+ PhysDevExtTramp 155
+ PhysDevExtTramp 156
+ PhysDevExtTramp 157
+ PhysDevExtTramp 158
+ PhysDevExtTramp 159
+ PhysDevExtTramp 160
+ PhysDevExtTramp 161
+ PhysDevExtTramp 162
+ PhysDevExtTramp 163
+ PhysDevExtTramp 164
+ PhysDevExtTramp 165
+ PhysDevExtTramp 166
+ PhysDevExtTramp 167
+ PhysDevExtTramp 168
+ PhysDevExtTramp 169
+ PhysDevExtTramp 170
+ PhysDevExtTramp 171
+ PhysDevExtTramp 172
+ PhysDevExtTramp 173
+ PhysDevExtTramp 174
+ PhysDevExtTramp 175
+ PhysDevExtTramp 176
+ PhysDevExtTramp 177
+ PhysDevExtTramp 178
+ PhysDevExtTramp 179
+ PhysDevExtTramp 180
+ PhysDevExtTramp 181
+ PhysDevExtTramp 182
+ PhysDevExtTramp 183
+ PhysDevExtTramp 184
+ PhysDevExtTramp 185
+ PhysDevExtTramp 186
+ PhysDevExtTramp 187
+ PhysDevExtTramp 188
+ PhysDevExtTramp 189
+ PhysDevExtTramp 190
+ PhysDevExtTramp 191
+ PhysDevExtTramp 192
+ PhysDevExtTramp 193
+ PhysDevExtTramp 194
+ PhysDevExtTramp 195
+ PhysDevExtTramp 196
+ PhysDevExtTramp 197
+ PhysDevExtTramp 198
+ PhysDevExtTramp 199
+ PhysDevExtTramp 200
+ PhysDevExtTramp 201
+ PhysDevExtTramp 202
+ PhysDevExtTramp 203
+ PhysDevExtTramp 204
+ PhysDevExtTramp 205
+ PhysDevExtTramp 206
+ PhysDevExtTramp 207
+ PhysDevExtTramp 208
+ PhysDevExtTramp 209
+ PhysDevExtTramp 210
+ PhysDevExtTramp 211
+ PhysDevExtTramp 212
+ PhysDevExtTramp 213
+ PhysDevExtTramp 214
+ PhysDevExtTramp 215
+ PhysDevExtTramp 216
+ PhysDevExtTramp 217
+ PhysDevExtTramp 218
+ PhysDevExtTramp 219
+ PhysDevExtTramp 220
+ PhysDevExtTramp 221
+ PhysDevExtTramp 222
+ PhysDevExtTramp 223
+ PhysDevExtTramp 224
+ PhysDevExtTramp 225
+ PhysDevExtTramp 226
+ PhysDevExtTramp 227
+ PhysDevExtTramp 228
+ PhysDevExtTramp 229
+ PhysDevExtTramp 230
+ PhysDevExtTramp 231
+ PhysDevExtTramp 232
+ PhysDevExtTramp 233
+ PhysDevExtTramp 234
+ PhysDevExtTramp 235
+ PhysDevExtTramp 236
+ PhysDevExtTramp 237
+ PhysDevExtTramp 238
+ PhysDevExtTramp 239
+ PhysDevExtTramp 240
+ PhysDevExtTramp 241
+ PhysDevExtTramp 242
+ PhysDevExtTramp 243
+ PhysDevExtTramp 244
+ PhysDevExtTramp 245
+ PhysDevExtTramp 246
+ PhysDevExtTramp 247
+ PhysDevExtTramp 248
+ PhysDevExtTramp 249
+
+ PhysDevExtTermin 0
+ PhysDevExtTermin 1
+ PhysDevExtTermin 2
+ PhysDevExtTermin 3
+ PhysDevExtTermin 4
+ PhysDevExtTermin 5
+ PhysDevExtTermin 6
+ PhysDevExtTermin 7
+ PhysDevExtTermin 8
+ PhysDevExtTermin 9
+ PhysDevExtTermin 10
+ PhysDevExtTermin 11
+ PhysDevExtTermin 12
+ PhysDevExtTermin 13
+ PhysDevExtTermin 14
+ PhysDevExtTermin 15
+ PhysDevExtTermin 16
+ PhysDevExtTermin 17
+ PhysDevExtTermin 18
+ PhysDevExtTermin 19
+ PhysDevExtTermin 20
+ PhysDevExtTermin 21
+ PhysDevExtTermin 22
+ PhysDevExtTermin 23
+ PhysDevExtTermin 24
+ PhysDevExtTermin 25
+ PhysDevExtTermin 26
+ PhysDevExtTermin 27
+ PhysDevExtTermin 28
+ PhysDevExtTermin 29
+ PhysDevExtTermin 30
+ PhysDevExtTermin 31
+ PhysDevExtTermin 32
+ PhysDevExtTermin 33
+ PhysDevExtTermin 34
+ PhysDevExtTermin 35
+ PhysDevExtTermin 36
+ PhysDevExtTermin 37
+ PhysDevExtTermin 38
+ PhysDevExtTermin 39
+ PhysDevExtTermin 40
+ PhysDevExtTermin 41
+ PhysDevExtTermin 42
+ PhysDevExtTermin 43
+ PhysDevExtTermin 44
+ PhysDevExtTermin 45
+ PhysDevExtTermin 46
+ PhysDevExtTermin 47
+ PhysDevExtTermin 48
+ PhysDevExtTermin 49
+ PhysDevExtTermin 50
+ PhysDevExtTermin 51
+ PhysDevExtTermin 52
+ PhysDevExtTermin 53
+ PhysDevExtTermin 54
+ PhysDevExtTermin 55
+ PhysDevExtTermin 56
+ PhysDevExtTermin 57
+ PhysDevExtTermin 58
+ PhysDevExtTermin 59
+ PhysDevExtTermin 60
+ PhysDevExtTermin 61
+ PhysDevExtTermin 62
+ PhysDevExtTermin 63
+ PhysDevExtTermin 64
+ PhysDevExtTermin 65
+ PhysDevExtTermin 66
+ PhysDevExtTermin 67
+ PhysDevExtTermin 68
+ PhysDevExtTermin 69
+ PhysDevExtTermin 70
+ PhysDevExtTermin 71
+ PhysDevExtTermin 72
+ PhysDevExtTermin 73
+ PhysDevExtTermin 74
+ PhysDevExtTermin 75
+ PhysDevExtTermin 76
+ PhysDevExtTermin 77
+ PhysDevExtTermin 78
+ PhysDevExtTermin 79
+ PhysDevExtTermin 80
+ PhysDevExtTermin 81
+ PhysDevExtTermin 82
+ PhysDevExtTermin 83
+ PhysDevExtTermin 84
+ PhysDevExtTermin 85
+ PhysDevExtTermin 86
+ PhysDevExtTermin 87
+ PhysDevExtTermin 88
+ PhysDevExtTermin 89
+ PhysDevExtTermin 90
+ PhysDevExtTermin 91
+ PhysDevExtTermin 92
+ PhysDevExtTermin 93
+ PhysDevExtTermin 94
+ PhysDevExtTermin 95
+ PhysDevExtTermin 96
+ PhysDevExtTermin 97
+ PhysDevExtTermin 98
+ PhysDevExtTermin 99
+ PhysDevExtTermin 100
+ PhysDevExtTermin 101
+ PhysDevExtTermin 102
+ PhysDevExtTermin 103
+ PhysDevExtTermin 104
+ PhysDevExtTermin 105
+ PhysDevExtTermin 106
+ PhysDevExtTermin 107
+ PhysDevExtTermin 108
+ PhysDevExtTermin 109
+ PhysDevExtTermin 110
+ PhysDevExtTermin 111
+ PhysDevExtTermin 112
+ PhysDevExtTermin 113
+ PhysDevExtTermin 114
+ PhysDevExtTermin 115
+ PhysDevExtTermin 116
+ PhysDevExtTermin 117
+ PhysDevExtTermin 118
+ PhysDevExtTermin 119
+ PhysDevExtTermin 120
+ PhysDevExtTermin 121
+ PhysDevExtTermin 122
+ PhysDevExtTermin 123
+ PhysDevExtTermin 124
+ PhysDevExtTermin 125
+ PhysDevExtTermin 126
+ PhysDevExtTermin 127
+ PhysDevExtTermin 128
+ PhysDevExtTermin 129
+ PhysDevExtTermin 130
+ PhysDevExtTermin 131
+ PhysDevExtTermin 132
+ PhysDevExtTermin 133
+ PhysDevExtTermin 134
+ PhysDevExtTermin 135
+ PhysDevExtTermin 136
+ PhysDevExtTermin 137
+ PhysDevExtTermin 138
+ PhysDevExtTermin 139
+ PhysDevExtTermin 140
+ PhysDevExtTermin 141
+ PhysDevExtTermin 142
+ PhysDevExtTermin 143
+ PhysDevExtTermin 144
+ PhysDevExtTermin 145
+ PhysDevExtTermin 146
+ PhysDevExtTermin 147
+ PhysDevExtTermin 148
+ PhysDevExtTermin 149
+ PhysDevExtTermin 150
+ PhysDevExtTermin 151
+ PhysDevExtTermin 152
+ PhysDevExtTermin 153
+ PhysDevExtTermin 154
+ PhysDevExtTermin 155
+ PhysDevExtTermin 156
+ PhysDevExtTermin 157
+ PhysDevExtTermin 158
+ PhysDevExtTermin 159
+ PhysDevExtTermin 160
+ PhysDevExtTermin 161
+ PhysDevExtTermin 162
+ PhysDevExtTermin 163
+ PhysDevExtTermin 164
+ PhysDevExtTermin 165
+ PhysDevExtTermin 166
+ PhysDevExtTermin 167
+ PhysDevExtTermin 168
+ PhysDevExtTermin 169
+ PhysDevExtTermin 170
+ PhysDevExtTermin 171
+ PhysDevExtTermin 172
+ PhysDevExtTermin 173
+ PhysDevExtTermin 174
+ PhysDevExtTermin 175
+ PhysDevExtTermin 176
+ PhysDevExtTermin 177
+ PhysDevExtTermin 178
+ PhysDevExtTermin 179
+ PhysDevExtTermin 180
+ PhysDevExtTermin 181
+ PhysDevExtTermin 182
+ PhysDevExtTermin 183
+ PhysDevExtTermin 184
+ PhysDevExtTermin 185
+ PhysDevExtTermin 186
+ PhysDevExtTermin 187
+ PhysDevExtTermin 188
+ PhysDevExtTermin 189
+ PhysDevExtTermin 190
+ PhysDevExtTermin 191
+ PhysDevExtTermin 192
+ PhysDevExtTermin 193
+ PhysDevExtTermin 194
+ PhysDevExtTermin 195
+ PhysDevExtTermin 196
+ PhysDevExtTermin 197
+ PhysDevExtTermin 198
+ PhysDevExtTermin 199
+ PhysDevExtTermin 200
+ PhysDevExtTermin 201
+ PhysDevExtTermin 202
+ PhysDevExtTermin 203
+ PhysDevExtTermin 204
+ PhysDevExtTermin 205
+ PhysDevExtTermin 206
+ PhysDevExtTermin 207
+ PhysDevExtTermin 208
+ PhysDevExtTermin 209
+ PhysDevExtTermin 210
+ PhysDevExtTermin 211
+ PhysDevExtTermin 212
+ PhysDevExtTermin 213
+ PhysDevExtTermin 214
+ PhysDevExtTermin 215
+ PhysDevExtTermin 216
+ PhysDevExtTermin 217
+ PhysDevExtTermin 218
+ PhysDevExtTermin 219
+ PhysDevExtTermin 220
+ PhysDevExtTermin 221
+ PhysDevExtTermin 222
+ PhysDevExtTermin 223
+ PhysDevExtTermin 224
+ PhysDevExtTermin 225
+ PhysDevExtTermin 226
+ PhysDevExtTermin 227
+ PhysDevExtTermin 228
+ PhysDevExtTermin 229
+ PhysDevExtTermin 230
+ PhysDevExtTermin 231
+ PhysDevExtTermin 232
+ PhysDevExtTermin 233
+ PhysDevExtTermin 234
+ PhysDevExtTermin 235
+ PhysDevExtTermin 236
+ PhysDevExtTermin 237
+ PhysDevExtTermin 238
+ PhysDevExtTermin 239
+ PhysDevExtTermin 240
+ PhysDevExtTermin 241
+ PhysDevExtTermin 242
+ PhysDevExtTermin 243
+ PhysDevExtTermin 244
+ PhysDevExtTermin 245
+ PhysDevExtTermin 246
+ PhysDevExtTermin 247
+ PhysDevExtTermin 248
+ PhysDevExtTermin 249
+
+ DevExtTramp 0
+ DevExtTramp 1
+ DevExtTramp 2
+ DevExtTramp 3
+ DevExtTramp 4
+ DevExtTramp 5
+ DevExtTramp 6
+ DevExtTramp 7
+ DevExtTramp 8
+ DevExtTramp 9
+ DevExtTramp 10
+ DevExtTramp 11
+ DevExtTramp 12
+ DevExtTramp 13
+ DevExtTramp 14
+ DevExtTramp 15
+ DevExtTramp 16
+ DevExtTramp 17
+ DevExtTramp 18
+ DevExtTramp 19
+ DevExtTramp 20
+ DevExtTramp 21
+ DevExtTramp 22
+ DevExtTramp 23
+ DevExtTramp 24
+ DevExtTramp 25
+ DevExtTramp 26
+ DevExtTramp 27
+ DevExtTramp 28
+ DevExtTramp 29
+ DevExtTramp 30
+ DevExtTramp 31
+ DevExtTramp 32
+ DevExtTramp 33
+ DevExtTramp 34
+ DevExtTramp 35
+ DevExtTramp 36
+ DevExtTramp 37
+ DevExtTramp 38
+ DevExtTramp 39
+ DevExtTramp 40
+ DevExtTramp 41
+ DevExtTramp 42
+ DevExtTramp 43
+ DevExtTramp 44
+ DevExtTramp 45
+ DevExtTramp 46
+ DevExtTramp 47
+ DevExtTramp 48
+ DevExtTramp 49
+ DevExtTramp 50
+ DevExtTramp 51
+ DevExtTramp 52
+ DevExtTramp 53
+ DevExtTramp 54
+ DevExtTramp 55
+ DevExtTramp 56
+ DevExtTramp 57
+ DevExtTramp 58
+ DevExtTramp 59
+ DevExtTramp 60
+ DevExtTramp 61
+ DevExtTramp 62
+ DevExtTramp 63
+ DevExtTramp 64
+ DevExtTramp 65
+ DevExtTramp 66
+ DevExtTramp 67
+ DevExtTramp 68
+ DevExtTramp 69
+ DevExtTramp 70
+ DevExtTramp 71
+ DevExtTramp 72
+ DevExtTramp 73
+ DevExtTramp 74
+ DevExtTramp 75
+ DevExtTramp 76
+ DevExtTramp 77
+ DevExtTramp 78
+ DevExtTramp 79
+ DevExtTramp 80
+ DevExtTramp 81
+ DevExtTramp 82
+ DevExtTramp 83
+ DevExtTramp 84
+ DevExtTramp 85
+ DevExtTramp 86
+ DevExtTramp 87
+ DevExtTramp 88
+ DevExtTramp 89
+ DevExtTramp 90
+ DevExtTramp 91
+ DevExtTramp 92
+ DevExtTramp 93
+ DevExtTramp 94
+ DevExtTramp 95
+ DevExtTramp 96
+ DevExtTramp 97
+ DevExtTramp 98
+ DevExtTramp 99
+ DevExtTramp 100
+ DevExtTramp 101
+ DevExtTramp 102
+ DevExtTramp 103
+ DevExtTramp 104
+ DevExtTramp 105
+ DevExtTramp 106
+ DevExtTramp 107
+ DevExtTramp 108
+ DevExtTramp 109
+ DevExtTramp 110
+ DevExtTramp 111
+ DevExtTramp 112
+ DevExtTramp 113
+ DevExtTramp 114
+ DevExtTramp 115
+ DevExtTramp 116
+ DevExtTramp 117
+ DevExtTramp 118
+ DevExtTramp 119
+ DevExtTramp 120
+ DevExtTramp 121
+ DevExtTramp 122
+ DevExtTramp 123
+ DevExtTramp 124
+ DevExtTramp 125
+ DevExtTramp 126
+ DevExtTramp 127
+ DevExtTramp 128
+ DevExtTramp 129
+ DevExtTramp 130
+ DevExtTramp 131
+ DevExtTramp 132
+ DevExtTramp 133
+ DevExtTramp 134
+ DevExtTramp 135
+ DevExtTramp 136
+ DevExtTramp 137
+ DevExtTramp 138
+ DevExtTramp 139
+ DevExtTramp 140
+ DevExtTramp 141
+ DevExtTramp 142
+ DevExtTramp 143
+ DevExtTramp 144
+ DevExtTramp 145
+ DevExtTramp 146
+ DevExtTramp 147
+ DevExtTramp 148
+ DevExtTramp 149
+ DevExtTramp 150
+ DevExtTramp 151
+ DevExtTramp 152
+ DevExtTramp 153
+ DevExtTramp 154
+ DevExtTramp 155
+ DevExtTramp 156
+ DevExtTramp 157
+ DevExtTramp 158
+ DevExtTramp 159
+ DevExtTramp 160
+ DevExtTramp 161
+ DevExtTramp 162
+ DevExtTramp 163
+ DevExtTramp 164
+ DevExtTramp 165
+ DevExtTramp 166
+ DevExtTramp 167
+ DevExtTramp 168
+ DevExtTramp 169
+ DevExtTramp 170
+ DevExtTramp 171
+ DevExtTramp 172
+ DevExtTramp 173
+ DevExtTramp 174
+ DevExtTramp 175
+ DevExtTramp 176
+ DevExtTramp 177
+ DevExtTramp 178
+ DevExtTramp 179
+ DevExtTramp 180
+ DevExtTramp 181
+ DevExtTramp 182
+ DevExtTramp 183
+ DevExtTramp 184
+ DevExtTramp 185
+ DevExtTramp 186
+ DevExtTramp 187
+ DevExtTramp 188
+ DevExtTramp 189
+ DevExtTramp 190
+ DevExtTramp 191
+ DevExtTramp 192
+ DevExtTramp 193
+ DevExtTramp 194
+ DevExtTramp 195
+ DevExtTramp 196
+ DevExtTramp 197
+ DevExtTramp 198
+ DevExtTramp 199
+ DevExtTramp 200
+ DevExtTramp 201
+ DevExtTramp 202
+ DevExtTramp 203
+ DevExtTramp 204
+ DevExtTramp 205
+ DevExtTramp 206
+ DevExtTramp 207
+ DevExtTramp 208
+ DevExtTramp 209
+ DevExtTramp 210
+ DevExtTramp 211
+ DevExtTramp 212
+ DevExtTramp 213
+ DevExtTramp 214
+ DevExtTramp 215
+ DevExtTramp 216
+ DevExtTramp 217
+ DevExtTramp 218
+ DevExtTramp 219
+ DevExtTramp 220
+ DevExtTramp 221
+ DevExtTramp 222
+ DevExtTramp 223
+ DevExtTramp 224
+ DevExtTramp 225
+ DevExtTramp 226
+ DevExtTramp 227
+ DevExtTramp 228
+ DevExtTramp 229
+ DevExtTramp 230
+ DevExtTramp 231
+ DevExtTramp 232
+ DevExtTramp 233
+ DevExtTramp 234
+ DevExtTramp 235
+ DevExtTramp 236
+ DevExtTramp 237
+ DevExtTramp 238
+ DevExtTramp 239
+ DevExtTramp 240
+ DevExtTramp 241
+ DevExtTramp 242
+ DevExtTramp 243
+ DevExtTramp 244
+ DevExtTramp 245
+ DevExtTramp 246
+ DevExtTramp 247
+ DevExtTramp 248
+ DevExtTramp 249
+
+end
diff --git a/thirdparty/vulkan/loader/vk_dispatch_table_helper.h b/thirdparty/vulkan/loader/vk_dispatch_table_helper.h
new file mode 100644
index 0000000000..d934798db4
--- /dev/null
+++ b/thirdparty/vulkan/loader/vk_dispatch_table_helper.h
@@ -0,0 +1,761 @@
+#pragma once
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See dispatch_helper_generator.py for modifications
+
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ */
+
+#include <vulkan/vulkan.h>
+#include <vulkan/vk_layer.h>
+#include <string.h>
+#include "vk_layer_dispatch_table.h"
+
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetDeviceGroupPresentCapabilitiesKHR(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR* pModes) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubGetDeviceGroupPeerMemoryFeaturesKHR(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetDeviceMaskKHR(VkCommandBuffer commandBuffer, uint32_t deviceMask) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) { };
+static VKAPI_ATTR void VKAPI_CALL StubTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags) { };
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryWin32HandleKHR(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryWin32HandlePropertiesKHR(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryFdKHR(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryFdPropertiesKHR(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties) { return VK_SUCCESS; };
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubImportSemaphoreWin32HandleKHR(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetSemaphoreWin32HandleKHR(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubImportSemaphoreFdKHR(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetSemaphoreFdKHR(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateDescriptorUpdateTemplateKHR(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubDestroyDescriptorUpdateTemplateKHR(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator) { };
+static VKAPI_ATTR void VKAPI_CALL StubUpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdBeginRenderPass2KHR(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfoKHR* pSubpassBeginInfo) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdNextSubpass2KHR(VkCommandBuffer commandBuffer, const VkSubpassBeginInfoKHR* pSubpassBeginInfo, const VkSubpassEndInfoKHR* pSubpassEndInfo) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdEndRenderPass2KHR(VkCommandBuffer commandBuffer, const VkSubpassEndInfoKHR* pSubpassEndInfo) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapchain) { return VK_SUCCESS; };
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubImportFenceWin32HandleKHR(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetFenceWin32HandleKHR(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubImportFenceFdKHR(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetFenceFdKHR(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubGetImageMemoryRequirements2KHR(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements) { };
+static VKAPI_ATTR void VKAPI_CALL StubGetBufferMemoryRequirements2KHR(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements) { };
+static VKAPI_ATTR void VKAPI_CALL StubGetImageSparseMemoryRequirements2KHR(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateSamplerYcbcrConversionKHR(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubDestroySamplerYcbcrConversionKHR(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubBindBufferMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubGetDescriptorSetLayoutSupportKHR(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetSemaphoreCounterValueKHR(VkDevice device, VkSemaphore semaphore, uint64_t* pValue) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubWaitSemaphoresKHR(VkDevice device, const VkSemaphoreWaitInfoKHR* pWaitInfo, uint64_t timeout) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubSignalSemaphoreKHR(VkDevice device, const VkSemaphoreSignalInfoKHR* pSignalInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutablePropertiesKHR(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutableStatisticsKHR(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPipelineExecutableInternalRepresentationsKHR(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubDebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubDebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdEndTransformFeedbackEXT(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdBeginQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride) { };
+static VKAPI_ATTR void VKAPI_CALL StubGetImageViewHandleNVX(VkDevice device, const VkImageViewHandleInfoNVX* pInfo) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawIndexedIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetShaderInfoAMD(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo) { return VK_SUCCESS; };
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR void VKAPI_CALL StubCmdBeginConditionalRenderingEXT(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdProcessCommandsNVX(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdReserveSpaceForCommandsNVX(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateIndirectCommandsLayoutNVX(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubDestroyIndirectCommandsLayoutNVX(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, const VkAllocationCallbacks* pAllocator) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateObjectTableNVX(VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkObjectTableNVX* pObjectTable) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubDestroyObjectTableNVX(VkDevice device, VkObjectTableNVX objectTable, const VkAllocationCallbacks* pAllocator) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubRegisterObjectsNVX(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectTableEntryNVX* const* ppObjectTableEntries, const uint32_t* pObjectIndices) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubUnregisterObjectsNVX(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectEntryTypeNVX* pObjectEntryTypes, const uint32_t* pObjectIndices) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetViewportWScalingNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubDisplayPowerControlEXT(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubRegisterDeviceEventEXT(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubRegisterDisplayEventEXT(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetSwapchainCounterEXT(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetDiscardRectangleEXT(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles) { };
+static VKAPI_ATTR void VKAPI_CALL StubSetHdrMetadataEXT(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata) { };
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetAndroidHardwareBufferPropertiesANDROID(VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryAndroidHardwareBufferANDROID(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT* pSampleLocationsInfo) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetImageDrmFormatModifierPropertiesEXT(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateValidationCacheEXT(VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubDestroyValidationCacheEXT(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubMergeValidationCachesEXT(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetValidationCacheDataEXT(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdBindShadingRateImageNV(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateAccelerationStructureNV(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubDestroyAccelerationStructureNV(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator) { };
+static VKAPI_ATTR void VKAPI_CALL StubGetAccelerationStructureMemoryRequirementsNV(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdCopyAccelerationStructureNV(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeNV mode) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetRayTracingShaderGroupHandlesNV(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetAccelerationStructureHandleNV(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdWriteAccelerationStructuresPropertiesNV(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCompileDeferredNV(VkDevice device, VkPipeline pipeline, uint32_t shader) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetMemoryHostPointerPropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHostPointer, VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetCalibratedTimestampsEXT(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoEXT* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors) { };
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetCheckpointNV(VkCommandBuffer commandBuffer, const void* pCheckpointMarker) { };
+static VKAPI_ATTR void VKAPI_CALL StubGetQueueCheckpointDataNV(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubInitializePerformanceApiINTEL(VkDevice device, const VkInitializePerformanceApiInfoINTEL* pInitializeInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubUninitializePerformanceApiINTEL(VkDevice device) { };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCmdSetPerformanceMarkerINTEL(VkCommandBuffer commandBuffer, const VkPerformanceMarkerInfoINTEL* pMarkerInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCmdSetPerformanceStreamMarkerINTEL(VkCommandBuffer commandBuffer, const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubCmdSetPerformanceOverrideINTEL(VkCommandBuffer commandBuffer, const VkPerformanceOverrideInfoINTEL* pOverrideInfo) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubAcquirePerformanceConfigurationINTEL(VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo, VkPerformanceConfigurationINTEL* pConfiguration) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubReleasePerformanceConfigurationINTEL(VkDevice device, VkPerformanceConfigurationINTEL configuration) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubQueueSetPerformanceConfigurationINTEL(VkQueue queue, VkPerformanceConfigurationINTEL configuration) { return VK_SUCCESS; };
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetPerformanceParameterINTEL(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue) { return VK_SUCCESS; };
+static VKAPI_ATTR void VKAPI_CALL StubSetLocalDimmingAMD(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable) { };
+static VKAPI_ATTR void VKAPI_CALL StubGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfoEXT* pInfo) { };
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubAcquireFullScreenExclusiveModeEXT(VkDevice device, VkSwapchainKHR swapchain) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubReleaseFullScreenExclusiveModeEXT(VkDevice device, VkSwapchainKHR swapchain) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR VkResult VKAPI_CALL StubGetDeviceGroupSurfacePresentModes2EXT(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes) { return VK_SUCCESS; };
+#endif // VK_USE_PLATFORM_WIN32_KHR
+static VKAPI_ATTR void VKAPI_CALL StubCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern) { };
+static VKAPI_ATTR void VKAPI_CALL StubResetQueryPoolEXT(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) { };
+
+
+
+static inline void layer_init_device_dispatch_table(VkDevice device, VkLayerDispatchTable *table, PFN_vkGetDeviceProcAddr gpa) {
+ memset(table, 0, sizeof(*table));
+ // Device function pointers
+ table->GetDeviceProcAddr = gpa;
+ table->DestroyDevice = (PFN_vkDestroyDevice) gpa(device, "vkDestroyDevice");
+ table->GetDeviceQueue = (PFN_vkGetDeviceQueue) gpa(device, "vkGetDeviceQueue");
+ table->QueueSubmit = (PFN_vkQueueSubmit) gpa(device, "vkQueueSubmit");
+ table->QueueWaitIdle = (PFN_vkQueueWaitIdle) gpa(device, "vkQueueWaitIdle");
+ table->DeviceWaitIdle = (PFN_vkDeviceWaitIdle) gpa(device, "vkDeviceWaitIdle");
+ table->AllocateMemory = (PFN_vkAllocateMemory) gpa(device, "vkAllocateMemory");
+ table->FreeMemory = (PFN_vkFreeMemory) gpa(device, "vkFreeMemory");
+ table->MapMemory = (PFN_vkMapMemory) gpa(device, "vkMapMemory");
+ table->UnmapMemory = (PFN_vkUnmapMemory) gpa(device, "vkUnmapMemory");
+ table->FlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) gpa(device, "vkFlushMappedMemoryRanges");
+ table->InvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) gpa(device, "vkInvalidateMappedMemoryRanges");
+ table->GetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) gpa(device, "vkGetDeviceMemoryCommitment");
+ table->BindBufferMemory = (PFN_vkBindBufferMemory) gpa(device, "vkBindBufferMemory");
+ table->BindImageMemory = (PFN_vkBindImageMemory) gpa(device, "vkBindImageMemory");
+ table->GetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) gpa(device, "vkGetBufferMemoryRequirements");
+ table->GetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) gpa(device, "vkGetImageMemoryRequirements");
+ table->GetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) gpa(device, "vkGetImageSparseMemoryRequirements");
+ table->QueueBindSparse = (PFN_vkQueueBindSparse) gpa(device, "vkQueueBindSparse");
+ table->CreateFence = (PFN_vkCreateFence) gpa(device, "vkCreateFence");
+ table->DestroyFence = (PFN_vkDestroyFence) gpa(device, "vkDestroyFence");
+ table->ResetFences = (PFN_vkResetFences) gpa(device, "vkResetFences");
+ table->GetFenceStatus = (PFN_vkGetFenceStatus) gpa(device, "vkGetFenceStatus");
+ table->WaitForFences = (PFN_vkWaitForFences) gpa(device, "vkWaitForFences");
+ table->CreateSemaphore = (PFN_vkCreateSemaphore) gpa(device, "vkCreateSemaphore");
+ table->DestroySemaphore = (PFN_vkDestroySemaphore) gpa(device, "vkDestroySemaphore");
+ table->CreateEvent = (PFN_vkCreateEvent) gpa(device, "vkCreateEvent");
+ table->DestroyEvent = (PFN_vkDestroyEvent) gpa(device, "vkDestroyEvent");
+ table->GetEventStatus = (PFN_vkGetEventStatus) gpa(device, "vkGetEventStatus");
+ table->SetEvent = (PFN_vkSetEvent) gpa(device, "vkSetEvent");
+ table->ResetEvent = (PFN_vkResetEvent) gpa(device, "vkResetEvent");
+ table->CreateQueryPool = (PFN_vkCreateQueryPool) gpa(device, "vkCreateQueryPool");
+ table->DestroyQueryPool = (PFN_vkDestroyQueryPool) gpa(device, "vkDestroyQueryPool");
+ table->GetQueryPoolResults = (PFN_vkGetQueryPoolResults) gpa(device, "vkGetQueryPoolResults");
+ table->CreateBuffer = (PFN_vkCreateBuffer) gpa(device, "vkCreateBuffer");
+ table->DestroyBuffer = (PFN_vkDestroyBuffer) gpa(device, "vkDestroyBuffer");
+ table->CreateBufferView = (PFN_vkCreateBufferView) gpa(device, "vkCreateBufferView");
+ table->DestroyBufferView = (PFN_vkDestroyBufferView) gpa(device, "vkDestroyBufferView");
+ table->CreateImage = (PFN_vkCreateImage) gpa(device, "vkCreateImage");
+ table->DestroyImage = (PFN_vkDestroyImage) gpa(device, "vkDestroyImage");
+ table->GetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) gpa(device, "vkGetImageSubresourceLayout");
+ table->CreateImageView = (PFN_vkCreateImageView) gpa(device, "vkCreateImageView");
+ table->DestroyImageView = (PFN_vkDestroyImageView) gpa(device, "vkDestroyImageView");
+ table->CreateShaderModule = (PFN_vkCreateShaderModule) gpa(device, "vkCreateShaderModule");
+ table->DestroyShaderModule = (PFN_vkDestroyShaderModule) gpa(device, "vkDestroyShaderModule");
+ table->CreatePipelineCache = (PFN_vkCreatePipelineCache) gpa(device, "vkCreatePipelineCache");
+ table->DestroyPipelineCache = (PFN_vkDestroyPipelineCache) gpa(device, "vkDestroyPipelineCache");
+ table->GetPipelineCacheData = (PFN_vkGetPipelineCacheData) gpa(device, "vkGetPipelineCacheData");
+ table->MergePipelineCaches = (PFN_vkMergePipelineCaches) gpa(device, "vkMergePipelineCaches");
+ table->CreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) gpa(device, "vkCreateGraphicsPipelines");
+ table->CreateComputePipelines = (PFN_vkCreateComputePipelines) gpa(device, "vkCreateComputePipelines");
+ table->DestroyPipeline = (PFN_vkDestroyPipeline) gpa(device, "vkDestroyPipeline");
+ table->CreatePipelineLayout = (PFN_vkCreatePipelineLayout) gpa(device, "vkCreatePipelineLayout");
+ table->DestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) gpa(device, "vkDestroyPipelineLayout");
+ table->CreateSampler = (PFN_vkCreateSampler) gpa(device, "vkCreateSampler");
+ table->DestroySampler = (PFN_vkDestroySampler) gpa(device, "vkDestroySampler");
+ table->CreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) gpa(device, "vkCreateDescriptorSetLayout");
+ table->DestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) gpa(device, "vkDestroyDescriptorSetLayout");
+ table->CreateDescriptorPool = (PFN_vkCreateDescriptorPool) gpa(device, "vkCreateDescriptorPool");
+ table->DestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) gpa(device, "vkDestroyDescriptorPool");
+ table->ResetDescriptorPool = (PFN_vkResetDescriptorPool) gpa(device, "vkResetDescriptorPool");
+ table->AllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) gpa(device, "vkAllocateDescriptorSets");
+ table->FreeDescriptorSets = (PFN_vkFreeDescriptorSets) gpa(device, "vkFreeDescriptorSets");
+ table->UpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) gpa(device, "vkUpdateDescriptorSets");
+ table->CreateFramebuffer = (PFN_vkCreateFramebuffer) gpa(device, "vkCreateFramebuffer");
+ table->DestroyFramebuffer = (PFN_vkDestroyFramebuffer) gpa(device, "vkDestroyFramebuffer");
+ table->CreateRenderPass = (PFN_vkCreateRenderPass) gpa(device, "vkCreateRenderPass");
+ table->DestroyRenderPass = (PFN_vkDestroyRenderPass) gpa(device, "vkDestroyRenderPass");
+ table->GetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) gpa(device, "vkGetRenderAreaGranularity");
+ table->CreateCommandPool = (PFN_vkCreateCommandPool) gpa(device, "vkCreateCommandPool");
+ table->DestroyCommandPool = (PFN_vkDestroyCommandPool) gpa(device, "vkDestroyCommandPool");
+ table->ResetCommandPool = (PFN_vkResetCommandPool) gpa(device, "vkResetCommandPool");
+ table->AllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) gpa(device, "vkAllocateCommandBuffers");
+ table->FreeCommandBuffers = (PFN_vkFreeCommandBuffers) gpa(device, "vkFreeCommandBuffers");
+ table->BeginCommandBuffer = (PFN_vkBeginCommandBuffer) gpa(device, "vkBeginCommandBuffer");
+ table->EndCommandBuffer = (PFN_vkEndCommandBuffer) gpa(device, "vkEndCommandBuffer");
+ table->ResetCommandBuffer = (PFN_vkResetCommandBuffer) gpa(device, "vkResetCommandBuffer");
+ table->CmdBindPipeline = (PFN_vkCmdBindPipeline) gpa(device, "vkCmdBindPipeline");
+ table->CmdSetViewport = (PFN_vkCmdSetViewport) gpa(device, "vkCmdSetViewport");
+ table->CmdSetScissor = (PFN_vkCmdSetScissor) gpa(device, "vkCmdSetScissor");
+ table->CmdSetLineWidth = (PFN_vkCmdSetLineWidth) gpa(device, "vkCmdSetLineWidth");
+ table->CmdSetDepthBias = (PFN_vkCmdSetDepthBias) gpa(device, "vkCmdSetDepthBias");
+ table->CmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) gpa(device, "vkCmdSetBlendConstants");
+ table->CmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) gpa(device, "vkCmdSetDepthBounds");
+ table->CmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) gpa(device, "vkCmdSetStencilCompareMask");
+ table->CmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) gpa(device, "vkCmdSetStencilWriteMask");
+ table->CmdSetStencilReference = (PFN_vkCmdSetStencilReference) gpa(device, "vkCmdSetStencilReference");
+ table->CmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) gpa(device, "vkCmdBindDescriptorSets");
+ table->CmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) gpa(device, "vkCmdBindIndexBuffer");
+ table->CmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) gpa(device, "vkCmdBindVertexBuffers");
+ table->CmdDraw = (PFN_vkCmdDraw) gpa(device, "vkCmdDraw");
+ table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed) gpa(device, "vkCmdDrawIndexed");
+ table->CmdDrawIndirect = (PFN_vkCmdDrawIndirect) gpa(device, "vkCmdDrawIndirect");
+ table->CmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) gpa(device, "vkCmdDrawIndexedIndirect");
+ table->CmdDispatch = (PFN_vkCmdDispatch) gpa(device, "vkCmdDispatch");
+ table->CmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) gpa(device, "vkCmdDispatchIndirect");
+ table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer) gpa(device, "vkCmdCopyBuffer");
+ table->CmdCopyImage = (PFN_vkCmdCopyImage) gpa(device, "vkCmdCopyImage");
+ table->CmdBlitImage = (PFN_vkCmdBlitImage) gpa(device, "vkCmdBlitImage");
+ table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) gpa(device, "vkCmdCopyBufferToImage");
+ table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) gpa(device, "vkCmdCopyImageToBuffer");
+ table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) gpa(device, "vkCmdUpdateBuffer");
+ table->CmdFillBuffer = (PFN_vkCmdFillBuffer) gpa(device, "vkCmdFillBuffer");
+ table->CmdClearColorImage = (PFN_vkCmdClearColorImage) gpa(device, "vkCmdClearColorImage");
+ table->CmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) gpa(device, "vkCmdClearDepthStencilImage");
+ table->CmdClearAttachments = (PFN_vkCmdClearAttachments) gpa(device, "vkCmdClearAttachments");
+ table->CmdResolveImage = (PFN_vkCmdResolveImage) gpa(device, "vkCmdResolveImage");
+ table->CmdSetEvent = (PFN_vkCmdSetEvent) gpa(device, "vkCmdSetEvent");
+ table->CmdResetEvent = (PFN_vkCmdResetEvent) gpa(device, "vkCmdResetEvent");
+ table->CmdWaitEvents = (PFN_vkCmdWaitEvents) gpa(device, "vkCmdWaitEvents");
+ table->CmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) gpa(device, "vkCmdPipelineBarrier");
+ table->CmdBeginQuery = (PFN_vkCmdBeginQuery) gpa(device, "vkCmdBeginQuery");
+ table->CmdEndQuery = (PFN_vkCmdEndQuery) gpa(device, "vkCmdEndQuery");
+ table->CmdResetQueryPool = (PFN_vkCmdResetQueryPool) gpa(device, "vkCmdResetQueryPool");
+ table->CmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) gpa(device, "vkCmdWriteTimestamp");
+ table->CmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) gpa(device, "vkCmdCopyQueryPoolResults");
+ table->CmdPushConstants = (PFN_vkCmdPushConstants) gpa(device, "vkCmdPushConstants");
+ table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) gpa(device, "vkCmdBeginRenderPass");
+ table->CmdNextSubpass = (PFN_vkCmdNextSubpass) gpa(device, "vkCmdNextSubpass");
+ table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass) gpa(device, "vkCmdEndRenderPass");
+ table->CmdExecuteCommands = (PFN_vkCmdExecuteCommands) gpa(device, "vkCmdExecuteCommands");
+ table->BindBufferMemory2 = (PFN_vkBindBufferMemory2) gpa(device, "vkBindBufferMemory2");
+ table->BindImageMemory2 = (PFN_vkBindImageMemory2) gpa(device, "vkBindImageMemory2");
+ table->GetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) gpa(device, "vkGetDeviceGroupPeerMemoryFeatures");
+ table->CmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) gpa(device, "vkCmdSetDeviceMask");
+ table->CmdDispatchBase = (PFN_vkCmdDispatchBase) gpa(device, "vkCmdDispatchBase");
+ table->GetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) gpa(device, "vkGetImageMemoryRequirements2");
+ table->GetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) gpa(device, "vkGetBufferMemoryRequirements2");
+ table->GetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) gpa(device, "vkGetImageSparseMemoryRequirements2");
+ table->TrimCommandPool = (PFN_vkTrimCommandPool) gpa(device, "vkTrimCommandPool");
+ table->GetDeviceQueue2 = (PFN_vkGetDeviceQueue2) gpa(device, "vkGetDeviceQueue2");
+ table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) gpa(device, "vkCreateSamplerYcbcrConversion");
+ table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) gpa(device, "vkDestroySamplerYcbcrConversion");
+ table->CreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) gpa(device, "vkCreateDescriptorUpdateTemplate");
+ table->DestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) gpa(device, "vkDestroyDescriptorUpdateTemplate");
+ table->UpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) gpa(device, "vkUpdateDescriptorSetWithTemplate");
+ table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) gpa(device, "vkGetDescriptorSetLayoutSupport");
+ table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
+ if (table->CreateSwapchainKHR == nullptr) { table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)StubCreateSwapchainKHR; }
+ table->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
+ if (table->DestroySwapchainKHR == nullptr) { table->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)StubDestroySwapchainKHR; }
+ table->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
+ if (table->GetSwapchainImagesKHR == nullptr) { table->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)StubGetSwapchainImagesKHR; }
+ table->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
+ if (table->AcquireNextImageKHR == nullptr) { table->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)StubAcquireNextImageKHR; }
+ table->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
+ if (table->QueuePresentKHR == nullptr) { table->QueuePresentKHR = (PFN_vkQueuePresentKHR)StubQueuePresentKHR; }
+ table->GetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) gpa(device, "vkGetDeviceGroupPresentCapabilitiesKHR");
+ if (table->GetDeviceGroupPresentCapabilitiesKHR == nullptr) { table->GetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)StubGetDeviceGroupPresentCapabilitiesKHR; }
+ table->GetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) gpa(device, "vkGetDeviceGroupSurfacePresentModesKHR");
+ if (table->GetDeviceGroupSurfacePresentModesKHR == nullptr) { table->GetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)StubGetDeviceGroupSurfacePresentModesKHR; }
+ table->AcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) gpa(device, "vkAcquireNextImage2KHR");
+ if (table->AcquireNextImage2KHR == nullptr) { table->AcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR)StubAcquireNextImage2KHR; }
+ table->CreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR) gpa(device, "vkCreateSharedSwapchainsKHR");
+ if (table->CreateSharedSwapchainsKHR == nullptr) { table->CreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)StubCreateSharedSwapchainsKHR; }
+ table->GetDeviceGroupPeerMemoryFeaturesKHR = (PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR) gpa(device, "vkGetDeviceGroupPeerMemoryFeaturesKHR");
+ if (table->GetDeviceGroupPeerMemoryFeaturesKHR == nullptr) { table->GetDeviceGroupPeerMemoryFeaturesKHR = (PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)StubGetDeviceGroupPeerMemoryFeaturesKHR; }
+ table->CmdSetDeviceMaskKHR = (PFN_vkCmdSetDeviceMaskKHR) gpa(device, "vkCmdSetDeviceMaskKHR");
+ if (table->CmdSetDeviceMaskKHR == nullptr) { table->CmdSetDeviceMaskKHR = (PFN_vkCmdSetDeviceMaskKHR)StubCmdSetDeviceMaskKHR; }
+ table->CmdDispatchBaseKHR = (PFN_vkCmdDispatchBaseKHR) gpa(device, "vkCmdDispatchBaseKHR");
+ if (table->CmdDispatchBaseKHR == nullptr) { table->CmdDispatchBaseKHR = (PFN_vkCmdDispatchBaseKHR)StubCmdDispatchBaseKHR; }
+ table->TrimCommandPoolKHR = (PFN_vkTrimCommandPoolKHR) gpa(device, "vkTrimCommandPoolKHR");
+ if (table->TrimCommandPoolKHR == nullptr) { table->TrimCommandPoolKHR = (PFN_vkTrimCommandPoolKHR)StubTrimCommandPoolKHR; }
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR) gpa(device, "vkGetMemoryWin32HandleKHR");
+ if (table->GetMemoryWin32HandleKHR == nullptr) { table->GetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)StubGetMemoryWin32HandleKHR; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetMemoryWin32HandlePropertiesKHR = (PFN_vkGetMemoryWin32HandlePropertiesKHR) gpa(device, "vkGetMemoryWin32HandlePropertiesKHR");
+ if (table->GetMemoryWin32HandlePropertiesKHR == nullptr) { table->GetMemoryWin32HandlePropertiesKHR = (PFN_vkGetMemoryWin32HandlePropertiesKHR)StubGetMemoryWin32HandlePropertiesKHR; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ table->GetMemoryFdKHR = (PFN_vkGetMemoryFdKHR) gpa(device, "vkGetMemoryFdKHR");
+ if (table->GetMemoryFdKHR == nullptr) { table->GetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)StubGetMemoryFdKHR; }
+ table->GetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR) gpa(device, "vkGetMemoryFdPropertiesKHR");
+ if (table->GetMemoryFdPropertiesKHR == nullptr) { table->GetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR)StubGetMemoryFdPropertiesKHR; }
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->ImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR) gpa(device, "vkImportSemaphoreWin32HandleKHR");
+ if (table->ImportSemaphoreWin32HandleKHR == nullptr) { table->ImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR)StubImportSemaphoreWin32HandleKHR; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR) gpa(device, "vkGetSemaphoreWin32HandleKHR");
+ if (table->GetSemaphoreWin32HandleKHR == nullptr) { table->GetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR)StubGetSemaphoreWin32HandleKHR; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ table->ImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR) gpa(device, "vkImportSemaphoreFdKHR");
+ if (table->ImportSemaphoreFdKHR == nullptr) { table->ImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)StubImportSemaphoreFdKHR; }
+ table->GetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR) gpa(device, "vkGetSemaphoreFdKHR");
+ if (table->GetSemaphoreFdKHR == nullptr) { table->GetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)StubGetSemaphoreFdKHR; }
+ table->CmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR) gpa(device, "vkCmdPushDescriptorSetKHR");
+ if (table->CmdPushDescriptorSetKHR == nullptr) { table->CmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)StubCmdPushDescriptorSetKHR; }
+ table->CmdPushDescriptorSetWithTemplateKHR = (PFN_vkCmdPushDescriptorSetWithTemplateKHR) gpa(device, "vkCmdPushDescriptorSetWithTemplateKHR");
+ if (table->CmdPushDescriptorSetWithTemplateKHR == nullptr) { table->CmdPushDescriptorSetWithTemplateKHR = (PFN_vkCmdPushDescriptorSetWithTemplateKHR)StubCmdPushDescriptorSetWithTemplateKHR; }
+ table->CreateDescriptorUpdateTemplateKHR = (PFN_vkCreateDescriptorUpdateTemplateKHR) gpa(device, "vkCreateDescriptorUpdateTemplateKHR");
+ if (table->CreateDescriptorUpdateTemplateKHR == nullptr) { table->CreateDescriptorUpdateTemplateKHR = (PFN_vkCreateDescriptorUpdateTemplateKHR)StubCreateDescriptorUpdateTemplateKHR; }
+ table->DestroyDescriptorUpdateTemplateKHR = (PFN_vkDestroyDescriptorUpdateTemplateKHR) gpa(device, "vkDestroyDescriptorUpdateTemplateKHR");
+ if (table->DestroyDescriptorUpdateTemplateKHR == nullptr) { table->DestroyDescriptorUpdateTemplateKHR = (PFN_vkDestroyDescriptorUpdateTemplateKHR)StubDestroyDescriptorUpdateTemplateKHR; }
+ table->UpdateDescriptorSetWithTemplateKHR = (PFN_vkUpdateDescriptorSetWithTemplateKHR) gpa(device, "vkUpdateDescriptorSetWithTemplateKHR");
+ if (table->UpdateDescriptorSetWithTemplateKHR == nullptr) { table->UpdateDescriptorSetWithTemplateKHR = (PFN_vkUpdateDescriptorSetWithTemplateKHR)StubUpdateDescriptorSetWithTemplateKHR; }
+ table->CreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR) gpa(device, "vkCreateRenderPass2KHR");
+ if (table->CreateRenderPass2KHR == nullptr) { table->CreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)StubCreateRenderPass2KHR; }
+ table->CmdBeginRenderPass2KHR = (PFN_vkCmdBeginRenderPass2KHR) gpa(device, "vkCmdBeginRenderPass2KHR");
+ if (table->CmdBeginRenderPass2KHR == nullptr) { table->CmdBeginRenderPass2KHR = (PFN_vkCmdBeginRenderPass2KHR)StubCmdBeginRenderPass2KHR; }
+ table->CmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR) gpa(device, "vkCmdNextSubpass2KHR");
+ if (table->CmdNextSubpass2KHR == nullptr) { table->CmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)StubCmdNextSubpass2KHR; }
+ table->CmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR) gpa(device, "vkCmdEndRenderPass2KHR");
+ if (table->CmdEndRenderPass2KHR == nullptr) { table->CmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)StubCmdEndRenderPass2KHR; }
+ table->GetSwapchainStatusKHR = (PFN_vkGetSwapchainStatusKHR) gpa(device, "vkGetSwapchainStatusKHR");
+ if (table->GetSwapchainStatusKHR == nullptr) { table->GetSwapchainStatusKHR = (PFN_vkGetSwapchainStatusKHR)StubGetSwapchainStatusKHR; }
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->ImportFenceWin32HandleKHR = (PFN_vkImportFenceWin32HandleKHR) gpa(device, "vkImportFenceWin32HandleKHR");
+ if (table->ImportFenceWin32HandleKHR == nullptr) { table->ImportFenceWin32HandleKHR = (PFN_vkImportFenceWin32HandleKHR)StubImportFenceWin32HandleKHR; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR) gpa(device, "vkGetFenceWin32HandleKHR");
+ if (table->GetFenceWin32HandleKHR == nullptr) { table->GetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR)StubGetFenceWin32HandleKHR; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ table->ImportFenceFdKHR = (PFN_vkImportFenceFdKHR) gpa(device, "vkImportFenceFdKHR");
+ if (table->ImportFenceFdKHR == nullptr) { table->ImportFenceFdKHR = (PFN_vkImportFenceFdKHR)StubImportFenceFdKHR; }
+ table->GetFenceFdKHR = (PFN_vkGetFenceFdKHR) gpa(device, "vkGetFenceFdKHR");
+ if (table->GetFenceFdKHR == nullptr) { table->GetFenceFdKHR = (PFN_vkGetFenceFdKHR)StubGetFenceFdKHR; }
+ table->GetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR) gpa(device, "vkGetImageMemoryRequirements2KHR");
+ if (table->GetImageMemoryRequirements2KHR == nullptr) { table->GetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR)StubGetImageMemoryRequirements2KHR; }
+ table->GetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2KHR) gpa(device, "vkGetBufferMemoryRequirements2KHR");
+ if (table->GetBufferMemoryRequirements2KHR == nullptr) { table->GetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2KHR)StubGetBufferMemoryRequirements2KHR; }
+ table->GetImageSparseMemoryRequirements2KHR = (PFN_vkGetImageSparseMemoryRequirements2KHR) gpa(device, "vkGetImageSparseMemoryRequirements2KHR");
+ if (table->GetImageSparseMemoryRequirements2KHR == nullptr) { table->GetImageSparseMemoryRequirements2KHR = (PFN_vkGetImageSparseMemoryRequirements2KHR)StubGetImageSparseMemoryRequirements2KHR; }
+ table->CreateSamplerYcbcrConversionKHR = (PFN_vkCreateSamplerYcbcrConversionKHR) gpa(device, "vkCreateSamplerYcbcrConversionKHR");
+ if (table->CreateSamplerYcbcrConversionKHR == nullptr) { table->CreateSamplerYcbcrConversionKHR = (PFN_vkCreateSamplerYcbcrConversionKHR)StubCreateSamplerYcbcrConversionKHR; }
+ table->DestroySamplerYcbcrConversionKHR = (PFN_vkDestroySamplerYcbcrConversionKHR) gpa(device, "vkDestroySamplerYcbcrConversionKHR");
+ if (table->DestroySamplerYcbcrConversionKHR == nullptr) { table->DestroySamplerYcbcrConversionKHR = (PFN_vkDestroySamplerYcbcrConversionKHR)StubDestroySamplerYcbcrConversionKHR; }
+ table->BindBufferMemory2KHR = (PFN_vkBindBufferMemory2KHR) gpa(device, "vkBindBufferMemory2KHR");
+ if (table->BindBufferMemory2KHR == nullptr) { table->BindBufferMemory2KHR = (PFN_vkBindBufferMemory2KHR)StubBindBufferMemory2KHR; }
+ table->BindImageMemory2KHR = (PFN_vkBindImageMemory2KHR) gpa(device, "vkBindImageMemory2KHR");
+ if (table->BindImageMemory2KHR == nullptr) { table->BindImageMemory2KHR = (PFN_vkBindImageMemory2KHR)StubBindImageMemory2KHR; }
+ table->GetDescriptorSetLayoutSupportKHR = (PFN_vkGetDescriptorSetLayoutSupportKHR) gpa(device, "vkGetDescriptorSetLayoutSupportKHR");
+ if (table->GetDescriptorSetLayoutSupportKHR == nullptr) { table->GetDescriptorSetLayoutSupportKHR = (PFN_vkGetDescriptorSetLayoutSupportKHR)StubGetDescriptorSetLayoutSupportKHR; }
+ table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR) gpa(device, "vkCmdDrawIndirectCountKHR");
+ if (table->CmdDrawIndirectCountKHR == nullptr) { table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)StubCmdDrawIndirectCountKHR; }
+ table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR) gpa(device, "vkCmdDrawIndexedIndirectCountKHR");
+ if (table->CmdDrawIndexedIndirectCountKHR == nullptr) { table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)StubCmdDrawIndexedIndirectCountKHR; }
+ table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR) gpa(device, "vkGetSemaphoreCounterValueKHR");
+ if (table->GetSemaphoreCounterValueKHR == nullptr) { table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)StubGetSemaphoreCounterValueKHR; }
+ table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR) gpa(device, "vkWaitSemaphoresKHR");
+ if (table->WaitSemaphoresKHR == nullptr) { table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)StubWaitSemaphoresKHR; }
+ table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR) gpa(device, "vkSignalSemaphoreKHR");
+ if (table->SignalSemaphoreKHR == nullptr) { table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)StubSignalSemaphoreKHR; }
+ table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR) gpa(device, "vkGetPipelineExecutablePropertiesKHR");
+ if (table->GetPipelineExecutablePropertiesKHR == nullptr) { table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)StubGetPipelineExecutablePropertiesKHR; }
+ table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR) gpa(device, "vkGetPipelineExecutableStatisticsKHR");
+ if (table->GetPipelineExecutableStatisticsKHR == nullptr) { table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)StubGetPipelineExecutableStatisticsKHR; }
+ table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR) gpa(device, "vkGetPipelineExecutableInternalRepresentationsKHR");
+ if (table->GetPipelineExecutableInternalRepresentationsKHR == nullptr) { table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)StubGetPipelineExecutableInternalRepresentationsKHR; }
+ table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT) gpa(device, "vkDebugMarkerSetObjectTagEXT");
+ if (table->DebugMarkerSetObjectTagEXT == nullptr) { table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)StubDebugMarkerSetObjectTagEXT; }
+ table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT) gpa(device, "vkDebugMarkerSetObjectNameEXT");
+ if (table->DebugMarkerSetObjectNameEXT == nullptr) { table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)StubDebugMarkerSetObjectNameEXT; }
+ table->CmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT) gpa(device, "vkCmdDebugMarkerBeginEXT");
+ if (table->CmdDebugMarkerBeginEXT == nullptr) { table->CmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)StubCmdDebugMarkerBeginEXT; }
+ table->CmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT) gpa(device, "vkCmdDebugMarkerEndEXT");
+ if (table->CmdDebugMarkerEndEXT == nullptr) { table->CmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)StubCmdDebugMarkerEndEXT; }
+ table->CmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT) gpa(device, "vkCmdDebugMarkerInsertEXT");
+ if (table->CmdDebugMarkerInsertEXT == nullptr) { table->CmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)StubCmdDebugMarkerInsertEXT; }
+ table->CmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT) gpa(device, "vkCmdBindTransformFeedbackBuffersEXT");
+ if (table->CmdBindTransformFeedbackBuffersEXT == nullptr) { table->CmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)StubCmdBindTransformFeedbackBuffersEXT; }
+ table->CmdBeginTransformFeedbackEXT = (PFN_vkCmdBeginTransformFeedbackEXT) gpa(device, "vkCmdBeginTransformFeedbackEXT");
+ if (table->CmdBeginTransformFeedbackEXT == nullptr) { table->CmdBeginTransformFeedbackEXT = (PFN_vkCmdBeginTransformFeedbackEXT)StubCmdBeginTransformFeedbackEXT; }
+ table->CmdEndTransformFeedbackEXT = (PFN_vkCmdEndTransformFeedbackEXT) gpa(device, "vkCmdEndTransformFeedbackEXT");
+ if (table->CmdEndTransformFeedbackEXT == nullptr) { table->CmdEndTransformFeedbackEXT = (PFN_vkCmdEndTransformFeedbackEXT)StubCmdEndTransformFeedbackEXT; }
+ table->CmdBeginQueryIndexedEXT = (PFN_vkCmdBeginQueryIndexedEXT) gpa(device, "vkCmdBeginQueryIndexedEXT");
+ if (table->CmdBeginQueryIndexedEXT == nullptr) { table->CmdBeginQueryIndexedEXT = (PFN_vkCmdBeginQueryIndexedEXT)StubCmdBeginQueryIndexedEXT; }
+ table->CmdEndQueryIndexedEXT = (PFN_vkCmdEndQueryIndexedEXT) gpa(device, "vkCmdEndQueryIndexedEXT");
+ if (table->CmdEndQueryIndexedEXT == nullptr) { table->CmdEndQueryIndexedEXT = (PFN_vkCmdEndQueryIndexedEXT)StubCmdEndQueryIndexedEXT; }
+ table->CmdDrawIndirectByteCountEXT = (PFN_vkCmdDrawIndirectByteCountEXT) gpa(device, "vkCmdDrawIndirectByteCountEXT");
+ if (table->CmdDrawIndirectByteCountEXT == nullptr) { table->CmdDrawIndirectByteCountEXT = (PFN_vkCmdDrawIndirectByteCountEXT)StubCmdDrawIndirectByteCountEXT; }
+ table->GetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX) gpa(device, "vkGetImageViewHandleNVX");
+ if (table->GetImageViewHandleNVX == nullptr) { table->GetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX)StubGetImageViewHandleNVX; }
+ table->CmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD) gpa(device, "vkCmdDrawIndirectCountAMD");
+ if (table->CmdDrawIndirectCountAMD == nullptr) { table->CmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD)StubCmdDrawIndirectCountAMD; }
+ table->CmdDrawIndexedIndirectCountAMD = (PFN_vkCmdDrawIndexedIndirectCountAMD) gpa(device, "vkCmdDrawIndexedIndirectCountAMD");
+ if (table->CmdDrawIndexedIndirectCountAMD == nullptr) { table->CmdDrawIndexedIndirectCountAMD = (PFN_vkCmdDrawIndexedIndirectCountAMD)StubCmdDrawIndexedIndirectCountAMD; }
+ table->GetShaderInfoAMD = (PFN_vkGetShaderInfoAMD) gpa(device, "vkGetShaderInfoAMD");
+ if (table->GetShaderInfoAMD == nullptr) { table->GetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)StubGetShaderInfoAMD; }
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV) gpa(device, "vkGetMemoryWin32HandleNV");
+ if (table->GetMemoryWin32HandleNV == nullptr) { table->GetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)StubGetMemoryWin32HandleNV; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ table->CmdBeginConditionalRenderingEXT = (PFN_vkCmdBeginConditionalRenderingEXT) gpa(device, "vkCmdBeginConditionalRenderingEXT");
+ if (table->CmdBeginConditionalRenderingEXT == nullptr) { table->CmdBeginConditionalRenderingEXT = (PFN_vkCmdBeginConditionalRenderingEXT)StubCmdBeginConditionalRenderingEXT; }
+ table->CmdEndConditionalRenderingEXT = (PFN_vkCmdEndConditionalRenderingEXT) gpa(device, "vkCmdEndConditionalRenderingEXT");
+ if (table->CmdEndConditionalRenderingEXT == nullptr) { table->CmdEndConditionalRenderingEXT = (PFN_vkCmdEndConditionalRenderingEXT)StubCmdEndConditionalRenderingEXT; }
+ table->CmdProcessCommandsNVX = (PFN_vkCmdProcessCommandsNVX) gpa(device, "vkCmdProcessCommandsNVX");
+ if (table->CmdProcessCommandsNVX == nullptr) { table->CmdProcessCommandsNVX = (PFN_vkCmdProcessCommandsNVX)StubCmdProcessCommandsNVX; }
+ table->CmdReserveSpaceForCommandsNVX = (PFN_vkCmdReserveSpaceForCommandsNVX) gpa(device, "vkCmdReserveSpaceForCommandsNVX");
+ if (table->CmdReserveSpaceForCommandsNVX == nullptr) { table->CmdReserveSpaceForCommandsNVX = (PFN_vkCmdReserveSpaceForCommandsNVX)StubCmdReserveSpaceForCommandsNVX; }
+ table->CreateIndirectCommandsLayoutNVX = (PFN_vkCreateIndirectCommandsLayoutNVX) gpa(device, "vkCreateIndirectCommandsLayoutNVX");
+ if (table->CreateIndirectCommandsLayoutNVX == nullptr) { table->CreateIndirectCommandsLayoutNVX = (PFN_vkCreateIndirectCommandsLayoutNVX)StubCreateIndirectCommandsLayoutNVX; }
+ table->DestroyIndirectCommandsLayoutNVX = (PFN_vkDestroyIndirectCommandsLayoutNVX) gpa(device, "vkDestroyIndirectCommandsLayoutNVX");
+ if (table->DestroyIndirectCommandsLayoutNVX == nullptr) { table->DestroyIndirectCommandsLayoutNVX = (PFN_vkDestroyIndirectCommandsLayoutNVX)StubDestroyIndirectCommandsLayoutNVX; }
+ table->CreateObjectTableNVX = (PFN_vkCreateObjectTableNVX) gpa(device, "vkCreateObjectTableNVX");
+ if (table->CreateObjectTableNVX == nullptr) { table->CreateObjectTableNVX = (PFN_vkCreateObjectTableNVX)StubCreateObjectTableNVX; }
+ table->DestroyObjectTableNVX = (PFN_vkDestroyObjectTableNVX) gpa(device, "vkDestroyObjectTableNVX");
+ if (table->DestroyObjectTableNVX == nullptr) { table->DestroyObjectTableNVX = (PFN_vkDestroyObjectTableNVX)StubDestroyObjectTableNVX; }
+ table->RegisterObjectsNVX = (PFN_vkRegisterObjectsNVX) gpa(device, "vkRegisterObjectsNVX");
+ if (table->RegisterObjectsNVX == nullptr) { table->RegisterObjectsNVX = (PFN_vkRegisterObjectsNVX)StubRegisterObjectsNVX; }
+ table->UnregisterObjectsNVX = (PFN_vkUnregisterObjectsNVX) gpa(device, "vkUnregisterObjectsNVX");
+ if (table->UnregisterObjectsNVX == nullptr) { table->UnregisterObjectsNVX = (PFN_vkUnregisterObjectsNVX)StubUnregisterObjectsNVX; }
+ table->CmdSetViewportWScalingNV = (PFN_vkCmdSetViewportWScalingNV) gpa(device, "vkCmdSetViewportWScalingNV");
+ if (table->CmdSetViewportWScalingNV == nullptr) { table->CmdSetViewportWScalingNV = (PFN_vkCmdSetViewportWScalingNV)StubCmdSetViewportWScalingNV; }
+ table->DisplayPowerControlEXT = (PFN_vkDisplayPowerControlEXT) gpa(device, "vkDisplayPowerControlEXT");
+ if (table->DisplayPowerControlEXT == nullptr) { table->DisplayPowerControlEXT = (PFN_vkDisplayPowerControlEXT)StubDisplayPowerControlEXT; }
+ table->RegisterDeviceEventEXT = (PFN_vkRegisterDeviceEventEXT) gpa(device, "vkRegisterDeviceEventEXT");
+ if (table->RegisterDeviceEventEXT == nullptr) { table->RegisterDeviceEventEXT = (PFN_vkRegisterDeviceEventEXT)StubRegisterDeviceEventEXT; }
+ table->RegisterDisplayEventEXT = (PFN_vkRegisterDisplayEventEXT) gpa(device, "vkRegisterDisplayEventEXT");
+ if (table->RegisterDisplayEventEXT == nullptr) { table->RegisterDisplayEventEXT = (PFN_vkRegisterDisplayEventEXT)StubRegisterDisplayEventEXT; }
+ table->GetSwapchainCounterEXT = (PFN_vkGetSwapchainCounterEXT) gpa(device, "vkGetSwapchainCounterEXT");
+ if (table->GetSwapchainCounterEXT == nullptr) { table->GetSwapchainCounterEXT = (PFN_vkGetSwapchainCounterEXT)StubGetSwapchainCounterEXT; }
+ table->GetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE) gpa(device, "vkGetRefreshCycleDurationGOOGLE");
+ if (table->GetRefreshCycleDurationGOOGLE == nullptr) { table->GetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)StubGetRefreshCycleDurationGOOGLE; }
+ table->GetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE) gpa(device, "vkGetPastPresentationTimingGOOGLE");
+ if (table->GetPastPresentationTimingGOOGLE == nullptr) { table->GetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)StubGetPastPresentationTimingGOOGLE; }
+ table->CmdSetDiscardRectangleEXT = (PFN_vkCmdSetDiscardRectangleEXT) gpa(device, "vkCmdSetDiscardRectangleEXT");
+ if (table->CmdSetDiscardRectangleEXT == nullptr) { table->CmdSetDiscardRectangleEXT = (PFN_vkCmdSetDiscardRectangleEXT)StubCmdSetDiscardRectangleEXT; }
+ table->SetHdrMetadataEXT = (PFN_vkSetHdrMetadataEXT) gpa(device, "vkSetHdrMetadataEXT");
+ if (table->SetHdrMetadataEXT == nullptr) { table->SetHdrMetadataEXT = (PFN_vkSetHdrMetadataEXT)StubSetHdrMetadataEXT; }
+ table->SetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT) gpa(device, "vkSetDebugUtilsObjectNameEXT");
+ table->SetDebugUtilsObjectTagEXT = (PFN_vkSetDebugUtilsObjectTagEXT) gpa(device, "vkSetDebugUtilsObjectTagEXT");
+ table->QueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT) gpa(device, "vkQueueBeginDebugUtilsLabelEXT");
+ table->QueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT) gpa(device, "vkQueueEndDebugUtilsLabelEXT");
+ table->QueueInsertDebugUtilsLabelEXT = (PFN_vkQueueInsertDebugUtilsLabelEXT) gpa(device, "vkQueueInsertDebugUtilsLabelEXT");
+ table->CmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT) gpa(device, "vkCmdBeginDebugUtilsLabelEXT");
+ table->CmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT) gpa(device, "vkCmdEndDebugUtilsLabelEXT");
+ table->CmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT) gpa(device, "vkCmdInsertDebugUtilsLabelEXT");
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ table->GetAndroidHardwareBufferPropertiesANDROID = (PFN_vkGetAndroidHardwareBufferPropertiesANDROID) gpa(device, "vkGetAndroidHardwareBufferPropertiesANDROID");
+ if (table->GetAndroidHardwareBufferPropertiesANDROID == nullptr) { table->GetAndroidHardwareBufferPropertiesANDROID = (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)StubGetAndroidHardwareBufferPropertiesANDROID; }
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ table->GetMemoryAndroidHardwareBufferANDROID = (PFN_vkGetMemoryAndroidHardwareBufferANDROID) gpa(device, "vkGetMemoryAndroidHardwareBufferANDROID");
+ if (table->GetMemoryAndroidHardwareBufferANDROID == nullptr) { table->GetMemoryAndroidHardwareBufferANDROID = (PFN_vkGetMemoryAndroidHardwareBufferANDROID)StubGetMemoryAndroidHardwareBufferANDROID; }
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+ table->CmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT) gpa(device, "vkCmdSetSampleLocationsEXT");
+ if (table->CmdSetSampleLocationsEXT == nullptr) { table->CmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)StubCmdSetSampleLocationsEXT; }
+ table->GetImageDrmFormatModifierPropertiesEXT = (PFN_vkGetImageDrmFormatModifierPropertiesEXT) gpa(device, "vkGetImageDrmFormatModifierPropertiesEXT");
+ if (table->GetImageDrmFormatModifierPropertiesEXT == nullptr) { table->GetImageDrmFormatModifierPropertiesEXT = (PFN_vkGetImageDrmFormatModifierPropertiesEXT)StubGetImageDrmFormatModifierPropertiesEXT; }
+ table->CreateValidationCacheEXT = (PFN_vkCreateValidationCacheEXT) gpa(device, "vkCreateValidationCacheEXT");
+ if (table->CreateValidationCacheEXT == nullptr) { table->CreateValidationCacheEXT = (PFN_vkCreateValidationCacheEXT)StubCreateValidationCacheEXT; }
+ table->DestroyValidationCacheEXT = (PFN_vkDestroyValidationCacheEXT) gpa(device, "vkDestroyValidationCacheEXT");
+ if (table->DestroyValidationCacheEXT == nullptr) { table->DestroyValidationCacheEXT = (PFN_vkDestroyValidationCacheEXT)StubDestroyValidationCacheEXT; }
+ table->MergeValidationCachesEXT = (PFN_vkMergeValidationCachesEXT) gpa(device, "vkMergeValidationCachesEXT");
+ if (table->MergeValidationCachesEXT == nullptr) { table->MergeValidationCachesEXT = (PFN_vkMergeValidationCachesEXT)StubMergeValidationCachesEXT; }
+ table->GetValidationCacheDataEXT = (PFN_vkGetValidationCacheDataEXT) gpa(device, "vkGetValidationCacheDataEXT");
+ if (table->GetValidationCacheDataEXT == nullptr) { table->GetValidationCacheDataEXT = (PFN_vkGetValidationCacheDataEXT)StubGetValidationCacheDataEXT; }
+ table->CmdBindShadingRateImageNV = (PFN_vkCmdBindShadingRateImageNV) gpa(device, "vkCmdBindShadingRateImageNV");
+ if (table->CmdBindShadingRateImageNV == nullptr) { table->CmdBindShadingRateImageNV = (PFN_vkCmdBindShadingRateImageNV)StubCmdBindShadingRateImageNV; }
+ table->CmdSetViewportShadingRatePaletteNV = (PFN_vkCmdSetViewportShadingRatePaletteNV) gpa(device, "vkCmdSetViewportShadingRatePaletteNV");
+ if (table->CmdSetViewportShadingRatePaletteNV == nullptr) { table->CmdSetViewportShadingRatePaletteNV = (PFN_vkCmdSetViewportShadingRatePaletteNV)StubCmdSetViewportShadingRatePaletteNV; }
+ table->CmdSetCoarseSampleOrderNV = (PFN_vkCmdSetCoarseSampleOrderNV) gpa(device, "vkCmdSetCoarseSampleOrderNV");
+ if (table->CmdSetCoarseSampleOrderNV == nullptr) { table->CmdSetCoarseSampleOrderNV = (PFN_vkCmdSetCoarseSampleOrderNV)StubCmdSetCoarseSampleOrderNV; }
+ table->CreateAccelerationStructureNV = (PFN_vkCreateAccelerationStructureNV) gpa(device, "vkCreateAccelerationStructureNV");
+ if (table->CreateAccelerationStructureNV == nullptr) { table->CreateAccelerationStructureNV = (PFN_vkCreateAccelerationStructureNV)StubCreateAccelerationStructureNV; }
+ table->DestroyAccelerationStructureNV = (PFN_vkDestroyAccelerationStructureNV) gpa(device, "vkDestroyAccelerationStructureNV");
+ if (table->DestroyAccelerationStructureNV == nullptr) { table->DestroyAccelerationStructureNV = (PFN_vkDestroyAccelerationStructureNV)StubDestroyAccelerationStructureNV; }
+ table->GetAccelerationStructureMemoryRequirementsNV = (PFN_vkGetAccelerationStructureMemoryRequirementsNV) gpa(device, "vkGetAccelerationStructureMemoryRequirementsNV");
+ if (table->GetAccelerationStructureMemoryRequirementsNV == nullptr) { table->GetAccelerationStructureMemoryRequirementsNV = (PFN_vkGetAccelerationStructureMemoryRequirementsNV)StubGetAccelerationStructureMemoryRequirementsNV; }
+ table->BindAccelerationStructureMemoryNV = (PFN_vkBindAccelerationStructureMemoryNV) gpa(device, "vkBindAccelerationStructureMemoryNV");
+ if (table->BindAccelerationStructureMemoryNV == nullptr) { table->BindAccelerationStructureMemoryNV = (PFN_vkBindAccelerationStructureMemoryNV)StubBindAccelerationStructureMemoryNV; }
+ table->CmdBuildAccelerationStructureNV = (PFN_vkCmdBuildAccelerationStructureNV) gpa(device, "vkCmdBuildAccelerationStructureNV");
+ if (table->CmdBuildAccelerationStructureNV == nullptr) { table->CmdBuildAccelerationStructureNV = (PFN_vkCmdBuildAccelerationStructureNV)StubCmdBuildAccelerationStructureNV; }
+ table->CmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV) gpa(device, "vkCmdCopyAccelerationStructureNV");
+ if (table->CmdCopyAccelerationStructureNV == nullptr) { table->CmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV)StubCmdCopyAccelerationStructureNV; }
+ table->CmdTraceRaysNV = (PFN_vkCmdTraceRaysNV) gpa(device, "vkCmdTraceRaysNV");
+ if (table->CmdTraceRaysNV == nullptr) { table->CmdTraceRaysNV = (PFN_vkCmdTraceRaysNV)StubCmdTraceRaysNV; }
+ table->CreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV) gpa(device, "vkCreateRayTracingPipelinesNV");
+ if (table->CreateRayTracingPipelinesNV == nullptr) { table->CreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV)StubCreateRayTracingPipelinesNV; }
+ table->GetRayTracingShaderGroupHandlesNV = (PFN_vkGetRayTracingShaderGroupHandlesNV) gpa(device, "vkGetRayTracingShaderGroupHandlesNV");
+ if (table->GetRayTracingShaderGroupHandlesNV == nullptr) { table->GetRayTracingShaderGroupHandlesNV = (PFN_vkGetRayTracingShaderGroupHandlesNV)StubGetRayTracingShaderGroupHandlesNV; }
+ table->GetAccelerationStructureHandleNV = (PFN_vkGetAccelerationStructureHandleNV) gpa(device, "vkGetAccelerationStructureHandleNV");
+ if (table->GetAccelerationStructureHandleNV == nullptr) { table->GetAccelerationStructureHandleNV = (PFN_vkGetAccelerationStructureHandleNV)StubGetAccelerationStructureHandleNV; }
+ table->CmdWriteAccelerationStructuresPropertiesNV = (PFN_vkCmdWriteAccelerationStructuresPropertiesNV) gpa(device, "vkCmdWriteAccelerationStructuresPropertiesNV");
+ if (table->CmdWriteAccelerationStructuresPropertiesNV == nullptr) { table->CmdWriteAccelerationStructuresPropertiesNV = (PFN_vkCmdWriteAccelerationStructuresPropertiesNV)StubCmdWriteAccelerationStructuresPropertiesNV; }
+ table->CompileDeferredNV = (PFN_vkCompileDeferredNV) gpa(device, "vkCompileDeferredNV");
+ if (table->CompileDeferredNV == nullptr) { table->CompileDeferredNV = (PFN_vkCompileDeferredNV)StubCompileDeferredNV; }
+ table->GetMemoryHostPointerPropertiesEXT = (PFN_vkGetMemoryHostPointerPropertiesEXT) gpa(device, "vkGetMemoryHostPointerPropertiesEXT");
+ if (table->GetMemoryHostPointerPropertiesEXT == nullptr) { table->GetMemoryHostPointerPropertiesEXT = (PFN_vkGetMemoryHostPointerPropertiesEXT)StubGetMemoryHostPointerPropertiesEXT; }
+ table->CmdWriteBufferMarkerAMD = (PFN_vkCmdWriteBufferMarkerAMD) gpa(device, "vkCmdWriteBufferMarkerAMD");
+ if (table->CmdWriteBufferMarkerAMD == nullptr) { table->CmdWriteBufferMarkerAMD = (PFN_vkCmdWriteBufferMarkerAMD)StubCmdWriteBufferMarkerAMD; }
+ table->GetCalibratedTimestampsEXT = (PFN_vkGetCalibratedTimestampsEXT) gpa(device, "vkGetCalibratedTimestampsEXT");
+ if (table->GetCalibratedTimestampsEXT == nullptr) { table->GetCalibratedTimestampsEXT = (PFN_vkGetCalibratedTimestampsEXT)StubGetCalibratedTimestampsEXT; }
+ table->CmdDrawMeshTasksNV = (PFN_vkCmdDrawMeshTasksNV) gpa(device, "vkCmdDrawMeshTasksNV");
+ if (table->CmdDrawMeshTasksNV == nullptr) { table->CmdDrawMeshTasksNV = (PFN_vkCmdDrawMeshTasksNV)StubCmdDrawMeshTasksNV; }
+ table->CmdDrawMeshTasksIndirectNV = (PFN_vkCmdDrawMeshTasksIndirectNV) gpa(device, "vkCmdDrawMeshTasksIndirectNV");
+ if (table->CmdDrawMeshTasksIndirectNV == nullptr) { table->CmdDrawMeshTasksIndirectNV = (PFN_vkCmdDrawMeshTasksIndirectNV)StubCmdDrawMeshTasksIndirectNV; }
+ table->CmdDrawMeshTasksIndirectCountNV = (PFN_vkCmdDrawMeshTasksIndirectCountNV) gpa(device, "vkCmdDrawMeshTasksIndirectCountNV");
+ if (table->CmdDrawMeshTasksIndirectCountNV == nullptr) { table->CmdDrawMeshTasksIndirectCountNV = (PFN_vkCmdDrawMeshTasksIndirectCountNV)StubCmdDrawMeshTasksIndirectCountNV; }
+ table->CmdSetExclusiveScissorNV = (PFN_vkCmdSetExclusiveScissorNV) gpa(device, "vkCmdSetExclusiveScissorNV");
+ if (table->CmdSetExclusiveScissorNV == nullptr) { table->CmdSetExclusiveScissorNV = (PFN_vkCmdSetExclusiveScissorNV)StubCmdSetExclusiveScissorNV; }
+ table->CmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV) gpa(device, "vkCmdSetCheckpointNV");
+ if (table->CmdSetCheckpointNV == nullptr) { table->CmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV)StubCmdSetCheckpointNV; }
+ table->GetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV) gpa(device, "vkGetQueueCheckpointDataNV");
+ if (table->GetQueueCheckpointDataNV == nullptr) { table->GetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV)StubGetQueueCheckpointDataNV; }
+ table->InitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL) gpa(device, "vkInitializePerformanceApiINTEL");
+ if (table->InitializePerformanceApiINTEL == nullptr) { table->InitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL)StubInitializePerformanceApiINTEL; }
+ table->UninitializePerformanceApiINTEL = (PFN_vkUninitializePerformanceApiINTEL) gpa(device, "vkUninitializePerformanceApiINTEL");
+ if (table->UninitializePerformanceApiINTEL == nullptr) { table->UninitializePerformanceApiINTEL = (PFN_vkUninitializePerformanceApiINTEL)StubUninitializePerformanceApiINTEL; }
+ table->CmdSetPerformanceMarkerINTEL = (PFN_vkCmdSetPerformanceMarkerINTEL) gpa(device, "vkCmdSetPerformanceMarkerINTEL");
+ if (table->CmdSetPerformanceMarkerINTEL == nullptr) { table->CmdSetPerformanceMarkerINTEL = (PFN_vkCmdSetPerformanceMarkerINTEL)StubCmdSetPerformanceMarkerINTEL; }
+ table->CmdSetPerformanceStreamMarkerINTEL = (PFN_vkCmdSetPerformanceStreamMarkerINTEL) gpa(device, "vkCmdSetPerformanceStreamMarkerINTEL");
+ if (table->CmdSetPerformanceStreamMarkerINTEL == nullptr) { table->CmdSetPerformanceStreamMarkerINTEL = (PFN_vkCmdSetPerformanceStreamMarkerINTEL)StubCmdSetPerformanceStreamMarkerINTEL; }
+ table->CmdSetPerformanceOverrideINTEL = (PFN_vkCmdSetPerformanceOverrideINTEL) gpa(device, "vkCmdSetPerformanceOverrideINTEL");
+ if (table->CmdSetPerformanceOverrideINTEL == nullptr) { table->CmdSetPerformanceOverrideINTEL = (PFN_vkCmdSetPerformanceOverrideINTEL)StubCmdSetPerformanceOverrideINTEL; }
+ table->AcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL) gpa(device, "vkAcquirePerformanceConfigurationINTEL");
+ if (table->AcquirePerformanceConfigurationINTEL == nullptr) { table->AcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)StubAcquirePerformanceConfigurationINTEL; }
+ table->ReleasePerformanceConfigurationINTEL = (PFN_vkReleasePerformanceConfigurationINTEL) gpa(device, "vkReleasePerformanceConfigurationINTEL");
+ if (table->ReleasePerformanceConfigurationINTEL == nullptr) { table->ReleasePerformanceConfigurationINTEL = (PFN_vkReleasePerformanceConfigurationINTEL)StubReleasePerformanceConfigurationINTEL; }
+ table->QueueSetPerformanceConfigurationINTEL = (PFN_vkQueueSetPerformanceConfigurationINTEL) gpa(device, "vkQueueSetPerformanceConfigurationINTEL");
+ if (table->QueueSetPerformanceConfigurationINTEL == nullptr) { table->QueueSetPerformanceConfigurationINTEL = (PFN_vkQueueSetPerformanceConfigurationINTEL)StubQueueSetPerformanceConfigurationINTEL; }
+ table->GetPerformanceParameterINTEL = (PFN_vkGetPerformanceParameterINTEL) gpa(device, "vkGetPerformanceParameterINTEL");
+ if (table->GetPerformanceParameterINTEL == nullptr) { table->GetPerformanceParameterINTEL = (PFN_vkGetPerformanceParameterINTEL)StubGetPerformanceParameterINTEL; }
+ table->SetLocalDimmingAMD = (PFN_vkSetLocalDimmingAMD) gpa(device, "vkSetLocalDimmingAMD");
+ if (table->SetLocalDimmingAMD == nullptr) { table->SetLocalDimmingAMD = (PFN_vkSetLocalDimmingAMD)StubSetLocalDimmingAMD; }
+ table->GetBufferDeviceAddressEXT = (PFN_vkGetBufferDeviceAddressEXT) gpa(device, "vkGetBufferDeviceAddressEXT");
+ if (table->GetBufferDeviceAddressEXT == nullptr) { table->GetBufferDeviceAddressEXT = (PFN_vkGetBufferDeviceAddressEXT)StubGetBufferDeviceAddressEXT; }
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->AcquireFullScreenExclusiveModeEXT = (PFN_vkAcquireFullScreenExclusiveModeEXT) gpa(device, "vkAcquireFullScreenExclusiveModeEXT");
+ if (table->AcquireFullScreenExclusiveModeEXT == nullptr) { table->AcquireFullScreenExclusiveModeEXT = (PFN_vkAcquireFullScreenExclusiveModeEXT)StubAcquireFullScreenExclusiveModeEXT; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->ReleaseFullScreenExclusiveModeEXT = (PFN_vkReleaseFullScreenExclusiveModeEXT) gpa(device, "vkReleaseFullScreenExclusiveModeEXT");
+ if (table->ReleaseFullScreenExclusiveModeEXT == nullptr) { table->ReleaseFullScreenExclusiveModeEXT = (PFN_vkReleaseFullScreenExclusiveModeEXT)StubReleaseFullScreenExclusiveModeEXT; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT) gpa(device, "vkGetDeviceGroupSurfacePresentModes2EXT");
+ if (table->GetDeviceGroupSurfacePresentModes2EXT == nullptr) { table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)StubGetDeviceGroupSurfacePresentModes2EXT; }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT) gpa(device, "vkCmdSetLineStippleEXT");
+ if (table->CmdSetLineStippleEXT == nullptr) { table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)StubCmdSetLineStippleEXT; }
+ table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT) gpa(device, "vkResetQueryPoolEXT");
+ if (table->ResetQueryPoolEXT == nullptr) { table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)StubResetQueryPoolEXT; }
+}
+
+
+static inline void layer_init_instance_dispatch_table(VkInstance instance, VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa) {
+ memset(table, 0, sizeof(*table));
+ // Instance function pointers
+ table->DestroyInstance = (PFN_vkDestroyInstance) gpa(instance, "vkDestroyInstance");
+ table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) gpa(instance, "vkEnumeratePhysicalDevices");
+ table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) gpa(instance, "vkGetPhysicalDeviceFeatures");
+ table->GetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) gpa(instance, "vkGetPhysicalDeviceFormatProperties");
+ table->GetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) gpa(instance, "vkGetPhysicalDeviceImageFormatProperties");
+ table->GetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) gpa(instance, "vkGetPhysicalDeviceProperties");
+ table->GetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties");
+ table->GetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) gpa(instance, "vkGetPhysicalDeviceMemoryProperties");
+ table->GetInstanceProcAddr = gpa;
+ table->EnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) gpa(instance, "vkEnumerateDeviceExtensionProperties");
+ table->EnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) gpa(instance, "vkEnumerateDeviceLayerProperties");
+ table->GetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties");
+ table->EnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) gpa(instance, "vkEnumeratePhysicalDeviceGroups");
+ table->GetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) gpa(instance, "vkGetPhysicalDeviceFeatures2");
+ table->GetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) gpa(instance, "vkGetPhysicalDeviceProperties2");
+ table->GetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) gpa(instance, "vkGetPhysicalDeviceFormatProperties2");
+ table->GetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) gpa(instance, "vkGetPhysicalDeviceImageFormatProperties2");
+ table->GetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties2");
+ table->GetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) gpa(instance, "vkGetPhysicalDeviceMemoryProperties2");
+ table->GetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2");
+ table->GetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) gpa(instance, "vkGetPhysicalDeviceExternalBufferProperties");
+ table->GetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) gpa(instance, "vkGetPhysicalDeviceExternalFenceProperties");
+ table->GetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) gpa(instance, "vkGetPhysicalDeviceExternalSemaphoreProperties");
+ table->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) gpa(instance, "vkDestroySurfaceKHR");
+ table->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceSupportKHR");
+ table->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
+ table->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR");
+ table->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR");
+ table->GetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) gpa(instance, "vkGetPhysicalDevicePresentRectanglesKHR");
+ table->GetPhysicalDeviceDisplayPropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR) gpa(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR");
+ table->GetPhysicalDeviceDisplayPlanePropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR) gpa(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
+ table->GetDisplayPlaneSupportedDisplaysKHR = (PFN_vkGetDisplayPlaneSupportedDisplaysKHR) gpa(instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
+ table->GetDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR) gpa(instance, "vkGetDisplayModePropertiesKHR");
+ table->CreateDisplayModeKHR = (PFN_vkCreateDisplayModeKHR) gpa(instance, "vkCreateDisplayModeKHR");
+ table->GetDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR) gpa(instance, "vkGetDisplayPlaneCapabilitiesKHR");
+ table->CreateDisplayPlaneSurfaceKHR = (PFN_vkCreateDisplayPlaneSurfaceKHR) gpa(instance, "vkCreateDisplayPlaneSurfaceKHR");
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ table->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) gpa(instance, "vkCreateXlibSurfaceKHR");
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ table->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ table->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR) gpa(instance, "vkCreateXcbSurfaceKHR");
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ table->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ table->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR) gpa(instance, "vkCreateWaylandSurfaceKHR");
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ table->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ table->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) gpa(instance, "vkCreateAndroidSurfaceKHR");
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR) gpa(instance, "vkCreateWin32SurfaceKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR) gpa(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ table->GetPhysicalDeviceFeatures2KHR = (PFN_vkGetPhysicalDeviceFeatures2KHR) gpa(instance, "vkGetPhysicalDeviceFeatures2KHR");
+ table->GetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2KHR) gpa(instance, "vkGetPhysicalDeviceProperties2KHR");
+ table->GetPhysicalDeviceFormatProperties2KHR = (PFN_vkGetPhysicalDeviceFormatProperties2KHR) gpa(instance, "vkGetPhysicalDeviceFormatProperties2KHR");
+ table->GetPhysicalDeviceImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR) gpa(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR");
+ table->GetPhysicalDeviceQueueFamilyProperties2KHR = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR) gpa(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR");
+ table->GetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2KHR) gpa(instance, "vkGetPhysicalDeviceMemoryProperties2KHR");
+ table->GetPhysicalDeviceSparseImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR) gpa(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
+ table->EnumeratePhysicalDeviceGroupsKHR = (PFN_vkEnumeratePhysicalDeviceGroupsKHR) gpa(instance, "vkEnumeratePhysicalDeviceGroupsKHR");
+ table->GetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR) gpa(instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
+ table->GetPhysicalDeviceExternalSemaphorePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR) gpa(instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
+ table->GetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR) gpa(instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR");
+ table->GetPhysicalDeviceSurfaceCapabilities2KHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR");
+ table->GetPhysicalDeviceSurfaceFormats2KHR = (PFN_vkGetPhysicalDeviceSurfaceFormats2KHR) gpa(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR");
+ table->GetPhysicalDeviceDisplayProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayProperties2KHR) gpa(instance, "vkGetPhysicalDeviceDisplayProperties2KHR");
+ table->GetPhysicalDeviceDisplayPlaneProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR) gpa(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
+ table->GetDisplayModeProperties2KHR = (PFN_vkGetDisplayModeProperties2KHR) gpa(instance, "vkGetDisplayModeProperties2KHR");
+ table->GetDisplayPlaneCapabilities2KHR = (PFN_vkGetDisplayPlaneCapabilities2KHR) gpa(instance, "vkGetDisplayPlaneCapabilities2KHR");
+ table->CreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) gpa(instance, "vkCreateDebugReportCallbackEXT");
+ table->DestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) gpa(instance, "vkDestroyDebugReportCallbackEXT");
+ table->DebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) gpa(instance, "vkDebugReportMessageEXT");
+#ifdef VK_USE_PLATFORM_GGP
+ table->CreateStreamDescriptorSurfaceGGP = (PFN_vkCreateStreamDescriptorSurfaceGGP) gpa(instance, "vkCreateStreamDescriptorSurfaceGGP");
+#endif // VK_USE_PLATFORM_GGP
+ table->GetPhysicalDeviceExternalImageFormatPropertiesNV = (PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV) gpa(instance, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
+#ifdef VK_USE_PLATFORM_VI_NN
+ table->CreateViSurfaceNN = (PFN_vkCreateViSurfaceNN) gpa(instance, "vkCreateViSurfaceNN");
+#endif // VK_USE_PLATFORM_VI_NN
+ table->GetPhysicalDeviceGeneratedCommandsPropertiesNVX = (PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX) gpa(instance, "vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX");
+ table->ReleaseDisplayEXT = (PFN_vkReleaseDisplayEXT) gpa(instance, "vkReleaseDisplayEXT");
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ table->AcquireXlibDisplayEXT = (PFN_vkAcquireXlibDisplayEXT) gpa(instance, "vkAcquireXlibDisplayEXT");
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ table->GetRandROutputDisplayEXT = (PFN_vkGetRandROutputDisplayEXT) gpa(instance, "vkGetRandROutputDisplayEXT");
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ table->GetPhysicalDeviceSurfaceCapabilities2EXT = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT) gpa(instance, "vkGetPhysicalDeviceSurfaceCapabilities2EXT");
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ table->CreateIOSSurfaceMVK = (PFN_vkCreateIOSSurfaceMVK) gpa(instance, "vkCreateIOSSurfaceMVK");
+#endif // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ table->CreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK) gpa(instance, "vkCreateMacOSSurfaceMVK");
+#endif // VK_USE_PLATFORM_MACOS_MVK
+ table->CreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT) gpa(instance, "vkCreateDebugUtilsMessengerEXT");
+ table->DestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT) gpa(instance, "vkDestroyDebugUtilsMessengerEXT");
+ table->SubmitDebugUtilsMessageEXT = (PFN_vkSubmitDebugUtilsMessageEXT) gpa(instance, "vkSubmitDebugUtilsMessageEXT");
+ table->GetPhysicalDeviceMultisamplePropertiesEXT = (PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT) gpa(instance, "vkGetPhysicalDeviceMultisamplePropertiesEXT");
+ table->GetPhysicalDeviceCalibrateableTimeDomainsEXT = (PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT) gpa(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ table->CreateImagePipeSurfaceFUCHSIA = (PFN_vkCreateImagePipeSurfaceFUCHSIA) gpa(instance, "vkCreateImagePipeSurfaceFUCHSIA");
+#endif // VK_USE_PLATFORM_FUCHSIA
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ table->CreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT) gpa(instance, "vkCreateMetalSurfaceEXT");
+#endif // VK_USE_PLATFORM_METAL_EXT
+ table->GetPhysicalDeviceCooperativeMatrixPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV) gpa(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
+ table->GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = (PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV) gpa(instance, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetPhysicalDeviceSurfacePresentModes2EXT = (PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT) gpa(instance, "vkGetPhysicalDeviceSurfacePresentModes2EXT");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ table->CreateHeadlessSurfaceEXT = (PFN_vkCreateHeadlessSurfaceEXT) gpa(instance, "vkCreateHeadlessSurfaceEXT");
+}
diff --git a/thirdparty/vulkan/loader/vk_layer_dispatch_table.h b/thirdparty/vulkan/loader/vk_layer_dispatch_table.h
new file mode 100644
index 0000000000..1f0342dc49
--- /dev/null
+++ b/thirdparty/vulkan/loader/vk_layer_dispatch_table.h
@@ -0,0 +1,651 @@
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See loader_extension_generator.py for modifications
+
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Mark Young <marky@lunarg.com>
+ */
+
+#pragma once
+
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
+
+// Instance function pointer dispatch table
+typedef struct VkLayerInstanceDispatchTable_ {
+ // Manually add in GetPhysicalDeviceProcAddr entry
+ PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
+
+ // ---- Core 1_0 commands
+ PFN_vkCreateInstance CreateInstance;
+ PFN_vkDestroyInstance DestroyInstance;
+ PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
+ PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
+ PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties;
+ PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties;
+ PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties;
+ PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties;
+ PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
+ PFN_vkCreateDevice CreateDevice;
+ PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
+ PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
+ PFN_vkEnumerateInstanceLayerProperties EnumerateInstanceLayerProperties;
+ PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties;
+
+ // ---- Core 1_1 commands
+ PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion;
+ PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups;
+ PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2;
+ PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2;
+ PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2;
+ PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysicalDeviceImageFormatProperties2;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2;
+ PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysicalDeviceSparseImageFormatProperties2;
+ PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties;
+ PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties;
+ PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties;
+
+ // ---- VK_KHR_surface extension commands
+ PFN_vkDestroySurfaceKHR DestroySurfaceKHR;
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR;
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR;
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR;
+
+ // ---- VK_KHR_swapchain extension commands
+ PFN_vkGetPhysicalDevicePresentRectanglesKHR GetPhysicalDevicePresentRectanglesKHR;
+
+ // ---- VK_KHR_display extension commands
+ PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR;
+ PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR;
+ PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR;
+ PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR;
+ PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR;
+ PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR;
+ PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR;
+
+ // ---- VK_KHR_xlib_surface extension commands
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR GetPhysicalDeviceXlibPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+ // ---- VK_KHR_xcb_surface extension commands
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR GetPhysicalDeviceXcbPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+ // ---- VK_KHR_wayland_surface extension commands
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR GetPhysicalDeviceWaylandPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+ // ---- VK_KHR_android_surface extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_KHR_win32_surface extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR GetPhysicalDeviceWin32PresentationSupportKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR;
+ PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR;
+ PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysicalDeviceFormatProperties2KHR;
+ PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysicalDeviceImageFormatProperties2KHR;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysicalDeviceQueueFamilyProperties2KHR;
+ PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysicalDeviceSparseImageFormatProperties2KHR;
+
+ // ---- VK_KHR_device_group_creation extension commands
+ PFN_vkEnumeratePhysicalDeviceGroupsKHR EnumeratePhysicalDeviceGroupsKHR;
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR;
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR;
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR;
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR;
+ PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR;
+
+ // ---- VK_KHR_get_display_properties2 extension commands
+ PFN_vkGetPhysicalDeviceDisplayProperties2KHR GetPhysicalDeviceDisplayProperties2KHR;
+ PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR GetPhysicalDeviceDisplayPlaneProperties2KHR;
+ PFN_vkGetDisplayModeProperties2KHR GetDisplayModeProperties2KHR;
+ PFN_vkGetDisplayPlaneCapabilities2KHR GetDisplayPlaneCapabilities2KHR;
+
+ // ---- VK_EXT_debug_report extension commands
+ PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
+ PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
+ PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ PFN_vkCreateStreamDescriptorSurfaceGGP CreateStreamDescriptorSurfaceGGP;
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV;
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ PFN_vkCreateViSurfaceNN CreateViSurfaceNN;
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX GetPhysicalDeviceGeneratedCommandsPropertiesNVX;
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ PFN_vkReleaseDisplayEXT ReleaseDisplayEXT;
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ PFN_vkAcquireXlibDisplayEXT AcquireXlibDisplayEXT;
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ PFN_vkGetRandROutputDisplayEXT GetRandROutputDisplayEXT;
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT GetPhysicalDeviceSurfaceCapabilities2EXT;
+
+ // ---- VK_MVK_ios_surface extension commands
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ PFN_vkCreateIOSSurfaceMVK CreateIOSSurfaceMVK;
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+ // ---- VK_MVK_macos_surface extension commands
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ PFN_vkCreateMacOSSurfaceMVK CreateMacOSSurfaceMVK;
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+ // ---- VK_EXT_debug_utils extension commands
+ PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
+ PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
+ PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
+
+ // ---- VK_EXT_sample_locations extension commands
+ PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT;
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT GetPhysicalDeviceCalibrateableTimeDomainsEXT;
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ PFN_vkCreateImagePipeSurfaceFUCHSIA CreateImagePipeSurfaceFUCHSIA;
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ // ---- VK_EXT_metal_surface extension commands
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ PFN_vkCreateMetalSurfaceEXT CreateMetalSurfaceEXT;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ // ---- VK_NV_cooperative_matrix extension commands
+ PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV GetPhysicalDeviceCooperativeMatrixPropertiesNV;
+
+ // ---- VK_NV_coverage_reduction_mode extension commands
+ PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT GetPhysicalDeviceSurfacePresentModes2EXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_headless_surface extension commands
+ PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT;
+} VkLayerInstanceDispatchTable;
+
+// Device function pointer dispatch table
+typedef struct VkLayerDispatchTable_ {
+
+ // ---- Core 1_0 commands
+ PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
+ PFN_vkDestroyDevice DestroyDevice;
+ PFN_vkGetDeviceQueue GetDeviceQueue;
+ PFN_vkQueueSubmit QueueSubmit;
+ PFN_vkQueueWaitIdle QueueWaitIdle;
+ PFN_vkDeviceWaitIdle DeviceWaitIdle;
+ PFN_vkAllocateMemory AllocateMemory;
+ PFN_vkFreeMemory FreeMemory;
+ PFN_vkMapMemory MapMemory;
+ PFN_vkUnmapMemory UnmapMemory;
+ PFN_vkFlushMappedMemoryRanges FlushMappedMemoryRanges;
+ PFN_vkInvalidateMappedMemoryRanges InvalidateMappedMemoryRanges;
+ PFN_vkGetDeviceMemoryCommitment GetDeviceMemoryCommitment;
+ PFN_vkBindBufferMemory BindBufferMemory;
+ PFN_vkBindImageMemory BindImageMemory;
+ PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements;
+ PFN_vkGetImageMemoryRequirements GetImageMemoryRequirements;
+ PFN_vkGetImageSparseMemoryRequirements GetImageSparseMemoryRequirements;
+ PFN_vkQueueBindSparse QueueBindSparse;
+ PFN_vkCreateFence CreateFence;
+ PFN_vkDestroyFence DestroyFence;
+ PFN_vkResetFences ResetFences;
+ PFN_vkGetFenceStatus GetFenceStatus;
+ PFN_vkWaitForFences WaitForFences;
+ PFN_vkCreateSemaphore CreateSemaphore;
+ PFN_vkDestroySemaphore DestroySemaphore;
+ PFN_vkCreateEvent CreateEvent;
+ PFN_vkDestroyEvent DestroyEvent;
+ PFN_vkGetEventStatus GetEventStatus;
+ PFN_vkSetEvent SetEvent;
+ PFN_vkResetEvent ResetEvent;
+ PFN_vkCreateQueryPool CreateQueryPool;
+ PFN_vkDestroyQueryPool DestroyQueryPool;
+ PFN_vkGetQueryPoolResults GetQueryPoolResults;
+ PFN_vkCreateBuffer CreateBuffer;
+ PFN_vkDestroyBuffer DestroyBuffer;
+ PFN_vkCreateBufferView CreateBufferView;
+ PFN_vkDestroyBufferView DestroyBufferView;
+ PFN_vkCreateImage CreateImage;
+ PFN_vkDestroyImage DestroyImage;
+ PFN_vkGetImageSubresourceLayout GetImageSubresourceLayout;
+ PFN_vkCreateImageView CreateImageView;
+ PFN_vkDestroyImageView DestroyImageView;
+ PFN_vkCreateShaderModule CreateShaderModule;
+ PFN_vkDestroyShaderModule DestroyShaderModule;
+ PFN_vkCreatePipelineCache CreatePipelineCache;
+ PFN_vkDestroyPipelineCache DestroyPipelineCache;
+ PFN_vkGetPipelineCacheData GetPipelineCacheData;
+ PFN_vkMergePipelineCaches MergePipelineCaches;
+ PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines;
+ PFN_vkCreateComputePipelines CreateComputePipelines;
+ PFN_vkDestroyPipeline DestroyPipeline;
+ PFN_vkCreatePipelineLayout CreatePipelineLayout;
+ PFN_vkDestroyPipelineLayout DestroyPipelineLayout;
+ PFN_vkCreateSampler CreateSampler;
+ PFN_vkDestroySampler DestroySampler;
+ PFN_vkCreateDescriptorSetLayout CreateDescriptorSetLayout;
+ PFN_vkDestroyDescriptorSetLayout DestroyDescriptorSetLayout;
+ PFN_vkCreateDescriptorPool CreateDescriptorPool;
+ PFN_vkDestroyDescriptorPool DestroyDescriptorPool;
+ PFN_vkResetDescriptorPool ResetDescriptorPool;
+ PFN_vkAllocateDescriptorSets AllocateDescriptorSets;
+ PFN_vkFreeDescriptorSets FreeDescriptorSets;
+ PFN_vkUpdateDescriptorSets UpdateDescriptorSets;
+ PFN_vkCreateFramebuffer CreateFramebuffer;
+ PFN_vkDestroyFramebuffer DestroyFramebuffer;
+ PFN_vkCreateRenderPass CreateRenderPass;
+ PFN_vkDestroyRenderPass DestroyRenderPass;
+ PFN_vkGetRenderAreaGranularity GetRenderAreaGranularity;
+ PFN_vkCreateCommandPool CreateCommandPool;
+ PFN_vkDestroyCommandPool DestroyCommandPool;
+ PFN_vkResetCommandPool ResetCommandPool;
+ PFN_vkAllocateCommandBuffers AllocateCommandBuffers;
+ PFN_vkFreeCommandBuffers FreeCommandBuffers;
+ PFN_vkBeginCommandBuffer BeginCommandBuffer;
+ PFN_vkEndCommandBuffer EndCommandBuffer;
+ PFN_vkResetCommandBuffer ResetCommandBuffer;
+ PFN_vkCmdBindPipeline CmdBindPipeline;
+ PFN_vkCmdSetViewport CmdSetViewport;
+ PFN_vkCmdSetScissor CmdSetScissor;
+ PFN_vkCmdSetLineWidth CmdSetLineWidth;
+ PFN_vkCmdSetDepthBias CmdSetDepthBias;
+ PFN_vkCmdSetBlendConstants CmdSetBlendConstants;
+ PFN_vkCmdSetDepthBounds CmdSetDepthBounds;
+ PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask;
+ PFN_vkCmdSetStencilWriteMask CmdSetStencilWriteMask;
+ PFN_vkCmdSetStencilReference CmdSetStencilReference;
+ PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets;
+ PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer;
+ PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers;
+ PFN_vkCmdDraw CmdDraw;
+ PFN_vkCmdDrawIndexed CmdDrawIndexed;
+ PFN_vkCmdDrawIndirect CmdDrawIndirect;
+ PFN_vkCmdDrawIndexedIndirect CmdDrawIndexedIndirect;
+ PFN_vkCmdDispatch CmdDispatch;
+ PFN_vkCmdDispatchIndirect CmdDispatchIndirect;
+ PFN_vkCmdCopyBuffer CmdCopyBuffer;
+ PFN_vkCmdCopyImage CmdCopyImage;
+ PFN_vkCmdBlitImage CmdBlitImage;
+ PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage;
+ PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer;
+ PFN_vkCmdUpdateBuffer CmdUpdateBuffer;
+ PFN_vkCmdFillBuffer CmdFillBuffer;
+ PFN_vkCmdClearColorImage CmdClearColorImage;
+ PFN_vkCmdClearDepthStencilImage CmdClearDepthStencilImage;
+ PFN_vkCmdClearAttachments CmdClearAttachments;
+ PFN_vkCmdResolveImage CmdResolveImage;
+ PFN_vkCmdSetEvent CmdSetEvent;
+ PFN_vkCmdResetEvent CmdResetEvent;
+ PFN_vkCmdWaitEvents CmdWaitEvents;
+ PFN_vkCmdPipelineBarrier CmdPipelineBarrier;
+ PFN_vkCmdBeginQuery CmdBeginQuery;
+ PFN_vkCmdEndQuery CmdEndQuery;
+ PFN_vkCmdResetQueryPool CmdResetQueryPool;
+ PFN_vkCmdWriteTimestamp CmdWriteTimestamp;
+ PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults;
+ PFN_vkCmdPushConstants CmdPushConstants;
+ PFN_vkCmdBeginRenderPass CmdBeginRenderPass;
+ PFN_vkCmdNextSubpass CmdNextSubpass;
+ PFN_vkCmdEndRenderPass CmdEndRenderPass;
+ PFN_vkCmdExecuteCommands CmdExecuteCommands;
+
+ // ---- Core 1_1 commands
+ PFN_vkBindBufferMemory2 BindBufferMemory2;
+ PFN_vkBindImageMemory2 BindImageMemory2;
+ PFN_vkGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeatures;
+ PFN_vkCmdSetDeviceMask CmdSetDeviceMask;
+ PFN_vkCmdDispatchBase CmdDispatchBase;
+ PFN_vkGetImageMemoryRequirements2 GetImageMemoryRequirements2;
+ PFN_vkGetBufferMemoryRequirements2 GetBufferMemoryRequirements2;
+ PFN_vkGetImageSparseMemoryRequirements2 GetImageSparseMemoryRequirements2;
+ PFN_vkTrimCommandPool TrimCommandPool;
+ PFN_vkGetDeviceQueue2 GetDeviceQueue2;
+ PFN_vkCreateSamplerYcbcrConversion CreateSamplerYcbcrConversion;
+ PFN_vkDestroySamplerYcbcrConversion DestroySamplerYcbcrConversion;
+ PFN_vkCreateDescriptorUpdateTemplate CreateDescriptorUpdateTemplate;
+ PFN_vkDestroyDescriptorUpdateTemplate DestroyDescriptorUpdateTemplate;
+ PFN_vkUpdateDescriptorSetWithTemplate UpdateDescriptorSetWithTemplate;
+ PFN_vkGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupport;
+
+ // ---- VK_KHR_swapchain extension commands
+ PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
+ PFN_vkDestroySwapchainKHR DestroySwapchainKHR;
+ PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR;
+ PFN_vkAcquireNextImageKHR AcquireNextImageKHR;
+ PFN_vkQueuePresentKHR QueuePresentKHR;
+ PFN_vkGetDeviceGroupPresentCapabilitiesKHR GetDeviceGroupPresentCapabilitiesKHR;
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR;
+ PFN_vkAcquireNextImage2KHR AcquireNextImage2KHR;
+
+ // ---- VK_KHR_display_swapchain extension commands
+ PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR;
+
+ // ---- VK_KHR_device_group extension commands
+ PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR GetDeviceGroupPeerMemoryFeaturesKHR;
+ PFN_vkCmdSetDeviceMaskKHR CmdSetDeviceMaskKHR;
+ PFN_vkCmdDispatchBaseKHR CmdDispatchBaseKHR;
+
+ // ---- VK_KHR_maintenance1 extension commands
+ PFN_vkTrimCommandPoolKHR TrimCommandPoolKHR;
+
+ // ---- VK_KHR_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetMemoryWin32HandleKHR GetMemoryWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetMemoryWin32HandlePropertiesKHR GetMemoryWin32HandlePropertiesKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_memory_fd extension commands
+ PFN_vkGetMemoryFdKHR GetMemoryFdKHR;
+ PFN_vkGetMemoryFdPropertiesKHR GetMemoryFdPropertiesKHR;
+
+ // ---- VK_KHR_external_semaphore_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkImportSemaphoreWin32HandleKHR ImportSemaphoreWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetSemaphoreWin32HandleKHR GetSemaphoreWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_semaphore_fd extension commands
+ PFN_vkImportSemaphoreFdKHR ImportSemaphoreFdKHR;
+ PFN_vkGetSemaphoreFdKHR GetSemaphoreFdKHR;
+
+ // ---- VK_KHR_push_descriptor extension commands
+ PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSetKHR;
+ PFN_vkCmdPushDescriptorSetWithTemplateKHR CmdPushDescriptorSetWithTemplateKHR;
+
+ // ---- VK_KHR_descriptor_update_template extension commands
+ PFN_vkCreateDescriptorUpdateTemplateKHR CreateDescriptorUpdateTemplateKHR;
+ PFN_vkDestroyDescriptorUpdateTemplateKHR DestroyDescriptorUpdateTemplateKHR;
+ PFN_vkUpdateDescriptorSetWithTemplateKHR UpdateDescriptorSetWithTemplateKHR;
+
+ // ---- VK_KHR_create_renderpass2 extension commands
+ PFN_vkCreateRenderPass2KHR CreateRenderPass2KHR;
+ PFN_vkCmdBeginRenderPass2KHR CmdBeginRenderPass2KHR;
+ PFN_vkCmdNextSubpass2KHR CmdNextSubpass2KHR;
+ PFN_vkCmdEndRenderPass2KHR CmdEndRenderPass2KHR;
+
+ // ---- VK_KHR_shared_presentable_image extension commands
+ PFN_vkGetSwapchainStatusKHR GetSwapchainStatusKHR;
+
+ // ---- VK_KHR_external_fence_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkImportFenceWin32HandleKHR ImportFenceWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetFenceWin32HandleKHR GetFenceWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_fence_fd extension commands
+ PFN_vkImportFenceFdKHR ImportFenceFdKHR;
+ PFN_vkGetFenceFdKHR GetFenceFdKHR;
+
+ // ---- VK_KHR_get_memory_requirements2 extension commands
+ PFN_vkGetImageMemoryRequirements2KHR GetImageMemoryRequirements2KHR;
+ PFN_vkGetBufferMemoryRequirements2KHR GetBufferMemoryRequirements2KHR;
+ PFN_vkGetImageSparseMemoryRequirements2KHR GetImageSparseMemoryRequirements2KHR;
+
+ // ---- VK_KHR_sampler_ycbcr_conversion extension commands
+ PFN_vkCreateSamplerYcbcrConversionKHR CreateSamplerYcbcrConversionKHR;
+ PFN_vkDestroySamplerYcbcrConversionKHR DestroySamplerYcbcrConversionKHR;
+
+ // ---- VK_KHR_bind_memory2 extension commands
+ PFN_vkBindBufferMemory2KHR BindBufferMemory2KHR;
+ PFN_vkBindImageMemory2KHR BindImageMemory2KHR;
+
+ // ---- VK_KHR_maintenance3 extension commands
+ PFN_vkGetDescriptorSetLayoutSupportKHR GetDescriptorSetLayoutSupportKHR;
+
+ // ---- VK_KHR_draw_indirect_count extension commands
+ PFN_vkCmdDrawIndirectCountKHR CmdDrawIndirectCountKHR;
+ PFN_vkCmdDrawIndexedIndirectCountKHR CmdDrawIndexedIndirectCountKHR;
+
+ // ---- VK_KHR_timeline_semaphore extension commands
+ PFN_vkGetSemaphoreCounterValueKHR GetSemaphoreCounterValueKHR;
+ PFN_vkWaitSemaphoresKHR WaitSemaphoresKHR;
+ PFN_vkSignalSemaphoreKHR SignalSemaphoreKHR;
+
+ // ---- VK_KHR_pipeline_executable_properties extension commands
+ PFN_vkGetPipelineExecutablePropertiesKHR GetPipelineExecutablePropertiesKHR;
+ PFN_vkGetPipelineExecutableStatisticsKHR GetPipelineExecutableStatisticsKHR;
+ PFN_vkGetPipelineExecutableInternalRepresentationsKHR GetPipelineExecutableInternalRepresentationsKHR;
+
+ // ---- VK_EXT_debug_marker extension commands
+ PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
+ PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
+ PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT;
+ PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT;
+ PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT;
+
+ // ---- VK_EXT_transform_feedback extension commands
+ PFN_vkCmdBindTransformFeedbackBuffersEXT CmdBindTransformFeedbackBuffersEXT;
+ PFN_vkCmdBeginTransformFeedbackEXT CmdBeginTransformFeedbackEXT;
+ PFN_vkCmdEndTransformFeedbackEXT CmdEndTransformFeedbackEXT;
+ PFN_vkCmdBeginQueryIndexedEXT CmdBeginQueryIndexedEXT;
+ PFN_vkCmdEndQueryIndexedEXT CmdEndQueryIndexedEXT;
+ PFN_vkCmdDrawIndirectByteCountEXT CmdDrawIndirectByteCountEXT;
+
+ // ---- VK_NVX_image_view_handle extension commands
+ PFN_vkGetImageViewHandleNVX GetImageViewHandleNVX;
+
+ // ---- VK_AMD_draw_indirect_count extension commands
+ PFN_vkCmdDrawIndirectCountAMD CmdDrawIndirectCountAMD;
+ PFN_vkCmdDrawIndexedIndirectCountAMD CmdDrawIndexedIndirectCountAMD;
+
+ // ---- VK_AMD_shader_info extension commands
+ PFN_vkGetShaderInfoAMD GetShaderInfoAMD;
+
+ // ---- VK_NV_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetMemoryWin32HandleNV GetMemoryWin32HandleNV;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_conditional_rendering extension commands
+ PFN_vkCmdBeginConditionalRenderingEXT CmdBeginConditionalRenderingEXT;
+ PFN_vkCmdEndConditionalRenderingEXT CmdEndConditionalRenderingEXT;
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ PFN_vkCmdProcessCommandsNVX CmdProcessCommandsNVX;
+ PFN_vkCmdReserveSpaceForCommandsNVX CmdReserveSpaceForCommandsNVX;
+ PFN_vkCreateIndirectCommandsLayoutNVX CreateIndirectCommandsLayoutNVX;
+ PFN_vkDestroyIndirectCommandsLayoutNVX DestroyIndirectCommandsLayoutNVX;
+ PFN_vkCreateObjectTableNVX CreateObjectTableNVX;
+ PFN_vkDestroyObjectTableNVX DestroyObjectTableNVX;
+ PFN_vkRegisterObjectsNVX RegisterObjectsNVX;
+ PFN_vkUnregisterObjectsNVX UnregisterObjectsNVX;
+
+ // ---- VK_NV_clip_space_w_scaling extension commands
+ PFN_vkCmdSetViewportWScalingNV CmdSetViewportWScalingNV;
+
+ // ---- VK_EXT_display_control extension commands
+ PFN_vkDisplayPowerControlEXT DisplayPowerControlEXT;
+ PFN_vkRegisterDeviceEventEXT RegisterDeviceEventEXT;
+ PFN_vkRegisterDisplayEventEXT RegisterDisplayEventEXT;
+ PFN_vkGetSwapchainCounterEXT GetSwapchainCounterEXT;
+
+ // ---- VK_GOOGLE_display_timing extension commands
+ PFN_vkGetRefreshCycleDurationGOOGLE GetRefreshCycleDurationGOOGLE;
+ PFN_vkGetPastPresentationTimingGOOGLE GetPastPresentationTimingGOOGLE;
+
+ // ---- VK_EXT_discard_rectangles extension commands
+ PFN_vkCmdSetDiscardRectangleEXT CmdSetDiscardRectangleEXT;
+
+ // ---- VK_EXT_hdr_metadata extension commands
+ PFN_vkSetHdrMetadataEXT SetHdrMetadataEXT;
+
+ // ---- VK_EXT_debug_utils extension commands
+ PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
+ PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT;
+ PFN_vkQueueBeginDebugUtilsLabelEXT QueueBeginDebugUtilsLabelEXT;
+ PFN_vkQueueEndDebugUtilsLabelEXT QueueEndDebugUtilsLabelEXT;
+ PFN_vkQueueInsertDebugUtilsLabelEXT QueueInsertDebugUtilsLabelEXT;
+ PFN_vkCmdBeginDebugUtilsLabelEXT CmdBeginDebugUtilsLabelEXT;
+ PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT;
+ PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT;
+
+ // ---- VK_ANDROID_external_memory_android_hardware_buffer extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ PFN_vkGetAndroidHardwareBufferPropertiesANDROID GetAndroidHardwareBufferPropertiesANDROID;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ PFN_vkGetMemoryAndroidHardwareBufferANDROID GetMemoryAndroidHardwareBufferANDROID;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_EXT_sample_locations extension commands
+ PFN_vkCmdSetSampleLocationsEXT CmdSetSampleLocationsEXT;
+
+ // ---- VK_EXT_image_drm_format_modifier extension commands
+ PFN_vkGetImageDrmFormatModifierPropertiesEXT GetImageDrmFormatModifierPropertiesEXT;
+
+ // ---- VK_EXT_validation_cache extension commands
+ PFN_vkCreateValidationCacheEXT CreateValidationCacheEXT;
+ PFN_vkDestroyValidationCacheEXT DestroyValidationCacheEXT;
+ PFN_vkMergeValidationCachesEXT MergeValidationCachesEXT;
+ PFN_vkGetValidationCacheDataEXT GetValidationCacheDataEXT;
+
+ // ---- VK_NV_shading_rate_image extension commands
+ PFN_vkCmdBindShadingRateImageNV CmdBindShadingRateImageNV;
+ PFN_vkCmdSetViewportShadingRatePaletteNV CmdSetViewportShadingRatePaletteNV;
+ PFN_vkCmdSetCoarseSampleOrderNV CmdSetCoarseSampleOrderNV;
+
+ // ---- VK_NV_ray_tracing extension commands
+ PFN_vkCreateAccelerationStructureNV CreateAccelerationStructureNV;
+ PFN_vkDestroyAccelerationStructureNV DestroyAccelerationStructureNV;
+ PFN_vkGetAccelerationStructureMemoryRequirementsNV GetAccelerationStructureMemoryRequirementsNV;
+ PFN_vkBindAccelerationStructureMemoryNV BindAccelerationStructureMemoryNV;
+ PFN_vkCmdBuildAccelerationStructureNV CmdBuildAccelerationStructureNV;
+ PFN_vkCmdCopyAccelerationStructureNV CmdCopyAccelerationStructureNV;
+ PFN_vkCmdTraceRaysNV CmdTraceRaysNV;
+ PFN_vkCreateRayTracingPipelinesNV CreateRayTracingPipelinesNV;
+ PFN_vkGetRayTracingShaderGroupHandlesNV GetRayTracingShaderGroupHandlesNV;
+ PFN_vkGetAccelerationStructureHandleNV GetAccelerationStructureHandleNV;
+ PFN_vkCmdWriteAccelerationStructuresPropertiesNV CmdWriteAccelerationStructuresPropertiesNV;
+ PFN_vkCompileDeferredNV CompileDeferredNV;
+
+ // ---- VK_EXT_external_memory_host extension commands
+ PFN_vkGetMemoryHostPointerPropertiesEXT GetMemoryHostPointerPropertiesEXT;
+
+ // ---- VK_AMD_buffer_marker extension commands
+ PFN_vkCmdWriteBufferMarkerAMD CmdWriteBufferMarkerAMD;
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ PFN_vkGetCalibratedTimestampsEXT GetCalibratedTimestampsEXT;
+
+ // ---- VK_NV_mesh_shader extension commands
+ PFN_vkCmdDrawMeshTasksNV CmdDrawMeshTasksNV;
+ PFN_vkCmdDrawMeshTasksIndirectNV CmdDrawMeshTasksIndirectNV;
+ PFN_vkCmdDrawMeshTasksIndirectCountNV CmdDrawMeshTasksIndirectCountNV;
+
+ // ---- VK_NV_scissor_exclusive extension commands
+ PFN_vkCmdSetExclusiveScissorNV CmdSetExclusiveScissorNV;
+
+ // ---- VK_NV_device_diagnostic_checkpoints extension commands
+ PFN_vkCmdSetCheckpointNV CmdSetCheckpointNV;
+ PFN_vkGetQueueCheckpointDataNV GetQueueCheckpointDataNV;
+
+ // ---- VK_INTEL_performance_query extension commands
+ PFN_vkInitializePerformanceApiINTEL InitializePerformanceApiINTEL;
+ PFN_vkUninitializePerformanceApiINTEL UninitializePerformanceApiINTEL;
+ PFN_vkCmdSetPerformanceMarkerINTEL CmdSetPerformanceMarkerINTEL;
+ PFN_vkCmdSetPerformanceStreamMarkerINTEL CmdSetPerformanceStreamMarkerINTEL;
+ PFN_vkCmdSetPerformanceOverrideINTEL CmdSetPerformanceOverrideINTEL;
+ PFN_vkAcquirePerformanceConfigurationINTEL AcquirePerformanceConfigurationINTEL;
+ PFN_vkReleasePerformanceConfigurationINTEL ReleasePerformanceConfigurationINTEL;
+ PFN_vkQueueSetPerformanceConfigurationINTEL QueueSetPerformanceConfigurationINTEL;
+ PFN_vkGetPerformanceParameterINTEL GetPerformanceParameterINTEL;
+
+ // ---- VK_AMD_display_native_hdr extension commands
+ PFN_vkSetLocalDimmingAMD SetLocalDimmingAMD;
+
+ // ---- VK_EXT_buffer_device_address extension commands
+ PFN_vkGetBufferDeviceAddressEXT GetBufferDeviceAddressEXT;
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkAcquireFullScreenExclusiveModeEXT AcquireFullScreenExclusiveModeEXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkReleaseFullScreenExclusiveModeEXT ReleaseFullScreenExclusiveModeEXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_line_rasterization extension commands
+ PFN_vkCmdSetLineStippleEXT CmdSetLineStippleEXT;
+
+ // ---- VK_EXT_host_query_reset extension commands
+ PFN_vkResetQueryPoolEXT ResetQueryPoolEXT;
+} VkLayerDispatchTable;
+
+
diff --git a/thirdparty/vulkan/loader/vk_loader_extensions.c b/thirdparty/vulkan/loader/vk_loader_extensions.c
new file mode 100644
index 0000000000..c7a55cf11a
--- /dev/null
+++ b/thirdparty/vulkan/loader/vk_loader_extensions.c
@@ -0,0 +1,4448 @@
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See loader_extension_generator.py for modifications
+
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Mark Young <marky@lunarg.com>
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "vk_loader_platform.h"
+#include "loader.h"
+#include "vk_loader_extensions.h"
+#include <vulkan/vk_icd.h>
+#include "wsi.h"
+#include "debug_utils.h"
+#include "extension_manual.h"
+
+// Device extension error function
+VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev) {
+ struct loader_device *found_dev;
+ // The device going in is a trampoline device
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(dev, &found_dev, NULL);
+
+ if (icd_term)
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "Bad destination in loader trampoline dispatch,"
+ "Are layers and extensions that you are calling enabled?");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+}
+
+VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_term, VkInstance inst,
+ const PFN_vkGetInstanceProcAddr fp_gipa) {
+
+#define LOOKUP_GIPA(func, required) \
+ do { \
+ icd_term->dispatch.func = (PFN_vk##func)fp_gipa(inst, "vk" #func); \
+ if (!icd_term->dispatch.func && required) { \
+ loader_log((struct loader_instance *)inst, VK_DEBUG_REPORT_WARNING_BIT_EXT, 0, \
+ loader_platform_get_proc_address_error("vk" #func)); \
+ return false; \
+ } \
+ } while (0)
+
+
+ // ---- Core 1_0
+ LOOKUP_GIPA(DestroyInstance, true);
+ LOOKUP_GIPA(EnumeratePhysicalDevices, true);
+ LOOKUP_GIPA(GetPhysicalDeviceFeatures, true);
+ LOOKUP_GIPA(GetPhysicalDeviceFormatProperties, true);
+ LOOKUP_GIPA(GetPhysicalDeviceImageFormatProperties, true);
+ LOOKUP_GIPA(GetPhysicalDeviceProperties, true);
+ LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyProperties, true);
+ LOOKUP_GIPA(GetPhysicalDeviceMemoryProperties, true);
+ LOOKUP_GIPA(GetDeviceProcAddr, true);
+ LOOKUP_GIPA(CreateDevice, true);
+ LOOKUP_GIPA(EnumerateDeviceExtensionProperties, true);
+ LOOKUP_GIPA(GetPhysicalDeviceSparseImageFormatProperties, true);
+
+ // ---- Core 1_1
+ LOOKUP_GIPA(EnumeratePhysicalDeviceGroups, false);
+ LOOKUP_GIPA(GetPhysicalDeviceFeatures2, false);
+ LOOKUP_GIPA(GetPhysicalDeviceProperties2, false);
+ LOOKUP_GIPA(GetPhysicalDeviceFormatProperties2, false);
+ LOOKUP_GIPA(GetPhysicalDeviceImageFormatProperties2, false);
+ LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyProperties2, false);
+ LOOKUP_GIPA(GetPhysicalDeviceMemoryProperties2, false);
+ LOOKUP_GIPA(GetPhysicalDeviceSparseImageFormatProperties2, false);
+ LOOKUP_GIPA(GetPhysicalDeviceExternalBufferProperties, false);
+ LOOKUP_GIPA(GetPhysicalDeviceExternalFenceProperties, false);
+ LOOKUP_GIPA(GetPhysicalDeviceExternalSemaphoreProperties, false);
+
+ // ---- VK_KHR_surface extension commands
+ LOOKUP_GIPA(DestroySurfaceKHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceSurfaceSupportKHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceSurfaceCapabilitiesKHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceSurfaceFormatsKHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceSurfacePresentModesKHR, false);
+
+ // ---- VK_KHR_swapchain extension commands
+ LOOKUP_GIPA(CreateSwapchainKHR, false);
+ LOOKUP_GIPA(GetDeviceGroupSurfacePresentModesKHR, false);
+ LOOKUP_GIPA(GetPhysicalDevicePresentRectanglesKHR, false);
+
+ // ---- VK_KHR_display extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceDisplayPropertiesKHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceDisplayPlanePropertiesKHR, false);
+ LOOKUP_GIPA(GetDisplayPlaneSupportedDisplaysKHR, false);
+ LOOKUP_GIPA(GetDisplayModePropertiesKHR, false);
+ LOOKUP_GIPA(CreateDisplayModeKHR, false);
+ LOOKUP_GIPA(GetDisplayPlaneCapabilitiesKHR, false);
+ LOOKUP_GIPA(CreateDisplayPlaneSurfaceKHR, false);
+
+ // ---- VK_KHR_display_swapchain extension commands
+ LOOKUP_GIPA(CreateSharedSwapchainsKHR, false);
+
+ // ---- VK_KHR_xlib_surface extension commands
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ LOOKUP_GIPA(CreateXlibSurfaceKHR, false);
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ LOOKUP_GIPA(GetPhysicalDeviceXlibPresentationSupportKHR, false);
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+ // ---- VK_KHR_xcb_surface extension commands
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ LOOKUP_GIPA(CreateXcbSurfaceKHR, false);
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ LOOKUP_GIPA(GetPhysicalDeviceXcbPresentationSupportKHR, false);
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+ // ---- VK_KHR_wayland_surface extension commands
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ LOOKUP_GIPA(CreateWaylandSurfaceKHR, false);
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ LOOKUP_GIPA(GetPhysicalDeviceWaylandPresentationSupportKHR, false);
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+ // ---- VK_KHR_android_surface extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ LOOKUP_GIPA(CreateAndroidSurfaceKHR, false);
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_KHR_win32_surface extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ LOOKUP_GIPA(CreateWin32SurfaceKHR, false);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ LOOKUP_GIPA(GetPhysicalDeviceWin32PresentationSupportKHR, false);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceFeatures2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceProperties2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceFormatProperties2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceImageFormatProperties2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyProperties2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceMemoryProperties2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceSparseImageFormatProperties2KHR, false);
+
+ // ---- VK_KHR_device_group_creation extension commands
+ LOOKUP_GIPA(EnumeratePhysicalDeviceGroupsKHR, false);
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceExternalBufferPropertiesKHR, false);
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceExternalSemaphorePropertiesKHR, false);
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceExternalFencePropertiesKHR, false);
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceSurfaceCapabilities2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceSurfaceFormats2KHR, false);
+
+ // ---- VK_KHR_get_display_properties2 extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceDisplayProperties2KHR, false);
+ LOOKUP_GIPA(GetPhysicalDeviceDisplayPlaneProperties2KHR, false);
+ LOOKUP_GIPA(GetDisplayModeProperties2KHR, false);
+ LOOKUP_GIPA(GetDisplayPlaneCapabilities2KHR, false);
+
+ // ---- VK_EXT_debug_report extension commands
+ LOOKUP_GIPA(CreateDebugReportCallbackEXT, false);
+ LOOKUP_GIPA(DestroyDebugReportCallbackEXT, false);
+ LOOKUP_GIPA(DebugReportMessageEXT, false);
+
+ // ---- VK_EXT_debug_marker extension commands
+ LOOKUP_GIPA(DebugMarkerSetObjectTagEXT, false);
+ LOOKUP_GIPA(DebugMarkerSetObjectNameEXT, false);
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ LOOKUP_GIPA(CreateStreamDescriptorSurfaceGGP, false);
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceExternalImageFormatPropertiesNV, false);
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ LOOKUP_GIPA(CreateViSurfaceNN, false);
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceGeneratedCommandsPropertiesNVX, false);
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ LOOKUP_GIPA(ReleaseDisplayEXT, false);
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ LOOKUP_GIPA(AcquireXlibDisplayEXT, false);
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ LOOKUP_GIPA(GetRandROutputDisplayEXT, false);
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceSurfaceCapabilities2EXT, false);
+
+ // ---- VK_MVK_ios_surface extension commands
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ LOOKUP_GIPA(CreateIOSSurfaceMVK, false);
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+ // ---- VK_MVK_macos_surface extension commands
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ LOOKUP_GIPA(CreateMacOSSurfaceMVK, false);
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+ // ---- VK_EXT_debug_utils extension commands
+ LOOKUP_GIPA(SetDebugUtilsObjectNameEXT, false);
+ LOOKUP_GIPA(SetDebugUtilsObjectTagEXT, false);
+ LOOKUP_GIPA(CreateDebugUtilsMessengerEXT, false);
+ LOOKUP_GIPA(DestroyDebugUtilsMessengerEXT, false);
+ LOOKUP_GIPA(SubmitDebugUtilsMessageEXT, false);
+
+ // ---- VK_EXT_sample_locations extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceMultisamplePropertiesEXT, false);
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceCalibrateableTimeDomainsEXT, false);
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ LOOKUP_GIPA(CreateImagePipeSurfaceFUCHSIA, false);
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ // ---- VK_EXT_metal_surface extension commands
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ LOOKUP_GIPA(CreateMetalSurfaceEXT, false);
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ // ---- VK_NV_cooperative_matrix extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceCooperativeMatrixPropertiesNV, false);
+
+ // ---- VK_NV_coverage_reduction_mode extension commands
+ LOOKUP_GIPA(GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV, false);
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ LOOKUP_GIPA(GetPhysicalDeviceSurfacePresentModes2EXT, false);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ LOOKUP_GIPA(GetDeviceGroupSurfacePresentModes2EXT, false);
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_headless_surface extension commands
+ LOOKUP_GIPA(CreateHeadlessSurfaceEXT, false);
+
+#undef LOOKUP_GIPA
+
+ return true;
+};
+
+// Init Device function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,
+ VkDevice dev) {
+ VkLayerDispatchTable *table = &dev_table->core_dispatch;
+ for (uint32_t i = 0; i < MAX_NUM_UNKNOWN_EXTS; i++) dev_table->ext_dispatch.dev_ext[i] = (PFN_vkDevExt)vkDevExtError;
+
+ // ---- Core 1_0 commands
+ table->GetDeviceProcAddr = gpa;
+ table->DestroyDevice = (PFN_vkDestroyDevice)gpa(dev, "vkDestroyDevice");
+ table->GetDeviceQueue = (PFN_vkGetDeviceQueue)gpa(dev, "vkGetDeviceQueue");
+ table->QueueSubmit = (PFN_vkQueueSubmit)gpa(dev, "vkQueueSubmit");
+ table->QueueWaitIdle = (PFN_vkQueueWaitIdle)gpa(dev, "vkQueueWaitIdle");
+ table->DeviceWaitIdle = (PFN_vkDeviceWaitIdle)gpa(dev, "vkDeviceWaitIdle");
+ table->AllocateMemory = (PFN_vkAllocateMemory)gpa(dev, "vkAllocateMemory");
+ table->FreeMemory = (PFN_vkFreeMemory)gpa(dev, "vkFreeMemory");
+ table->MapMemory = (PFN_vkMapMemory)gpa(dev, "vkMapMemory");
+ table->UnmapMemory = (PFN_vkUnmapMemory)gpa(dev, "vkUnmapMemory");
+ table->FlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)gpa(dev, "vkFlushMappedMemoryRanges");
+ table->InvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)gpa(dev, "vkInvalidateMappedMemoryRanges");
+ table->GetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)gpa(dev, "vkGetDeviceMemoryCommitment");
+ table->BindBufferMemory = (PFN_vkBindBufferMemory)gpa(dev, "vkBindBufferMemory");
+ table->BindImageMemory = (PFN_vkBindImageMemory)gpa(dev, "vkBindImageMemory");
+ table->GetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)gpa(dev, "vkGetBufferMemoryRequirements");
+ table->GetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)gpa(dev, "vkGetImageMemoryRequirements");
+ table->GetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements)gpa(dev, "vkGetImageSparseMemoryRequirements");
+ table->QueueBindSparse = (PFN_vkQueueBindSparse)gpa(dev, "vkQueueBindSparse");
+ table->CreateFence = (PFN_vkCreateFence)gpa(dev, "vkCreateFence");
+ table->DestroyFence = (PFN_vkDestroyFence)gpa(dev, "vkDestroyFence");
+ table->ResetFences = (PFN_vkResetFences)gpa(dev, "vkResetFences");
+ table->GetFenceStatus = (PFN_vkGetFenceStatus)gpa(dev, "vkGetFenceStatus");
+ table->WaitForFences = (PFN_vkWaitForFences)gpa(dev, "vkWaitForFences");
+ table->CreateSemaphore = (PFN_vkCreateSemaphore)gpa(dev, "vkCreateSemaphore");
+ table->DestroySemaphore = (PFN_vkDestroySemaphore)gpa(dev, "vkDestroySemaphore");
+ table->CreateEvent = (PFN_vkCreateEvent)gpa(dev, "vkCreateEvent");
+ table->DestroyEvent = (PFN_vkDestroyEvent)gpa(dev, "vkDestroyEvent");
+ table->GetEventStatus = (PFN_vkGetEventStatus)gpa(dev, "vkGetEventStatus");
+ table->SetEvent = (PFN_vkSetEvent)gpa(dev, "vkSetEvent");
+ table->ResetEvent = (PFN_vkResetEvent)gpa(dev, "vkResetEvent");
+ table->CreateQueryPool = (PFN_vkCreateQueryPool)gpa(dev, "vkCreateQueryPool");
+ table->DestroyQueryPool = (PFN_vkDestroyQueryPool)gpa(dev, "vkDestroyQueryPool");
+ table->GetQueryPoolResults = (PFN_vkGetQueryPoolResults)gpa(dev, "vkGetQueryPoolResults");
+ table->CreateBuffer = (PFN_vkCreateBuffer)gpa(dev, "vkCreateBuffer");
+ table->DestroyBuffer = (PFN_vkDestroyBuffer)gpa(dev, "vkDestroyBuffer");
+ table->CreateBufferView = (PFN_vkCreateBufferView)gpa(dev, "vkCreateBufferView");
+ table->DestroyBufferView = (PFN_vkDestroyBufferView)gpa(dev, "vkDestroyBufferView");
+ table->CreateImage = (PFN_vkCreateImage)gpa(dev, "vkCreateImage");
+ table->DestroyImage = (PFN_vkDestroyImage)gpa(dev, "vkDestroyImage");
+ table->GetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)gpa(dev, "vkGetImageSubresourceLayout");
+ table->CreateImageView = (PFN_vkCreateImageView)gpa(dev, "vkCreateImageView");
+ table->DestroyImageView = (PFN_vkDestroyImageView)gpa(dev, "vkDestroyImageView");
+ table->CreateShaderModule = (PFN_vkCreateShaderModule)gpa(dev, "vkCreateShaderModule");
+ table->DestroyShaderModule = (PFN_vkDestroyShaderModule)gpa(dev, "vkDestroyShaderModule");
+ table->CreatePipelineCache = (PFN_vkCreatePipelineCache)gpa(dev, "vkCreatePipelineCache");
+ table->DestroyPipelineCache = (PFN_vkDestroyPipelineCache)gpa(dev, "vkDestroyPipelineCache");
+ table->GetPipelineCacheData = (PFN_vkGetPipelineCacheData)gpa(dev, "vkGetPipelineCacheData");
+ table->MergePipelineCaches = (PFN_vkMergePipelineCaches)gpa(dev, "vkMergePipelineCaches");
+ table->CreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)gpa(dev, "vkCreateGraphicsPipelines");
+ table->CreateComputePipelines = (PFN_vkCreateComputePipelines)gpa(dev, "vkCreateComputePipelines");
+ table->DestroyPipeline = (PFN_vkDestroyPipeline)gpa(dev, "vkDestroyPipeline");
+ table->CreatePipelineLayout = (PFN_vkCreatePipelineLayout)gpa(dev, "vkCreatePipelineLayout");
+ table->DestroyPipelineLayout = (PFN_vkDestroyPipelineLayout)gpa(dev, "vkDestroyPipelineLayout");
+ table->CreateSampler = (PFN_vkCreateSampler)gpa(dev, "vkCreateSampler");
+ table->DestroySampler = (PFN_vkDestroySampler)gpa(dev, "vkDestroySampler");
+ table->CreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)gpa(dev, "vkCreateDescriptorSetLayout");
+ table->DestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)gpa(dev, "vkDestroyDescriptorSetLayout");
+ table->CreateDescriptorPool = (PFN_vkCreateDescriptorPool)gpa(dev, "vkCreateDescriptorPool");
+ table->DestroyDescriptorPool = (PFN_vkDestroyDescriptorPool)gpa(dev, "vkDestroyDescriptorPool");
+ table->ResetDescriptorPool = (PFN_vkResetDescriptorPool)gpa(dev, "vkResetDescriptorPool");
+ table->AllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)gpa(dev, "vkAllocateDescriptorSets");
+ table->FreeDescriptorSets = (PFN_vkFreeDescriptorSets)gpa(dev, "vkFreeDescriptorSets");
+ table->UpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)gpa(dev, "vkUpdateDescriptorSets");
+ table->CreateFramebuffer = (PFN_vkCreateFramebuffer)gpa(dev, "vkCreateFramebuffer");
+ table->DestroyFramebuffer = (PFN_vkDestroyFramebuffer)gpa(dev, "vkDestroyFramebuffer");
+ table->CreateRenderPass = (PFN_vkCreateRenderPass)gpa(dev, "vkCreateRenderPass");
+ table->DestroyRenderPass = (PFN_vkDestroyRenderPass)gpa(dev, "vkDestroyRenderPass");
+ table->GetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)gpa(dev, "vkGetRenderAreaGranularity");
+ table->CreateCommandPool = (PFN_vkCreateCommandPool)gpa(dev, "vkCreateCommandPool");
+ table->DestroyCommandPool = (PFN_vkDestroyCommandPool)gpa(dev, "vkDestroyCommandPool");
+ table->ResetCommandPool = (PFN_vkResetCommandPool)gpa(dev, "vkResetCommandPool");
+ table->AllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)gpa(dev, "vkAllocateCommandBuffers");
+ table->FreeCommandBuffers = (PFN_vkFreeCommandBuffers)gpa(dev, "vkFreeCommandBuffers");
+ table->BeginCommandBuffer = (PFN_vkBeginCommandBuffer)gpa(dev, "vkBeginCommandBuffer");
+ table->EndCommandBuffer = (PFN_vkEndCommandBuffer)gpa(dev, "vkEndCommandBuffer");
+ table->ResetCommandBuffer = (PFN_vkResetCommandBuffer)gpa(dev, "vkResetCommandBuffer");
+ table->CmdBindPipeline = (PFN_vkCmdBindPipeline)gpa(dev, "vkCmdBindPipeline");
+ table->CmdSetViewport = (PFN_vkCmdSetViewport)gpa(dev, "vkCmdSetViewport");
+ table->CmdSetScissor = (PFN_vkCmdSetScissor)gpa(dev, "vkCmdSetScissor");
+ table->CmdSetLineWidth = (PFN_vkCmdSetLineWidth)gpa(dev, "vkCmdSetLineWidth");
+ table->CmdSetDepthBias = (PFN_vkCmdSetDepthBias)gpa(dev, "vkCmdSetDepthBias");
+ table->CmdSetBlendConstants = (PFN_vkCmdSetBlendConstants)gpa(dev, "vkCmdSetBlendConstants");
+ table->CmdSetDepthBounds = (PFN_vkCmdSetDepthBounds)gpa(dev, "vkCmdSetDepthBounds");
+ table->CmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)gpa(dev, "vkCmdSetStencilCompareMask");
+ table->CmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)gpa(dev, "vkCmdSetStencilWriteMask");
+ table->CmdSetStencilReference = (PFN_vkCmdSetStencilReference)gpa(dev, "vkCmdSetStencilReference");
+ table->CmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)gpa(dev, "vkCmdBindDescriptorSets");
+ table->CmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)gpa(dev, "vkCmdBindIndexBuffer");
+ table->CmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)gpa(dev, "vkCmdBindVertexBuffers");
+ table->CmdDraw = (PFN_vkCmdDraw)gpa(dev, "vkCmdDraw");
+ table->CmdDrawIndexed = (PFN_vkCmdDrawIndexed)gpa(dev, "vkCmdDrawIndexed");
+ table->CmdDrawIndirect = (PFN_vkCmdDrawIndirect)gpa(dev, "vkCmdDrawIndirect");
+ table->CmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)gpa(dev, "vkCmdDrawIndexedIndirect");
+ table->CmdDispatch = (PFN_vkCmdDispatch)gpa(dev, "vkCmdDispatch");
+ table->CmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)gpa(dev, "vkCmdDispatchIndirect");
+ table->CmdCopyBuffer = (PFN_vkCmdCopyBuffer)gpa(dev, "vkCmdCopyBuffer");
+ table->CmdCopyImage = (PFN_vkCmdCopyImage)gpa(dev, "vkCmdCopyImage");
+ table->CmdBlitImage = (PFN_vkCmdBlitImage)gpa(dev, "vkCmdBlitImage");
+ table->CmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)gpa(dev, "vkCmdCopyBufferToImage");
+ table->CmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)gpa(dev, "vkCmdCopyImageToBuffer");
+ table->CmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)gpa(dev, "vkCmdUpdateBuffer");
+ table->CmdFillBuffer = (PFN_vkCmdFillBuffer)gpa(dev, "vkCmdFillBuffer");
+ table->CmdClearColorImage = (PFN_vkCmdClearColorImage)gpa(dev, "vkCmdClearColorImage");
+ table->CmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)gpa(dev, "vkCmdClearDepthStencilImage");
+ table->CmdClearAttachments = (PFN_vkCmdClearAttachments)gpa(dev, "vkCmdClearAttachments");
+ table->CmdResolveImage = (PFN_vkCmdResolveImage)gpa(dev, "vkCmdResolveImage");
+ table->CmdSetEvent = (PFN_vkCmdSetEvent)gpa(dev, "vkCmdSetEvent");
+ table->CmdResetEvent = (PFN_vkCmdResetEvent)gpa(dev, "vkCmdResetEvent");
+ table->CmdWaitEvents = (PFN_vkCmdWaitEvents)gpa(dev, "vkCmdWaitEvents");
+ table->CmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)gpa(dev, "vkCmdPipelineBarrier");
+ table->CmdBeginQuery = (PFN_vkCmdBeginQuery)gpa(dev, "vkCmdBeginQuery");
+ table->CmdEndQuery = (PFN_vkCmdEndQuery)gpa(dev, "vkCmdEndQuery");
+ table->CmdResetQueryPool = (PFN_vkCmdResetQueryPool)gpa(dev, "vkCmdResetQueryPool");
+ table->CmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)gpa(dev, "vkCmdWriteTimestamp");
+ table->CmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)gpa(dev, "vkCmdCopyQueryPoolResults");
+ table->CmdPushConstants = (PFN_vkCmdPushConstants)gpa(dev, "vkCmdPushConstants");
+ table->CmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)gpa(dev, "vkCmdBeginRenderPass");
+ table->CmdNextSubpass = (PFN_vkCmdNextSubpass)gpa(dev, "vkCmdNextSubpass");
+ table->CmdEndRenderPass = (PFN_vkCmdEndRenderPass)gpa(dev, "vkCmdEndRenderPass");
+ table->CmdExecuteCommands = (PFN_vkCmdExecuteCommands)gpa(dev, "vkCmdExecuteCommands");
+
+ // ---- Core 1_1 commands
+ table->BindBufferMemory2 = (PFN_vkBindBufferMemory2)gpa(dev, "vkBindBufferMemory2");
+ table->BindImageMemory2 = (PFN_vkBindImageMemory2)gpa(dev, "vkBindImageMemory2");
+ table->GetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures)gpa(dev, "vkGetDeviceGroupPeerMemoryFeatures");
+ table->CmdSetDeviceMask = (PFN_vkCmdSetDeviceMask)gpa(dev, "vkCmdSetDeviceMask");
+ table->CmdDispatchBase = (PFN_vkCmdDispatchBase)gpa(dev, "vkCmdDispatchBase");
+ table->GetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2)gpa(dev, "vkGetImageMemoryRequirements2");
+ table->GetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2)gpa(dev, "vkGetBufferMemoryRequirements2");
+ table->GetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2)gpa(dev, "vkGetImageSparseMemoryRequirements2");
+ table->TrimCommandPool = (PFN_vkTrimCommandPool)gpa(dev, "vkTrimCommandPool");
+ table->GetDeviceQueue2 = (PFN_vkGetDeviceQueue2)gpa(dev, "vkGetDeviceQueue2");
+ table->CreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)gpa(dev, "vkCreateSamplerYcbcrConversion");
+ table->DestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)gpa(dev, "vkDestroySamplerYcbcrConversion");
+ table->CreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate)gpa(dev, "vkCreateDescriptorUpdateTemplate");
+ table->DestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate)gpa(dev, "vkDestroyDescriptorUpdateTemplate");
+ table->UpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate)gpa(dev, "vkUpdateDescriptorSetWithTemplate");
+ table->GetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)gpa(dev, "vkGetDescriptorSetLayoutSupport");
+}
+
+// Init Device function pointer dispatch table with extension commands
+VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct loader_dev_dispatch_table *dev_table,
+ PFN_vkGetInstanceProcAddr gipa,
+ PFN_vkGetDeviceProcAddr gdpa,
+ VkInstance inst,
+ VkDevice dev) {
+ VkLayerDispatchTable *table = &dev_table->core_dispatch;
+
+ // ---- VK_KHR_swapchain extension commands
+ table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gdpa(dev, "vkCreateSwapchainKHR");
+ table->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gdpa(dev, "vkDestroySwapchainKHR");
+ table->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gdpa(dev, "vkGetSwapchainImagesKHR");
+ table->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gdpa(dev, "vkAcquireNextImageKHR");
+ table->QueuePresentKHR = (PFN_vkQueuePresentKHR)gdpa(dev, "vkQueuePresentKHR");
+ table->GetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)gdpa(dev, "vkGetDeviceGroupPresentCapabilitiesKHR");
+ table->GetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)gdpa(dev, "vkGetDeviceGroupSurfacePresentModesKHR");
+ table->AcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR)gdpa(dev, "vkAcquireNextImage2KHR");
+
+ // ---- VK_KHR_display_swapchain extension commands
+ table->CreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)gdpa(dev, "vkCreateSharedSwapchainsKHR");
+
+ // ---- VK_KHR_device_group extension commands
+ table->GetDeviceGroupPeerMemoryFeaturesKHR = (PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)gdpa(dev, "vkGetDeviceGroupPeerMemoryFeaturesKHR");
+ table->CmdSetDeviceMaskKHR = (PFN_vkCmdSetDeviceMaskKHR)gdpa(dev, "vkCmdSetDeviceMaskKHR");
+ table->CmdDispatchBaseKHR = (PFN_vkCmdDispatchBaseKHR)gdpa(dev, "vkCmdDispatchBaseKHR");
+
+ // ---- VK_KHR_maintenance1 extension commands
+ table->TrimCommandPoolKHR = (PFN_vkTrimCommandPoolKHR)gdpa(dev, "vkTrimCommandPoolKHR");
+
+ // ---- VK_KHR_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)gdpa(dev, "vkGetMemoryWin32HandleKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetMemoryWin32HandlePropertiesKHR = (PFN_vkGetMemoryWin32HandlePropertiesKHR)gdpa(dev, "vkGetMemoryWin32HandlePropertiesKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_memory_fd extension commands
+ table->GetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)gdpa(dev, "vkGetMemoryFdKHR");
+ table->GetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR)gdpa(dev, "vkGetMemoryFdPropertiesKHR");
+
+ // ---- VK_KHR_external_semaphore_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->ImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR)gdpa(dev, "vkImportSemaphoreWin32HandleKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR)gdpa(dev, "vkGetSemaphoreWin32HandleKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_semaphore_fd extension commands
+ table->ImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)gdpa(dev, "vkImportSemaphoreFdKHR");
+ table->GetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)gdpa(dev, "vkGetSemaphoreFdKHR");
+
+ // ---- VK_KHR_push_descriptor extension commands
+ table->CmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)gdpa(dev, "vkCmdPushDescriptorSetKHR");
+ table->CmdPushDescriptorSetWithTemplateKHR = (PFN_vkCmdPushDescriptorSetWithTemplateKHR)gdpa(dev, "vkCmdPushDescriptorSetWithTemplateKHR");
+
+ // ---- VK_KHR_descriptor_update_template extension commands
+ table->CreateDescriptorUpdateTemplateKHR = (PFN_vkCreateDescriptorUpdateTemplateKHR)gdpa(dev, "vkCreateDescriptorUpdateTemplateKHR");
+ table->DestroyDescriptorUpdateTemplateKHR = (PFN_vkDestroyDescriptorUpdateTemplateKHR)gdpa(dev, "vkDestroyDescriptorUpdateTemplateKHR");
+ table->UpdateDescriptorSetWithTemplateKHR = (PFN_vkUpdateDescriptorSetWithTemplateKHR)gdpa(dev, "vkUpdateDescriptorSetWithTemplateKHR");
+
+ // ---- VK_KHR_create_renderpass2 extension commands
+ table->CreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)gdpa(dev, "vkCreateRenderPass2KHR");
+ table->CmdBeginRenderPass2KHR = (PFN_vkCmdBeginRenderPass2KHR)gdpa(dev, "vkCmdBeginRenderPass2KHR");
+ table->CmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)gdpa(dev, "vkCmdNextSubpass2KHR");
+ table->CmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)gdpa(dev, "vkCmdEndRenderPass2KHR");
+
+ // ---- VK_KHR_shared_presentable_image extension commands
+ table->GetSwapchainStatusKHR = (PFN_vkGetSwapchainStatusKHR)gdpa(dev, "vkGetSwapchainStatusKHR");
+
+ // ---- VK_KHR_external_fence_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->ImportFenceWin32HandleKHR = (PFN_vkImportFenceWin32HandleKHR)gdpa(dev, "vkImportFenceWin32HandleKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR)gdpa(dev, "vkGetFenceWin32HandleKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_fence_fd extension commands
+ table->ImportFenceFdKHR = (PFN_vkImportFenceFdKHR)gdpa(dev, "vkImportFenceFdKHR");
+ table->GetFenceFdKHR = (PFN_vkGetFenceFdKHR)gdpa(dev, "vkGetFenceFdKHR");
+
+ // ---- VK_KHR_get_memory_requirements2 extension commands
+ table->GetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR)gdpa(dev, "vkGetImageMemoryRequirements2KHR");
+ table->GetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2KHR)gdpa(dev, "vkGetBufferMemoryRequirements2KHR");
+ table->GetImageSparseMemoryRequirements2KHR = (PFN_vkGetImageSparseMemoryRequirements2KHR)gdpa(dev, "vkGetImageSparseMemoryRequirements2KHR");
+
+ // ---- VK_KHR_sampler_ycbcr_conversion extension commands
+ table->CreateSamplerYcbcrConversionKHR = (PFN_vkCreateSamplerYcbcrConversionKHR)gdpa(dev, "vkCreateSamplerYcbcrConversionKHR");
+ table->DestroySamplerYcbcrConversionKHR = (PFN_vkDestroySamplerYcbcrConversionKHR)gdpa(dev, "vkDestroySamplerYcbcrConversionKHR");
+
+ // ---- VK_KHR_bind_memory2 extension commands
+ table->BindBufferMemory2KHR = (PFN_vkBindBufferMemory2KHR)gdpa(dev, "vkBindBufferMemory2KHR");
+ table->BindImageMemory2KHR = (PFN_vkBindImageMemory2KHR)gdpa(dev, "vkBindImageMemory2KHR");
+
+ // ---- VK_KHR_maintenance3 extension commands
+ table->GetDescriptorSetLayoutSupportKHR = (PFN_vkGetDescriptorSetLayoutSupportKHR)gdpa(dev, "vkGetDescriptorSetLayoutSupportKHR");
+
+ // ---- VK_KHR_draw_indirect_count extension commands
+ table->CmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)gdpa(dev, "vkCmdDrawIndirectCountKHR");
+ table->CmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)gdpa(dev, "vkCmdDrawIndexedIndirectCountKHR");
+
+ // ---- VK_KHR_timeline_semaphore extension commands
+ table->GetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)gdpa(dev, "vkGetSemaphoreCounterValueKHR");
+ table->WaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)gdpa(dev, "vkWaitSemaphoresKHR");
+ table->SignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)gdpa(dev, "vkSignalSemaphoreKHR");
+
+ // ---- VK_KHR_pipeline_executable_properties extension commands
+ table->GetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)gdpa(dev, "vkGetPipelineExecutablePropertiesKHR");
+ table->GetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)gdpa(dev, "vkGetPipelineExecutableStatisticsKHR");
+ table->GetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)gdpa(dev, "vkGetPipelineExecutableInternalRepresentationsKHR");
+
+ // ---- VK_EXT_debug_marker extension commands
+ table->DebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)gdpa(dev, "vkDebugMarkerSetObjectTagEXT");
+ table->DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)gdpa(dev, "vkDebugMarkerSetObjectNameEXT");
+ table->CmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)gdpa(dev, "vkCmdDebugMarkerBeginEXT");
+ table->CmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)gdpa(dev, "vkCmdDebugMarkerEndEXT");
+ table->CmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)gdpa(dev, "vkCmdDebugMarkerInsertEXT");
+
+ // ---- VK_EXT_transform_feedback extension commands
+ table->CmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)gdpa(dev, "vkCmdBindTransformFeedbackBuffersEXT");
+ table->CmdBeginTransformFeedbackEXT = (PFN_vkCmdBeginTransformFeedbackEXT)gdpa(dev, "vkCmdBeginTransformFeedbackEXT");
+ table->CmdEndTransformFeedbackEXT = (PFN_vkCmdEndTransformFeedbackEXT)gdpa(dev, "vkCmdEndTransformFeedbackEXT");
+ table->CmdBeginQueryIndexedEXT = (PFN_vkCmdBeginQueryIndexedEXT)gdpa(dev, "vkCmdBeginQueryIndexedEXT");
+ table->CmdEndQueryIndexedEXT = (PFN_vkCmdEndQueryIndexedEXT)gdpa(dev, "vkCmdEndQueryIndexedEXT");
+ table->CmdDrawIndirectByteCountEXT = (PFN_vkCmdDrawIndirectByteCountEXT)gdpa(dev, "vkCmdDrawIndirectByteCountEXT");
+
+ // ---- VK_NVX_image_view_handle extension commands
+ table->GetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX)gdpa(dev, "vkGetImageViewHandleNVX");
+
+ // ---- VK_AMD_draw_indirect_count extension commands
+ table->CmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD)gdpa(dev, "vkCmdDrawIndirectCountAMD");
+ table->CmdDrawIndexedIndirectCountAMD = (PFN_vkCmdDrawIndexedIndirectCountAMD)gdpa(dev, "vkCmdDrawIndexedIndirectCountAMD");
+
+ // ---- VK_AMD_shader_info extension commands
+ table->GetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)gdpa(dev, "vkGetShaderInfoAMD");
+
+ // ---- VK_NV_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)gdpa(dev, "vkGetMemoryWin32HandleNV");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_conditional_rendering extension commands
+ table->CmdBeginConditionalRenderingEXT = (PFN_vkCmdBeginConditionalRenderingEXT)gdpa(dev, "vkCmdBeginConditionalRenderingEXT");
+ table->CmdEndConditionalRenderingEXT = (PFN_vkCmdEndConditionalRenderingEXT)gdpa(dev, "vkCmdEndConditionalRenderingEXT");
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ table->CmdProcessCommandsNVX = (PFN_vkCmdProcessCommandsNVX)gdpa(dev, "vkCmdProcessCommandsNVX");
+ table->CmdReserveSpaceForCommandsNVX = (PFN_vkCmdReserveSpaceForCommandsNVX)gdpa(dev, "vkCmdReserveSpaceForCommandsNVX");
+ table->CreateIndirectCommandsLayoutNVX = (PFN_vkCreateIndirectCommandsLayoutNVX)gdpa(dev, "vkCreateIndirectCommandsLayoutNVX");
+ table->DestroyIndirectCommandsLayoutNVX = (PFN_vkDestroyIndirectCommandsLayoutNVX)gdpa(dev, "vkDestroyIndirectCommandsLayoutNVX");
+ table->CreateObjectTableNVX = (PFN_vkCreateObjectTableNVX)gdpa(dev, "vkCreateObjectTableNVX");
+ table->DestroyObjectTableNVX = (PFN_vkDestroyObjectTableNVX)gdpa(dev, "vkDestroyObjectTableNVX");
+ table->RegisterObjectsNVX = (PFN_vkRegisterObjectsNVX)gdpa(dev, "vkRegisterObjectsNVX");
+ table->UnregisterObjectsNVX = (PFN_vkUnregisterObjectsNVX)gdpa(dev, "vkUnregisterObjectsNVX");
+
+ // ---- VK_NV_clip_space_w_scaling extension commands
+ table->CmdSetViewportWScalingNV = (PFN_vkCmdSetViewportWScalingNV)gdpa(dev, "vkCmdSetViewportWScalingNV");
+
+ // ---- VK_EXT_display_control extension commands
+ table->DisplayPowerControlEXT = (PFN_vkDisplayPowerControlEXT)gdpa(dev, "vkDisplayPowerControlEXT");
+ table->RegisterDeviceEventEXT = (PFN_vkRegisterDeviceEventEXT)gdpa(dev, "vkRegisterDeviceEventEXT");
+ table->RegisterDisplayEventEXT = (PFN_vkRegisterDisplayEventEXT)gdpa(dev, "vkRegisterDisplayEventEXT");
+ table->GetSwapchainCounterEXT = (PFN_vkGetSwapchainCounterEXT)gdpa(dev, "vkGetSwapchainCounterEXT");
+
+ // ---- VK_GOOGLE_display_timing extension commands
+ table->GetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)gdpa(dev, "vkGetRefreshCycleDurationGOOGLE");
+ table->GetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)gdpa(dev, "vkGetPastPresentationTimingGOOGLE");
+
+ // ---- VK_EXT_discard_rectangles extension commands
+ table->CmdSetDiscardRectangleEXT = (PFN_vkCmdSetDiscardRectangleEXT)gdpa(dev, "vkCmdSetDiscardRectangleEXT");
+
+ // ---- VK_EXT_hdr_metadata extension commands
+ table->SetHdrMetadataEXT = (PFN_vkSetHdrMetadataEXT)gdpa(dev, "vkSetHdrMetadataEXT");
+
+ // ---- VK_EXT_debug_utils extension commands
+ table->SetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)gipa(inst, "vkSetDebugUtilsObjectNameEXT");
+ table->SetDebugUtilsObjectTagEXT = (PFN_vkSetDebugUtilsObjectTagEXT)gipa(inst, "vkSetDebugUtilsObjectTagEXT");
+ table->QueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)gipa(inst, "vkQueueBeginDebugUtilsLabelEXT");
+ table->QueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)gipa(inst, "vkQueueEndDebugUtilsLabelEXT");
+ table->QueueInsertDebugUtilsLabelEXT = (PFN_vkQueueInsertDebugUtilsLabelEXT)gipa(inst, "vkQueueInsertDebugUtilsLabelEXT");
+ table->CmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)gipa(inst, "vkCmdBeginDebugUtilsLabelEXT");
+ table->CmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)gipa(inst, "vkCmdEndDebugUtilsLabelEXT");
+ table->CmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)gipa(inst, "vkCmdInsertDebugUtilsLabelEXT");
+
+ // ---- VK_ANDROID_external_memory_android_hardware_buffer extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ table->GetAndroidHardwareBufferPropertiesANDROID = (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)gdpa(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ table->GetMemoryAndroidHardwareBufferANDROID = (PFN_vkGetMemoryAndroidHardwareBufferANDROID)gdpa(dev, "vkGetMemoryAndroidHardwareBufferANDROID");
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_EXT_sample_locations extension commands
+ table->CmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)gdpa(dev, "vkCmdSetSampleLocationsEXT");
+
+ // ---- VK_EXT_image_drm_format_modifier extension commands
+ table->GetImageDrmFormatModifierPropertiesEXT = (PFN_vkGetImageDrmFormatModifierPropertiesEXT)gdpa(dev, "vkGetImageDrmFormatModifierPropertiesEXT");
+
+ // ---- VK_EXT_validation_cache extension commands
+ table->CreateValidationCacheEXT = (PFN_vkCreateValidationCacheEXT)gdpa(dev, "vkCreateValidationCacheEXT");
+ table->DestroyValidationCacheEXT = (PFN_vkDestroyValidationCacheEXT)gdpa(dev, "vkDestroyValidationCacheEXT");
+ table->MergeValidationCachesEXT = (PFN_vkMergeValidationCachesEXT)gdpa(dev, "vkMergeValidationCachesEXT");
+ table->GetValidationCacheDataEXT = (PFN_vkGetValidationCacheDataEXT)gdpa(dev, "vkGetValidationCacheDataEXT");
+
+ // ---- VK_NV_shading_rate_image extension commands
+ table->CmdBindShadingRateImageNV = (PFN_vkCmdBindShadingRateImageNV)gdpa(dev, "vkCmdBindShadingRateImageNV");
+ table->CmdSetViewportShadingRatePaletteNV = (PFN_vkCmdSetViewportShadingRatePaletteNV)gdpa(dev, "vkCmdSetViewportShadingRatePaletteNV");
+ table->CmdSetCoarseSampleOrderNV = (PFN_vkCmdSetCoarseSampleOrderNV)gdpa(dev, "vkCmdSetCoarseSampleOrderNV");
+
+ // ---- VK_NV_ray_tracing extension commands
+ table->CreateAccelerationStructureNV = (PFN_vkCreateAccelerationStructureNV)gdpa(dev, "vkCreateAccelerationStructureNV");
+ table->DestroyAccelerationStructureNV = (PFN_vkDestroyAccelerationStructureNV)gdpa(dev, "vkDestroyAccelerationStructureNV");
+ table->GetAccelerationStructureMemoryRequirementsNV = (PFN_vkGetAccelerationStructureMemoryRequirementsNV)gdpa(dev, "vkGetAccelerationStructureMemoryRequirementsNV");
+ table->BindAccelerationStructureMemoryNV = (PFN_vkBindAccelerationStructureMemoryNV)gdpa(dev, "vkBindAccelerationStructureMemoryNV");
+ table->CmdBuildAccelerationStructureNV = (PFN_vkCmdBuildAccelerationStructureNV)gdpa(dev, "vkCmdBuildAccelerationStructureNV");
+ table->CmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV)gdpa(dev, "vkCmdCopyAccelerationStructureNV");
+ table->CmdTraceRaysNV = (PFN_vkCmdTraceRaysNV)gdpa(dev, "vkCmdTraceRaysNV");
+ table->CreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV)gdpa(dev, "vkCreateRayTracingPipelinesNV");
+ table->GetRayTracingShaderGroupHandlesNV = (PFN_vkGetRayTracingShaderGroupHandlesNV)gdpa(dev, "vkGetRayTracingShaderGroupHandlesNV");
+ table->GetAccelerationStructureHandleNV = (PFN_vkGetAccelerationStructureHandleNV)gdpa(dev, "vkGetAccelerationStructureHandleNV");
+ table->CmdWriteAccelerationStructuresPropertiesNV = (PFN_vkCmdWriteAccelerationStructuresPropertiesNV)gdpa(dev, "vkCmdWriteAccelerationStructuresPropertiesNV");
+ table->CompileDeferredNV = (PFN_vkCompileDeferredNV)gdpa(dev, "vkCompileDeferredNV");
+
+ // ---- VK_EXT_external_memory_host extension commands
+ table->GetMemoryHostPointerPropertiesEXT = (PFN_vkGetMemoryHostPointerPropertiesEXT)gdpa(dev, "vkGetMemoryHostPointerPropertiesEXT");
+
+ // ---- VK_AMD_buffer_marker extension commands
+ table->CmdWriteBufferMarkerAMD = (PFN_vkCmdWriteBufferMarkerAMD)gdpa(dev, "vkCmdWriteBufferMarkerAMD");
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ table->GetCalibratedTimestampsEXT = (PFN_vkGetCalibratedTimestampsEXT)gdpa(dev, "vkGetCalibratedTimestampsEXT");
+
+ // ---- VK_NV_mesh_shader extension commands
+ table->CmdDrawMeshTasksNV = (PFN_vkCmdDrawMeshTasksNV)gdpa(dev, "vkCmdDrawMeshTasksNV");
+ table->CmdDrawMeshTasksIndirectNV = (PFN_vkCmdDrawMeshTasksIndirectNV)gdpa(dev, "vkCmdDrawMeshTasksIndirectNV");
+ table->CmdDrawMeshTasksIndirectCountNV = (PFN_vkCmdDrawMeshTasksIndirectCountNV)gdpa(dev, "vkCmdDrawMeshTasksIndirectCountNV");
+
+ // ---- VK_NV_scissor_exclusive extension commands
+ table->CmdSetExclusiveScissorNV = (PFN_vkCmdSetExclusiveScissorNV)gdpa(dev, "vkCmdSetExclusiveScissorNV");
+
+ // ---- VK_NV_device_diagnostic_checkpoints extension commands
+ table->CmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV)gdpa(dev, "vkCmdSetCheckpointNV");
+ table->GetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV)gdpa(dev, "vkGetQueueCheckpointDataNV");
+
+ // ---- VK_INTEL_performance_query extension commands
+ table->InitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL)gdpa(dev, "vkInitializePerformanceApiINTEL");
+ table->UninitializePerformanceApiINTEL = (PFN_vkUninitializePerformanceApiINTEL)gdpa(dev, "vkUninitializePerformanceApiINTEL");
+ table->CmdSetPerformanceMarkerINTEL = (PFN_vkCmdSetPerformanceMarkerINTEL)gdpa(dev, "vkCmdSetPerformanceMarkerINTEL");
+ table->CmdSetPerformanceStreamMarkerINTEL = (PFN_vkCmdSetPerformanceStreamMarkerINTEL)gdpa(dev, "vkCmdSetPerformanceStreamMarkerINTEL");
+ table->CmdSetPerformanceOverrideINTEL = (PFN_vkCmdSetPerformanceOverrideINTEL)gdpa(dev, "vkCmdSetPerformanceOverrideINTEL");
+ table->AcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)gdpa(dev, "vkAcquirePerformanceConfigurationINTEL");
+ table->ReleasePerformanceConfigurationINTEL = (PFN_vkReleasePerformanceConfigurationINTEL)gdpa(dev, "vkReleasePerformanceConfigurationINTEL");
+ table->QueueSetPerformanceConfigurationINTEL = (PFN_vkQueueSetPerformanceConfigurationINTEL)gdpa(dev, "vkQueueSetPerformanceConfigurationINTEL");
+ table->GetPerformanceParameterINTEL = (PFN_vkGetPerformanceParameterINTEL)gdpa(dev, "vkGetPerformanceParameterINTEL");
+
+ // ---- VK_AMD_display_native_hdr extension commands
+ table->SetLocalDimmingAMD = (PFN_vkSetLocalDimmingAMD)gdpa(dev, "vkSetLocalDimmingAMD");
+
+ // ---- VK_EXT_buffer_device_address extension commands
+ table->GetBufferDeviceAddressEXT = (PFN_vkGetBufferDeviceAddressEXT)gdpa(dev, "vkGetBufferDeviceAddressEXT");
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->AcquireFullScreenExclusiveModeEXT = (PFN_vkAcquireFullScreenExclusiveModeEXT)gdpa(dev, "vkAcquireFullScreenExclusiveModeEXT");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->ReleaseFullScreenExclusiveModeEXT = (PFN_vkReleaseFullScreenExclusiveModeEXT)gdpa(dev, "vkReleaseFullScreenExclusiveModeEXT");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gdpa(dev, "vkGetDeviceGroupSurfacePresentModes2EXT");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_line_rasterization extension commands
+ table->CmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)gdpa(dev, "vkCmdSetLineStippleEXT");
+
+ // ---- VK_EXT_host_query_reset extension commands
+ table->ResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)gdpa(dev, "vkResetQueryPoolEXT");
+}
+
+// Init Instance function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
+ VkInstance inst) {
+
+ // ---- Core 1_0 commands
+ table->DestroyInstance = (PFN_vkDestroyInstance)gpa(inst, "vkDestroyInstance");
+ table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)gpa(inst, "vkEnumeratePhysicalDevices");
+ table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)gpa(inst, "vkGetPhysicalDeviceFeatures");
+ table->GetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties)gpa(inst, "vkGetPhysicalDeviceFormatProperties");
+ table->GetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties)gpa(inst, "vkGetPhysicalDeviceImageFormatProperties");
+ table->GetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)gpa(inst, "vkGetPhysicalDeviceProperties");
+ table->GetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)gpa(inst, "vkGetPhysicalDeviceQueueFamilyProperties");
+ table->GetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)gpa(inst, "vkGetPhysicalDeviceMemoryProperties");
+ table->GetInstanceProcAddr = gpa;
+ table->EnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)gpa(inst, "vkEnumerateDeviceExtensionProperties");
+ table->EnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties)gpa(inst, "vkEnumerateDeviceLayerProperties");
+ table->GetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties)gpa(inst, "vkGetPhysicalDeviceSparseImageFormatProperties");
+
+ // ---- Core 1_1 commands
+ table->EnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups)gpa(inst, "vkEnumeratePhysicalDeviceGroups");
+ table->GetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)gpa(inst, "vkGetPhysicalDeviceFeatures2");
+ table->GetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)gpa(inst, "vkGetPhysicalDeviceProperties2");
+ table->GetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2)gpa(inst, "vkGetPhysicalDeviceFormatProperties2");
+ table->GetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2)gpa(inst, "vkGetPhysicalDeviceImageFormatProperties2");
+ table->GetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)gpa(inst, "vkGetPhysicalDeviceQueueFamilyProperties2");
+ table->GetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2)gpa(inst, "vkGetPhysicalDeviceMemoryProperties2");
+ table->GetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)gpa(inst, "vkGetPhysicalDeviceSparseImageFormatProperties2");
+ table->GetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties)gpa(inst, "vkGetPhysicalDeviceExternalBufferProperties");
+ table->GetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties)gpa(inst, "vkGetPhysicalDeviceExternalFenceProperties");
+ table->GetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)gpa(inst, "vkGetPhysicalDeviceExternalSemaphoreProperties");
+}
+
+// Init Instance function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
+ VkInstance inst) {
+
+ // ---- VK_KHR_surface extension commands
+ table->DestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)gpa(inst, "vkDestroySurfaceKHR");
+ table->GetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)gpa(inst, "vkGetPhysicalDeviceSurfaceSupportKHR");
+ table->GetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)gpa(inst, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
+ table->GetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)gpa(inst, "vkGetPhysicalDeviceSurfaceFormatsKHR");
+ table->GetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)gpa(inst, "vkGetPhysicalDeviceSurfacePresentModesKHR");
+
+ // ---- VK_KHR_swapchain extension commands
+ table->GetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR)gpa(inst, "vkGetPhysicalDevicePresentRectanglesKHR");
+
+ // ---- VK_KHR_display extension commands
+ table->GetPhysicalDeviceDisplayPropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)gpa(inst, "vkGetPhysicalDeviceDisplayPropertiesKHR");
+ table->GetPhysicalDeviceDisplayPlanePropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)gpa(inst, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
+ table->GetDisplayPlaneSupportedDisplaysKHR = (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)gpa(inst, "vkGetDisplayPlaneSupportedDisplaysKHR");
+ table->GetDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR)gpa(inst, "vkGetDisplayModePropertiesKHR");
+ table->CreateDisplayModeKHR = (PFN_vkCreateDisplayModeKHR)gpa(inst, "vkCreateDisplayModeKHR");
+ table->GetDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR)gpa(inst, "vkGetDisplayPlaneCapabilitiesKHR");
+ table->CreateDisplayPlaneSurfaceKHR = (PFN_vkCreateDisplayPlaneSurfaceKHR)gpa(inst, "vkCreateDisplayPlaneSurfaceKHR");
+
+ // ---- VK_KHR_xlib_surface extension commands
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ table->CreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)gpa(inst, "vkCreateXlibSurfaceKHR");
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ table->GetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)gpa(inst, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+ // ---- VK_KHR_xcb_surface extension commands
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ table->CreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)gpa(inst, "vkCreateXcbSurfaceKHR");
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ table->GetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)gpa(inst, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+ // ---- VK_KHR_wayland_surface extension commands
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ table->CreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)gpa(inst, "vkCreateWaylandSurfaceKHR");
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ table->GetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)gpa(inst, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+ // ---- VK_KHR_android_surface extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ table->CreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)gpa(inst, "vkCreateAndroidSurfaceKHR");
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_KHR_win32_surface extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->CreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)gpa(inst, "vkCreateWin32SurfaceKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)gpa(inst, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ table->GetPhysicalDeviceFeatures2KHR = (PFN_vkGetPhysicalDeviceFeatures2KHR)gpa(inst, "vkGetPhysicalDeviceFeatures2KHR");
+ table->GetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2KHR)gpa(inst, "vkGetPhysicalDeviceProperties2KHR");
+ table->GetPhysicalDeviceFormatProperties2KHR = (PFN_vkGetPhysicalDeviceFormatProperties2KHR)gpa(inst, "vkGetPhysicalDeviceFormatProperties2KHR");
+ table->GetPhysicalDeviceImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)gpa(inst, "vkGetPhysicalDeviceImageFormatProperties2KHR");
+ table->GetPhysicalDeviceQueueFamilyProperties2KHR = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)gpa(inst, "vkGetPhysicalDeviceQueueFamilyProperties2KHR");
+ table->GetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2KHR)gpa(inst, "vkGetPhysicalDeviceMemoryProperties2KHR");
+ table->GetPhysicalDeviceSparseImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)gpa(inst, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
+
+ // ---- VK_KHR_device_group_creation extension commands
+ table->EnumeratePhysicalDeviceGroupsKHR = (PFN_vkEnumeratePhysicalDeviceGroupsKHR)gpa(inst, "vkEnumeratePhysicalDeviceGroupsKHR");
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ table->GetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)gpa(inst, "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ table->GetPhysicalDeviceExternalSemaphorePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)gpa(inst, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ table->GetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)gpa(inst, "vkGetPhysicalDeviceExternalFencePropertiesKHR");
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ table->GetPhysicalDeviceSurfaceCapabilities2KHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)gpa(inst, "vkGetPhysicalDeviceSurfaceCapabilities2KHR");
+ table->GetPhysicalDeviceSurfaceFormats2KHR = (PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)gpa(inst, "vkGetPhysicalDeviceSurfaceFormats2KHR");
+
+ // ---- VK_KHR_get_display_properties2 extension commands
+ table->GetPhysicalDeviceDisplayProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayProperties2KHR)gpa(inst, "vkGetPhysicalDeviceDisplayProperties2KHR");
+ table->GetPhysicalDeviceDisplayPlaneProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)gpa(inst, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
+ table->GetDisplayModeProperties2KHR = (PFN_vkGetDisplayModeProperties2KHR)gpa(inst, "vkGetDisplayModeProperties2KHR");
+ table->GetDisplayPlaneCapabilities2KHR = (PFN_vkGetDisplayPlaneCapabilities2KHR)gpa(inst, "vkGetDisplayPlaneCapabilities2KHR");
+
+ // ---- VK_EXT_debug_report extension commands
+ table->CreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)gpa(inst, "vkCreateDebugReportCallbackEXT");
+ table->DestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)gpa(inst, "vkDestroyDebugReportCallbackEXT");
+ table->DebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)gpa(inst, "vkDebugReportMessageEXT");
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ table->CreateStreamDescriptorSurfaceGGP = (PFN_vkCreateStreamDescriptorSurfaceGGP)gpa(inst, "vkCreateStreamDescriptorSurfaceGGP");
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ table->GetPhysicalDeviceExternalImageFormatPropertiesNV = (PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)gpa(inst, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ table->CreateViSurfaceNN = (PFN_vkCreateViSurfaceNN)gpa(inst, "vkCreateViSurfaceNN");
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ table->GetPhysicalDeviceGeneratedCommandsPropertiesNVX = (PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)gpa(inst, "vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX");
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ table->ReleaseDisplayEXT = (PFN_vkReleaseDisplayEXT)gpa(inst, "vkReleaseDisplayEXT");
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ table->AcquireXlibDisplayEXT = (PFN_vkAcquireXlibDisplayEXT)gpa(inst, "vkAcquireXlibDisplayEXT");
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ table->GetRandROutputDisplayEXT = (PFN_vkGetRandROutputDisplayEXT)gpa(inst, "vkGetRandROutputDisplayEXT");
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ table->GetPhysicalDeviceSurfaceCapabilities2EXT = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)gpa(inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT");
+
+ // ---- VK_MVK_ios_surface extension commands
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ table->CreateIOSSurfaceMVK = (PFN_vkCreateIOSSurfaceMVK)gpa(inst, "vkCreateIOSSurfaceMVK");
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+ // ---- VK_MVK_macos_surface extension commands
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ table->CreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)gpa(inst, "vkCreateMacOSSurfaceMVK");
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+ // ---- VK_EXT_debug_utils extension commands
+ table->CreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)gpa(inst, "vkCreateDebugUtilsMessengerEXT");
+ table->DestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)gpa(inst, "vkDestroyDebugUtilsMessengerEXT");
+ table->SubmitDebugUtilsMessageEXT = (PFN_vkSubmitDebugUtilsMessageEXT)gpa(inst, "vkSubmitDebugUtilsMessageEXT");
+
+ // ---- VK_EXT_sample_locations extension commands
+ table->GetPhysicalDeviceMultisamplePropertiesEXT = (PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)gpa(inst, "vkGetPhysicalDeviceMultisamplePropertiesEXT");
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ table->GetPhysicalDeviceCalibrateableTimeDomainsEXT = (PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)gpa(inst, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ table->CreateImagePipeSurfaceFUCHSIA = (PFN_vkCreateImagePipeSurfaceFUCHSIA)gpa(inst, "vkCreateImagePipeSurfaceFUCHSIA");
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ // ---- VK_EXT_metal_surface extension commands
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ table->CreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT)gpa(inst, "vkCreateMetalSurfaceEXT");
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ // ---- VK_NV_cooperative_matrix extension commands
+ table->GetPhysicalDeviceCooperativeMatrixPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)gpa(inst, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
+
+ // ---- VK_NV_coverage_reduction_mode extension commands
+ table->GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = (PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)gpa(inst, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ table->GetPhysicalDeviceSurfacePresentModes2EXT = (PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)gpa(inst, "vkGetPhysicalDeviceSurfacePresentModes2EXT");
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_headless_surface extension commands
+ table->CreateHeadlessSurfaceEXT = (PFN_vkCreateHeadlessSurfaceEXT)gpa(inst, "vkCreateHeadlessSurfaceEXT");
+}
+
+// Device command lookup function
+VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name) {
+ if (!name || name[0] != 'v' || name[1] != 'k') return NULL;
+
+ name += 2;
+
+ // ---- Core 1_0 commands
+ if (!strcmp(name, "GetDeviceProcAddr")) return (void *)table->GetDeviceProcAddr;
+ if (!strcmp(name, "DestroyDevice")) return (void *)table->DestroyDevice;
+ if (!strcmp(name, "GetDeviceQueue")) return (void *)table->GetDeviceQueue;
+ if (!strcmp(name, "QueueSubmit")) return (void *)table->QueueSubmit;
+ if (!strcmp(name, "QueueWaitIdle")) return (void *)table->QueueWaitIdle;
+ if (!strcmp(name, "DeviceWaitIdle")) return (void *)table->DeviceWaitIdle;
+ if (!strcmp(name, "AllocateMemory")) return (void *)table->AllocateMemory;
+ if (!strcmp(name, "FreeMemory")) return (void *)table->FreeMemory;
+ if (!strcmp(name, "MapMemory")) return (void *)table->MapMemory;
+ if (!strcmp(name, "UnmapMemory")) return (void *)table->UnmapMemory;
+ if (!strcmp(name, "FlushMappedMemoryRanges")) return (void *)table->FlushMappedMemoryRanges;
+ if (!strcmp(name, "InvalidateMappedMemoryRanges")) return (void *)table->InvalidateMappedMemoryRanges;
+ if (!strcmp(name, "GetDeviceMemoryCommitment")) return (void *)table->GetDeviceMemoryCommitment;
+ if (!strcmp(name, "BindBufferMemory")) return (void *)table->BindBufferMemory;
+ if (!strcmp(name, "BindImageMemory")) return (void *)table->BindImageMemory;
+ if (!strcmp(name, "GetBufferMemoryRequirements")) return (void *)table->GetBufferMemoryRequirements;
+ if (!strcmp(name, "GetImageMemoryRequirements")) return (void *)table->GetImageMemoryRequirements;
+ if (!strcmp(name, "GetImageSparseMemoryRequirements")) return (void *)table->GetImageSparseMemoryRequirements;
+ if (!strcmp(name, "QueueBindSparse")) return (void *)table->QueueBindSparse;
+ if (!strcmp(name, "CreateFence")) return (void *)table->CreateFence;
+ if (!strcmp(name, "DestroyFence")) return (void *)table->DestroyFence;
+ if (!strcmp(name, "ResetFences")) return (void *)table->ResetFences;
+ if (!strcmp(name, "GetFenceStatus")) return (void *)table->GetFenceStatus;
+ if (!strcmp(name, "WaitForFences")) return (void *)table->WaitForFences;
+ if (!strcmp(name, "CreateSemaphore")) return (void *)table->CreateSemaphore;
+ if (!strcmp(name, "DestroySemaphore")) return (void *)table->DestroySemaphore;
+ if (!strcmp(name, "CreateEvent")) return (void *)table->CreateEvent;
+ if (!strcmp(name, "DestroyEvent")) return (void *)table->DestroyEvent;
+ if (!strcmp(name, "GetEventStatus")) return (void *)table->GetEventStatus;
+ if (!strcmp(name, "SetEvent")) return (void *)table->SetEvent;
+ if (!strcmp(name, "ResetEvent")) return (void *)table->ResetEvent;
+ if (!strcmp(name, "CreateQueryPool")) return (void *)table->CreateQueryPool;
+ if (!strcmp(name, "DestroyQueryPool")) return (void *)table->DestroyQueryPool;
+ if (!strcmp(name, "GetQueryPoolResults")) return (void *)table->GetQueryPoolResults;
+ if (!strcmp(name, "CreateBuffer")) return (void *)table->CreateBuffer;
+ if (!strcmp(name, "DestroyBuffer")) return (void *)table->DestroyBuffer;
+ if (!strcmp(name, "CreateBufferView")) return (void *)table->CreateBufferView;
+ if (!strcmp(name, "DestroyBufferView")) return (void *)table->DestroyBufferView;
+ if (!strcmp(name, "CreateImage")) return (void *)table->CreateImage;
+ if (!strcmp(name, "DestroyImage")) return (void *)table->DestroyImage;
+ if (!strcmp(name, "GetImageSubresourceLayout")) return (void *)table->GetImageSubresourceLayout;
+ if (!strcmp(name, "CreateImageView")) return (void *)table->CreateImageView;
+ if (!strcmp(name, "DestroyImageView")) return (void *)table->DestroyImageView;
+ if (!strcmp(name, "CreateShaderModule")) return (void *)table->CreateShaderModule;
+ if (!strcmp(name, "DestroyShaderModule")) return (void *)table->DestroyShaderModule;
+ if (!strcmp(name, "CreatePipelineCache")) return (void *)table->CreatePipelineCache;
+ if (!strcmp(name, "DestroyPipelineCache")) return (void *)table->DestroyPipelineCache;
+ if (!strcmp(name, "GetPipelineCacheData")) return (void *)table->GetPipelineCacheData;
+ if (!strcmp(name, "MergePipelineCaches")) return (void *)table->MergePipelineCaches;
+ if (!strcmp(name, "CreateGraphicsPipelines")) return (void *)table->CreateGraphicsPipelines;
+ if (!strcmp(name, "CreateComputePipelines")) return (void *)table->CreateComputePipelines;
+ if (!strcmp(name, "DestroyPipeline")) return (void *)table->DestroyPipeline;
+ if (!strcmp(name, "CreatePipelineLayout")) return (void *)table->CreatePipelineLayout;
+ if (!strcmp(name, "DestroyPipelineLayout")) return (void *)table->DestroyPipelineLayout;
+ if (!strcmp(name, "CreateSampler")) return (void *)table->CreateSampler;
+ if (!strcmp(name, "DestroySampler")) return (void *)table->DestroySampler;
+ if (!strcmp(name, "CreateDescriptorSetLayout")) return (void *)table->CreateDescriptorSetLayout;
+ if (!strcmp(name, "DestroyDescriptorSetLayout")) return (void *)table->DestroyDescriptorSetLayout;
+ if (!strcmp(name, "CreateDescriptorPool")) return (void *)table->CreateDescriptorPool;
+ if (!strcmp(name, "DestroyDescriptorPool")) return (void *)table->DestroyDescriptorPool;
+ if (!strcmp(name, "ResetDescriptorPool")) return (void *)table->ResetDescriptorPool;
+ if (!strcmp(name, "AllocateDescriptorSets")) return (void *)table->AllocateDescriptorSets;
+ if (!strcmp(name, "FreeDescriptorSets")) return (void *)table->FreeDescriptorSets;
+ if (!strcmp(name, "UpdateDescriptorSets")) return (void *)table->UpdateDescriptorSets;
+ if (!strcmp(name, "CreateFramebuffer")) return (void *)table->CreateFramebuffer;
+ if (!strcmp(name, "DestroyFramebuffer")) return (void *)table->DestroyFramebuffer;
+ if (!strcmp(name, "CreateRenderPass")) return (void *)table->CreateRenderPass;
+ if (!strcmp(name, "DestroyRenderPass")) return (void *)table->DestroyRenderPass;
+ if (!strcmp(name, "GetRenderAreaGranularity")) return (void *)table->GetRenderAreaGranularity;
+ if (!strcmp(name, "CreateCommandPool")) return (void *)table->CreateCommandPool;
+ if (!strcmp(name, "DestroyCommandPool")) return (void *)table->DestroyCommandPool;
+ if (!strcmp(name, "ResetCommandPool")) return (void *)table->ResetCommandPool;
+ if (!strcmp(name, "AllocateCommandBuffers")) return (void *)table->AllocateCommandBuffers;
+ if (!strcmp(name, "FreeCommandBuffers")) return (void *)table->FreeCommandBuffers;
+ if (!strcmp(name, "BeginCommandBuffer")) return (void *)table->BeginCommandBuffer;
+ if (!strcmp(name, "EndCommandBuffer")) return (void *)table->EndCommandBuffer;
+ if (!strcmp(name, "ResetCommandBuffer")) return (void *)table->ResetCommandBuffer;
+ if (!strcmp(name, "CmdBindPipeline")) return (void *)table->CmdBindPipeline;
+ if (!strcmp(name, "CmdSetViewport")) return (void *)table->CmdSetViewport;
+ if (!strcmp(name, "CmdSetScissor")) return (void *)table->CmdSetScissor;
+ if (!strcmp(name, "CmdSetLineWidth")) return (void *)table->CmdSetLineWidth;
+ if (!strcmp(name, "CmdSetDepthBias")) return (void *)table->CmdSetDepthBias;
+ if (!strcmp(name, "CmdSetBlendConstants")) return (void *)table->CmdSetBlendConstants;
+ if (!strcmp(name, "CmdSetDepthBounds")) return (void *)table->CmdSetDepthBounds;
+ if (!strcmp(name, "CmdSetStencilCompareMask")) return (void *)table->CmdSetStencilCompareMask;
+ if (!strcmp(name, "CmdSetStencilWriteMask")) return (void *)table->CmdSetStencilWriteMask;
+ if (!strcmp(name, "CmdSetStencilReference")) return (void *)table->CmdSetStencilReference;
+ if (!strcmp(name, "CmdBindDescriptorSets")) return (void *)table->CmdBindDescriptorSets;
+ if (!strcmp(name, "CmdBindIndexBuffer")) return (void *)table->CmdBindIndexBuffer;
+ if (!strcmp(name, "CmdBindVertexBuffers")) return (void *)table->CmdBindVertexBuffers;
+ if (!strcmp(name, "CmdDraw")) return (void *)table->CmdDraw;
+ if (!strcmp(name, "CmdDrawIndexed")) return (void *)table->CmdDrawIndexed;
+ if (!strcmp(name, "CmdDrawIndirect")) return (void *)table->CmdDrawIndirect;
+ if (!strcmp(name, "CmdDrawIndexedIndirect")) return (void *)table->CmdDrawIndexedIndirect;
+ if (!strcmp(name, "CmdDispatch")) return (void *)table->CmdDispatch;
+ if (!strcmp(name, "CmdDispatchIndirect")) return (void *)table->CmdDispatchIndirect;
+ if (!strcmp(name, "CmdCopyBuffer")) return (void *)table->CmdCopyBuffer;
+ if (!strcmp(name, "CmdCopyImage")) return (void *)table->CmdCopyImage;
+ if (!strcmp(name, "CmdBlitImage")) return (void *)table->CmdBlitImage;
+ if (!strcmp(name, "CmdCopyBufferToImage")) return (void *)table->CmdCopyBufferToImage;
+ if (!strcmp(name, "CmdCopyImageToBuffer")) return (void *)table->CmdCopyImageToBuffer;
+ if (!strcmp(name, "CmdUpdateBuffer")) return (void *)table->CmdUpdateBuffer;
+ if (!strcmp(name, "CmdFillBuffer")) return (void *)table->CmdFillBuffer;
+ if (!strcmp(name, "CmdClearColorImage")) return (void *)table->CmdClearColorImage;
+ if (!strcmp(name, "CmdClearDepthStencilImage")) return (void *)table->CmdClearDepthStencilImage;
+ if (!strcmp(name, "CmdClearAttachments")) return (void *)table->CmdClearAttachments;
+ if (!strcmp(name, "CmdResolveImage")) return (void *)table->CmdResolveImage;
+ if (!strcmp(name, "CmdSetEvent")) return (void *)table->CmdSetEvent;
+ if (!strcmp(name, "CmdResetEvent")) return (void *)table->CmdResetEvent;
+ if (!strcmp(name, "CmdWaitEvents")) return (void *)table->CmdWaitEvents;
+ if (!strcmp(name, "CmdPipelineBarrier")) return (void *)table->CmdPipelineBarrier;
+ if (!strcmp(name, "CmdBeginQuery")) return (void *)table->CmdBeginQuery;
+ if (!strcmp(name, "CmdEndQuery")) return (void *)table->CmdEndQuery;
+ if (!strcmp(name, "CmdResetQueryPool")) return (void *)table->CmdResetQueryPool;
+ if (!strcmp(name, "CmdWriteTimestamp")) return (void *)table->CmdWriteTimestamp;
+ if (!strcmp(name, "CmdCopyQueryPoolResults")) return (void *)table->CmdCopyQueryPoolResults;
+ if (!strcmp(name, "CmdPushConstants")) return (void *)table->CmdPushConstants;
+ if (!strcmp(name, "CmdBeginRenderPass")) return (void *)table->CmdBeginRenderPass;
+ if (!strcmp(name, "CmdNextSubpass")) return (void *)table->CmdNextSubpass;
+ if (!strcmp(name, "CmdEndRenderPass")) return (void *)table->CmdEndRenderPass;
+ if (!strcmp(name, "CmdExecuteCommands")) return (void *)table->CmdExecuteCommands;
+
+ // ---- Core 1_1 commands
+ if (!strcmp(name, "BindBufferMemory2")) return (void *)table->BindBufferMemory2;
+ if (!strcmp(name, "BindImageMemory2")) return (void *)table->BindImageMemory2;
+ if (!strcmp(name, "GetDeviceGroupPeerMemoryFeatures")) return (void *)table->GetDeviceGroupPeerMemoryFeatures;
+ if (!strcmp(name, "CmdSetDeviceMask")) return (void *)table->CmdSetDeviceMask;
+ if (!strcmp(name, "CmdDispatchBase")) return (void *)table->CmdDispatchBase;
+ if (!strcmp(name, "GetImageMemoryRequirements2")) return (void *)table->GetImageMemoryRequirements2;
+ if (!strcmp(name, "GetBufferMemoryRequirements2")) return (void *)table->GetBufferMemoryRequirements2;
+ if (!strcmp(name, "GetImageSparseMemoryRequirements2")) return (void *)table->GetImageSparseMemoryRequirements2;
+ if (!strcmp(name, "TrimCommandPool")) return (void *)table->TrimCommandPool;
+ if (!strcmp(name, "GetDeviceQueue2")) return (void *)table->GetDeviceQueue2;
+ if (!strcmp(name, "CreateSamplerYcbcrConversion")) return (void *)table->CreateSamplerYcbcrConversion;
+ if (!strcmp(name, "DestroySamplerYcbcrConversion")) return (void *)table->DestroySamplerYcbcrConversion;
+ if (!strcmp(name, "CreateDescriptorUpdateTemplate")) return (void *)table->CreateDescriptorUpdateTemplate;
+ if (!strcmp(name, "DestroyDescriptorUpdateTemplate")) return (void *)table->DestroyDescriptorUpdateTemplate;
+ if (!strcmp(name, "UpdateDescriptorSetWithTemplate")) return (void *)table->UpdateDescriptorSetWithTemplate;
+ if (!strcmp(name, "GetDescriptorSetLayoutSupport")) return (void *)table->GetDescriptorSetLayoutSupport;
+
+ // ---- VK_KHR_swapchain extension commands
+ if (!strcmp(name, "CreateSwapchainKHR")) return (void *)table->CreateSwapchainKHR;
+ if (!strcmp(name, "DestroySwapchainKHR")) return (void *)table->DestroySwapchainKHR;
+ if (!strcmp(name, "GetSwapchainImagesKHR")) return (void *)table->GetSwapchainImagesKHR;
+ if (!strcmp(name, "AcquireNextImageKHR")) return (void *)table->AcquireNextImageKHR;
+ if (!strcmp(name, "QueuePresentKHR")) return (void *)table->QueuePresentKHR;
+ if (!strcmp(name, "GetDeviceGroupPresentCapabilitiesKHR")) return (void *)table->GetDeviceGroupPresentCapabilitiesKHR;
+ if (!strcmp(name, "GetDeviceGroupSurfacePresentModesKHR")) return (void *)table->GetDeviceGroupSurfacePresentModesKHR;
+ if (!strcmp(name, "AcquireNextImage2KHR")) return (void *)table->AcquireNextImage2KHR;
+
+ // ---- VK_KHR_display_swapchain extension commands
+ if (!strcmp(name, "CreateSharedSwapchainsKHR")) return (void *)table->CreateSharedSwapchainsKHR;
+
+ // ---- VK_KHR_device_group extension commands
+ if (!strcmp(name, "GetDeviceGroupPeerMemoryFeaturesKHR")) return (void *)table->GetDeviceGroupPeerMemoryFeaturesKHR;
+ if (!strcmp(name, "CmdSetDeviceMaskKHR")) return (void *)table->CmdSetDeviceMaskKHR;
+ if (!strcmp(name, "CmdDispatchBaseKHR")) return (void *)table->CmdDispatchBaseKHR;
+
+ // ---- VK_KHR_maintenance1 extension commands
+ if (!strcmp(name, "TrimCommandPoolKHR")) return (void *)table->TrimCommandPoolKHR;
+
+ // ---- VK_KHR_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetMemoryWin32HandleKHR")) return (void *)table->GetMemoryWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetMemoryWin32HandlePropertiesKHR")) return (void *)table->GetMemoryWin32HandlePropertiesKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_memory_fd extension commands
+ if (!strcmp(name, "GetMemoryFdKHR")) return (void *)table->GetMemoryFdKHR;
+ if (!strcmp(name, "GetMemoryFdPropertiesKHR")) return (void *)table->GetMemoryFdPropertiesKHR;
+
+ // ---- VK_KHR_external_semaphore_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "ImportSemaphoreWin32HandleKHR")) return (void *)table->ImportSemaphoreWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetSemaphoreWin32HandleKHR")) return (void *)table->GetSemaphoreWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_semaphore_fd extension commands
+ if (!strcmp(name, "ImportSemaphoreFdKHR")) return (void *)table->ImportSemaphoreFdKHR;
+ if (!strcmp(name, "GetSemaphoreFdKHR")) return (void *)table->GetSemaphoreFdKHR;
+
+ // ---- VK_KHR_push_descriptor extension commands
+ if (!strcmp(name, "CmdPushDescriptorSetKHR")) return (void *)table->CmdPushDescriptorSetKHR;
+ if (!strcmp(name, "CmdPushDescriptorSetWithTemplateKHR")) return (void *)table->CmdPushDescriptorSetWithTemplateKHR;
+
+ // ---- VK_KHR_descriptor_update_template extension commands
+ if (!strcmp(name, "CreateDescriptorUpdateTemplateKHR")) return (void *)table->CreateDescriptorUpdateTemplateKHR;
+ if (!strcmp(name, "DestroyDescriptorUpdateTemplateKHR")) return (void *)table->DestroyDescriptorUpdateTemplateKHR;
+ if (!strcmp(name, "UpdateDescriptorSetWithTemplateKHR")) return (void *)table->UpdateDescriptorSetWithTemplateKHR;
+
+ // ---- VK_KHR_create_renderpass2 extension commands
+ if (!strcmp(name, "CreateRenderPass2KHR")) return (void *)table->CreateRenderPass2KHR;
+ if (!strcmp(name, "CmdBeginRenderPass2KHR")) return (void *)table->CmdBeginRenderPass2KHR;
+ if (!strcmp(name, "CmdNextSubpass2KHR")) return (void *)table->CmdNextSubpass2KHR;
+ if (!strcmp(name, "CmdEndRenderPass2KHR")) return (void *)table->CmdEndRenderPass2KHR;
+
+ // ---- VK_KHR_shared_presentable_image extension commands
+ if (!strcmp(name, "GetSwapchainStatusKHR")) return (void *)table->GetSwapchainStatusKHR;
+
+ // ---- VK_KHR_external_fence_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "ImportFenceWin32HandleKHR")) return (void *)table->ImportFenceWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetFenceWin32HandleKHR")) return (void *)table->GetFenceWin32HandleKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_fence_fd extension commands
+ if (!strcmp(name, "ImportFenceFdKHR")) return (void *)table->ImportFenceFdKHR;
+ if (!strcmp(name, "GetFenceFdKHR")) return (void *)table->GetFenceFdKHR;
+
+ // ---- VK_KHR_get_memory_requirements2 extension commands
+ if (!strcmp(name, "GetImageMemoryRequirements2KHR")) return (void *)table->GetImageMemoryRequirements2KHR;
+ if (!strcmp(name, "GetBufferMemoryRequirements2KHR")) return (void *)table->GetBufferMemoryRequirements2KHR;
+ if (!strcmp(name, "GetImageSparseMemoryRequirements2KHR")) return (void *)table->GetImageSparseMemoryRequirements2KHR;
+
+ // ---- VK_KHR_sampler_ycbcr_conversion extension commands
+ if (!strcmp(name, "CreateSamplerYcbcrConversionKHR")) return (void *)table->CreateSamplerYcbcrConversionKHR;
+ if (!strcmp(name, "DestroySamplerYcbcrConversionKHR")) return (void *)table->DestroySamplerYcbcrConversionKHR;
+
+ // ---- VK_KHR_bind_memory2 extension commands
+ if (!strcmp(name, "BindBufferMemory2KHR")) return (void *)table->BindBufferMemory2KHR;
+ if (!strcmp(name, "BindImageMemory2KHR")) return (void *)table->BindImageMemory2KHR;
+
+ // ---- VK_KHR_maintenance3 extension commands
+ if (!strcmp(name, "GetDescriptorSetLayoutSupportKHR")) return (void *)table->GetDescriptorSetLayoutSupportKHR;
+
+ // ---- VK_KHR_draw_indirect_count extension commands
+ if (!strcmp(name, "CmdDrawIndirectCountKHR")) return (void *)table->CmdDrawIndirectCountKHR;
+ if (!strcmp(name, "CmdDrawIndexedIndirectCountKHR")) return (void *)table->CmdDrawIndexedIndirectCountKHR;
+
+ // ---- VK_KHR_timeline_semaphore extension commands
+ if (!strcmp(name, "GetSemaphoreCounterValueKHR")) return (void *)table->GetSemaphoreCounterValueKHR;
+ if (!strcmp(name, "WaitSemaphoresKHR")) return (void *)table->WaitSemaphoresKHR;
+ if (!strcmp(name, "SignalSemaphoreKHR")) return (void *)table->SignalSemaphoreKHR;
+
+ // ---- VK_KHR_pipeline_executable_properties extension commands
+ if (!strcmp(name, "GetPipelineExecutablePropertiesKHR")) return (void *)table->GetPipelineExecutablePropertiesKHR;
+ if (!strcmp(name, "GetPipelineExecutableStatisticsKHR")) return (void *)table->GetPipelineExecutableStatisticsKHR;
+ if (!strcmp(name, "GetPipelineExecutableInternalRepresentationsKHR")) return (void *)table->GetPipelineExecutableInternalRepresentationsKHR;
+
+ // ---- VK_EXT_debug_marker extension commands
+ if (!strcmp(name, "DebugMarkerSetObjectTagEXT")) return (void *)table->DebugMarkerSetObjectTagEXT;
+ if (!strcmp(name, "DebugMarkerSetObjectNameEXT")) return (void *)table->DebugMarkerSetObjectNameEXT;
+ if (!strcmp(name, "CmdDebugMarkerBeginEXT")) return (void *)table->CmdDebugMarkerBeginEXT;
+ if (!strcmp(name, "CmdDebugMarkerEndEXT")) return (void *)table->CmdDebugMarkerEndEXT;
+ if (!strcmp(name, "CmdDebugMarkerInsertEXT")) return (void *)table->CmdDebugMarkerInsertEXT;
+
+ // ---- VK_EXT_transform_feedback extension commands
+ if (!strcmp(name, "CmdBindTransformFeedbackBuffersEXT")) return (void *)table->CmdBindTransformFeedbackBuffersEXT;
+ if (!strcmp(name, "CmdBeginTransformFeedbackEXT")) return (void *)table->CmdBeginTransformFeedbackEXT;
+ if (!strcmp(name, "CmdEndTransformFeedbackEXT")) return (void *)table->CmdEndTransformFeedbackEXT;
+ if (!strcmp(name, "CmdBeginQueryIndexedEXT")) return (void *)table->CmdBeginQueryIndexedEXT;
+ if (!strcmp(name, "CmdEndQueryIndexedEXT")) return (void *)table->CmdEndQueryIndexedEXT;
+ if (!strcmp(name, "CmdDrawIndirectByteCountEXT")) return (void *)table->CmdDrawIndirectByteCountEXT;
+
+ // ---- VK_NVX_image_view_handle extension commands
+ if (!strcmp(name, "GetImageViewHandleNVX")) return (void *)table->GetImageViewHandleNVX;
+
+ // ---- VK_AMD_draw_indirect_count extension commands
+ if (!strcmp(name, "CmdDrawIndirectCountAMD")) return (void *)table->CmdDrawIndirectCountAMD;
+ if (!strcmp(name, "CmdDrawIndexedIndirectCountAMD")) return (void *)table->CmdDrawIndexedIndirectCountAMD;
+
+ // ---- VK_AMD_shader_info extension commands
+ if (!strcmp(name, "GetShaderInfoAMD")) return (void *)table->GetShaderInfoAMD;
+
+ // ---- VK_NV_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetMemoryWin32HandleNV")) return (void *)table->GetMemoryWin32HandleNV;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_conditional_rendering extension commands
+ if (!strcmp(name, "CmdBeginConditionalRenderingEXT")) return (void *)table->CmdBeginConditionalRenderingEXT;
+ if (!strcmp(name, "CmdEndConditionalRenderingEXT")) return (void *)table->CmdEndConditionalRenderingEXT;
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ if (!strcmp(name, "CmdProcessCommandsNVX")) return (void *)table->CmdProcessCommandsNVX;
+ if (!strcmp(name, "CmdReserveSpaceForCommandsNVX")) return (void *)table->CmdReserveSpaceForCommandsNVX;
+ if (!strcmp(name, "CreateIndirectCommandsLayoutNVX")) return (void *)table->CreateIndirectCommandsLayoutNVX;
+ if (!strcmp(name, "DestroyIndirectCommandsLayoutNVX")) return (void *)table->DestroyIndirectCommandsLayoutNVX;
+ if (!strcmp(name, "CreateObjectTableNVX")) return (void *)table->CreateObjectTableNVX;
+ if (!strcmp(name, "DestroyObjectTableNVX")) return (void *)table->DestroyObjectTableNVX;
+ if (!strcmp(name, "RegisterObjectsNVX")) return (void *)table->RegisterObjectsNVX;
+ if (!strcmp(name, "UnregisterObjectsNVX")) return (void *)table->UnregisterObjectsNVX;
+
+ // ---- VK_NV_clip_space_w_scaling extension commands
+ if (!strcmp(name, "CmdSetViewportWScalingNV")) return (void *)table->CmdSetViewportWScalingNV;
+
+ // ---- VK_EXT_display_control extension commands
+ if (!strcmp(name, "DisplayPowerControlEXT")) return (void *)table->DisplayPowerControlEXT;
+ if (!strcmp(name, "RegisterDeviceEventEXT")) return (void *)table->RegisterDeviceEventEXT;
+ if (!strcmp(name, "RegisterDisplayEventEXT")) return (void *)table->RegisterDisplayEventEXT;
+ if (!strcmp(name, "GetSwapchainCounterEXT")) return (void *)table->GetSwapchainCounterEXT;
+
+ // ---- VK_GOOGLE_display_timing extension commands
+ if (!strcmp(name, "GetRefreshCycleDurationGOOGLE")) return (void *)table->GetRefreshCycleDurationGOOGLE;
+ if (!strcmp(name, "GetPastPresentationTimingGOOGLE")) return (void *)table->GetPastPresentationTimingGOOGLE;
+
+ // ---- VK_EXT_discard_rectangles extension commands
+ if (!strcmp(name, "CmdSetDiscardRectangleEXT")) return (void *)table->CmdSetDiscardRectangleEXT;
+
+ // ---- VK_EXT_hdr_metadata extension commands
+ if (!strcmp(name, "SetHdrMetadataEXT")) return (void *)table->SetHdrMetadataEXT;
+
+ // ---- VK_EXT_debug_utils extension commands
+ if (!strcmp(name, "SetDebugUtilsObjectNameEXT")) return (void *)table->SetDebugUtilsObjectNameEXT;
+ if (!strcmp(name, "SetDebugUtilsObjectTagEXT")) return (void *)table->SetDebugUtilsObjectTagEXT;
+ if (!strcmp(name, "QueueBeginDebugUtilsLabelEXT")) return (void *)table->QueueBeginDebugUtilsLabelEXT;
+ if (!strcmp(name, "QueueEndDebugUtilsLabelEXT")) return (void *)table->QueueEndDebugUtilsLabelEXT;
+ if (!strcmp(name, "QueueInsertDebugUtilsLabelEXT")) return (void *)table->QueueInsertDebugUtilsLabelEXT;
+ if (!strcmp(name, "CmdBeginDebugUtilsLabelEXT")) return (void *)table->CmdBeginDebugUtilsLabelEXT;
+ if (!strcmp(name, "CmdEndDebugUtilsLabelEXT")) return (void *)table->CmdEndDebugUtilsLabelEXT;
+ if (!strcmp(name, "CmdInsertDebugUtilsLabelEXT")) return (void *)table->CmdInsertDebugUtilsLabelEXT;
+
+ // ---- VK_ANDROID_external_memory_android_hardware_buffer extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ if (!strcmp(name, "GetAndroidHardwareBufferPropertiesANDROID")) return (void *)table->GetAndroidHardwareBufferPropertiesANDROID;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ if (!strcmp(name, "GetMemoryAndroidHardwareBufferANDROID")) return (void *)table->GetMemoryAndroidHardwareBufferANDROID;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_EXT_sample_locations extension commands
+ if (!strcmp(name, "CmdSetSampleLocationsEXT")) return (void *)table->CmdSetSampleLocationsEXT;
+
+ // ---- VK_EXT_image_drm_format_modifier extension commands
+ if (!strcmp(name, "GetImageDrmFormatModifierPropertiesEXT")) return (void *)table->GetImageDrmFormatModifierPropertiesEXT;
+
+ // ---- VK_EXT_validation_cache extension commands
+ if (!strcmp(name, "CreateValidationCacheEXT")) return (void *)table->CreateValidationCacheEXT;
+ if (!strcmp(name, "DestroyValidationCacheEXT")) return (void *)table->DestroyValidationCacheEXT;
+ if (!strcmp(name, "MergeValidationCachesEXT")) return (void *)table->MergeValidationCachesEXT;
+ if (!strcmp(name, "GetValidationCacheDataEXT")) return (void *)table->GetValidationCacheDataEXT;
+
+ // ---- VK_NV_shading_rate_image extension commands
+ if (!strcmp(name, "CmdBindShadingRateImageNV")) return (void *)table->CmdBindShadingRateImageNV;
+ if (!strcmp(name, "CmdSetViewportShadingRatePaletteNV")) return (void *)table->CmdSetViewportShadingRatePaletteNV;
+ if (!strcmp(name, "CmdSetCoarseSampleOrderNV")) return (void *)table->CmdSetCoarseSampleOrderNV;
+
+ // ---- VK_NV_ray_tracing extension commands
+ if (!strcmp(name, "CreateAccelerationStructureNV")) return (void *)table->CreateAccelerationStructureNV;
+ if (!strcmp(name, "DestroyAccelerationStructureNV")) return (void *)table->DestroyAccelerationStructureNV;
+ if (!strcmp(name, "GetAccelerationStructureMemoryRequirementsNV")) return (void *)table->GetAccelerationStructureMemoryRequirementsNV;
+ if (!strcmp(name, "BindAccelerationStructureMemoryNV")) return (void *)table->BindAccelerationStructureMemoryNV;
+ if (!strcmp(name, "CmdBuildAccelerationStructureNV")) return (void *)table->CmdBuildAccelerationStructureNV;
+ if (!strcmp(name, "CmdCopyAccelerationStructureNV")) return (void *)table->CmdCopyAccelerationStructureNV;
+ if (!strcmp(name, "CmdTraceRaysNV")) return (void *)table->CmdTraceRaysNV;
+ if (!strcmp(name, "CreateRayTracingPipelinesNV")) return (void *)table->CreateRayTracingPipelinesNV;
+ if (!strcmp(name, "GetRayTracingShaderGroupHandlesNV")) return (void *)table->GetRayTracingShaderGroupHandlesNV;
+ if (!strcmp(name, "GetAccelerationStructureHandleNV")) return (void *)table->GetAccelerationStructureHandleNV;
+ if (!strcmp(name, "CmdWriteAccelerationStructuresPropertiesNV")) return (void *)table->CmdWriteAccelerationStructuresPropertiesNV;
+ if (!strcmp(name, "CompileDeferredNV")) return (void *)table->CompileDeferredNV;
+
+ // ---- VK_EXT_external_memory_host extension commands
+ if (!strcmp(name, "GetMemoryHostPointerPropertiesEXT")) return (void *)table->GetMemoryHostPointerPropertiesEXT;
+
+ // ---- VK_AMD_buffer_marker extension commands
+ if (!strcmp(name, "CmdWriteBufferMarkerAMD")) return (void *)table->CmdWriteBufferMarkerAMD;
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ if (!strcmp(name, "GetCalibratedTimestampsEXT")) return (void *)table->GetCalibratedTimestampsEXT;
+
+ // ---- VK_NV_mesh_shader extension commands
+ if (!strcmp(name, "CmdDrawMeshTasksNV")) return (void *)table->CmdDrawMeshTasksNV;
+ if (!strcmp(name, "CmdDrawMeshTasksIndirectNV")) return (void *)table->CmdDrawMeshTasksIndirectNV;
+ if (!strcmp(name, "CmdDrawMeshTasksIndirectCountNV")) return (void *)table->CmdDrawMeshTasksIndirectCountNV;
+
+ // ---- VK_NV_scissor_exclusive extension commands
+ if (!strcmp(name, "CmdSetExclusiveScissorNV")) return (void *)table->CmdSetExclusiveScissorNV;
+
+ // ---- VK_NV_device_diagnostic_checkpoints extension commands
+ if (!strcmp(name, "CmdSetCheckpointNV")) return (void *)table->CmdSetCheckpointNV;
+ if (!strcmp(name, "GetQueueCheckpointDataNV")) return (void *)table->GetQueueCheckpointDataNV;
+
+ // ---- VK_INTEL_performance_query extension commands
+ if (!strcmp(name, "InitializePerformanceApiINTEL")) return (void *)table->InitializePerformanceApiINTEL;
+ if (!strcmp(name, "UninitializePerformanceApiINTEL")) return (void *)table->UninitializePerformanceApiINTEL;
+ if (!strcmp(name, "CmdSetPerformanceMarkerINTEL")) return (void *)table->CmdSetPerformanceMarkerINTEL;
+ if (!strcmp(name, "CmdSetPerformanceStreamMarkerINTEL")) return (void *)table->CmdSetPerformanceStreamMarkerINTEL;
+ if (!strcmp(name, "CmdSetPerformanceOverrideINTEL")) return (void *)table->CmdSetPerformanceOverrideINTEL;
+ if (!strcmp(name, "AcquirePerformanceConfigurationINTEL")) return (void *)table->AcquirePerformanceConfigurationINTEL;
+ if (!strcmp(name, "ReleasePerformanceConfigurationINTEL")) return (void *)table->ReleasePerformanceConfigurationINTEL;
+ if (!strcmp(name, "QueueSetPerformanceConfigurationINTEL")) return (void *)table->QueueSetPerformanceConfigurationINTEL;
+ if (!strcmp(name, "GetPerformanceParameterINTEL")) return (void *)table->GetPerformanceParameterINTEL;
+
+ // ---- VK_AMD_display_native_hdr extension commands
+ if (!strcmp(name, "SetLocalDimmingAMD")) return (void *)table->SetLocalDimmingAMD;
+
+ // ---- VK_EXT_buffer_device_address extension commands
+ if (!strcmp(name, "GetBufferDeviceAddressEXT")) return (void *)table->GetBufferDeviceAddressEXT;
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "AcquireFullScreenExclusiveModeEXT")) return (void *)table->AcquireFullScreenExclusiveModeEXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "ReleaseFullScreenExclusiveModeEXT")) return (void *)table->ReleaseFullScreenExclusiveModeEXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetDeviceGroupSurfacePresentModes2EXT")) return (void *)table->GetDeviceGroupSurfacePresentModes2EXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_line_rasterization extension commands
+ if (!strcmp(name, "CmdSetLineStippleEXT")) return (void *)table->CmdSetLineStippleEXT;
+
+ // ---- VK_EXT_host_query_reset extension commands
+ if (!strcmp(name, "ResetQueryPoolEXT")) return (void *)table->ResetQueryPoolEXT;
+
+ return NULL;
+}
+
+// Instance command lookup function
+VKAPI_ATTR void* VKAPI_CALL loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table, const char *name,
+ bool *found_name) {
+ if (!name || name[0] != 'v' || name[1] != 'k') {
+ *found_name = false;
+ return NULL;
+ }
+
+ *found_name = true;
+ name += 2;
+
+ // ---- Core 1_0 commands
+ if (!strcmp(name, "DestroyInstance")) return (void *)table->DestroyInstance;
+ if (!strcmp(name, "EnumeratePhysicalDevices")) return (void *)table->EnumeratePhysicalDevices;
+ if (!strcmp(name, "GetPhysicalDeviceFeatures")) return (void *)table->GetPhysicalDeviceFeatures;
+ if (!strcmp(name, "GetPhysicalDeviceFormatProperties")) return (void *)table->GetPhysicalDeviceFormatProperties;
+ if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties")) return (void *)table->GetPhysicalDeviceImageFormatProperties;
+ if (!strcmp(name, "GetPhysicalDeviceProperties")) return (void *)table->GetPhysicalDeviceProperties;
+ if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties")) return (void *)table->GetPhysicalDeviceQueueFamilyProperties;
+ if (!strcmp(name, "GetPhysicalDeviceMemoryProperties")) return (void *)table->GetPhysicalDeviceMemoryProperties;
+ if (!strcmp(name, "GetInstanceProcAddr")) return (void *)table->GetInstanceProcAddr;
+ if (!strcmp(name, "EnumerateDeviceExtensionProperties")) return (void *)table->EnumerateDeviceExtensionProperties;
+ if (!strcmp(name, "EnumerateDeviceLayerProperties")) return (void *)table->EnumerateDeviceLayerProperties;
+ if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties")) return (void *)table->GetPhysicalDeviceSparseImageFormatProperties;
+
+ // ---- Core 1_1 commands
+ if (!strcmp(name, "EnumeratePhysicalDeviceGroups")) return (void *)table->EnumeratePhysicalDeviceGroups;
+ if (!strcmp(name, "GetPhysicalDeviceFeatures2")) return (void *)table->GetPhysicalDeviceFeatures2;
+ if (!strcmp(name, "GetPhysicalDeviceProperties2")) return (void *)table->GetPhysicalDeviceProperties2;
+ if (!strcmp(name, "GetPhysicalDeviceFormatProperties2")) return (void *)table->GetPhysicalDeviceFormatProperties2;
+ if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties2")) return (void *)table->GetPhysicalDeviceImageFormatProperties2;
+ if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties2")) return (void *)table->GetPhysicalDeviceQueueFamilyProperties2;
+ if (!strcmp(name, "GetPhysicalDeviceMemoryProperties2")) return (void *)table->GetPhysicalDeviceMemoryProperties2;
+ if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties2")) return (void *)table->GetPhysicalDeviceSparseImageFormatProperties2;
+ if (!strcmp(name, "GetPhysicalDeviceExternalBufferProperties")) return (void *)table->GetPhysicalDeviceExternalBufferProperties;
+ if (!strcmp(name, "GetPhysicalDeviceExternalFenceProperties")) return (void *)table->GetPhysicalDeviceExternalFenceProperties;
+ if (!strcmp(name, "GetPhysicalDeviceExternalSemaphoreProperties")) return (void *)table->GetPhysicalDeviceExternalSemaphoreProperties;
+
+ // ---- VK_KHR_surface extension commands
+ if (!strcmp(name, "DestroySurfaceKHR")) return (void *)table->DestroySurfaceKHR;
+ if (!strcmp(name, "GetPhysicalDeviceSurfaceSupportKHR")) return (void *)table->GetPhysicalDeviceSurfaceSupportKHR;
+ if (!strcmp(name, "GetPhysicalDeviceSurfaceCapabilitiesKHR")) return (void *)table->GetPhysicalDeviceSurfaceCapabilitiesKHR;
+ if (!strcmp(name, "GetPhysicalDeviceSurfaceFormatsKHR")) return (void *)table->GetPhysicalDeviceSurfaceFormatsKHR;
+ if (!strcmp(name, "GetPhysicalDeviceSurfacePresentModesKHR")) return (void *)table->GetPhysicalDeviceSurfacePresentModesKHR;
+
+ // ---- VK_KHR_swapchain extension commands
+ if (!strcmp(name, "GetPhysicalDevicePresentRectanglesKHR")) return (void *)table->GetPhysicalDevicePresentRectanglesKHR;
+
+ // ---- VK_KHR_display extension commands
+ if (!strcmp(name, "GetPhysicalDeviceDisplayPropertiesKHR")) return (void *)table->GetPhysicalDeviceDisplayPropertiesKHR;
+ if (!strcmp(name, "GetPhysicalDeviceDisplayPlanePropertiesKHR")) return (void *)table->GetPhysicalDeviceDisplayPlanePropertiesKHR;
+ if (!strcmp(name, "GetDisplayPlaneSupportedDisplaysKHR")) return (void *)table->GetDisplayPlaneSupportedDisplaysKHR;
+ if (!strcmp(name, "GetDisplayModePropertiesKHR")) return (void *)table->GetDisplayModePropertiesKHR;
+ if (!strcmp(name, "CreateDisplayModeKHR")) return (void *)table->CreateDisplayModeKHR;
+ if (!strcmp(name, "GetDisplayPlaneCapabilitiesKHR")) return (void *)table->GetDisplayPlaneCapabilitiesKHR;
+ if (!strcmp(name, "CreateDisplayPlaneSurfaceKHR")) return (void *)table->CreateDisplayPlaneSurfaceKHR;
+
+ // ---- VK_KHR_xlib_surface extension commands
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ if (!strcmp(name, "CreateXlibSurfaceKHR")) return (void *)table->CreateXlibSurfaceKHR;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ if (!strcmp(name, "GetPhysicalDeviceXlibPresentationSupportKHR")) return (void *)table->GetPhysicalDeviceXlibPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+ // ---- VK_KHR_xcb_surface extension commands
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ if (!strcmp(name, "CreateXcbSurfaceKHR")) return (void *)table->CreateXcbSurfaceKHR;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ if (!strcmp(name, "GetPhysicalDeviceXcbPresentationSupportKHR")) return (void *)table->GetPhysicalDeviceXcbPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+ // ---- VK_KHR_wayland_surface extension commands
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ if (!strcmp(name, "CreateWaylandSurfaceKHR")) return (void *)table->CreateWaylandSurfaceKHR;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ if (!strcmp(name, "GetPhysicalDeviceWaylandPresentationSupportKHR")) return (void *)table->GetPhysicalDeviceWaylandPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+ // ---- VK_KHR_android_surface extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ if (!strcmp(name, "CreateAndroidSurfaceKHR")) return (void *)table->CreateAndroidSurfaceKHR;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_KHR_win32_surface extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "CreateWin32SurfaceKHR")) return (void *)table->CreateWin32SurfaceKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetPhysicalDeviceWin32PresentationSupportKHR")) return (void *)table->GetPhysicalDeviceWin32PresentationSupportKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ if (!strcmp(name, "GetPhysicalDeviceFeatures2KHR")) return (void *)table->GetPhysicalDeviceFeatures2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceProperties2KHR")) return (void *)table->GetPhysicalDeviceProperties2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceFormatProperties2KHR")) return (void *)table->GetPhysicalDeviceFormatProperties2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceImageFormatProperties2KHR")) return (void *)table->GetPhysicalDeviceImageFormatProperties2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceQueueFamilyProperties2KHR")) return (void *)table->GetPhysicalDeviceQueueFamilyProperties2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceMemoryProperties2KHR")) return (void *)table->GetPhysicalDeviceMemoryProperties2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties2KHR")) return (void *)table->GetPhysicalDeviceSparseImageFormatProperties2KHR;
+
+ // ---- VK_KHR_device_group_creation extension commands
+ if (!strcmp(name, "EnumeratePhysicalDeviceGroupsKHR")) return (void *)table->EnumeratePhysicalDeviceGroupsKHR;
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ if (!strcmp(name, "GetPhysicalDeviceExternalBufferPropertiesKHR")) return (void *)table->GetPhysicalDeviceExternalBufferPropertiesKHR;
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ if (!strcmp(name, "GetPhysicalDeviceExternalSemaphorePropertiesKHR")) return (void *)table->GetPhysicalDeviceExternalSemaphorePropertiesKHR;
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ if (!strcmp(name, "GetPhysicalDeviceExternalFencePropertiesKHR")) return (void *)table->GetPhysicalDeviceExternalFencePropertiesKHR;
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ if (!strcmp(name, "GetPhysicalDeviceSurfaceCapabilities2KHR")) return (void *)table->GetPhysicalDeviceSurfaceCapabilities2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceSurfaceFormats2KHR")) return (void *)table->GetPhysicalDeviceSurfaceFormats2KHR;
+
+ // ---- VK_KHR_get_display_properties2 extension commands
+ if (!strcmp(name, "GetPhysicalDeviceDisplayProperties2KHR")) return (void *)table->GetPhysicalDeviceDisplayProperties2KHR;
+ if (!strcmp(name, "GetPhysicalDeviceDisplayPlaneProperties2KHR")) return (void *)table->GetPhysicalDeviceDisplayPlaneProperties2KHR;
+ if (!strcmp(name, "GetDisplayModeProperties2KHR")) return (void *)table->GetDisplayModeProperties2KHR;
+ if (!strcmp(name, "GetDisplayPlaneCapabilities2KHR")) return (void *)table->GetDisplayPlaneCapabilities2KHR;
+
+ // ---- VK_EXT_debug_report extension commands
+ if (!strcmp(name, "CreateDebugReportCallbackEXT")) return (void *)table->CreateDebugReportCallbackEXT;
+ if (!strcmp(name, "DestroyDebugReportCallbackEXT")) return (void *)table->DestroyDebugReportCallbackEXT;
+ if (!strcmp(name, "DebugReportMessageEXT")) return (void *)table->DebugReportMessageEXT;
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ if (!strcmp(name, "CreateStreamDescriptorSurfaceGGP")) return (void *)table->CreateStreamDescriptorSurfaceGGP;
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ if (!strcmp(name, "GetPhysicalDeviceExternalImageFormatPropertiesNV")) return (void *)table->GetPhysicalDeviceExternalImageFormatPropertiesNV;
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ if (!strcmp(name, "CreateViSurfaceNN")) return (void *)table->CreateViSurfaceNN;
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ if (!strcmp(name, "GetPhysicalDeviceGeneratedCommandsPropertiesNVX")) return (void *)table->GetPhysicalDeviceGeneratedCommandsPropertiesNVX;
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ if (!strcmp(name, "ReleaseDisplayEXT")) return (void *)table->ReleaseDisplayEXT;
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ if (!strcmp(name, "AcquireXlibDisplayEXT")) return (void *)table->AcquireXlibDisplayEXT;
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ if (!strcmp(name, "GetRandROutputDisplayEXT")) return (void *)table->GetRandROutputDisplayEXT;
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ if (!strcmp(name, "GetPhysicalDeviceSurfaceCapabilities2EXT")) return (void *)table->GetPhysicalDeviceSurfaceCapabilities2EXT;
+
+ // ---- VK_MVK_ios_surface extension commands
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ if (!strcmp(name, "CreateIOSSurfaceMVK")) return (void *)table->CreateIOSSurfaceMVK;
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+ // ---- VK_MVK_macos_surface extension commands
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ if (!strcmp(name, "CreateMacOSSurfaceMVK")) return (void *)table->CreateMacOSSurfaceMVK;
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+ // ---- VK_EXT_debug_utils extension commands
+ if (!strcmp(name, "CreateDebugUtilsMessengerEXT")) return (void *)table->CreateDebugUtilsMessengerEXT;
+ if (!strcmp(name, "DestroyDebugUtilsMessengerEXT")) return (void *)table->DestroyDebugUtilsMessengerEXT;
+ if (!strcmp(name, "SubmitDebugUtilsMessageEXT")) return (void *)table->SubmitDebugUtilsMessageEXT;
+
+ // ---- VK_EXT_sample_locations extension commands
+ if (!strcmp(name, "GetPhysicalDeviceMultisamplePropertiesEXT")) return (void *)table->GetPhysicalDeviceMultisamplePropertiesEXT;
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ if (!strcmp(name, "GetPhysicalDeviceCalibrateableTimeDomainsEXT")) return (void *)table->GetPhysicalDeviceCalibrateableTimeDomainsEXT;
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ if (!strcmp(name, "CreateImagePipeSurfaceFUCHSIA")) return (void *)table->CreateImagePipeSurfaceFUCHSIA;
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ // ---- VK_EXT_metal_surface extension commands
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ if (!strcmp(name, "CreateMetalSurfaceEXT")) return (void *)table->CreateMetalSurfaceEXT;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ // ---- VK_NV_cooperative_matrix extension commands
+ if (!strcmp(name, "GetPhysicalDeviceCooperativeMatrixPropertiesNV")) return (void *)table->GetPhysicalDeviceCooperativeMatrixPropertiesNV;
+
+ // ---- VK_NV_coverage_reduction_mode extension commands
+ if (!strcmp(name, "GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV")) return (void *)table->GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp(name, "GetPhysicalDeviceSurfacePresentModes2EXT")) return (void *)table->GetPhysicalDeviceSurfacePresentModes2EXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_headless_surface extension commands
+ if (!strcmp(name, "CreateHeadlessSurfaceEXT")) return (void *)table->CreateHeadlessSurfaceEXT;
+
+ *found_name = false;
+ return NULL;
+}
+
+
+// ---- VK_KHR_device_group extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL GetDeviceGroupPeerMemoryFeaturesKHR(
+ VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetDeviceMaskKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t deviceMask) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetDeviceMaskKHR(commandBuffer, deviceMask);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDispatchBaseKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t baseGroupX,
+ uint32_t baseGroupY,
+ uint32_t baseGroupZ,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ);
+}
+
+
+// ---- VK_KHR_maintenance1 extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL TrimCommandPoolKHR(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolTrimFlags flags) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->TrimCommandPoolKHR(device, commandPool, flags);
+}
+
+
+// ---- VK_KHR_external_memory_win32 extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleKHR(
+ VkDevice device,
+ const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetMemoryWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandlePropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ HANDLE handle,
+ VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetMemoryWin32HandlePropertiesKHR(device, handleType, handle, pMemoryWin32HandleProperties);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+// ---- VK_KHR_external_memory_fd extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryFdKHR(
+ VkDevice device,
+ const VkMemoryGetFdInfoKHR* pGetFdInfo,
+ int* pFd) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetMemoryFdKHR(device, pGetFdInfo, pFd);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryFdPropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ int fd,
+ VkMemoryFdPropertiesKHR* pMemoryFdProperties) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetMemoryFdPropertiesKHR(device, handleType, fd, pMemoryFdProperties);
+}
+
+
+// ---- VK_KHR_external_semaphore_win32 extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL ImportSemaphoreWin32HandleKHR(
+ VkDevice device,
+ const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->ImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreWin32HandleKHR(
+ VkDevice device,
+ const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+// ---- VK_KHR_external_semaphore_fd extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL ImportSemaphoreFdKHR(
+ VkDevice device,
+ const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->ImportSemaphoreFdKHR(device, pImportSemaphoreFdInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreFdKHR(
+ VkDevice device,
+ const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
+ int* pFd) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetSemaphoreFdKHR(device, pGetFdInfo, pFd);
+}
+
+
+// ---- VK_KHR_push_descriptor extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetKHR(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout layout,
+ uint32_t set,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdPushDescriptorSetKHR(commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(
+ VkCommandBuffer commandBuffer,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ VkPipelineLayout layout,
+ uint32_t set,
+ const void* pData) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData);
+}
+
+
+// ---- VK_KHR_descriptor_update_template extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks* pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void* pData) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
+}
+
+
+// ---- VK_KHR_create_renderpass2 extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass2KHR(
+ VkDevice device,
+ const VkRenderPassCreateInfo2KHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkRenderPass* pRenderPass) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo* pRenderPassBegin,
+ const VkSubpassBeginInfoKHR* pSubpassBeginInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdBeginRenderPass2KHR(commandBuffer, pRenderPassBegin, pSubpassBeginInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdNextSubpass2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkSubpassBeginInfoKHR* pSubpassBeginInfo,
+ const VkSubpassEndInfoKHR* pSubpassEndInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdNextSubpass2KHR(commandBuffer, pSubpassBeginInfo, pSubpassEndInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndRenderPass2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkSubpassEndInfoKHR* pSubpassEndInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdEndRenderPass2KHR(commandBuffer, pSubpassEndInfo);
+}
+
+
+// ---- VK_KHR_shared_presentable_image extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainStatusKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetSwapchainStatusKHR(device, swapchain);
+}
+
+
+// ---- VK_KHR_external_fence_win32 extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL ImportFenceWin32HandleKHR(
+ VkDevice device,
+ const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->ImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetFenceWin32HandleKHR(
+ VkDevice device,
+ const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+// ---- VK_KHR_external_fence_fd extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL ImportFenceFdKHR(
+ VkDevice device,
+ const VkImportFenceFdInfoKHR* pImportFenceFdInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->ImportFenceFdKHR(device, pImportFenceFdInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetFenceFdKHR(
+ VkDevice device,
+ const VkFenceGetFdInfoKHR* pGetFdInfo,
+ int* pFd) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetFenceFdKHR(device, pGetFdInfo, pFd);
+}
+
+
+// ---- VK_KHR_get_memory_requirements2 extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetImageMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements2KHR(
+ VkDevice device,
+ const VkBufferMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetImageSparseMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+}
+
+
+// ---- VK_KHR_sampler_ycbcr_conversion extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateSamplerYcbcrConversionKHR(
+ VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSamplerYcbcrConversion* pYcbcrConversion) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateSamplerYcbcrConversionKHR(device, pCreateInfo, pAllocator, pYcbcrConversion);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroySamplerYcbcrConversionKHR(
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator);
+}
+
+
+// ---- VK_KHR_bind_memory2 extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory2KHR(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindBufferMemoryInfo* pBindInfos) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->BindBufferMemory2KHR(device, bindInfoCount, pBindInfos);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BindImageMemory2KHR(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->BindImageMemory2KHR(device, bindInfoCount, pBindInfos);
+}
+
+
+// ---- VK_KHR_maintenance3 extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL GetDescriptorSetLayoutSupportKHR(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ VkDescriptorSetLayoutSupport* pSupport) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport);
+}
+
+
+// ---- VK_KHR_draw_indirect_count extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+}
+
+
+// ---- VK_KHR_timeline_semaphore extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSemaphoreCounterValueKHR(
+ VkDevice device,
+ VkSemaphore semaphore,
+ uint64_t* pValue) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetSemaphoreCounterValueKHR(device, semaphore, pValue);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL WaitSemaphoresKHR(
+ VkDevice device,
+ const VkSemaphoreWaitInfoKHR* pWaitInfo,
+ uint64_t timeout) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->WaitSemaphoresKHR(device, pWaitInfo, timeout);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL SignalSemaphoreKHR(
+ VkDevice device,
+ const VkSemaphoreSignalInfoKHR* pSignalInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->SignalSemaphoreKHR(device, pSignalInfo);
+}
+
+
+// ---- VK_KHR_pipeline_executable_properties extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutablePropertiesKHR(
+ VkDevice device,
+ const VkPipelineInfoKHR* pPipelineInfo,
+ uint32_t* pExecutableCount,
+ VkPipelineExecutablePropertiesKHR* pProperties) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetPipelineExecutablePropertiesKHR(device, pPipelineInfo, pExecutableCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableStatisticsKHR(
+ VkDevice device,
+ const VkPipelineExecutableInfoKHR* pExecutableInfo,
+ uint32_t* pStatisticCount,
+ VkPipelineExecutableStatisticKHR* pStatistics) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetPipelineExecutableStatisticsKHR(device, pExecutableInfo, pStatisticCount, pStatistics);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPipelineExecutableInternalRepresentationsKHR(
+ VkDevice device,
+ const VkPipelineExecutableInfoKHR* pExecutableInfo,
+ uint32_t* pInternalRepresentationCount,
+ VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetPipelineExecutableInternalRepresentationsKHR(device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations);
+}
+
+
+// ---- VK_EXT_debug_marker extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ VkDebugMarkerObjectTagInfoEXT local_tag_info;
+ memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugMarkerObjectTagInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pTagInfo->object;
+ local_tag_info.object = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;
+ }
+ return disp->DebugMarkerSetObjectTagEXT(device, &local_tag_info);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectTagEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectTagInfoEXT* pTagInfo) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.DebugMarkerSetObjectTagEXT) {
+ VkDebugMarkerObjectTagInfoEXT local_tag_info;
+ memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugMarkerObjectTagInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->object;
+ local_tag_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;
+ // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
+ } else if (pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
+ if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->object;
+ if (NULL != icd_surface->real_icd_surfaces) {
+ local_tag_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index];
+ }
+ }
+ }
+ return icd_term->dispatch.DebugMarkerSetObjectTagEXT(device, &local_tag_info);
+ } else {
+ return VK_SUCCESS;
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ VkDebugMarkerObjectNameInfoEXT local_name_info;
+ memcpy(&local_name_info, pNameInfo, sizeof(VkDebugMarkerObjectNameInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pNameInfo->object;
+ local_name_info.object = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;
+ }
+ return disp->DebugMarkerSetObjectNameEXT(device, &local_name_info);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_DebugMarkerSetObjectNameEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectNameInfoEXT* pNameInfo) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.DebugMarkerSetObjectNameEXT) {
+ VkDebugMarkerObjectNameInfoEXT local_name_info;
+ memcpy(&local_name_info, pNameInfo, sizeof(VkDebugMarkerObjectNameInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->object;
+ local_name_info.object = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;
+ // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
+ } else if (pNameInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
+ if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->object;
+ if (NULL != icd_surface->real_icd_surfaces) {
+ local_name_info.object = (uint64_t)icd_surface->real_icd_surfaces[icd_index];
+ }
+ }
+ }
+ return icd_term->dispatch.DebugMarkerSetObjectNameEXT(device, &local_name_info);
+ } else {
+ return VK_SUCCESS;
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerEndEXT(
+ VkCommandBuffer commandBuffer) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDebugMarkerEndEXT(commandBuffer);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugMarkerMarkerInfoEXT* pMarkerInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo);
+}
+
+
+// ---- VK_EXT_transform_feedback extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdBindTransformFeedbackBuffersEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer* pBuffers,
+ const VkDeviceSize* pOffsets,
+ const VkDeviceSize* pSizes) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdBindTransformFeedbackBuffersEXT(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginTransformFeedbackEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstCounterBuffer,
+ uint32_t counterBufferCount,
+ const VkBuffer* pCounterBuffers,
+ const VkDeviceSize* pCounterBufferOffsets) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdBeginTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers, pCounterBufferOffsets);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndTransformFeedbackEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstCounterBuffer,
+ uint32_t counterBufferCount,
+ const VkBuffer* pCounterBuffers,
+ const VkDeviceSize* pCounterBufferOffsets) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdEndTransformFeedbackEXT(commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers, pCounterBufferOffsets);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginQueryIndexedEXT(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query,
+ VkQueryControlFlags flags,
+ uint32_t index) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, index);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndQueryIndexedEXT(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query,
+ uint32_t index) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdEndQueryIndexedEXT(commandBuffer, queryPool, query, index);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectByteCountEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t instanceCount,
+ uint32_t firstInstance,
+ VkBuffer counterBuffer,
+ VkDeviceSize counterBufferOffset,
+ uint32_t counterOffset,
+ uint32_t vertexStride) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer, counterBufferOffset, counterOffset, vertexStride);
+}
+
+
+// ---- VK_NVX_image_view_handle extension trampoline/terminators
+
+VKAPI_ATTR uint32_t VKAPI_CALL GetImageViewHandleNVX(
+ VkDevice device,
+ const VkImageViewHandleInfoNVX* pInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetImageViewHandleNVX(device, pInfo);
+}
+
+
+// ---- VK_AMD_draw_indirect_count extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCountAMD(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountAMD(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawIndexedIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+}
+
+
+// ---- VK_AMD_shader_info extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetShaderInfoAMD(
+ VkDevice device,
+ VkPipeline pipeline,
+ VkShaderStageFlagBits shaderStage,
+ VkShaderInfoTypeAMD infoType,
+ size_t* pInfoSize,
+ void* pInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetShaderInfoAMD(device, pipeline, shaderStage, infoType, pInfoSize, pInfo);
+}
+
+
+// ---- VK_GGP_stream_descriptor_surface extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_GGP
+VKAPI_ATTR VkResult VKAPI_CALL CreateStreamDescriptorSurfaceGGP(
+ VkInstance instance,
+ const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface) {
+#error("Not implemented. Likely needs to be manually generated!");
+ return disp->CreateStreamDescriptorSurfaceGGP(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateStreamDescriptorSurfaceGGP(
+ VkInstance instance,
+ const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface) {
+#error("Not implemented. Likely needs to be manually generated!");
+}
+
+#endif // VK_USE_PLATFORM_GGP
+
+// ---- VK_NV_external_memory_win32 extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(
+ VkDevice device,
+ VkDeviceMemory memory,
+ VkExternalMemoryHandleTypeFlagsNV handleType,
+ HANDLE* pHandle) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetMemoryWin32HandleNV(device, memory, handleType, pHandle);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+// ---- VK_NN_vi_surface extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_VI_NN
+VKAPI_ATTR VkResult VKAPI_CALL CreateViSurfaceNN(
+ VkInstance instance,
+ const VkViSurfaceCreateInfoNN* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface) {
+#error("Not implemented. Likely needs to be manually generated!");
+ return disp->CreateViSurfaceNN(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateViSurfaceNN(
+ VkInstance instance,
+ const VkViSurfaceCreateInfoNN* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface) {
+#error("Not implemented. Likely needs to be manually generated!");
+}
+
+#endif // VK_USE_PLATFORM_VI_NN
+
+// ---- VK_EXT_conditional_rendering extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginConditionalRenderingEXT(
+ VkCommandBuffer commandBuffer,
+ const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdBeginConditionalRenderingEXT(commandBuffer, pConditionalRenderingBegin);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndConditionalRenderingEXT(
+ VkCommandBuffer commandBuffer) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdEndConditionalRenderingEXT(commandBuffer);
+}
+
+
+// ---- VK_NVX_device_generated_commands extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdProcessCommandsNVX(
+ VkCommandBuffer commandBuffer,
+ const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdProcessCommandsNVX(commandBuffer, pProcessCommandsInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdReserveSpaceForCommandsNVX(
+ VkCommandBuffer commandBuffer,
+ const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdReserveSpaceForCommandsNVX(commandBuffer, pReserveSpaceInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateIndirectCommandsLayoutNVX(
+ VkDevice device,
+ const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateIndirectCommandsLayoutNVX(device, pCreateInfo, pAllocator, pIndirectCommandsLayout);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyIndirectCommandsLayoutNVX(
+ VkDevice device,
+ VkIndirectCommandsLayoutNVX indirectCommandsLayout,
+ const VkAllocationCallbacks* pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroyIndirectCommandsLayoutNVX(device, indirectCommandsLayout, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateObjectTableNVX(
+ VkDevice device,
+ const VkObjectTableCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkObjectTableNVX* pObjectTable) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateObjectTableNVX(device, pCreateInfo, pAllocator, pObjectTable);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyObjectTableNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ const VkAllocationCallbacks* pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroyObjectTableNVX(device, objectTable, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL RegisterObjectsNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ uint32_t objectCount,
+ const VkObjectTableEntryNVX* const* ppObjectTableEntries,
+ const uint32_t* pObjectIndices) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->RegisterObjectsNVX(device, objectTable, objectCount, ppObjectTableEntries, pObjectIndices);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL UnregisterObjectsNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ uint32_t objectCount,
+ const VkObjectEntryTypeNVX* pObjectEntryTypes,
+ const uint32_t* pObjectIndices) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->UnregisterObjectsNVX(device, objectTable, objectCount, pObjectEntryTypes, pObjectIndices);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceGeneratedCommandsPropertiesNVX(
+ VkPhysicalDevice physicalDevice,
+ VkDeviceGeneratedCommandsFeaturesNVX* pFeatures,
+ VkDeviceGeneratedCommandsLimitsNVX* pLimits) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ disp->GetPhysicalDeviceGeneratedCommandsPropertiesNVX(unwrapped_phys_dev, pFeatures, pLimits);
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceGeneratedCommandsPropertiesNVX(
+ VkPhysicalDevice physicalDevice,
+ VkDeviceGeneratedCommandsFeaturesNVX* pFeatures,
+ VkDeviceGeneratedCommandsLimitsNVX* pLimits) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceGeneratedCommandsPropertiesNVX) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceGeneratedCommandsPropertiesNVX");
+ }
+ icd_term->dispatch.GetPhysicalDeviceGeneratedCommandsPropertiesNVX(phys_dev_term->phys_dev, pFeatures, pLimits);
+}
+
+
+// ---- VK_NV_clip_space_w_scaling extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetViewportWScalingNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewportWScalingNV* pViewportWScalings) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetViewportWScalingNV(commandBuffer, firstViewport, viewportCount, pViewportWScalings);
+}
+
+
+// ---- VK_EXT_display_control extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL DisplayPowerControlEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayPowerInfoEXT* pDisplayPowerInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->DisplayPowerControlEXT(device, display, pDisplayPowerInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL RegisterDeviceEventEXT(
+ VkDevice device,
+ const VkDeviceEventInfoEXT* pDeviceEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->RegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL RegisterDisplayEventEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayEventInfoEXT* pDisplayEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->RegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainCounterEXT(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkSurfaceCounterFlagBitsEXT counter,
+ uint64_t* pCounterValue) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetSwapchainCounterEXT(device, swapchain, counter, pCounterValue);
+}
+
+
+// ---- VK_GOOGLE_display_timing extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetRefreshCycleDurationGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPastPresentationTimingGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pPresentationTimingCount,
+ VkPastPresentationTimingGOOGLE* pPresentationTimings) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings);
+}
+
+
+// ---- VK_EXT_discard_rectangles extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetDiscardRectangleEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle,
+ uint32_t discardRectangleCount,
+ const VkRect2D* pDiscardRectangles) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetDiscardRectangleEXT(commandBuffer, firstDiscardRectangle, discardRectangleCount, pDiscardRectangles);
+}
+
+
+// ---- VK_EXT_hdr_metadata extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL SetHdrMetadataEXT(
+ VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainKHR* pSwapchains,
+ const VkHdrMetadataEXT* pMetadata) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->SetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata);
+}
+
+
+// ---- VK_EXT_debug_utils extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ VkDebugUtilsObjectNameInfoEXT local_name_info;
+ memcpy(&local_name_info, pNameInfo, sizeof(VkDebugUtilsObjectNameInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
+ struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pNameInfo->objectHandle;
+ local_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;
+ }
+ if (disp->SetDebugUtilsObjectNameEXT != NULL) {
+ return disp->SetDebugUtilsObjectNameEXT(device, &local_name_info);
+ } else {
+ return VK_SUCCESS;
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectNameEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.SetDebugUtilsObjectNameEXT) {
+ VkDebugUtilsObjectNameInfoEXT local_name_info;
+ memcpy(&local_name_info, pNameInfo, sizeof(VkDebugUtilsObjectNameInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pNameInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pNameInfo->objectHandle;
+ local_name_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;
+ // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
+ } else if (pNameInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
+ if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pNameInfo->objectHandle;
+ if (NULL != icd_surface->real_icd_surfaces) {
+ local_name_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index];
+ }
+ }
+ }
+ return icd_term->dispatch.SetDebugUtilsObjectNameEXT(device, &local_name_info);
+ } else {
+ return VK_SUCCESS;
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ VkDebugUtilsObjectTagInfoEXT local_tag_info;
+ memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugUtilsObjectTagInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
+ struct loader_physical_device_tramp *phys_dev_tramp = (struct loader_physical_device_tramp *)(uintptr_t)pTagInfo->objectHandle;
+ local_tag_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_tramp->phys_dev;
+ }
+ if (disp->SetDebugUtilsObjectTagEXT != NULL) {
+ return disp->SetDebugUtilsObjectTagEXT(device, &local_tag_info);
+ } else {
+ return VK_SUCCESS;
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_SetDebugUtilsObjectTagEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.SetDebugUtilsObjectTagEXT) {
+ VkDebugUtilsObjectTagInfoEXT local_tag_info;
+ memcpy(&local_tag_info, pTagInfo, sizeof(VkDebugUtilsObjectTagInfoEXT));
+ // If this is a physical device, we have to replace it with the proper one for the next call.
+ if (pTagInfo->objectType == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)(uintptr_t)pTagInfo->objectHandle;
+ local_tag_info.objectHandle = (uint64_t)(uintptr_t)phys_dev_term->phys_dev;
+ // If this is a KHR_surface, and the ICD has created its own, we have to replace it with the proper one for the next call.
+ } else if (pTagInfo->objectType == VK_OBJECT_TYPE_SURFACE_KHR) {
+ if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pTagInfo->objectHandle;
+ if (NULL != icd_surface->real_icd_surfaces) {
+ local_tag_info.objectHandle = (uint64_t)icd_surface->real_icd_surfaces[icd_index];
+ }
+ }
+ }
+ return icd_term->dispatch.SetDebugUtilsObjectTagEXT(device, &local_tag_info);
+ } else {
+ return VK_SUCCESS;
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueBeginDebugUtilsLabelEXT(
+ VkQueue queue,
+ const VkDebugUtilsLabelEXT* pLabelInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
+ if (disp->QueueBeginDebugUtilsLabelEXT != NULL) {
+ disp->QueueBeginDebugUtilsLabelEXT(queue, pLabelInfo);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueEndDebugUtilsLabelEXT(
+ VkQueue queue) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
+ if (disp->QueueEndDebugUtilsLabelEXT != NULL) {
+ disp->QueueEndDebugUtilsLabelEXT(queue);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueInsertDebugUtilsLabelEXT(
+ VkQueue queue,
+ const VkDebugUtilsLabelEXT* pLabelInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
+ if (disp->QueueInsertDebugUtilsLabelEXT != NULL) {
+ disp->QueueInsertDebugUtilsLabelEXT(queue, pLabelInfo);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginDebugUtilsLabelEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugUtilsLabelEXT* pLabelInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ if (disp->CmdBeginDebugUtilsLabelEXT != NULL) {
+ disp->CmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndDebugUtilsLabelEXT(
+ VkCommandBuffer commandBuffer) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ if (disp->CmdEndDebugUtilsLabelEXT != NULL) {
+ disp->CmdEndDebugUtilsLabelEXT(commandBuffer);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdInsertDebugUtilsLabelEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugUtilsLabelEXT* pLabelInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ if (disp->CmdInsertDebugUtilsLabelEXT != NULL) {
+ disp->CmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
+ }
+}
+
+
+// ---- VK_ANDROID_external_memory_android_hardware_buffer extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetAndroidHardwareBufferPropertiesANDROID(
+ VkDevice device,
+ const struct AHardwareBuffer* buffer,
+ VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetAndroidHardwareBufferPropertiesANDROID(device, buffer, pProperties);
+}
+
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryAndroidHardwareBufferANDROID(
+ VkDevice device,
+ const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
+ struct AHardwareBuffer** pBuffer) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetMemoryAndroidHardwareBufferANDROID(device, pInfo, pBuffer);
+}
+
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+// ---- VK_EXT_sample_locations extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetSampleLocationsEXT(
+ VkCommandBuffer commandBuffer,
+ const VkSampleLocationsInfoEXT* pSampleLocationsInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetSampleLocationsEXT(commandBuffer, pSampleLocationsInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceMultisamplePropertiesEXT(
+ VkPhysicalDevice physicalDevice,
+ VkSampleCountFlagBits samples,
+ VkMultisamplePropertiesEXT* pMultisampleProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ disp->GetPhysicalDeviceMultisamplePropertiesEXT(unwrapped_phys_dev, samples, pMultisampleProperties);
+}
+
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMultisamplePropertiesEXT(
+ VkPhysicalDevice physicalDevice,
+ VkSampleCountFlagBits samples,
+ VkMultisamplePropertiesEXT* pMultisampleProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceMultisamplePropertiesEXT) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceMultisamplePropertiesEXT");
+ }
+ icd_term->dispatch.GetPhysicalDeviceMultisamplePropertiesEXT(phys_dev_term->phys_dev, samples, pMultisampleProperties);
+}
+
+
+// ---- VK_EXT_image_drm_format_modifier extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetImageDrmFormatModifierPropertiesEXT(
+ VkDevice device,
+ VkImage image,
+ VkImageDrmFormatModifierPropertiesEXT* pProperties) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetImageDrmFormatModifierPropertiesEXT(device, image, pProperties);
+}
+
+
+// ---- VK_EXT_validation_cache extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateValidationCacheEXT(
+ VkDevice device,
+ const VkValidationCacheCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkValidationCacheEXT* pValidationCache) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateValidationCacheEXT(device, pCreateInfo, pAllocator, pValidationCache);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyValidationCacheEXT(
+ VkDevice device,
+ VkValidationCacheEXT validationCache,
+ const VkAllocationCallbacks* pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroyValidationCacheEXT(device, validationCache, pAllocator);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL MergeValidationCachesEXT(
+ VkDevice device,
+ VkValidationCacheEXT dstCache,
+ uint32_t srcCacheCount,
+ const VkValidationCacheEXT* pSrcCaches) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->MergeValidationCachesEXT(device, dstCache, srcCacheCount, pSrcCaches);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetValidationCacheDataEXT(
+ VkDevice device,
+ VkValidationCacheEXT validationCache,
+ size_t* pDataSize,
+ void* pData) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetValidationCacheDataEXT(device, validationCache, pDataSize, pData);
+}
+
+
+// ---- VK_NV_shading_rate_image extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdBindShadingRateImageNV(
+ VkCommandBuffer commandBuffer,
+ VkImageView imageView,
+ VkImageLayout imageLayout) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdBindShadingRateImageNV(commandBuffer, imageView, imageLayout);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetViewportShadingRatePaletteNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkShadingRatePaletteNV* pShadingRatePalettes) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetViewportShadingRatePaletteNV(commandBuffer, firstViewport, viewportCount, pShadingRatePalettes);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdSetCoarseSampleOrderNV(
+ VkCommandBuffer commandBuffer,
+ VkCoarseSampleOrderTypeNV sampleOrderType,
+ uint32_t customSampleOrderCount,
+ const VkCoarseSampleOrderCustomNV* pCustomSampleOrders) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetCoarseSampleOrderNV(commandBuffer, sampleOrderType, customSampleOrderCount, pCustomSampleOrders);
+}
+
+
+// ---- VK_NV_ray_tracing extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateAccelerationStructureNV(
+ VkDevice device,
+ const VkAccelerationStructureCreateInfoNV* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkAccelerationStructureNV* pAccelerationStructure) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateAccelerationStructureNV(device, pCreateInfo, pAllocator, pAccelerationStructure);
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyAccelerationStructureNV(
+ VkDevice device,
+ VkAccelerationStructureNV accelerationStructure,
+ const VkAllocationCallbacks* pAllocator) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->DestroyAccelerationStructureNV(device, accelerationStructure, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetAccelerationStructureMemoryRequirementsNV(
+ VkDevice device,
+ const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo,
+ VkMemoryRequirements2KHR* pMemoryRequirements) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->GetAccelerationStructureMemoryRequirementsNV(device, pInfo, pMemoryRequirements);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL BindAccelerationStructureMemoryNV(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindAccelerationStructureMemoryInfoNV* pBindInfos) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->BindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBuildAccelerationStructureNV(
+ VkCommandBuffer commandBuffer,
+ const VkAccelerationStructureInfoNV* pInfo,
+ VkBuffer instanceData,
+ VkDeviceSize instanceOffset,
+ VkBool32 update,
+ VkAccelerationStructureNV dst,
+ VkAccelerationStructureNV src,
+ VkBuffer scratch,
+ VkDeviceSize scratchOffset) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update, dst, src, scratch, scratchOffset);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdCopyAccelerationStructureNV(
+ VkCommandBuffer commandBuffer,
+ VkAccelerationStructureNV dst,
+ VkAccelerationStructureNV src,
+ VkCopyAccelerationStructureModeNV mode) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdCopyAccelerationStructureNV(commandBuffer, dst, src, mode);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdTraceRaysNV(
+ VkCommandBuffer commandBuffer,
+ VkBuffer raygenShaderBindingTableBuffer,
+ VkDeviceSize raygenShaderBindingOffset,
+ VkBuffer missShaderBindingTableBuffer,
+ VkDeviceSize missShaderBindingOffset,
+ VkDeviceSize missShaderBindingStride,
+ VkBuffer hitShaderBindingTableBuffer,
+ VkDeviceSize hitShaderBindingOffset,
+ VkDeviceSize hitShaderBindingStride,
+ VkBuffer callableShaderBindingTableBuffer,
+ VkDeviceSize callableShaderBindingOffset,
+ VkDeviceSize callableShaderBindingStride,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdTraceRaysNV(commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer, missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset, hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width, height, depth);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateRayTracingPipelinesNV(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkRayTracingPipelineCreateInfoNV* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CreateRayTracingPipelinesNV(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetRayTracingShaderGroupHandlesNV(
+ VkDevice device,
+ VkPipeline pipeline,
+ uint32_t firstGroup,
+ uint32_t groupCount,
+ size_t dataSize,
+ void* pData) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetRayTracingShaderGroupHandlesNV(device, pipeline, firstGroup, groupCount, dataSize, pData);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetAccelerationStructureHandleNV(
+ VkDevice device,
+ VkAccelerationStructureNV accelerationStructure,
+ size_t dataSize,
+ void* pData) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetAccelerationStructureHandleNV(device, accelerationStructure, dataSize, pData);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdWriteAccelerationStructuresPropertiesNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t accelerationStructureCount,
+ const VkAccelerationStructureNV* pAccelerationStructures,
+ VkQueryType queryType,
+ VkQueryPool queryPool,
+ uint32_t firstQuery) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdWriteAccelerationStructuresPropertiesNV(commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CompileDeferredNV(
+ VkDevice device,
+ VkPipeline pipeline,
+ uint32_t shader) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->CompileDeferredNV(device, pipeline, shader);
+}
+
+
+// ---- VK_EXT_external_memory_host extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryHostPointerPropertiesEXT(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ const void* pHostPointer,
+ VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetMemoryHostPointerPropertiesEXT(device, handleType, pHostPointer, pMemoryHostPointerProperties);
+}
+
+
+// ---- VK_AMD_buffer_marker extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdWriteBufferMarkerAMD(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ uint32_t marker) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdWriteBufferMarkerAMD(commandBuffer, pipelineStage, dstBuffer, dstOffset, marker);
+}
+
+
+// ---- VK_EXT_calibrated_timestamps extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pTimeDomainCount,
+ VkTimeDomainEXT* pTimeDomains) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceCalibrateableTimeDomainsEXT(unwrapped_phys_dev, pTimeDomainCount, pTimeDomains);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pTimeDomainCount,
+ VkTimeDomainEXT* pTimeDomains) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceCalibrateableTimeDomainsEXT) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceCalibrateableTimeDomainsEXT");
+ }
+ return icd_term->dispatch.GetPhysicalDeviceCalibrateableTimeDomainsEXT(phys_dev_term->phys_dev, pTimeDomainCount, pTimeDomains);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetCalibratedTimestampsEXT(
+ VkDevice device,
+ uint32_t timestampCount,
+ const VkCalibratedTimestampInfoEXT* pTimestampInfos,
+ uint64_t* pTimestamps,
+ uint64_t* pMaxDeviation) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetCalibratedTimestampsEXT(device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation);
+}
+
+
+// ---- VK_NV_mesh_shader extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t taskCount,
+ uint32_t firstTask) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectNV(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ uint32_t drawCount,
+ uint32_t stride) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawMeshTasksIndirectCountNV(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+}
+
+
+// ---- VK_NV_scissor_exclusive extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetExclusiveScissorNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstExclusiveScissor,
+ uint32_t exclusiveScissorCount,
+ const VkRect2D* pExclusiveScissors) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetExclusiveScissorNV(commandBuffer, firstExclusiveScissor, exclusiveScissorCount, pExclusiveScissors);
+}
+
+
+// ---- VK_NV_device_diagnostic_checkpoints extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetCheckpointNV(
+ VkCommandBuffer commandBuffer,
+ const void* pCheckpointMarker) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetCheckpointNV(commandBuffer, pCheckpointMarker);
+}
+
+VKAPI_ATTR void VKAPI_CALL GetQueueCheckpointDataNV(
+ VkQueue queue,
+ uint32_t* pCheckpointDataCount,
+ VkCheckpointDataNV* pCheckpointData) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
+ disp->GetQueueCheckpointDataNV(queue, pCheckpointDataCount, pCheckpointData);
+}
+
+
+// ---- VK_INTEL_performance_query extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL InitializePerformanceApiINTEL(
+ VkDevice device,
+ const VkInitializePerformanceApiInfoINTEL* pInitializeInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->InitializePerformanceApiINTEL(device, pInitializeInfo);
+}
+
+VKAPI_ATTR void VKAPI_CALL UninitializePerformanceApiINTEL(
+ VkDevice device) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->UninitializePerformanceApiINTEL(device);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CmdSetPerformanceMarkerINTEL(
+ VkCommandBuffer commandBuffer,
+ const VkPerformanceMarkerInfoINTEL* pMarkerInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ return disp->CmdSetPerformanceMarkerINTEL(commandBuffer, pMarkerInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CmdSetPerformanceStreamMarkerINTEL(
+ VkCommandBuffer commandBuffer,
+ const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ return disp->CmdSetPerformanceStreamMarkerINTEL(commandBuffer, pMarkerInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CmdSetPerformanceOverrideINTEL(
+ VkCommandBuffer commandBuffer,
+ const VkPerformanceOverrideInfoINTEL* pOverrideInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ return disp->CmdSetPerformanceOverrideINTEL(commandBuffer, pOverrideInfo);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL AcquirePerformanceConfigurationINTEL(
+ VkDevice device,
+ const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo,
+ VkPerformanceConfigurationINTEL* pConfiguration) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->AcquirePerformanceConfigurationINTEL(device, pAcquireInfo, pConfiguration);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL ReleasePerformanceConfigurationINTEL(
+ VkDevice device,
+ VkPerformanceConfigurationINTEL configuration) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->ReleasePerformanceConfigurationINTEL(device, configuration);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL QueueSetPerformanceConfigurationINTEL(
+ VkQueue queue,
+ VkPerformanceConfigurationINTEL configuration) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(queue);
+ return disp->QueueSetPerformanceConfigurationINTEL(queue, configuration);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPerformanceParameterINTEL(
+ VkDevice device,
+ VkPerformanceParameterTypeINTEL parameter,
+ VkPerformanceValueINTEL* pValue) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetPerformanceParameterINTEL(device, parameter, pValue);
+}
+
+
+// ---- VK_AMD_display_native_hdr extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL SetLocalDimmingAMD(
+ VkDevice device,
+ VkSwapchainKHR swapChain,
+ VkBool32 localDimmingEnable) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->SetLocalDimmingAMD(device, swapChain, localDimmingEnable);
+}
+
+
+// ---- VK_FUCHSIA_imagepipe_surface extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+VKAPI_ATTR VkResult VKAPI_CALL CreateImagePipeSurfaceFUCHSIA(
+ VkInstance instance,
+ const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface) {
+#error("Not implemented. Likely needs to be manually generated!");
+ return disp->CreateImagePipeSurfaceFUCHSIA(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateImagePipeSurfaceFUCHSIA(
+ VkInstance instance,
+ const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface) {
+#error("Not implemented. Likely needs to be manually generated!");
+}
+
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+// ---- VK_EXT_buffer_device_address extension trampoline/terminators
+
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL GetBufferDeviceAddressEXT(
+ VkDevice device,
+ const VkBufferDeviceAddressInfoEXT* pInfo) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetBufferDeviceAddressEXT(device, pInfo);
+}
+
+
+// ---- VK_NV_cooperative_matrix extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceCooperativeMatrixPropertiesNV(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkCooperativeMatrixPropertiesNV* pProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceCooperativeMatrixPropertiesNV(unwrapped_phys_dev, pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceCooperativeMatrixPropertiesNV(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkCooperativeMatrixPropertiesNV* pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceCooperativeMatrixPropertiesNV) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceCooperativeMatrixPropertiesNV");
+ }
+ return icd_term->dispatch.GetPhysicalDeviceCooperativeMatrixPropertiesNV(phys_dev_term->phys_dev, pPropertyCount, pProperties);
+}
+
+
+// ---- VK_NV_coverage_reduction_mode extension trampoline/terminators
+
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pCombinationCount,
+ VkFramebufferMixedSamplesCombinationNV* pCombinations) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(unwrapped_phys_dev, pCombinationCount, pCombinations);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pCombinationCount,
+ VkFramebufferMixedSamplesCombinationNV* pCombinations) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD associated with VkPhysicalDevice does not support GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
+ }
+ return icd_term->dispatch.GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(phys_dev_term->phys_dev, pCombinationCount, pCombinations);
+}
+
+
+// ---- VK_EXT_full_screen_exclusive extension trampoline/terminators
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL AcquireFullScreenExclusiveModeEXT(
+ VkDevice device,
+ VkSwapchainKHR swapchain) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->AcquireFullScreenExclusiveModeEXT(device, swapchain);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL ReleaseFullScreenExclusiveModeEXT(
+ VkDevice device,
+ VkSwapchainKHR swapchain) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->ReleaseFullScreenExclusiveModeEXT(device, swapchain);
+}
+
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+// ---- VK_EXT_line_rasterization extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL CmdSetLineStippleEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t lineStippleFactor,
+ uint16_t lineStipplePattern) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(commandBuffer);
+ disp->CmdSetLineStippleEXT(commandBuffer, lineStippleFactor, lineStipplePattern);
+}
+
+
+// ---- VK_EXT_host_query_reset extension trampoline/terminators
+
+VKAPI_ATTR void VKAPI_CALL ResetQueryPoolEXT(
+ VkDevice device,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ disp->ResetQueryPoolEXT(device, queryPool, firstQuery, queryCount);
+}
+
+// GPA helpers for extensions
+bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr) {
+ *addr = NULL;
+
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ if (!strcmp("vkGetPhysicalDeviceFeatures2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+ ? (void *)vkGetPhysicalDeviceFeatures2
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceProperties2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+ ? (void *)vkGetPhysicalDeviceProperties2
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceFormatProperties2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+ ? (void *)vkGetPhysicalDeviceFormatProperties2
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceImageFormatProperties2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+ ? (void *)vkGetPhysicalDeviceImageFormatProperties2
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceQueueFamilyProperties2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+ ? (void *)vkGetPhysicalDeviceQueueFamilyProperties2
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceMemoryProperties2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+ ? (void *)vkGetPhysicalDeviceMemoryProperties2
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceSparseImageFormatProperties2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 == 1)
+ ? (void *)vkGetPhysicalDeviceSparseImageFormatProperties2
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_KHR_device_group extension commands
+ if (!strcmp("vkGetDeviceGroupPeerMemoryFeaturesKHR", name)) {
+ *addr = (void *)GetDeviceGroupPeerMemoryFeaturesKHR;
+ return true;
+ }
+ if (!strcmp("vkCmdSetDeviceMaskKHR", name)) {
+ *addr = (void *)CmdSetDeviceMaskKHR;
+ return true;
+ }
+ if (!strcmp("vkCmdDispatchBaseKHR", name)) {
+ *addr = (void *)CmdDispatchBaseKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_maintenance1 extension commands
+ if (!strcmp("vkTrimCommandPoolKHR", name)) {
+ *addr = (void *)TrimCommandPoolKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_device_group_creation extension commands
+ if (!strcmp("vkEnumeratePhysicalDeviceGroupsKHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_device_group_creation == 1)
+ ? (void *)vkEnumeratePhysicalDeviceGroups
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ if (!strcmp("vkGetPhysicalDeviceExternalBufferPropertiesKHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_external_memory_capabilities == 1)
+ ? (void *)vkGetPhysicalDeviceExternalBufferProperties
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_KHR_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkGetMemoryWin32HandleKHR", name)) {
+ *addr = (void *)GetMemoryWin32HandleKHR;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkGetMemoryWin32HandlePropertiesKHR", name)) {
+ *addr = (void *)GetMemoryWin32HandlePropertiesKHR;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_memory_fd extension commands
+ if (!strcmp("vkGetMemoryFdKHR", name)) {
+ *addr = (void *)GetMemoryFdKHR;
+ return true;
+ }
+ if (!strcmp("vkGetMemoryFdPropertiesKHR", name)) {
+ *addr = (void *)GetMemoryFdPropertiesKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ if (!strcmp("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_external_semaphore_capabilities == 1)
+ ? (void *)vkGetPhysicalDeviceExternalSemaphoreProperties
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_KHR_external_semaphore_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkImportSemaphoreWin32HandleKHR", name)) {
+ *addr = (void *)ImportSemaphoreWin32HandleKHR;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkGetSemaphoreWin32HandleKHR", name)) {
+ *addr = (void *)GetSemaphoreWin32HandleKHR;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_semaphore_fd extension commands
+ if (!strcmp("vkImportSemaphoreFdKHR", name)) {
+ *addr = (void *)ImportSemaphoreFdKHR;
+ return true;
+ }
+ if (!strcmp("vkGetSemaphoreFdKHR", name)) {
+ *addr = (void *)GetSemaphoreFdKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_push_descriptor extension commands
+ if (!strcmp("vkCmdPushDescriptorSetKHR", name)) {
+ *addr = (void *)CmdPushDescriptorSetKHR;
+ return true;
+ }
+ if (!strcmp("vkCmdPushDescriptorSetWithTemplateKHR", name)) {
+ *addr = (void *)CmdPushDescriptorSetWithTemplateKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_descriptor_update_template extension commands
+ if (!strcmp("vkCreateDescriptorUpdateTemplateKHR", name)) {
+ *addr = (void *)CreateDescriptorUpdateTemplateKHR;
+ return true;
+ }
+ if (!strcmp("vkDestroyDescriptorUpdateTemplateKHR", name)) {
+ *addr = (void *)DestroyDescriptorUpdateTemplateKHR;
+ return true;
+ }
+ if (!strcmp("vkUpdateDescriptorSetWithTemplateKHR", name)) {
+ *addr = (void *)UpdateDescriptorSetWithTemplateKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_create_renderpass2 extension commands
+ if (!strcmp("vkCreateRenderPass2KHR", name)) {
+ *addr = (void *)CreateRenderPass2KHR;
+ return true;
+ }
+ if (!strcmp("vkCmdBeginRenderPass2KHR", name)) {
+ *addr = (void *)CmdBeginRenderPass2KHR;
+ return true;
+ }
+ if (!strcmp("vkCmdNextSubpass2KHR", name)) {
+ *addr = (void *)CmdNextSubpass2KHR;
+ return true;
+ }
+ if (!strcmp("vkCmdEndRenderPass2KHR", name)) {
+ *addr = (void *)CmdEndRenderPass2KHR;
+ return true;
+ }
+
+ // ---- VK_KHR_shared_presentable_image extension commands
+ if (!strcmp("vkGetSwapchainStatusKHR", name)) {
+ *addr = (void *)GetSwapchainStatusKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ if (!strcmp("vkGetPhysicalDeviceExternalFencePropertiesKHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_external_fence_capabilities == 1)
+ ? (void *)vkGetPhysicalDeviceExternalFenceProperties
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_KHR_external_fence_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkImportFenceWin32HandleKHR", name)) {
+ *addr = (void *)ImportFenceWin32HandleKHR;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkGetFenceWin32HandleKHR", name)) {
+ *addr = (void *)GetFenceWin32HandleKHR;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_external_fence_fd extension commands
+ if (!strcmp("vkImportFenceFdKHR", name)) {
+ *addr = (void *)ImportFenceFdKHR;
+ return true;
+ }
+ if (!strcmp("vkGetFenceFdKHR", name)) {
+ *addr = (void *)GetFenceFdKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_surface_capabilities2 == 1)
+ ? (void *)GetPhysicalDeviceSurfaceCapabilities2KHR
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.khr_get_surface_capabilities2 == 1)
+ ? (void *)GetPhysicalDeviceSurfaceFormats2KHR
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_KHR_get_memory_requirements2 extension commands
+ if (!strcmp("vkGetImageMemoryRequirements2KHR", name)) {
+ *addr = (void *)GetImageMemoryRequirements2KHR;
+ return true;
+ }
+ if (!strcmp("vkGetBufferMemoryRequirements2KHR", name)) {
+ *addr = (void *)GetBufferMemoryRequirements2KHR;
+ return true;
+ }
+ if (!strcmp("vkGetImageSparseMemoryRequirements2KHR", name)) {
+ *addr = (void *)GetImageSparseMemoryRequirements2KHR;
+ return true;
+ }
+
+ // ---- VK_KHR_sampler_ycbcr_conversion extension commands
+ if (!strcmp("vkCreateSamplerYcbcrConversionKHR", name)) {
+ *addr = (void *)CreateSamplerYcbcrConversionKHR;
+ return true;
+ }
+ if (!strcmp("vkDestroySamplerYcbcrConversionKHR", name)) {
+ *addr = (void *)DestroySamplerYcbcrConversionKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_bind_memory2 extension commands
+ if (!strcmp("vkBindBufferMemory2KHR", name)) {
+ *addr = (void *)BindBufferMemory2KHR;
+ return true;
+ }
+ if (!strcmp("vkBindImageMemory2KHR", name)) {
+ *addr = (void *)BindImageMemory2KHR;
+ return true;
+ }
+
+ // ---- VK_KHR_maintenance3 extension commands
+ if (!strcmp("vkGetDescriptorSetLayoutSupportKHR", name)) {
+ *addr = (void *)GetDescriptorSetLayoutSupportKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_draw_indirect_count extension commands
+ if (!strcmp("vkCmdDrawIndirectCountKHR", name)) {
+ *addr = (void *)CmdDrawIndirectCountKHR;
+ return true;
+ }
+ if (!strcmp("vkCmdDrawIndexedIndirectCountKHR", name)) {
+ *addr = (void *)CmdDrawIndexedIndirectCountKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_timeline_semaphore extension commands
+ if (!strcmp("vkGetSemaphoreCounterValueKHR", name)) {
+ *addr = (void *)GetSemaphoreCounterValueKHR;
+ return true;
+ }
+ if (!strcmp("vkWaitSemaphoresKHR", name)) {
+ *addr = (void *)WaitSemaphoresKHR;
+ return true;
+ }
+ if (!strcmp("vkSignalSemaphoreKHR", name)) {
+ *addr = (void *)SignalSemaphoreKHR;
+ return true;
+ }
+
+ // ---- VK_KHR_pipeline_executable_properties extension commands
+ if (!strcmp("vkGetPipelineExecutablePropertiesKHR", name)) {
+ *addr = (void *)GetPipelineExecutablePropertiesKHR;
+ return true;
+ }
+ if (!strcmp("vkGetPipelineExecutableStatisticsKHR", name)) {
+ *addr = (void *)GetPipelineExecutableStatisticsKHR;
+ return true;
+ }
+ if (!strcmp("vkGetPipelineExecutableInternalRepresentationsKHR", name)) {
+ *addr = (void *)GetPipelineExecutableInternalRepresentationsKHR;
+ return true;
+ }
+
+ // ---- VK_EXT_debug_marker extension commands
+ if (!strcmp("vkDebugMarkerSetObjectTagEXT", name)) {
+ *addr = (void *)DebugMarkerSetObjectTagEXT;
+ return true;
+ }
+ if (!strcmp("vkDebugMarkerSetObjectNameEXT", name)) {
+ *addr = (void *)DebugMarkerSetObjectNameEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdDebugMarkerBeginEXT", name)) {
+ *addr = (void *)CmdDebugMarkerBeginEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdDebugMarkerEndEXT", name)) {
+ *addr = (void *)CmdDebugMarkerEndEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdDebugMarkerInsertEXT", name)) {
+ *addr = (void *)CmdDebugMarkerInsertEXT;
+ return true;
+ }
+
+ // ---- VK_EXT_transform_feedback extension commands
+ if (!strcmp("vkCmdBindTransformFeedbackBuffersEXT", name)) {
+ *addr = (void *)CmdBindTransformFeedbackBuffersEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdBeginTransformFeedbackEXT", name)) {
+ *addr = (void *)CmdBeginTransformFeedbackEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdEndTransformFeedbackEXT", name)) {
+ *addr = (void *)CmdEndTransformFeedbackEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdBeginQueryIndexedEXT", name)) {
+ *addr = (void *)CmdBeginQueryIndexedEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdEndQueryIndexedEXT", name)) {
+ *addr = (void *)CmdEndQueryIndexedEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdDrawIndirectByteCountEXT", name)) {
+ *addr = (void *)CmdDrawIndirectByteCountEXT;
+ return true;
+ }
+
+ // ---- VK_NVX_image_view_handle extension commands
+ if (!strcmp("vkGetImageViewHandleNVX", name)) {
+ *addr = (void *)GetImageViewHandleNVX;
+ return true;
+ }
+
+ // ---- VK_AMD_draw_indirect_count extension commands
+ if (!strcmp("vkCmdDrawIndirectCountAMD", name)) {
+ *addr = (void *)CmdDrawIndirectCountAMD;
+ return true;
+ }
+ if (!strcmp("vkCmdDrawIndexedIndirectCountAMD", name)) {
+ *addr = (void *)CmdDrawIndexedIndirectCountAMD;
+ return true;
+ }
+
+ // ---- VK_AMD_shader_info extension commands
+ if (!strcmp("vkGetShaderInfoAMD", name)) {
+ *addr = (void *)GetShaderInfoAMD;
+ return true;
+ }
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ if (!strcmp("vkCreateStreamDescriptorSurfaceGGP", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ggp_stream_descriptor_surface == 1)
+ ? (void *)CreateStreamDescriptorSurfaceGGP
+ : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ if (!strcmp("vkGetPhysicalDeviceExternalImageFormatPropertiesNV", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.nv_external_memory_capabilities == 1)
+ ? (void *)GetPhysicalDeviceExternalImageFormatPropertiesNV
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_NV_external_memory_win32 extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkGetMemoryWin32HandleNV", name)) {
+ *addr = (void *)GetMemoryWin32HandleNV;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ if (!strcmp("vkCreateViSurfaceNN", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.nn_vi_surface == 1)
+ ? (void *)CreateViSurfaceNN
+ : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_EXT_conditional_rendering extension commands
+ if (!strcmp("vkCmdBeginConditionalRenderingEXT", name)) {
+ *addr = (void *)CmdBeginConditionalRenderingEXT;
+ return true;
+ }
+ if (!strcmp("vkCmdEndConditionalRenderingEXT", name)) {
+ *addr = (void *)CmdEndConditionalRenderingEXT;
+ return true;
+ }
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ if (!strcmp("vkCmdProcessCommandsNVX", name)) {
+ *addr = (void *)CmdProcessCommandsNVX;
+ return true;
+ }
+ if (!strcmp("vkCmdReserveSpaceForCommandsNVX", name)) {
+ *addr = (void *)CmdReserveSpaceForCommandsNVX;
+ return true;
+ }
+ if (!strcmp("vkCreateIndirectCommandsLayoutNVX", name)) {
+ *addr = (void *)CreateIndirectCommandsLayoutNVX;
+ return true;
+ }
+ if (!strcmp("vkDestroyIndirectCommandsLayoutNVX", name)) {
+ *addr = (void *)DestroyIndirectCommandsLayoutNVX;
+ return true;
+ }
+ if (!strcmp("vkCreateObjectTableNVX", name)) {
+ *addr = (void *)CreateObjectTableNVX;
+ return true;
+ }
+ if (!strcmp("vkDestroyObjectTableNVX", name)) {
+ *addr = (void *)DestroyObjectTableNVX;
+ return true;
+ }
+ if (!strcmp("vkRegisterObjectsNVX", name)) {
+ *addr = (void *)RegisterObjectsNVX;
+ return true;
+ }
+ if (!strcmp("vkUnregisterObjectsNVX", name)) {
+ *addr = (void *)UnregisterObjectsNVX;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX", name)) {
+ *addr = (void *)GetPhysicalDeviceGeneratedCommandsPropertiesNVX;
+ return true;
+ }
+
+ // ---- VK_NV_clip_space_w_scaling extension commands
+ if (!strcmp("vkCmdSetViewportWScalingNV", name)) {
+ *addr = (void *)CmdSetViewportWScalingNV;
+ return true;
+ }
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ if (!strcmp("vkReleaseDisplayEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_direct_mode_display == 1)
+ ? (void *)ReleaseDisplayEXT
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ if (!strcmp("vkAcquireXlibDisplayEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_acquire_xlib_display == 1)
+ ? (void *)AcquireXlibDisplayEXT
+ : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ if (!strcmp("vkGetRandROutputDisplayEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_acquire_xlib_display == 1)
+ ? (void *)GetRandROutputDisplayEXT
+ : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilities2EXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_display_surface_counter == 1)
+ ? (void *)GetPhysicalDeviceSurfaceCapabilities2EXT
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_EXT_display_control extension commands
+ if (!strcmp("vkDisplayPowerControlEXT", name)) {
+ *addr = (void *)DisplayPowerControlEXT;
+ return true;
+ }
+ if (!strcmp("vkRegisterDeviceEventEXT", name)) {
+ *addr = (void *)RegisterDeviceEventEXT;
+ return true;
+ }
+ if (!strcmp("vkRegisterDisplayEventEXT", name)) {
+ *addr = (void *)RegisterDisplayEventEXT;
+ return true;
+ }
+ if (!strcmp("vkGetSwapchainCounterEXT", name)) {
+ *addr = (void *)GetSwapchainCounterEXT;
+ return true;
+ }
+
+ // ---- VK_GOOGLE_display_timing extension commands
+ if (!strcmp("vkGetRefreshCycleDurationGOOGLE", name)) {
+ *addr = (void *)GetRefreshCycleDurationGOOGLE;
+ return true;
+ }
+ if (!strcmp("vkGetPastPresentationTimingGOOGLE", name)) {
+ *addr = (void *)GetPastPresentationTimingGOOGLE;
+ return true;
+ }
+
+ // ---- VK_EXT_discard_rectangles extension commands
+ if (!strcmp("vkCmdSetDiscardRectangleEXT", name)) {
+ *addr = (void *)CmdSetDiscardRectangleEXT;
+ return true;
+ }
+
+ // ---- VK_EXT_hdr_metadata extension commands
+ if (!strcmp("vkSetHdrMetadataEXT", name)) {
+ *addr = (void *)SetHdrMetadataEXT;
+ return true;
+ }
+
+ // ---- VK_EXT_debug_utils extension commands
+ if (!strcmp("vkSetDebugUtilsObjectNameEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)SetDebugUtilsObjectNameEXT
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkSetDebugUtilsObjectTagEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)SetDebugUtilsObjectTagEXT
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkQueueBeginDebugUtilsLabelEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)QueueBeginDebugUtilsLabelEXT
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkQueueEndDebugUtilsLabelEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)QueueEndDebugUtilsLabelEXT
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkQueueInsertDebugUtilsLabelEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)QueueInsertDebugUtilsLabelEXT
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkCmdBeginDebugUtilsLabelEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)CmdBeginDebugUtilsLabelEXT
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkCmdEndDebugUtilsLabelEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)CmdEndDebugUtilsLabelEXT
+ : NULL;
+ return true;
+ }
+ if (!strcmp("vkCmdInsertDebugUtilsLabelEXT", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.ext_debug_utils == 1)
+ ? (void *)CmdInsertDebugUtilsLabelEXT
+ : NULL;
+ return true;
+ }
+
+ // ---- VK_ANDROID_external_memory_android_hardware_buffer extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ if (!strcmp("vkGetAndroidHardwareBufferPropertiesANDROID", name)) {
+ *addr = (void *)GetAndroidHardwareBufferPropertiesANDROID;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ if (!strcmp("vkGetMemoryAndroidHardwareBufferANDROID", name)) {
+ *addr = (void *)GetMemoryAndroidHardwareBufferANDROID;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_EXT_sample_locations extension commands
+ if (!strcmp("vkCmdSetSampleLocationsEXT", name)) {
+ *addr = (void *)CmdSetSampleLocationsEXT;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceMultisamplePropertiesEXT", name)) {
+ *addr = (void *)GetPhysicalDeviceMultisamplePropertiesEXT;
+ return true;
+ }
+
+ // ---- VK_EXT_image_drm_format_modifier extension commands
+ if (!strcmp("vkGetImageDrmFormatModifierPropertiesEXT", name)) {
+ *addr = (void *)GetImageDrmFormatModifierPropertiesEXT;
+ return true;
+ }
+
+ // ---- VK_EXT_validation_cache extension commands
+ if (!strcmp("vkCreateValidationCacheEXT", name)) {
+ *addr = (void *)CreateValidationCacheEXT;
+ return true;
+ }
+ if (!strcmp("vkDestroyValidationCacheEXT", name)) {
+ *addr = (void *)DestroyValidationCacheEXT;
+ return true;
+ }
+ if (!strcmp("vkMergeValidationCachesEXT", name)) {
+ *addr = (void *)MergeValidationCachesEXT;
+ return true;
+ }
+ if (!strcmp("vkGetValidationCacheDataEXT", name)) {
+ *addr = (void *)GetValidationCacheDataEXT;
+ return true;
+ }
+
+ // ---- VK_NV_shading_rate_image extension commands
+ if (!strcmp("vkCmdBindShadingRateImageNV", name)) {
+ *addr = (void *)CmdBindShadingRateImageNV;
+ return true;
+ }
+ if (!strcmp("vkCmdSetViewportShadingRatePaletteNV", name)) {
+ *addr = (void *)CmdSetViewportShadingRatePaletteNV;
+ return true;
+ }
+ if (!strcmp("vkCmdSetCoarseSampleOrderNV", name)) {
+ *addr = (void *)CmdSetCoarseSampleOrderNV;
+ return true;
+ }
+
+ // ---- VK_NV_ray_tracing extension commands
+ if (!strcmp("vkCreateAccelerationStructureNV", name)) {
+ *addr = (void *)CreateAccelerationStructureNV;
+ return true;
+ }
+ if (!strcmp("vkDestroyAccelerationStructureNV", name)) {
+ *addr = (void *)DestroyAccelerationStructureNV;
+ return true;
+ }
+ if (!strcmp("vkGetAccelerationStructureMemoryRequirementsNV", name)) {
+ *addr = (void *)GetAccelerationStructureMemoryRequirementsNV;
+ return true;
+ }
+ if (!strcmp("vkBindAccelerationStructureMemoryNV", name)) {
+ *addr = (void *)BindAccelerationStructureMemoryNV;
+ return true;
+ }
+ if (!strcmp("vkCmdBuildAccelerationStructureNV", name)) {
+ *addr = (void *)CmdBuildAccelerationStructureNV;
+ return true;
+ }
+ if (!strcmp("vkCmdCopyAccelerationStructureNV", name)) {
+ *addr = (void *)CmdCopyAccelerationStructureNV;
+ return true;
+ }
+ if (!strcmp("vkCmdTraceRaysNV", name)) {
+ *addr = (void *)CmdTraceRaysNV;
+ return true;
+ }
+ if (!strcmp("vkCreateRayTracingPipelinesNV", name)) {
+ *addr = (void *)CreateRayTracingPipelinesNV;
+ return true;
+ }
+ if (!strcmp("vkGetRayTracingShaderGroupHandlesNV", name)) {
+ *addr = (void *)GetRayTracingShaderGroupHandlesNV;
+ return true;
+ }
+ if (!strcmp("vkGetAccelerationStructureHandleNV", name)) {
+ *addr = (void *)GetAccelerationStructureHandleNV;
+ return true;
+ }
+ if (!strcmp("vkCmdWriteAccelerationStructuresPropertiesNV", name)) {
+ *addr = (void *)CmdWriteAccelerationStructuresPropertiesNV;
+ return true;
+ }
+ if (!strcmp("vkCompileDeferredNV", name)) {
+ *addr = (void *)CompileDeferredNV;
+ return true;
+ }
+
+ // ---- VK_EXT_external_memory_host extension commands
+ if (!strcmp("vkGetMemoryHostPointerPropertiesEXT", name)) {
+ *addr = (void *)GetMemoryHostPointerPropertiesEXT;
+ return true;
+ }
+
+ // ---- VK_AMD_buffer_marker extension commands
+ if (!strcmp("vkCmdWriteBufferMarkerAMD", name)) {
+ *addr = (void *)CmdWriteBufferMarkerAMD;
+ return true;
+ }
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ if (!strcmp("vkGetPhysicalDeviceCalibrateableTimeDomainsEXT", name)) {
+ *addr = (void *)GetPhysicalDeviceCalibrateableTimeDomainsEXT;
+ return true;
+ }
+ if (!strcmp("vkGetCalibratedTimestampsEXT", name)) {
+ *addr = (void *)GetCalibratedTimestampsEXT;
+ return true;
+ }
+
+ // ---- VK_NV_mesh_shader extension commands
+ if (!strcmp("vkCmdDrawMeshTasksNV", name)) {
+ *addr = (void *)CmdDrawMeshTasksNV;
+ return true;
+ }
+ if (!strcmp("vkCmdDrawMeshTasksIndirectNV", name)) {
+ *addr = (void *)CmdDrawMeshTasksIndirectNV;
+ return true;
+ }
+ if (!strcmp("vkCmdDrawMeshTasksIndirectCountNV", name)) {
+ *addr = (void *)CmdDrawMeshTasksIndirectCountNV;
+ return true;
+ }
+
+ // ---- VK_NV_scissor_exclusive extension commands
+ if (!strcmp("vkCmdSetExclusiveScissorNV", name)) {
+ *addr = (void *)CmdSetExclusiveScissorNV;
+ return true;
+ }
+
+ // ---- VK_NV_device_diagnostic_checkpoints extension commands
+ if (!strcmp("vkCmdSetCheckpointNV", name)) {
+ *addr = (void *)CmdSetCheckpointNV;
+ return true;
+ }
+ if (!strcmp("vkGetQueueCheckpointDataNV", name)) {
+ *addr = (void *)GetQueueCheckpointDataNV;
+ return true;
+ }
+
+ // ---- VK_INTEL_performance_query extension commands
+ if (!strcmp("vkInitializePerformanceApiINTEL", name)) {
+ *addr = (void *)InitializePerformanceApiINTEL;
+ return true;
+ }
+ if (!strcmp("vkUninitializePerformanceApiINTEL", name)) {
+ *addr = (void *)UninitializePerformanceApiINTEL;
+ return true;
+ }
+ if (!strcmp("vkCmdSetPerformanceMarkerINTEL", name)) {
+ *addr = (void *)CmdSetPerformanceMarkerINTEL;
+ return true;
+ }
+ if (!strcmp("vkCmdSetPerformanceStreamMarkerINTEL", name)) {
+ *addr = (void *)CmdSetPerformanceStreamMarkerINTEL;
+ return true;
+ }
+ if (!strcmp("vkCmdSetPerformanceOverrideINTEL", name)) {
+ *addr = (void *)CmdSetPerformanceOverrideINTEL;
+ return true;
+ }
+ if (!strcmp("vkAcquirePerformanceConfigurationINTEL", name)) {
+ *addr = (void *)AcquirePerformanceConfigurationINTEL;
+ return true;
+ }
+ if (!strcmp("vkReleasePerformanceConfigurationINTEL", name)) {
+ *addr = (void *)ReleasePerformanceConfigurationINTEL;
+ return true;
+ }
+ if (!strcmp("vkQueueSetPerformanceConfigurationINTEL", name)) {
+ *addr = (void *)QueueSetPerformanceConfigurationINTEL;
+ return true;
+ }
+ if (!strcmp("vkGetPerformanceParameterINTEL", name)) {
+ *addr = (void *)GetPerformanceParameterINTEL;
+ return true;
+ }
+
+ // ---- VK_AMD_display_native_hdr extension commands
+ if (!strcmp("vkSetLocalDimmingAMD", name)) {
+ *addr = (void *)SetLocalDimmingAMD;
+ return true;
+ }
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ if (!strcmp("vkCreateImagePipeSurfaceFUCHSIA", name)) {
+ *addr = (ptr_instance->enabled_known_extensions.fuchsia_imagepipe_surface == 1)
+ ? (void *)CreateImagePipeSurfaceFUCHSIA
+ : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ // ---- VK_EXT_buffer_device_address extension commands
+ if (!strcmp("vkGetBufferDeviceAddressEXT", name)) {
+ *addr = (void *)GetBufferDeviceAddressEXT;
+ return true;
+ }
+
+ // ---- VK_NV_cooperative_matrix extension commands
+ if (!strcmp("vkGetPhysicalDeviceCooperativeMatrixPropertiesNV", name)) {
+ *addr = (void *)GetPhysicalDeviceCooperativeMatrixPropertiesNV;
+ return true;
+ }
+
+ // ---- VK_NV_coverage_reduction_mode extension commands
+ if (!strcmp("vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV", name)) {
+ *addr = (void *)GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
+ return true;
+ }
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkGetPhysicalDeviceSurfacePresentModes2EXT", name)) {
+ *addr = (void *)GetPhysicalDeviceSurfacePresentModes2EXT;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkAcquireFullScreenExclusiveModeEXT", name)) {
+ *addr = (void *)AcquireFullScreenExclusiveModeEXT;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkReleaseFullScreenExclusiveModeEXT", name)) {
+ *addr = (void *)ReleaseFullScreenExclusiveModeEXT;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (!strcmp("vkGetDeviceGroupSurfacePresentModes2EXT", name)) {
+ *addr = (void *)GetDeviceGroupSurfacePresentModes2EXT;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_line_rasterization extension commands
+ if (!strcmp("vkCmdSetLineStippleEXT", name)) {
+ *addr = (void *)CmdSetLineStippleEXT;
+ return true;
+ }
+
+ // ---- VK_EXT_host_query_reset extension commands
+ if (!strcmp("vkResetQueryPoolEXT", name)) {
+ *addr = (void *)ResetQueryPoolEXT;
+ return true;
+ }
+ return false;
+}
+
+// A function that can be used to query enabled extensions during a vkCreateInstance call
+void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
+ for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.khr_get_physical_device_properties2 = 1;
+
+ // ---- VK_KHR_device_group_creation extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.khr_device_group_creation = 1;
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.khr_external_memory_capabilities = 1;
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.khr_external_semaphore_capabilities = 1;
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.khr_external_fence_capabilities = 1;
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.khr_get_surface_capabilities2 = 1;
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.ggp_stream_descriptor_surface = 1;
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.nv_external_memory_capabilities = 1;
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_NN_VI_SURFACE_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.nn_vi_surface = 1;
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.ext_direct_mode_display = 1;
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.ext_acquire_xlib_display = 1;
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.ext_display_surface_counter = 1;
+
+ // ---- VK_EXT_debug_utils extension commands
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.ext_debug_utils = 1;
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ } else if (0 == strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME)) {
+ ptr_instance->enabled_known_extensions.fuchsia_imagepipe_surface = 1;
+#endif // VK_USE_PLATFORM_FUCHSIA
+ }
+ }
+}
+
+// Some device commands still need a terminator because the loader needs to unwrap something about them.
+// In many cases, the item needing unwrapping is a VkPhysicalDevice or VkSurfaceKHR object. But there may be other items
+// in the future.
+PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName) {
+ PFN_vkVoidFunction addr = NULL;
+
+ // ---- VK_KHR_swapchain extension commands
+ if (dev->extensions.khr_swapchain_enabled) {
+ if(!strcmp(pName, "vkCreateSwapchainKHR")) {
+ addr = (PFN_vkVoidFunction)terminator_CreateSwapchainKHR;
+ } else if(!strcmp(pName, "vkGetDeviceGroupSurfacePresentModesKHR")) {
+ addr = (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModesKHR;
+ }
+ }
+
+ // ---- VK_KHR_display_swapchain extension commands
+ if (dev->extensions.khr_display_swapchain_enabled) {
+ if(!strcmp(pName, "vkCreateSharedSwapchainsKHR")) {
+ addr = (PFN_vkVoidFunction)terminator_CreateSharedSwapchainsKHR;
+ }
+ }
+
+ // ---- VK_EXT_debug_marker extension commands
+ if (dev->extensions.ext_debug_marker_enabled) {
+ if(!strcmp(pName, "vkDebugMarkerSetObjectTagEXT")) {
+ addr = (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectTagEXT;
+ } else if(!strcmp(pName, "vkDebugMarkerSetObjectNameEXT")) {
+ addr = (PFN_vkVoidFunction)terminator_DebugMarkerSetObjectNameEXT;
+ }
+ }
+
+ // ---- VK_EXT_debug_utils extension commands
+ if (dev->extensions.ext_debug_utils_enabled) {
+ if(!strcmp(pName, "vkSetDebugUtilsObjectNameEXT")) {
+ addr = (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectNameEXT;
+ } else if(!strcmp(pName, "vkSetDebugUtilsObjectTagEXT")) {
+ addr = (PFN_vkVoidFunction)terminator_SetDebugUtilsObjectTagEXT;
+ }
+ }
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+ if (dev->extensions.ext_full_screen_exclusive_enabled && dev->extensions.khr_device_group_enabled) {
+ if(!strcmp(pName, "vkGetDeviceGroupSurfacePresentModes2EXT")) {
+ addr = (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModes2EXT;
+ }
+ }
+#endif // None
+ return addr;
+}
+
+// This table contains the loader's instance dispatch table, which contains
+// default functions if no instance layers are activated. This contains
+// pointers to "terminator functions".
+const VkLayerInstanceDispatchTable instance_disp = {
+
+ // ---- Core 1_0 commands
+ .DestroyInstance = terminator_DestroyInstance,
+ .EnumeratePhysicalDevices = terminator_EnumeratePhysicalDevices,
+ .GetPhysicalDeviceFeatures = terminator_GetPhysicalDeviceFeatures,
+ .GetPhysicalDeviceFormatProperties = terminator_GetPhysicalDeviceFormatProperties,
+ .GetPhysicalDeviceImageFormatProperties = terminator_GetPhysicalDeviceImageFormatProperties,
+ .GetPhysicalDeviceProperties = terminator_GetPhysicalDeviceProperties,
+ .GetPhysicalDeviceQueueFamilyProperties = terminator_GetPhysicalDeviceQueueFamilyProperties,
+ .GetPhysicalDeviceMemoryProperties = terminator_GetPhysicalDeviceMemoryProperties,
+ .GetInstanceProcAddr = vkGetInstanceProcAddr,
+ .EnumerateDeviceExtensionProperties = terminator_EnumerateDeviceExtensionProperties,
+ .EnumerateDeviceLayerProperties = terminator_EnumerateDeviceLayerProperties,
+ .GetPhysicalDeviceSparseImageFormatProperties = terminator_GetPhysicalDeviceSparseImageFormatProperties,
+
+ // ---- Core 1_1 commands
+ .EnumeratePhysicalDeviceGroups = terminator_EnumeratePhysicalDeviceGroups,
+ .GetPhysicalDeviceFeatures2 = terminator_GetPhysicalDeviceFeatures2,
+ .GetPhysicalDeviceProperties2 = terminator_GetPhysicalDeviceProperties2,
+ .GetPhysicalDeviceFormatProperties2 = terminator_GetPhysicalDeviceFormatProperties2,
+ .GetPhysicalDeviceImageFormatProperties2 = terminator_GetPhysicalDeviceImageFormatProperties2,
+ .GetPhysicalDeviceQueueFamilyProperties2 = terminator_GetPhysicalDeviceQueueFamilyProperties2,
+ .GetPhysicalDeviceMemoryProperties2 = terminator_GetPhysicalDeviceMemoryProperties2,
+ .GetPhysicalDeviceSparseImageFormatProperties2 = terminator_GetPhysicalDeviceSparseImageFormatProperties2,
+ .GetPhysicalDeviceExternalBufferProperties = terminator_GetPhysicalDeviceExternalBufferProperties,
+ .GetPhysicalDeviceExternalFenceProperties = terminator_GetPhysicalDeviceExternalFenceProperties,
+ .GetPhysicalDeviceExternalSemaphoreProperties = terminator_GetPhysicalDeviceExternalSemaphoreProperties,
+
+ // ---- VK_KHR_surface extension commands
+ .DestroySurfaceKHR = terminator_DestroySurfaceKHR,
+ .GetPhysicalDeviceSurfaceSupportKHR = terminator_GetPhysicalDeviceSurfaceSupportKHR,
+ .GetPhysicalDeviceSurfaceCapabilitiesKHR = terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR,
+ .GetPhysicalDeviceSurfaceFormatsKHR = terminator_GetPhysicalDeviceSurfaceFormatsKHR,
+ .GetPhysicalDeviceSurfacePresentModesKHR = terminator_GetPhysicalDeviceSurfacePresentModesKHR,
+
+ // ---- VK_KHR_swapchain extension commands
+ .GetPhysicalDevicePresentRectanglesKHR = terminator_GetPhysicalDevicePresentRectanglesKHR,
+
+ // ---- VK_KHR_display extension commands
+ .GetPhysicalDeviceDisplayPropertiesKHR = terminator_GetPhysicalDeviceDisplayPropertiesKHR,
+ .GetPhysicalDeviceDisplayPlanePropertiesKHR = terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR,
+ .GetDisplayPlaneSupportedDisplaysKHR = terminator_GetDisplayPlaneSupportedDisplaysKHR,
+ .GetDisplayModePropertiesKHR = terminator_GetDisplayModePropertiesKHR,
+ .CreateDisplayModeKHR = terminator_CreateDisplayModeKHR,
+ .GetDisplayPlaneCapabilitiesKHR = terminator_GetDisplayPlaneCapabilitiesKHR,
+ .CreateDisplayPlaneSurfaceKHR = terminator_CreateDisplayPlaneSurfaceKHR,
+
+ // ---- VK_KHR_xlib_surface extension commands
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ .CreateXlibSurfaceKHR = terminator_CreateXlibSurfaceKHR,
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ .GetPhysicalDeviceXlibPresentationSupportKHR = terminator_GetPhysicalDeviceXlibPresentationSupportKHR,
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+ // ---- VK_KHR_xcb_surface extension commands
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ .CreateXcbSurfaceKHR = terminator_CreateXcbSurfaceKHR,
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ .GetPhysicalDeviceXcbPresentationSupportKHR = terminator_GetPhysicalDeviceXcbPresentationSupportKHR,
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+ // ---- VK_KHR_wayland_surface extension commands
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ .CreateWaylandSurfaceKHR = terminator_CreateWaylandSurfaceKHR,
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ .GetPhysicalDeviceWaylandPresentationSupportKHR = terminator_GetPhysicalDeviceWaylandPresentationSupportKHR,
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+ // ---- VK_KHR_android_surface extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ .CreateAndroidSurfaceKHR = terminator_CreateAndroidSurfaceKHR,
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_KHR_win32_surface extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ .CreateWin32SurfaceKHR = terminator_CreateWin32SurfaceKHR,
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ .GetPhysicalDeviceWin32PresentationSupportKHR = terminator_GetPhysicalDeviceWin32PresentationSupportKHR,
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ .GetPhysicalDeviceFeatures2KHR = terminator_GetPhysicalDeviceFeatures2,
+ .GetPhysicalDeviceProperties2KHR = terminator_GetPhysicalDeviceProperties2,
+ .GetPhysicalDeviceFormatProperties2KHR = terminator_GetPhysicalDeviceFormatProperties2,
+ .GetPhysicalDeviceImageFormatProperties2KHR = terminator_GetPhysicalDeviceImageFormatProperties2,
+ .GetPhysicalDeviceQueueFamilyProperties2KHR = terminator_GetPhysicalDeviceQueueFamilyProperties2,
+ .GetPhysicalDeviceMemoryProperties2KHR = terminator_GetPhysicalDeviceMemoryProperties2,
+ .GetPhysicalDeviceSparseImageFormatProperties2KHR = terminator_GetPhysicalDeviceSparseImageFormatProperties2,
+
+ // ---- VK_KHR_device_group_creation extension commands
+ .EnumeratePhysicalDeviceGroupsKHR = terminator_EnumeratePhysicalDeviceGroups,
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ .GetPhysicalDeviceExternalBufferPropertiesKHR = terminator_GetPhysicalDeviceExternalBufferProperties,
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ .GetPhysicalDeviceExternalSemaphorePropertiesKHR = terminator_GetPhysicalDeviceExternalSemaphoreProperties,
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ .GetPhysicalDeviceExternalFencePropertiesKHR = terminator_GetPhysicalDeviceExternalFenceProperties,
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ .GetPhysicalDeviceSurfaceCapabilities2KHR = terminator_GetPhysicalDeviceSurfaceCapabilities2KHR,
+ .GetPhysicalDeviceSurfaceFormats2KHR = terminator_GetPhysicalDeviceSurfaceFormats2KHR,
+
+ // ---- VK_KHR_get_display_properties2 extension commands
+ .GetPhysicalDeviceDisplayProperties2KHR = terminator_GetPhysicalDeviceDisplayProperties2KHR,
+ .GetPhysicalDeviceDisplayPlaneProperties2KHR = terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR,
+ .GetDisplayModeProperties2KHR = terminator_GetDisplayModeProperties2KHR,
+ .GetDisplayPlaneCapabilities2KHR = terminator_GetDisplayPlaneCapabilities2KHR,
+
+ // ---- VK_EXT_debug_report extension commands
+ .CreateDebugReportCallbackEXT = terminator_CreateDebugReportCallbackEXT,
+ .DestroyDebugReportCallbackEXT = terminator_DestroyDebugReportCallbackEXT,
+ .DebugReportMessageEXT = terminator_DebugReportMessageEXT,
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ .CreateStreamDescriptorSurfaceGGP = terminator_CreateStreamDescriptorSurfaceGGP,
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ .GetPhysicalDeviceExternalImageFormatPropertiesNV = terminator_GetPhysicalDeviceExternalImageFormatPropertiesNV,
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ .CreateViSurfaceNN = terminator_CreateViSurfaceNN,
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ .GetPhysicalDeviceGeneratedCommandsPropertiesNVX = terminator_GetPhysicalDeviceGeneratedCommandsPropertiesNVX,
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ .ReleaseDisplayEXT = terminator_ReleaseDisplayEXT,
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ .AcquireXlibDisplayEXT = terminator_AcquireXlibDisplayEXT,
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ .GetRandROutputDisplayEXT = terminator_GetRandROutputDisplayEXT,
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ .GetPhysicalDeviceSurfaceCapabilities2EXT = terminator_GetPhysicalDeviceSurfaceCapabilities2EXT,
+
+ // ---- VK_MVK_ios_surface extension commands
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ .CreateIOSSurfaceMVK = terminator_CreateIOSSurfaceMVK,
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+ // ---- VK_MVK_macos_surface extension commands
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ .CreateMacOSSurfaceMVK = terminator_CreateMacOSSurfaceMVK,
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+ // ---- VK_EXT_debug_utils extension commands
+ .CreateDebugUtilsMessengerEXT = terminator_CreateDebugUtilsMessengerEXT,
+ .DestroyDebugUtilsMessengerEXT = terminator_DestroyDebugUtilsMessengerEXT,
+ .SubmitDebugUtilsMessageEXT = terminator_SubmitDebugUtilsMessageEXT,
+
+ // ---- VK_EXT_sample_locations extension commands
+ .GetPhysicalDeviceMultisamplePropertiesEXT = terminator_GetPhysicalDeviceMultisamplePropertiesEXT,
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ .GetPhysicalDeviceCalibrateableTimeDomainsEXT = terminator_GetPhysicalDeviceCalibrateableTimeDomainsEXT,
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ .CreateImagePipeSurfaceFUCHSIA = terminator_CreateImagePipeSurfaceFUCHSIA,
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ // ---- VK_EXT_metal_surface extension commands
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ .CreateMetalSurfaceEXT = terminator_CreateMetalSurfaceEXT,
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ // ---- VK_NV_cooperative_matrix extension commands
+ .GetPhysicalDeviceCooperativeMatrixPropertiesNV = terminator_GetPhysicalDeviceCooperativeMatrixPropertiesNV,
+
+ // ---- VK_NV_coverage_reduction_mode extension commands
+ .GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = terminator_GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV,
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ .GetPhysicalDeviceSurfacePresentModes2EXT = terminator_GetPhysicalDeviceSurfacePresentModes2EXT,
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_headless_surface extension commands
+ .CreateHeadlessSurfaceEXT = terminator_CreateHeadlessSurfaceEXT,
+};
+
+// A null-terminated list of all of the instance extensions supported by the loader.
+// If an instance extension name is not in this list, but it is exported by one or more of the
+// ICDs detected by the loader, then the extension name not in the list will be filtered out
+// before passing the list of extensions to the application.
+const char *const LOADER_INSTANCE_EXTENSIONS[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME,
+ VK_KHR_DISPLAY_EXTENSION_NAME,
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_WIN32_KHR
+ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
+ VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME,
+ VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
+ VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME,
+ VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME,
+ VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
+#ifdef VK_USE_PLATFORM_GGP
+ VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_GGP
+ VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
+ VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME,
+#ifdef VK_USE_PLATFORM_VI_NN
+ VK_NN_VI_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_VI_NN
+ VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME,
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME,
+ VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ VK_MVK_IOS_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_IOS_MVK
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ VK_MVK_MACOS_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_MACOS_MVK
+ VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_FUCHSIA
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ VK_EXT_METAL_SURFACE_EXTENSION_NAME,
+#endif // VK_USE_PLATFORM_METAL_EXT
+ VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME,
+ VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME,
+ NULL };
+
diff --git a/thirdparty/vulkan/loader/vk_loader_extensions.h b/thirdparty/vulkan/loader/vk_loader_extensions.h
new file mode 100644
index 0000000000..b08af33838
--- /dev/null
+++ b/thirdparty/vulkan/loader/vk_loader_extensions.h
@@ -0,0 +1,444 @@
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See loader_extension_generator.py for modifications
+
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Mark Young <marky@lunarg.com>
+ */
+
+#pragma once
+
+// Structures defined externally, but used here
+struct loader_instance;
+struct loader_device;
+struct loader_icd_term;
+struct loader_dev_dispatch_table;
+
+// Device extension error function
+VKAPI_ATTR VkResult VKAPI_CALL vkDevExtError(VkDevice dev);
+
+// Extension interception for vkGetInstanceProcAddr function, so we can return
+// the appropriate information for any instance extensions we know about.
+bool extension_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);
+
+// Extension interception for vkCreateInstance function, so we can properly
+// detect and enable any instance extension information for extensions we know
+// about.
+void extensions_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);
+
+// Extension interception for vkGetDeviceProcAddr function, so we can return
+// an appropriate terminator if this is one of those few device commands requiring
+// a terminator.
+PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *dev, const char *pName);
+
+// Dispatch table properly filled in with appropriate terminators for the
+// supported extensions.
+extern const VkLayerInstanceDispatchTable instance_disp;
+
+// Array of extension strings for instance extensions we support.
+extern const char *const LOADER_INSTANCE_EXTENSIONS[];
+
+VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_term, VkInstance inst,
+ const PFN_vkGetInstanceProcAddr fp_gipa);
+
+// Init Device function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_device_dispatch_table(struct loader_dev_dispatch_table *dev_table, PFN_vkGetDeviceProcAddr gpa,
+ VkDevice dev);
+
+// Init Device function pointer dispatch table with extension commands
+VKAPI_ATTR void VKAPI_CALL loader_init_device_extension_dispatch_table(struct loader_dev_dispatch_table *dev_table,
+ PFN_vkGetInstanceProcAddr gipa,
+ PFN_vkGetDeviceProcAddr gdpa,
+ VkInstance inst,
+ VkDevice dev);
+
+// Init Instance function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_instance_core_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
+ VkInstance inst);
+
+// Init Instance function pointer dispatch table with core commands
+VKAPI_ATTR void VKAPI_CALL loader_init_instance_extension_dispatch_table(VkLayerInstanceDispatchTable *table, PFN_vkGetInstanceProcAddr gpa,
+ VkInstance inst);
+
+// Device command lookup function
+VKAPI_ATTR void* VKAPI_CALL loader_lookup_device_dispatch_table(const VkLayerDispatchTable *table, const char *name);
+
+// Instance command lookup function
+VKAPI_ATTR void* VKAPI_CALL loader_lookup_instance_dispatch_table(const VkLayerInstanceDispatchTable *table, const char *name,
+ bool *found_name);
+
+VKAPI_ATTR bool VKAPI_CALL loader_icd_init_entries(struct loader_icd_term *icd_term, VkInstance inst,
+ const PFN_vkGetInstanceProcAddr fp_gipa);
+
+// Loader core instance terminators
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(
+ const VkInstanceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkInstance* pInstance);
+VKAPI_ATTR void VKAPI_CALL terminator_DestroyInstance(
+ VkInstance instance,
+ const VkAllocationCallbacks* pAllocator);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(
+ VkInstance instance,
+ uint32_t* pPhysicalDeviceCount,
+ VkPhysicalDevice* pPhysicalDevices);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures* pFeatures);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties* pFormatProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkImageFormatProperties* pImageFormatProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties* pProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties* pQueueFamilyProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties* pMemoryProperties);
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL terminator_GetInstanceProcAddr(
+ VkInstance instance,
+ const char* pName);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDevice* pDevice);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceExtensionProperties(
+ const VkEnumerateInstanceExtensionPropertiesChain* chain,
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(
+ VkPhysicalDevice physicalDevice,
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceLayerProperties(
+ const VkEnumerateInstanceLayerPropertiesChain* chain,
+ uint32_t* pPropertyCount,
+ VkLayerProperties* pProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceLayerProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkLayerProperties* pProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkSampleCountFlagBits samples,
+ VkImageUsageFlags usage,
+ VkImageTiling tiling,
+ uint32_t* pPropertyCount,
+ VkSparseImageFormatProperties* pProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceVersion(
+ const VkEnumerateInstanceVersionChain* chain,
+ uint32_t* pApiVersion);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
+ VkInstance instance,
+ uint32_t* pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFeatures2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures2* pFeatures);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties2* pProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceFormatProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties2* pFormatProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceImageFormatProperties2(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
+ VkImageFormatProperties2* pImageFormatProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties2(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2* pQueueFamilyProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceSparseImageFormatProperties2(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
+ uint32_t* pPropertyCount,
+ VkSparseImageFormatProperties2* pProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalBufferProperties(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
+ VkExternalBufferProperties* pExternalBufferProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalFenceProperties(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
+ VkExternalFenceProperties* pExternalFenceProperties);
+VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceExternalSemaphoreProperties(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
+ VkExternalSemaphoreProperties* pExternalSemaphoreProperties);
+
+// ICD function pointer dispatch table
+struct loader_icd_term_dispatch {
+
+ // ---- Core 1_0 commands
+ PFN_vkCreateInstance CreateInstance;
+ PFN_vkDestroyInstance DestroyInstance;
+ PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
+ PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
+ PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties;
+ PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties;
+ PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties;
+ PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties;
+ PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
+ PFN_vkCreateDevice CreateDevice;
+ PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
+ PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
+ PFN_vkEnumerateInstanceLayerProperties EnumerateInstanceLayerProperties;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties;
+
+ // ---- Core 1_1 commands
+ PFN_vkEnumerateInstanceVersion EnumerateInstanceVersion;
+ PFN_vkEnumeratePhysicalDeviceGroups EnumeratePhysicalDeviceGroups;
+ PFN_vkGetPhysicalDeviceFeatures2 GetPhysicalDeviceFeatures2;
+ PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2;
+ PFN_vkGetPhysicalDeviceFormatProperties2 GetPhysicalDeviceFormatProperties2;
+ PFN_vkGetPhysicalDeviceImageFormatProperties2 GetPhysicalDeviceImageFormatProperties2;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2 GetPhysicalDeviceQueueFamilyProperties2;
+ PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 GetPhysicalDeviceSparseImageFormatProperties2;
+ PFN_vkGetPhysicalDeviceExternalBufferProperties GetPhysicalDeviceExternalBufferProperties;
+ PFN_vkGetPhysicalDeviceExternalFenceProperties GetPhysicalDeviceExternalFenceProperties;
+ PFN_vkGetPhysicalDeviceExternalSemaphoreProperties GetPhysicalDeviceExternalSemaphoreProperties;
+
+ // ---- VK_KHR_surface extension commands
+ PFN_vkDestroySurfaceKHR DestroySurfaceKHR;
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR;
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR;
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR;
+
+ // ---- VK_KHR_swapchain extension commands
+ PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR GetDeviceGroupSurfacePresentModesKHR;
+ PFN_vkGetPhysicalDevicePresentRectanglesKHR GetPhysicalDevicePresentRectanglesKHR;
+
+ // ---- VK_KHR_display extension commands
+ PFN_vkGetPhysicalDeviceDisplayPropertiesKHR GetPhysicalDeviceDisplayPropertiesKHR;
+ PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR GetPhysicalDeviceDisplayPlanePropertiesKHR;
+ PFN_vkGetDisplayPlaneSupportedDisplaysKHR GetDisplayPlaneSupportedDisplaysKHR;
+ PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR;
+ PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR;
+ PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR;
+ PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR;
+
+ // ---- VK_KHR_display_swapchain extension commands
+ PFN_vkCreateSharedSwapchainsKHR CreateSharedSwapchainsKHR;
+
+ // ---- VK_KHR_xlib_surface extension commands
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR GetPhysicalDeviceXlibPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+ // ---- VK_KHR_xcb_surface extension commands
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR GetPhysicalDeviceXcbPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+ // ---- VK_KHR_wayland_surface extension commands
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR GetPhysicalDeviceWaylandPresentationSupportKHR;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+ // ---- VK_KHR_android_surface extension commands
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ PFN_vkCreateAndroidSurfaceKHR CreateAndroidSurfaceKHR;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+ // ---- VK_KHR_win32_surface extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR GetPhysicalDeviceWin32PresentationSupportKHR;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_KHR_get_physical_device_properties2 extension commands
+ PFN_vkGetPhysicalDeviceFeatures2KHR GetPhysicalDeviceFeatures2KHR;
+ PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR;
+ PFN_vkGetPhysicalDeviceFormatProperties2KHR GetPhysicalDeviceFormatProperties2KHR;
+ PFN_vkGetPhysicalDeviceImageFormatProperties2KHR GetPhysicalDeviceImageFormatProperties2KHR;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR GetPhysicalDeviceQueueFamilyProperties2KHR;
+ PFN_vkGetPhysicalDeviceMemoryProperties2KHR GetPhysicalDeviceMemoryProperties2KHR;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR GetPhysicalDeviceSparseImageFormatProperties2KHR;
+
+ // ---- VK_KHR_device_group_creation extension commands
+ PFN_vkEnumeratePhysicalDeviceGroupsKHR EnumeratePhysicalDeviceGroupsKHR;
+
+ // ---- VK_KHR_external_memory_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR GetPhysicalDeviceExternalBufferPropertiesKHR;
+
+ // ---- VK_KHR_external_semaphore_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR GetPhysicalDeviceExternalSemaphorePropertiesKHR;
+
+ // ---- VK_KHR_external_fence_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR GetPhysicalDeviceExternalFencePropertiesKHR;
+
+ // ---- VK_KHR_get_surface_capabilities2 extension commands
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR GetPhysicalDeviceSurfaceCapabilities2KHR;
+ PFN_vkGetPhysicalDeviceSurfaceFormats2KHR GetPhysicalDeviceSurfaceFormats2KHR;
+
+ // ---- VK_KHR_get_display_properties2 extension commands
+ PFN_vkGetPhysicalDeviceDisplayProperties2KHR GetPhysicalDeviceDisplayProperties2KHR;
+ PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR GetPhysicalDeviceDisplayPlaneProperties2KHR;
+ PFN_vkGetDisplayModeProperties2KHR GetDisplayModeProperties2KHR;
+ PFN_vkGetDisplayPlaneCapabilities2KHR GetDisplayPlaneCapabilities2KHR;
+
+ // ---- VK_EXT_debug_report extension commands
+ PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
+ PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
+ PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
+
+ // ---- VK_EXT_debug_marker extension commands
+ PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT;
+ PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT;
+
+ // ---- VK_GGP_stream_descriptor_surface extension commands
+#ifdef VK_USE_PLATFORM_GGP
+ PFN_vkCreateStreamDescriptorSurfaceGGP CreateStreamDescriptorSurfaceGGP;
+#endif // VK_USE_PLATFORM_GGP
+
+ // ---- VK_NV_external_memory_capabilities extension commands
+ PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV;
+
+ // ---- VK_NN_vi_surface extension commands
+#ifdef VK_USE_PLATFORM_VI_NN
+ PFN_vkCreateViSurfaceNN CreateViSurfaceNN;
+#endif // VK_USE_PLATFORM_VI_NN
+
+ // ---- VK_NVX_device_generated_commands extension commands
+ PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX GetPhysicalDeviceGeneratedCommandsPropertiesNVX;
+
+ // ---- VK_EXT_direct_mode_display extension commands
+ PFN_vkReleaseDisplayEXT ReleaseDisplayEXT;
+
+ // ---- VK_EXT_acquire_xlib_display extension commands
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ PFN_vkAcquireXlibDisplayEXT AcquireXlibDisplayEXT;
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+ PFN_vkGetRandROutputDisplayEXT GetRandROutputDisplayEXT;
+#endif // VK_USE_PLATFORM_XLIB_XRANDR_EXT
+
+ // ---- VK_EXT_display_surface_counter extension commands
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT GetPhysicalDeviceSurfaceCapabilities2EXT;
+
+ // ---- VK_MVK_ios_surface extension commands
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ PFN_vkCreateIOSSurfaceMVK CreateIOSSurfaceMVK;
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+ // ---- VK_MVK_macos_surface extension commands
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ PFN_vkCreateMacOSSurfaceMVK CreateMacOSSurfaceMVK;
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+ // ---- VK_EXT_debug_utils extension commands
+ PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
+ PFN_vkSetDebugUtilsObjectTagEXT SetDebugUtilsObjectTagEXT;
+ PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
+ PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
+ PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
+
+ // ---- VK_EXT_sample_locations extension commands
+ PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT GetPhysicalDeviceMultisamplePropertiesEXT;
+
+ // ---- VK_EXT_calibrated_timestamps extension commands
+ PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT GetPhysicalDeviceCalibrateableTimeDomainsEXT;
+
+ // ---- VK_FUCHSIA_imagepipe_surface extension commands
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ PFN_vkCreateImagePipeSurfaceFUCHSIA CreateImagePipeSurfaceFUCHSIA;
+#endif // VK_USE_PLATFORM_FUCHSIA
+
+ // ---- VK_EXT_metal_surface extension commands
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ PFN_vkCreateMetalSurfaceEXT CreateMetalSurfaceEXT;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ // ---- VK_NV_cooperative_matrix extension commands
+ PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV GetPhysicalDeviceCooperativeMatrixPropertiesNV;
+
+ // ---- VK_NV_coverage_reduction_mode extension commands
+ PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
+
+ // ---- VK_EXT_full_screen_exclusive extension commands
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT GetPhysicalDeviceSurfacePresentModes2EXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ PFN_vkGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModes2EXT;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+ // ---- VK_EXT_headless_surface extension commands
+ PFN_vkCreateHeadlessSurfaceEXT CreateHeadlessSurfaceEXT;
+};
+
+union loader_instance_extension_enables {
+ struct {
+ uint8_t khr_get_physical_device_properties2 : 1;
+ uint8_t khr_device_group_creation : 1;
+ uint8_t khr_external_memory_capabilities : 1;
+ uint8_t khr_external_semaphore_capabilities : 1;
+ uint8_t khr_external_fence_capabilities : 1;
+ uint8_t khr_get_surface_capabilities2 : 1;
+ uint8_t ext_debug_report : 1;
+ uint8_t ggp_stream_descriptor_surface : 1;
+ uint8_t nv_external_memory_capabilities : 1;
+ uint8_t nn_vi_surface : 1;
+ uint8_t ext_direct_mode_display : 1;
+ uint8_t ext_acquire_xlib_display : 1;
+ uint8_t ext_display_surface_counter : 1;
+ uint8_t ext_debug_utils : 1;
+ uint8_t fuchsia_imagepipe_surface : 1;
+ };
+ uint64_t padding[4];
+};
+
+
diff --git a/thirdparty/vulkan/loader/vk_loader_layer.h b/thirdparty/vulkan/loader/vk_loader_layer.h
new file mode 100644
index 0000000000..dfcf5b2a46
--- /dev/null
+++ b/thirdparty/vulkan/loader/vk_loader_layer.h
@@ -0,0 +1,46 @@
+/*
+*
+* Copyright (c) 2016 The Khronos Group Inc.
+* Copyright (c) 2016 Valve Corporation
+* Copyright (c) 2016 LunarG, Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* Author: Mark Lobodzinski <mark@lunarg.com>
+*
+*/
+#pragma once
+
+// Linked list node for tree of debug callbacks
+typedef struct VkDebugReportContent {
+ VkDebugReportCallbackEXT msgCallback;
+ PFN_vkDebugReportCallbackEXT pfnMsgCallback;
+ VkFlags msgFlags;
+} VkDebugReportContent;
+
+typedef struct VkDebugUtilsMessengerContent {
+ VkDebugUtilsMessengerEXT messenger;
+ VkDebugUtilsMessageSeverityFlagsEXT messageSeverity;
+ VkDebugUtilsMessageTypeFlagsEXT messageType;
+ PFN_vkDebugUtilsMessengerCallbackEXT pfnUserCallback;
+} VkDebugUtilsMessengerContent;
+
+typedef struct VkLayerDbgFunctionNode_ {
+ bool is_messenger;
+ union {
+ VkDebugReportContent report;
+ VkDebugUtilsMessengerContent messenger;
+ };
+ void *pUserData;
+ struct VkLayerDbgFunctionNode_ *pNext;
+} VkLayerDbgFunctionNode;
diff --git a/thirdparty/vulkan/loader/vk_loader_platform.h b/thirdparty/vulkan/loader/vk_loader_platform.h
new file mode 100644
index 0000000000..2ffda55367
--- /dev/null
+++ b/thirdparty/vulkan/loader/vk_loader_platform.h
@@ -0,0 +1,411 @@
+/*
+ *
+ * Copyright (c) 2015-2018 The Khronos Group Inc.
+ * Copyright (c) 2015-2018 Valve Corporation
+ * Copyright (c) 2015-2018 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Ian Elliot <ian@lunarg.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ *
+ */
+#pragma once
+
+#if defined(_WIN32)
+// WinSock2.h must be included *BEFORE* windows.h
+#include <winsock2.h>
+#endif // _WIN32
+
+#include "vulkan/vk_platform.h"
+#include "vulkan/vk_sdk_platform.h"
+
+#if defined(__linux__) || defined(__APPLE__)
+/* Linux-specific common code: */
+
+// Headers:
+//#ifndef _GNU_SOURCE
+//#define _GNU_SOURCE 1
+//#endif
+// TBD: Are the contents of the following file used?
+#include <unistd.h>
+// Note: The following file is for dynamic loading:
+#include <dlfcn.h>
+#include <pthread.h>
+#include <assert.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <libgen.h>
+
+// VK Library Filenames, Paths, etc.:
+#define PATH_SEPARATOR ':'
+#define DIRECTORY_SYMBOL '/'
+
+#define VULKAN_DIR "vulkan/"
+#define VULKAN_ICDCONF_DIR "icd.d"
+#define VULKAN_ICD_DIR "icd"
+#define VULKAN_SETTINGSCONF_DIR "settings.d"
+#define VULKAN_ELAYERCONF_DIR "explicit_layer.d"
+#define VULKAN_ILAYERCONF_DIR "implicit_layer.d"
+#define VULKAN_LAYER_DIR "layer"
+
+#define VK_DRIVERS_INFO_RELATIVE_DIR VULKAN_DIR VULKAN_ICDCONF_DIR
+#define VK_SETTINGS_INFO_RELATIVE_DIR VULKAN_DIR VULKAN_SETTINGSCONF_DIR
+#define VK_ELAYERS_INFO_RELATIVE_DIR VULKAN_DIR VULKAN_ELAYERCONF_DIR
+#define VK_ILAYERS_INFO_RELATIVE_DIR VULKAN_DIR VULKAN_ILAYERCONF_DIR
+
+#define VK_DRIVERS_INFO_REGISTRY_LOC ""
+#define VK_SETTINGS_INFO_REGISTRY_LOC ""
+#define VK_ELAYERS_INFO_REGISTRY_LOC ""
+#define VK_ILAYERS_INFO_REGISTRY_LOC ""
+
+#if !defined(DEFAULT_VK_LAYERS_PATH)
+#define DEFAULT_VK_LAYERS_PATH ""
+#endif
+#if !defined(LAYERS_SOURCE_PATH)
+#define LAYERS_SOURCE_PATH NULL
+#endif
+#define LAYERS_PATH_ENV "VK_LAYER_PATH"
+#define ENABLED_LAYERS_ENV "VK_INSTANCE_LAYERS"
+
+// C99:
+#define PRINTF_SIZE_T_SPECIFIER "%zu"
+
+// File IO
+static inline bool loader_platform_file_exists(const char *path) {
+ if (access(path, F_OK))
+ return false;
+ else
+ return true;
+}
+
+static inline bool loader_platform_is_path_absolute(const char *path) {
+ if (path[0] == '/')
+ return true;
+ else
+ return false;
+}
+
+static inline char *loader_platform_dirname(char *path) { return dirname(path); }
+
+// Dynamic Loading of libraries:
+typedef void *loader_platform_dl_handle;
+static inline loader_platform_dl_handle loader_platform_open_library(const char *libPath) {
+ // When loading the library, we use RTLD_LAZY so that not all symbols have to be
+ // resolved at this time (which improves performance). Note that if not all symbols
+ // can be resolved, this could cause crashes later. Use the LD_BIND_NOW environment
+ // variable to force all symbols to be resolved here.
+ return dlopen(libPath, RTLD_LAZY | RTLD_LOCAL);
+}
+static inline const char *loader_platform_open_library_error(const char *libPath) { return dlerror(); }
+static inline void loader_platform_close_library(loader_platform_dl_handle library) { dlclose(library); }
+static inline void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
+ assert(library);
+ assert(name);
+ return dlsym(library, name);
+}
+static inline const char *loader_platform_get_proc_address_error(const char *name) { return dlerror(); }
+
+// Threads:
+typedef pthread_t loader_platform_thread;
+#define THREAD_LOCAL_DECL __thread
+
+// The once init functionality is not used on Linux
+#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var)
+#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var)
+#define LOADER_PLATFORM_THREAD_ONCE(ctl, func)
+
+// Thread IDs:
+typedef pthread_t loader_platform_thread_id;
+static inline loader_platform_thread_id loader_platform_get_thread_id() { return pthread_self(); }
+
+// Thread mutex:
+typedef pthread_mutex_t loader_platform_thread_mutex;
+static inline void loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_init(pMutex, NULL); }
+static inline void loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_lock(pMutex); }
+static inline void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_unlock(pMutex); }
+static inline void loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) { pthread_mutex_destroy(pMutex); }
+typedef pthread_cond_t loader_platform_thread_cond;
+static inline void loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) { pthread_cond_init(pCond, NULL); }
+static inline void loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond, loader_platform_thread_mutex *pMutex) {
+ pthread_cond_wait(pCond, pMutex);
+}
+static inline void loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) { pthread_cond_broadcast(pCond); }
+
+#define loader_stack_alloc(size) alloca(size)
+
+#elif defined(_WIN32) // defined(__linux__)
+/* Windows-specific common code: */
+// WinBase.h defines CreateSemaphore and synchapi.h defines CreateEvent
+// undefine them to avoid conflicts with VkLayerDispatchTable struct members.
+#ifdef CreateSemaphore
+#undef CreateSemaphore
+#endif
+#ifdef CreateEvent
+#undef CreateEvent
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <io.h>
+#include <stdbool.h>
+#include <shlwapi.h>
+#ifdef __cplusplus
+#include <iostream>
+#include <string>
+#endif // __cplusplus
+
+// VK Library Filenames, Paths, etc.:
+#define PATH_SEPARATOR ';'
+#define DIRECTORY_SYMBOL '\\'
+#define DEFAULT_VK_REGISTRY_HIVE HKEY_LOCAL_MACHINE
+#define DEFAULT_VK_REGISTRY_HIVE_STR "HKEY_LOCAL_MACHINE"
+#define SECONDARY_VK_REGISTRY_HIVE HKEY_CURRENT_USER
+#define SECONDARY_VK_REGISTRY_HIVE_STR "HKEY_CURRENT_USER"
+
+#define VK_DRIVERS_INFO_RELATIVE_DIR ""
+#define VK_SETTINGS_INFO_RELATIVE_DIR ""
+#define VK_ELAYERS_INFO_RELATIVE_DIR ""
+#define VK_ILAYERS_INFO_RELATIVE_DIR ""
+
+#ifdef _WIN64
+#define HKR_VK_DRIVER_NAME API_NAME "DriverName"
+#else
+#define HKR_VK_DRIVER_NAME API_NAME "DriverNameWow"
+#endif
+#define VK_DRIVERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\Drivers"
+#define VK_SETTINGS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\Settings"
+#define VK_ELAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\ExplicitLayers"
+#define VK_ILAYERS_INFO_REGISTRY_LOC "SOFTWARE\\Khronos\\" API_NAME "\\ImplicitLayers"
+
+#if !defined(DEFAULT_VK_LAYERS_PATH)
+#define DEFAULT_VK_LAYERS_PATH ""
+#endif
+#if !defined(LAYERS_SOURCE_PATH)
+#define LAYERS_SOURCE_PATH NULL
+#endif
+#define LAYERS_PATH_ENV "VK_LAYER_PATH"
+#define ENABLED_LAYERS_ENV "VK_INSTANCE_LAYERS"
+
+#define PRINTF_SIZE_T_SPECIFIER "%Iu"
+
+#if defined(_WIN32)
+// Get the key for the plug n play driver registry
+// The string returned by this function should NOT be freed
+static inline const char *LoaderPnpDriverRegistry() {
+ BOOL is_wow;
+ IsWow64Process(GetCurrentProcess(), &is_wow);
+ return is_wow ? "VulkanDriverNameWow" : "VulkanDriverName";
+}
+static inline const wchar_t *LoaderPnpDriverRegistryWide() {
+ BOOL is_wow;
+ IsWow64Process(GetCurrentProcess(), &is_wow);
+ return is_wow ? L"VulkanDriverNameWow" : L"VulkanDriverName";
+}
+
+// Get the key for the plug 'n play explicit layer registry
+// The string returned by this function should NOT be freed
+static inline const char *LoaderPnpELayerRegistry() {
+ BOOL is_wow;
+ IsWow64Process(GetCurrentProcess(), &is_wow);
+ return is_wow ? "VulkanExplicitLayersWow" : "VulkanExplicitLayers";
+}
+static inline const wchar_t *LoaderPnpELayerRegistryWide() {
+ BOOL is_wow;
+ IsWow64Process(GetCurrentProcess(), &is_wow);
+ return is_wow ? L"VulkanExplicitLayersWow" : L"VulkanExplicitLayers";
+}
+
+// Get the key for the plug 'n play implicit layer registry
+// The string returned by this function should NOT be freed
+static inline const char *LoaderPnpILayerRegistry() {
+ BOOL is_wow;
+ IsWow64Process(GetCurrentProcess(), &is_wow);
+ return is_wow ? "VulkanImplicitLayersWow" : "VulkanImplicitLayers";
+}
+static inline const wchar_t *LoaderPnpILayerRegistryWide() {
+ BOOL is_wow;
+ IsWow64Process(GetCurrentProcess(), &is_wow);
+ return is_wow ? L"VulkanImplicitLayersWow" : L"VulkanImplicitLayers";
+}
+#endif
+
+// File IO
+static bool loader_platform_file_exists(const char *path) {
+ if ((_access(path, 0)) == -1)
+ return false;
+ else
+ return true;
+}
+
+static bool loader_platform_is_path_absolute(const char *path) {
+ if (!path || !*path) {
+ return false;
+ }
+ if (*path == DIRECTORY_SYMBOL || path[1] == ':') {
+ return true;
+ }
+ return false;
+}
+
+// WIN32 runtime doesn't have dirname().
+static inline char *loader_platform_dirname(char *path) {
+ char *current, *next;
+
+ // TODO/TBD: Do we need to deal with the Windows's ":" character?
+
+ for (current = path; *current != '\0'; current = next) {
+ next = strchr(current, DIRECTORY_SYMBOL);
+ if (next == NULL) {
+ if (current != path) *(current - 1) = '\0';
+ return path;
+ } else {
+ // Point one character past the DIRECTORY_SYMBOL:
+ next++;
+ }
+ }
+ return path;
+}
+
+// WIN32 runtime doesn't have basename().
+// Microsoft also doesn't have basename(). Paths are different on Windows, and
+// so this is just a temporary solution in order to get us compiling, so that we
+// can test some scenarios, and develop the correct solution for Windows.
+// TODO: Develop a better, permanent solution for Windows, to replace this
+// temporary code:
+static char *loader_platform_basename(char *pathname) {
+ char *current, *next;
+
+ // TODO/TBD: Do we need to deal with the Windows's ":" character?
+
+ for (current = pathname; *current != '\0'; current = next) {
+ next = strchr(current, DIRECTORY_SYMBOL);
+ if (next == NULL) {
+ // No more DIRECTORY_SYMBOL's so return p:
+ return current;
+ } else {
+ // Point one character past the DIRECTORY_SYMBOL:
+ next++;
+ }
+ }
+ // We shouldn't get to here, but this makes the compiler happy:
+ return current;
+}
+
+// Dynamic Loading:
+typedef HMODULE loader_platform_dl_handle;
+static loader_platform_dl_handle loader_platform_open_library(const char *lib_path) {
+ // Try loading the library the original way first.
+ loader_platform_dl_handle lib_handle = LoadLibrary(lib_path);
+ if (lib_handle == NULL && GetLastError() == ERROR_MOD_NOT_FOUND) {
+ // If that failed, then try loading it with broader search folders.
+ lib_handle = LoadLibraryEx(lib_path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
+ }
+ return lib_handle;
+}
+static char *loader_platform_open_library_error(const char *libPath) {
+ static char errorMsg[164];
+ (void)snprintf(errorMsg, 163, "Failed to open dynamic library \"%s\" with error %lu", libPath, GetLastError());
+ return errorMsg;
+}
+static void loader_platform_close_library(loader_platform_dl_handle library) { FreeLibrary(library); }
+static void *loader_platform_get_proc_address(loader_platform_dl_handle library, const char *name) {
+ assert(library);
+ assert(name);
+ return (void *)GetProcAddress(library, name);
+}
+static char *loader_platform_get_proc_address_error(const char *name) {
+ static char errorMsg[120];
+ (void)snprintf(errorMsg, 119, "Failed to find function \"%s\" in dynamic library", name);
+ return errorMsg;
+}
+
+// Threads:
+typedef HANDLE loader_platform_thread;
+
+// __declspec(thread) is not supported by MinGW compiler (ignored with warning or
+// cause erorr depending on compiler switches)
+//
+// __thread should be used instead
+//
+// __MINGW32__ defined for both 32 and 64 bit MinGW compilers, so it is enough to
+// detect any (32 or 64) flawor of MinGW compiler.
+//
+// @note __GNUC__ could be used as a more generic way to detect _any_
+// GCC[-compitible] compiler on Windows, but this fix was tested
+// only with MinGW, so keep it explicit at the moment.
+#if defined(__MINGW32__)
+#define THREAD_LOCAL_DECL __thread
+#else
+#define THREAD_LOCAL_DECL __declspec(thread)
+#endif
+
+// The once init functionality is not used when building a DLL on Windows. This is because there is no way to clean up the
+// resources allocated by anything allocated by once init. This isn't a problem for static libraries, but it is for dynamic
+// ones. When building a DLL, we use DllMain() instead to allow properly cleaning up resources.
+#if defined(LOADER_DYNAMIC_LIB)
+#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var)
+#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var)
+#define LOADER_PLATFORM_THREAD_ONCE(ctl, func)
+#else
+#define LOADER_PLATFORM_THREAD_ONCE_DECLARATION(var) INIT_ONCE var = INIT_ONCE_STATIC_INIT;
+#define LOADER_PLATFORM_THREAD_ONCE_DEFINITION(var) INIT_ONCE var;
+#define LOADER_PLATFORM_THREAD_ONCE(ctl, func) loader_platform_thread_once_fn(ctl, func)
+static BOOL CALLBACK InitFuncWrapper(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
+ void (*func)(void) = (void (*)(void))Parameter;
+ func();
+ return TRUE;
+}
+static void loader_platform_thread_once_fn(void *ctl, void (*func)(void)) {
+ assert(func != NULL);
+ assert(ctl != NULL);
+ InitOnceExecuteOnce((PINIT_ONCE)ctl, InitFuncWrapper, (void *)func, NULL);
+}
+#endif
+
+// Thread IDs:
+typedef DWORD loader_platform_thread_id;
+static loader_platform_thread_id loader_platform_get_thread_id() { return GetCurrentThreadId(); }
+
+// Thread mutex:
+typedef CRITICAL_SECTION loader_platform_thread_mutex;
+static void loader_platform_thread_create_mutex(loader_platform_thread_mutex *pMutex) { InitializeCriticalSection(pMutex); }
+static void loader_platform_thread_lock_mutex(loader_platform_thread_mutex *pMutex) { EnterCriticalSection(pMutex); }
+static void loader_platform_thread_unlock_mutex(loader_platform_thread_mutex *pMutex) { LeaveCriticalSection(pMutex); }
+static void loader_platform_thread_delete_mutex(loader_platform_thread_mutex *pMutex) { DeleteCriticalSection(pMutex); }
+typedef CONDITION_VARIABLE loader_platform_thread_cond;
+static void loader_platform_thread_init_cond(loader_platform_thread_cond *pCond) { InitializeConditionVariable(pCond); }
+static void loader_platform_thread_cond_wait(loader_platform_thread_cond *pCond, loader_platform_thread_mutex *pMutex) {
+ SleepConditionVariableCS(pCond, pMutex, INFINITE);
+}
+static void loader_platform_thread_cond_broadcast(loader_platform_thread_cond *pCond) { WakeAllConditionVariable(pCond); }
+
+#define loader_stack_alloc(size) _alloca(size)
+#else // defined(_WIN32)
+
+#error The "loader_platform.h" file must be modified for this OS.
+
+// NOTE: In order to support another OS, an #elif needs to be added (above the
+// "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
+// contents of this file must be created.
+
+// NOTE: Other OS-specific changes are also needed for this OS. Search for
+// files with "WIN32" in it, as a quick way to find files that must be changed.
+
+#endif // defined(_WIN32)
+
+// returns true if the given string appears to be a relative or absolute
+// path, as opposed to a bare filename.
+static inline bool loader_platform_is_path(const char *path) { return strchr(path, DIRECTORY_SYMBOL) != NULL; }
diff --git a/thirdparty/vulkan/loader/vk_object_types.h b/thirdparty/vulkan/loader/vk_object_types.h
new file mode 100644
index 0000000000..7fdf77aa6a
--- /dev/null
+++ b/thirdparty/vulkan/loader/vk_object_types.h
@@ -0,0 +1,383 @@
+// *** THIS FILE IS GENERATED - DO NOT EDIT ***
+// See helper_file_generator.py for modifications
+
+
+/***************************************************************************
+ *
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ * Copyright (c) 2015-2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
+ * Author: Tobin Ehlis <tobine@google.com>
+ * Author: Chris Forbes <chrisforbes@google.com>
+ * Author: John Zulauf<jzulauf@lunarg.com>
+ *
+ ****************************************************************************/
+
+
+#pragma once
+
+#include <vulkan/vulkan.h>
+
+// Object Type enum for validation layer internal object handling
+typedef enum VulkanObjectType {
+ kVulkanObjectTypeUnknown = 0,
+ kVulkanObjectTypeInstance = 1,
+ kVulkanObjectTypePhysicalDevice = 2,
+ kVulkanObjectTypeDevice = 3,
+ kVulkanObjectTypeQueue = 4,
+ kVulkanObjectTypeSemaphore = 5,
+ kVulkanObjectTypeCommandBuffer = 6,
+ kVulkanObjectTypeFence = 7,
+ kVulkanObjectTypeDeviceMemory = 8,
+ kVulkanObjectTypeBuffer = 9,
+ kVulkanObjectTypeImage = 10,
+ kVulkanObjectTypeEvent = 11,
+ kVulkanObjectTypeQueryPool = 12,
+ kVulkanObjectTypeBufferView = 13,
+ kVulkanObjectTypeImageView = 14,
+ kVulkanObjectTypeShaderModule = 15,
+ kVulkanObjectTypePipelineCache = 16,
+ kVulkanObjectTypePipelineLayout = 17,
+ kVulkanObjectTypeRenderPass = 18,
+ kVulkanObjectTypePipeline = 19,
+ kVulkanObjectTypeDescriptorSetLayout = 20,
+ kVulkanObjectTypeSampler = 21,
+ kVulkanObjectTypeDescriptorPool = 22,
+ kVulkanObjectTypeDescriptorSet = 23,
+ kVulkanObjectTypeFramebuffer = 24,
+ kVulkanObjectTypeCommandPool = 25,
+ kVulkanObjectTypeSamplerYcbcrConversion = 26,
+ kVulkanObjectTypeDescriptorUpdateTemplate = 27,
+ kVulkanObjectTypeSurfaceKHR = 28,
+ kVulkanObjectTypeSwapchainKHR = 29,
+ kVulkanObjectTypeDisplayKHR = 30,
+ kVulkanObjectTypeDisplayModeKHR = 31,
+ kVulkanObjectTypeDebugReportCallbackEXT = 32,
+ kVulkanObjectTypeObjectTableNVX = 33,
+ kVulkanObjectTypeIndirectCommandsLayoutNVX = 34,
+ kVulkanObjectTypeDebugUtilsMessengerEXT = 35,
+ kVulkanObjectTypeValidationCacheEXT = 36,
+ kVulkanObjectTypeAccelerationStructureNV = 37,
+ kVulkanObjectTypePerformanceConfigurationINTEL = 38,
+ kVulkanObjectTypeMax = 39,
+ // Aliases for backwards compatibilty of "promoted" types
+ kVulkanObjectTypeDescriptorUpdateTemplateKHR = kVulkanObjectTypeDescriptorUpdateTemplate,
+ kVulkanObjectTypeSamplerYcbcrConversionKHR = kVulkanObjectTypeSamplerYcbcrConversion,
+} VulkanObjectType;
+
+// Array of object name strings for OBJECT_TYPE enum conversion
+static const char * const object_string[kVulkanObjectTypeMax] = {
+ "Unknown",
+ "Instance",
+ "PhysicalDevice",
+ "Device",
+ "Queue",
+ "Semaphore",
+ "CommandBuffer",
+ "Fence",
+ "DeviceMemory",
+ "Buffer",
+ "Image",
+ "Event",
+ "QueryPool",
+ "BufferView",
+ "ImageView",
+ "ShaderModule",
+ "PipelineCache",
+ "PipelineLayout",
+ "RenderPass",
+ "Pipeline",
+ "DescriptorSetLayout",
+ "Sampler",
+ "DescriptorPool",
+ "DescriptorSet",
+ "Framebuffer",
+ "CommandPool",
+ "SamplerYcbcrConversion",
+ "DescriptorUpdateTemplate",
+ "SurfaceKHR",
+ "SwapchainKHR",
+ "DisplayKHR",
+ "DisplayModeKHR",
+ "DebugReportCallbackEXT",
+ "ObjectTableNVX",
+ "IndirectCommandsLayoutNVX",
+ "DebugUtilsMessengerEXT",
+ "ValidationCacheEXT",
+ "AccelerationStructureNV",
+ "PerformanceConfigurationINTEL",
+};
+
+// Helper array to get Vulkan VK_EXT_debug_report object type enum from the internal layers version
+const VkDebugReportObjectTypeEXT get_debug_report_enum[] = {
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeUnknown
+ VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, // kVulkanObjectTypeInstance
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, // kVulkanObjectTypePhysicalDevice
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, // kVulkanObjectTypeDevice
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, // kVulkanObjectTypeQueue
+ VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, // kVulkanObjectTypeSemaphore
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, // kVulkanObjectTypeCommandBuffer
+ VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, // kVulkanObjectTypeFence
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, // kVulkanObjectTypeDeviceMemory
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, // kVulkanObjectTypeBuffer
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, // kVulkanObjectTypeImage
+ VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, // kVulkanObjectTypeEvent
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, // kVulkanObjectTypeQueryPool
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, // kVulkanObjectTypeBufferView
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, // kVulkanObjectTypeImageView
+ VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, // kVulkanObjectTypeShaderModule
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, // kVulkanObjectTypePipelineCache
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, // kVulkanObjectTypePipelineLayout
+ VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, // kVulkanObjectTypeRenderPass
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, // kVulkanObjectTypePipeline
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, // kVulkanObjectTypeDescriptorSetLayout
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, // kVulkanObjectTypeSampler
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, // kVulkanObjectTypeDescriptorPool
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, // kVulkanObjectTypeDescriptorSet
+ VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, // kVulkanObjectTypeFramebuffer
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, // kVulkanObjectTypeCommandPool
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, // kVulkanObjectTypeSamplerYcbcrConversion
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, // kVulkanObjectTypeDescriptorUpdateTemplate
+ VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, // kVulkanObjectTypeSurfaceKHR
+ VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, // kVulkanObjectTypeSwapchainKHR
+ VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT, // kVulkanObjectTypeDisplayKHR
+ VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT, // kVulkanObjectTypeDisplayModeKHR
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, // kVulkanObjectTypeDebugReportCallbackEXT
+ VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT, // kVulkanObjectTypeObjectTableNVX
+ VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT, // kVulkanObjectTypeIndirectCommandsLayoutNVX
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypeDebugUtilsMessengerEXT
+ VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, // kVulkanObjectTypeValidationCacheEXT
+ VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT, // kVulkanObjectTypeAccelerationStructureNV
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, // kVulkanObjectTypePerformanceConfigurationINTEL
+};
+
+// Helper array to get Official Vulkan VkObjectType enum from the internal layers version
+const VkObjectType get_object_type_enum[] = {
+ VK_OBJECT_TYPE_UNKNOWN, // kVulkanObjectTypeUnknown
+ VK_OBJECT_TYPE_INSTANCE, // kVulkanObjectTypeInstance
+ VK_OBJECT_TYPE_PHYSICAL_DEVICE, // kVulkanObjectTypePhysicalDevice
+ VK_OBJECT_TYPE_DEVICE, // kVulkanObjectTypeDevice
+ VK_OBJECT_TYPE_QUEUE, // kVulkanObjectTypeQueue
+ VK_OBJECT_TYPE_SEMAPHORE, // kVulkanObjectTypeSemaphore
+ VK_OBJECT_TYPE_COMMAND_BUFFER, // kVulkanObjectTypeCommandBuffer
+ VK_OBJECT_TYPE_FENCE, // kVulkanObjectTypeFence
+ VK_OBJECT_TYPE_DEVICE_MEMORY, // kVulkanObjectTypeDeviceMemory
+ VK_OBJECT_TYPE_BUFFER, // kVulkanObjectTypeBuffer
+ VK_OBJECT_TYPE_IMAGE, // kVulkanObjectTypeImage
+ VK_OBJECT_TYPE_EVENT, // kVulkanObjectTypeEvent
+ VK_OBJECT_TYPE_QUERY_POOL, // kVulkanObjectTypeQueryPool
+ VK_OBJECT_TYPE_BUFFER_VIEW, // kVulkanObjectTypeBufferView
+ VK_OBJECT_TYPE_IMAGE_VIEW, // kVulkanObjectTypeImageView
+ VK_OBJECT_TYPE_SHADER_MODULE, // kVulkanObjectTypeShaderModule
+ VK_OBJECT_TYPE_PIPELINE_CACHE, // kVulkanObjectTypePipelineCache
+ VK_OBJECT_TYPE_PIPELINE_LAYOUT, // kVulkanObjectTypePipelineLayout
+ VK_OBJECT_TYPE_RENDER_PASS, // kVulkanObjectTypeRenderPass
+ VK_OBJECT_TYPE_PIPELINE, // kVulkanObjectTypePipeline
+ VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, // kVulkanObjectTypeDescriptorSetLayout
+ VK_OBJECT_TYPE_SAMPLER, // kVulkanObjectTypeSampler
+ VK_OBJECT_TYPE_DESCRIPTOR_POOL, // kVulkanObjectTypeDescriptorPool
+ VK_OBJECT_TYPE_DESCRIPTOR_SET, // kVulkanObjectTypeDescriptorSet
+ VK_OBJECT_TYPE_FRAMEBUFFER, // kVulkanObjectTypeFramebuffer
+ VK_OBJECT_TYPE_COMMAND_POOL, // kVulkanObjectTypeCommandPool
+ VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, // kVulkanObjectTypeSamplerYcbcrConversion
+ VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, // kVulkanObjectTypeDescriptorUpdateTemplate
+ VK_OBJECT_TYPE_SURFACE_KHR, // kVulkanObjectTypeSurfaceKHR
+ VK_OBJECT_TYPE_SWAPCHAIN_KHR, // kVulkanObjectTypeSwapchainKHR
+ VK_OBJECT_TYPE_DISPLAY_KHR, // kVulkanObjectTypeDisplayKHR
+ VK_OBJECT_TYPE_DISPLAY_MODE_KHR, // kVulkanObjectTypeDisplayModeKHR
+ VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, // kVulkanObjectTypeDebugReportCallbackEXT
+ VK_OBJECT_TYPE_OBJECT_TABLE_NVX, // kVulkanObjectTypeObjectTableNVX
+ VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX, // kVulkanObjectTypeIndirectCommandsLayoutNVX
+ VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT, // kVulkanObjectTypeDebugUtilsMessengerEXT
+ VK_OBJECT_TYPE_VALIDATION_CACHE_EXT, // kVulkanObjectTypeValidationCacheEXT
+ VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV, // kVulkanObjectTypeAccelerationStructureNV
+ VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL, // kVulkanObjectTypePerformanceConfigurationINTEL
+};
+
+// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType
+static inline VkObjectType convertDebugReportObjectToCoreObject(VkDebugReportObjectTypeEXT debug_report_obj){
+ if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT) {
+ return VK_OBJECT_TYPE_UNKNOWN;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT) {
+ return VK_OBJECT_TYPE_UNKNOWN;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT) {
+ return VK_OBJECT_TYPE_INSTANCE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT) {
+ return VK_OBJECT_TYPE_PHYSICAL_DEVICE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT) {
+ return VK_OBJECT_TYPE_DEVICE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT) {
+ return VK_OBJECT_TYPE_QUEUE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT) {
+ return VK_OBJECT_TYPE_SEMAPHORE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT) {
+ return VK_OBJECT_TYPE_COMMAND_BUFFER;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT) {
+ return VK_OBJECT_TYPE_FENCE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT) {
+ return VK_OBJECT_TYPE_DEVICE_MEMORY;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT) {
+ return VK_OBJECT_TYPE_BUFFER;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT) {
+ return VK_OBJECT_TYPE_IMAGE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT) {
+ return VK_OBJECT_TYPE_EVENT;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT) {
+ return VK_OBJECT_TYPE_QUERY_POOL;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT) {
+ return VK_OBJECT_TYPE_BUFFER_VIEW;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT) {
+ return VK_OBJECT_TYPE_IMAGE_VIEW;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT) {
+ return VK_OBJECT_TYPE_SHADER_MODULE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT) {
+ return VK_OBJECT_TYPE_PIPELINE_CACHE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT) {
+ return VK_OBJECT_TYPE_PIPELINE_LAYOUT;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT) {
+ return VK_OBJECT_TYPE_RENDER_PASS;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT) {
+ return VK_OBJECT_TYPE_PIPELINE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT) {
+ return VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT) {
+ return VK_OBJECT_TYPE_SAMPLER;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT) {
+ return VK_OBJECT_TYPE_DESCRIPTOR_POOL;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT) {
+ return VK_OBJECT_TYPE_DESCRIPTOR_SET;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT) {
+ return VK_OBJECT_TYPE_FRAMEBUFFER;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT) {
+ return VK_OBJECT_TYPE_COMMAND_POOL;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT) {
+ return VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT) {
+ return VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT) {
+ return VK_OBJECT_TYPE_SURFACE_KHR;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT) {
+ return VK_OBJECT_TYPE_SWAPCHAIN_KHR;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT) {
+ return VK_OBJECT_TYPE_DISPLAY_KHR;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT) {
+ return VK_OBJECT_TYPE_DISPLAY_MODE_KHR;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT) {
+ return VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT) {
+ return VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT) {
+ return VK_OBJECT_TYPE_OBJECT_TABLE_NVX;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT) {
+ return VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT) {
+ return VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT) {
+ return VK_OBJECT_TYPE_VALIDATION_CACHE_EXT;
+ } else if (debug_report_obj == VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT) {
+ return VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV;
+ }
+ return VK_OBJECT_TYPE_UNKNOWN;
+}
+
+// Helper function to convert from VkDebugReportObjectTypeEXT to VkObjectType
+static inline VkDebugReportObjectTypeEXT convertCoreObjectToDebugReportObject(VkObjectType core_report_obj){
+ if (core_report_obj == VK_OBJECT_TYPE_UNKNOWN) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_UNKNOWN) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_INSTANCE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_PHYSICAL_DEVICE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DEVICE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_QUEUE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_SEMAPHORE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_COMMAND_BUFFER) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_FENCE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DEVICE_MEMORY) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_BUFFER) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_IMAGE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_EVENT) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_QUERY_POOL) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_BUFFER_VIEW) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_IMAGE_VIEW) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_SHADER_MODULE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_PIPELINE_CACHE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_PIPELINE_LAYOUT) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_RENDER_PASS) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_PIPELINE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_SAMPLER) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DESCRIPTOR_POOL) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DESCRIPTOR_SET) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_FRAMEBUFFER) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_COMMAND_POOL) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_SURFACE_KHR) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_SWAPCHAIN_KHR) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DISPLAY_KHR) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DISPLAY_MODE_KHR) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_OBJECT_TABLE_NVX) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_VALIDATION_CACHE_EXT) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT;
+ } else if (core_report_obj == VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV) {
+ return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT;
+ }
+ return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
+}
diff --git a/thirdparty/vulkan/loader/wsi.c b/thirdparty/vulkan/loader/wsi.c
new file mode 100644
index 0000000000..f8d8e5374c
--- /dev/null
+++ b/thirdparty/vulkan/loader/wsi.c
@@ -0,0 +1,2023 @@
+/*
+ * Copyright (c) 2015-2016, 2019 The Khronos Group Inc.
+ * Copyright (c) 2015-2016, 2019 Valve Corporation
+ * Copyright (c) 2015-2016, 2019 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Ian Elliott <ian@lunarg.com>
+ * Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Ian Elliott <ianelliott@google.com>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
+ * Author: Lenny Komow <lenny@lunarg.com>
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "vk_loader_platform.h"
+#include "loader.h"
+#include "wsi.h"
+#include <vulkan/vk_icd.h>
+
+// The first ICD/Loader interface that support querying the SurfaceKHR from
+// the ICDs.
+#define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3
+
+void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
+ ptr_instance->wsi_surface_enabled = false;
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ ptr_instance->wsi_win32_surface_enabled = false;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ ptr_instance->wsi_wayland_surface_enabled = false;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ ptr_instance->wsi_xcb_surface_enabled = false;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ ptr_instance->wsi_xlib_surface_enabled = false;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ ptr_instance->wsi_android_surface_enabled = false;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ ptr_instance->wsi_macos_surface_enabled = false;
+#endif // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ ptr_instance->wsi_ios_surface_enabled = false;
+#endif // VK_USE_PLATFORM_IOS_MVK
+ ptr_instance->wsi_display_enabled = false;
+ ptr_instance->wsi_display_props2_enabled = false;
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ ptr_instance->wsi_metal_surface_enabled = false;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_surface_enabled = true;
+ continue;
+ }
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_win32_surface_enabled = true;
+ continue;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_wayland_surface_enabled = true;
+ continue;
+ }
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_xcb_surface_enabled = true;
+ continue;
+ }
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_xlib_surface_enabled = true;
+ continue;
+ }
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_android_surface_enabled = true;
+ continue;
+ }
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_MACOS_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_macos_surface_enabled = true;
+ continue;
+ }
+#endif // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_IOS_MVK
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_MVK_IOS_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_ios_surface_enabled = true;
+ continue;
+ }
+#endif // VK_USE_PLATFORM_IOS_MVK
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_headless_surface_enabled = true;
+ continue;
+ }
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_METAL_SURFACE_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_metal_surface_enabled = true;
+ continue;
+ }
+#endif
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_display_enabled = true;
+ continue;
+ }
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME) == 0) {
+ ptr_instance->wsi_display_props2_enabled = true;
+ continue;
+ }
+ }
+}
+
+// Linux WSI surface extensions are not always compiled into the loader. (Assume
+// for Windows the KHR_win32_surface is always compiled into loader). A given
+// Linux build environment might not have the headers required for building one
+// of the three extensions (Xlib, Xcb, Wayland). Thus, need to check if
+// the built loader actually supports the particular Linux surface extension.
+// If not supported by the built loader it will not be included in the list of
+// enumerated instance extensions. This solves the issue where an ICD or layer
+// advertises support for a given Linux surface extension but the loader was not
+// built to support the extension.
+bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) {
+#ifndef VK_USE_PLATFORM_WAYLAND_KHR
+ if (!strcmp(ext_prop->extensionName, "VK_KHR_wayland_surface")) return true;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifndef VK_USE_PLATFORM_XCB_KHR
+ if (!strcmp(ext_prop->extensionName, "VK_KHR_xcb_surface")) return true;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifndef VK_USE_PLATFORM_XLIB_KHR
+ if (!strcmp(ext_prop->extensionName, "VK_KHR_xlib_surface")) return true;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+ return false;
+}
+
+// Functions for the VK_KHR_surface extension:
+
+// This is the trampoline entrypoint for DestroySurfaceKHR
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ disp->DestroySurfaceKHR(instance, surface, pAllocator);
+}
+
+// TODO probably need to lock around all the loader_get_instance() calls.
+
+// This is the instance chain terminator function for DestroySurfaceKHR
+VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
+ const VkAllocationCallbacks *pAllocator) {
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
+ if (NULL != icd_surface) {
+ if (NULL != icd_surface->real_icd_surfaces) {
+ uint32_t i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.DestroySurfaceKHR && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[i]) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
+ icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)NULL;
+ }
+ } else {
+ // The real_icd_surface for any ICD not supporting the
+ // proper interface version should be NULL. If not, then
+ // we have a problem.
+ assert((VkSurfaceKHR)NULL == icd_surface->real_icd_surfaces[i]);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
+ }
+
+ loader_instance_heap_free(ptr_instance, (void *)(uintptr_t)surface);
+ }
+}
+
+// This is the trampoline entrypoint for GetPhysicalDeviceSurfaceSupportKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex, VkSurfaceKHR surface,
+ VkBool32 *pSupported) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetPhysicalDeviceSurfaceSupportKHR(unwrapped_phys_dev, queueFamilyIndex, surface, pSupported);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceSurfaceSupportKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex, VkSurfaceKHR surface,
+ VkBool32 *pSupported) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == pSupported) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "NULL pointer passed into vkGetPhysicalDeviceSurfaceSupportKHR for pSupported!\n");
+ assert(false && "GetPhysicalDeviceSurfaceSupportKHR: Error, null pSupported");
+ }
+ *pSupported = false;
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceSupportKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceSurfaceSupportKHR ICD pointer");
+ }
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
+ if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(
+ phys_dev_term->phys_dev, queueFamilyIndex, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSupported);
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, surface, pSupported);
+}
+
+// This is the trampoline entrypoint for GetPhysicalDeviceSurfaceCapabilitiesKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
+ VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetPhysicalDeviceSurfaceCapabilitiesKHR(unwrapped_phys_dev, surface, pSurfaceCapabilities);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceSurfaceCapabilitiesKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == pSurfaceCapabilities) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "NULL pointer passed into vkGetPhysicalDeviceSurfaceCapabilitiesKHR for pSurfaceCapabilities!\n");
+ assert(false && "GetPhysicalDeviceSurfaceCapabilitiesKHR: Error, null pSurfaceCapabilities");
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceCapabilitiesKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceSurfaceCapabilitiesKHR ICD pointer");
+ }
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
+ if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(
+ phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pSurfaceCapabilities);
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev_term->phys_dev, surface, pSurfaceCapabilities);
+}
+
+// This is the trampoline entrypoint for GetPhysicalDeviceSurfaceFormatsKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t *pSurfaceFormatCount,
+ VkSurfaceFormatKHR *pSurfaceFormats) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetPhysicalDeviceSurfaceFormatsKHR(unwrapped_phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceSurfaceFormatsKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+ uint32_t *pSurfaceFormatCount,
+ VkSurfaceFormatKHR *pSurfaceFormats) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == pSurfaceFormatCount) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "NULL pointer passed into vkGetPhysicalDeviceSurfaceFormatsKHR for pSurfaceFormatCount!\n");
+ assert(false && "GetPhysicalDeviceSurfaceFormatsKHR(: Error, null pSurfaceFormatCount");
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfaceCapabilitiesKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceSurfaceFormatsKHR ICD pointer");
+ }
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
+ if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev,
+ icd_surface->real_icd_surfaces[phys_dev_term->icd_index],
+ pSurfaceFormatCount, pSurfaceFormats);
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceSurfaceFormatsKHR(phys_dev_term->phys_dev, surface, pSurfaceFormatCount,
+ pSurfaceFormats);
+}
+
+// This is the trampoline entrypoint for GetPhysicalDeviceSurfacePresentModesKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t *pPresentModeCount,
+ VkPresentModeKHR *pPresentModes) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetPhysicalDeviceSurfacePresentModesKHR(unwrapped_phys_dev, surface, pPresentModeCount, pPresentModes);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceSurfacePresentModesKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface, uint32_t *pPresentModeCount,
+ VkPresentModeKHR *pPresentModes) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_surface extension not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == pPresentModeCount) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "NULL pointer passed into vkGetPhysicalDeviceSurfacePresentModesKHR for pPresentModeCount!\n");
+ assert(false && "GetPhysicalDeviceSurfacePresentModesKHR(: Error, null pPresentModeCount");
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceSurfacePresentModesKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceSurfacePresentModesKHR ICD pointer");
+ }
+
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
+ if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[phys_dev_term->icd_index]) {
+ return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(
+ phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[phys_dev_term->icd_index], pPresentModeCount, pPresentModes);
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceSurfacePresentModesKHR(phys_dev_term->phys_dev, surface, pPresentModeCount,
+ pPresentModes);
+}
+
+// Functions for the VK_KHR_swapchain extension:
+
+// This is the trampoline entrypoint for CreateSwapchainKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSwapchainKHR *pSwapchain) {
+ const VkLayerDispatchTable *disp;
+ disp = loader_get_dispatch(device);
+ return disp->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.CreateSwapchainKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfo->surface;
+ if (NULL != icd_surface->real_icd_surfaces) {
+ if ((VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {
+ // We found the ICD, and there is an ICD KHR surface
+ // associated with it, so copy the CreateInfo struct
+ // and point it at the ICD's surface.
+ VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR));
+ if (NULL == pCreateCopy) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR));
+ pCreateCopy->surface = icd_surface->real_icd_surfaces[icd_index];
+ return icd_term->dispatch.CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain);
+ }
+ }
+ return icd_term->dispatch.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+ }
+ return VK_SUCCESS;
+}
+
+// This is the trampoline entrypoint for DestroySwapchainKHR
+LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
+ const VkAllocationCallbacks *pAllocator) {
+ const VkLayerDispatchTable *disp;
+ disp = loader_get_dispatch(device);
+ disp->DestroySwapchainKHR(device, swapchain, pAllocator);
+}
+
+// This is the trampoline entrypoint for GetSwapchainImagesKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
+ uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) {
+ const VkLayerDispatchTable *disp;
+ disp = loader_get_dispatch(device);
+ return disp->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+}
+
+// This is the trampoline entrypoint for AcquireNextImageKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
+ VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
+ const VkLayerDispatchTable *disp;
+ disp = loader_get_dispatch(device);
+ return disp->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+}
+
+// This is the trampoline entrypoint for QueuePresentKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
+ const VkLayerDispatchTable *disp;
+ disp = loader_get_dispatch(queue);
+ return disp->QueuePresentKHR(queue, pPresentInfo);
+}
+
+static VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance, size_t base_size, size_t platform_size) {
+ // Next, if so, proceed with the implementation of this function:
+ VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface != NULL) {
+ // Setup the new sizes and offsets so we can grow the structures in the
+ // future without having problems
+ pIcdSurface->base_size = (uint32_t)base_size;
+ pIcdSurface->platform_size = (uint32_t)platform_size;
+ pIcdSurface->non_platform_offset = (uint32_t)((uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+ pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+ pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface->real_icd_surfaces == NULL) {
+ loader_instance_heap_free(instance, pIcdSurface);
+ pIcdSurface = NULL;
+ } else {
+ memset(pIcdSurface->real_icd_surfaces, 0, sizeof(VkSurfaceKHR) * instance->total_icd_count);
+ }
+ }
+ return pIcdSurface;
+}
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+
+// Functions for the VK_KHR_win32_surface extension:
+
+// This is the trampoline entrypoint for CreateWin32SurfaceKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR(VkInstance instance,
+ const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+// This is the instance chain terminator function for CreateWin32SurfaceKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
+ VkIcdSurface *pIcdSurface = NULL;
+ uint32_t i = 0;
+
+ // Initialize pSurface to NULL just to be safe.
+ *pSurface = VK_NULL_HANDLE;
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_win32_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_win32_surface extension not enabled. vkCreateWin32SurfaceKHR not executed!\n");
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->win_surf.base), sizeof(pIcdSurface->win_surf));
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
+ pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance;
+ pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd;
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.CreateWin32SurfaceKHR) {
+ vkRes = icd_term->dispatch.CreateWin32SurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
+
+ *pSurface = (VkSurfaceKHR)(pIcdSurface);
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
+}
+
+// This is the trampoline entrypoint for
+// GetPhysicalDeviceWin32PresentationSupportKHR
+LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkBool32 res = disp->GetPhysicalDeviceWin32PresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceWin32PresentationSupportKHR
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_win32_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_win32_surface extension not enabled. vkGetPhysicalDeviceWin32PresentationSupportKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceWin32PresentationSupportKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceWin32PresentationSupportKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceWin32PresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex);
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+// This is the trampoline entrypoint for CreateWaylandSurfaceKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(VkInstance instance,
+ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateWaylandSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+// This is the instance chain terminator function for CreateWaylandSurfaceKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance,
+ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
+ VkIcdSurface *pIcdSurface = NULL;
+ uint32_t i = 0;
+
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_wayland_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_wayland_surface extension not enabled. vkCreateWaylandSurfaceKHR not executed!\n");
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->wayland_surf.base), sizeof(pIcdSurface->wayland_surf));
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
+ pIcdSurface->wayland_surf.display = pCreateInfo->display;
+ pIcdSurface->wayland_surf.surface = pCreateInfo->surface;
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.CreateWaylandSurfaceKHR) {
+ vkRes = icd_term->dispatch.CreateWaylandSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
+}
+
+// This is the trampoline entrypoint for
+// GetPhysicalDeviceWaylandPresentationSupportKHR
+LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ struct wl_display *display) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkBool32 res = disp->GetPhysicalDeviceWaylandPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, display);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceWaylandPresentationSupportKHR
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ struct wl_display *display) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_wayland_surface_enabled) {
+ loader_log(
+ ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_wayland_surface extension not enabled. vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceWaylandPresentationSupportKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceWaylandPresentationSupportKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceWaylandPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, display);
+}
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+
+// Functions for the VK_KHR_xcb_surface extension:
+
+// This is the trampoline entrypoint for CreateXcbSurfaceKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR(VkInstance instance,
+ const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateXcbSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+// This is the instance chain terminator function for CreateXcbSurfaceKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
+ VkIcdSurface *pIcdSurface = NULL;
+ uint32_t i = 0;
+
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_xcb_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_xcb_surface extension not enabled. vkCreateXcbSurfaceKHR not executed!\n");
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->xcb_surf.base), sizeof(pIcdSurface->xcb_surf));
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB;
+ pIcdSurface->xcb_surf.connection = pCreateInfo->connection;
+ pIcdSurface->xcb_surf.window = pCreateInfo->window;
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.CreateXcbSurfaceKHR) {
+ vkRes = icd_term->dispatch.CreateXcbSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
+}
+
+// This is the trampoline entrypoint for
+// GetPhysicalDeviceXcbPresentationSupportKHR
+LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ xcb_connection_t *connection,
+ xcb_visualid_t visual_id) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkBool32 res = disp->GetPhysicalDeviceXcbPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, connection, visual_id);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceXcbPresentationSupportKHR
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ xcb_connection_t *connection,
+ xcb_visualid_t visual_id) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_xcb_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_xcb_surface extension not enabled. vkGetPhysicalDeviceXcbPresentationSupportKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceXcbPresentationSupportKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceXcbPresentationSupportKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceXcbPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, connection,
+ visual_id);
+}
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+
+// Functions for the VK_KHR_xlib_surface extension:
+
+// This is the trampoline entrypoint for CreateXlibSurfaceKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR(VkInstance instance,
+ const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateXlibSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+// This is the instance chain terminator function for CreateXlibSurfaceKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
+ VkIcdSurface *pIcdSurface = NULL;
+ uint32_t i = 0;
+
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_xlib_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_xlib_surface extension not enabled. vkCreateXlibSurfaceKHR not executed!\n");
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->xlib_surf.base), sizeof(pIcdSurface->xlib_surf));
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB;
+ pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy;
+ pIcdSurface->xlib_surf.window = pCreateInfo->window;
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.CreateXlibSurfaceKHR) {
+ vkRes = icd_term->dispatch.CreateXlibSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
+}
+
+// This is the trampoline entrypoint for
+// GetPhysicalDeviceXlibPresentationSupportKHR
+LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex, Display *dpy,
+ VisualID visualID) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkBool32 res = disp->GetPhysicalDeviceXlibPresentationSupportKHR(unwrapped_phys_dev, queueFamilyIndex, dpy, visualID);
+ return res;
+}
+
+// This is the instance chain terminator function for
+// GetPhysicalDeviceXlibPresentationSupportKHR
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex, Display *dpy,
+ VisualID visualID) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_xlib_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_xlib_surface extension not enabled. vkGetPhysicalDeviceXlibPresentationSupportKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceXlibPresentationSupportKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceXlibPresentationSupportKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceXlibPresentationSupportKHR(phys_dev_term->phys_dev, queueFamilyIndex, dpy, visualID);
+}
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+
+// Functions for the VK_KHR_android_surface extension:
+
+// This is the trampoline entrypoint for CreateAndroidSurfaceKHR
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR(VkInstance instance, ANativeWindow *window,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateAndroidSurfaceKHR(instance, window, pAllocator, pSurface);
+ return res;
+}
+
+// This is the instance chain terminator function for CreateAndroidSurfaceKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateAndroidSurfaceKHR(VkInstance instance, Window window,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_display_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_display extension not enabled. vkCreateAndroidSurfaceKHR not executed!\n");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ VkIcdSurfaceAndroid *pIcdSurface =
+ loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceAndroid), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_ANDROID;
+ pIcdSurface->window = window;
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+ return VK_SUCCESS;
+}
+
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+// Functions for the VK_EXT_headless_surface extension:
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateHeadlessSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance instance,
+ const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ struct loader_instance *inst = loader_get_instance(instance);
+ VkIcdSurface *pIcdSurface = NULL;
+ VkResult vkRes = VK_SUCCESS;
+ uint32_t i = 0;
+
+ if (!inst->wsi_headless_surface_enabled) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_EXT_headless_surface extension not enabled. "
+ "vkCreateHeadlessSurfaceEXT not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->headless_surf.base), sizeof(pIcdSurface->headless_surf));
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ pIcdSurface->headless_surf.base.platform = VK_ICD_WSI_PLATFORM_HEADLESS;
+ // Loop through each ICD and determine if they need to create a surface
+ for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.CreateHeadlessSurfaceEXT) {
+ vkRes = icd_term->dispatch.CreateHeadlessSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(inst, pIcdSurface);
+ }
+
+ return vkRes;
+}
+
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+
+// Functions for the VK_MVK_macos_surface extension:
+
+// This is the trampoline entrypoint for CreateMacOSSurfaceMVK
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK(VkInstance instance,
+ const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateMacOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+// This is the instance chain terminator function for CreateMacOSSurfaceKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult vkRes = VK_SUCCESS;
+ VkIcdSurface *pIcdSurface = NULL;
+ uint32_t i = 0;
+
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_macos_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_MVK_macos_surface extension not enabled. vkCreateMacOSSurfaceMVK not executed!\n");
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->macos_surf.base), sizeof(pIcdSurface->macos_surf));
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ pIcdSurface->macos_surf.base.platform = VK_ICD_WSI_PLATFORM_MACOS;
+ pIcdSurface->macos_surf.pView = pCreateInfo->pView;
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.CreateMacOSSurfaceMVK) {
+ vkRes = icd_term->dispatch.CreateMacOSSurfaceMVK(icd_term->instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, pIcdSurface);
+ }
+
+ return vkRes;
+}
+
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+#ifdef VK_USE_PLATFORM_IOS_MVK
+
+// Functions for the VK_MVK_ios_surface extension:
+
+// This is the trampoline entrypoint for CreateIOSSurfaceMVK
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK(VkInstance instance,
+ const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateIOSSurfaceMVK(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+// This is the instance chain terminator function for CreateIOSSurfaceKHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_ios_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_MVK_ios_surface extension not enabled. vkCreateIOSSurfaceMVK not executed!\n");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ VkIcdSurfaceIOS *pIcdSurface =
+ loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceIOS), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pIcdSurface == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_IOS;
+ pIcdSurface->pView = pCreateInfo->pView;
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+ return VK_SUCCESS;
+}
+
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT(VkInstance instance,
+ const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp = loader_get_instance_layer_dispatch(instance);
+ return disp->CreateMetalSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+ VkResult result = VK_SUCCESS;
+ VkIcdSurface *icd_surface = NULL;
+ uint32_t i;
+
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_instance *ptr_instance = loader_get_instance(instance);
+ if (!ptr_instance->wsi_metal_surface_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_EXT_metal_surface extension not enabled. vkCreateMetalSurfaceEXT will not be executed.\n");
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ icd_surface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf));
+ if (icd_surface == NULL) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ icd_surface->metal_surf.base.platform = VK_ICD_WSI_PLATFORM_METAL;
+ icd_surface->metal_surf.pLayer = pCreateInfo->pLayer;
+
+ // Loop through each ICD and determine if they need to create a surface
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (icd_term->dispatch.CreateMetalSurfaceEXT != NULL) {
+ result = icd_term->dispatch.CreateMetalSurfaceEXT(icd_term->instance, pCreateInfo, pAllocator,
+ &icd_surface->real_icd_surfaces[i]);
+ if (result != VK_SUCCESS) {
+ goto out;
+ }
+ }
+ }
+ }
+ *pSurface = (VkSurfaceKHR)icd_surface;
+
+out:
+ if (result != VK_SUCCESS && icd_surface != NULL) {
+ if (icd_surface->real_icd_surfaces != NULL) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, ++i) {
+ if (icd_surface->real_icd_surfaces[i] == VK_NULL_HANDLE && icd_term->dispatch.DestroySurfaceKHR != NULL) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_surface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(ptr_instance, icd_surface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(ptr_instance, icd_surface);
+ }
+ return result;
+}
+
+#endif
+
+// Functions for the VK_KHR_display instance extension:
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayPropertiesKHR *pProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetPhysicalDeviceDisplayPropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayPropertiesKHR *pProperties) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_display_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPropertiesKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceDisplayPropertiesKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceDisplayPropertiesKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
+ VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlanePropertiesKHR *pProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetPhysicalDeviceDisplayPlanePropertiesKHR(unwrapped_phys_dev, pPropertyCount, pProperties);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayPlanePropertiesKHR *pProperties) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_display_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_display extension not enabled. vkGetPhysicalDeviceDisplayPlanePropertiesKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetPhysicalDeviceDisplayPlanePropertiesKHR!\n");
+ assert(false && "loader: null GetPhysicalDeviceDisplayPlanePropertiesKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
+ uint32_t planeIndex, uint32_t *pDisplayCount,
+ VkDisplayKHR *pDisplays) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetDisplayPlaneSupportedDisplaysKHR(unwrapped_phys_dev, planeIndex, pDisplayCount, pDisplays);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
+ uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_display_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_display extension not enabled. vkGetDisplayPlaneSupportedDisplaysKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetDisplayPlaneSupportedDisplaysKHR!\n");
+ assert(false && "loader: null GetDisplayPlaneSupportedDisplaysKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetDisplayPlaneSupportedDisplaysKHR(phys_dev_term->phys_dev, planeIndex, pDisplayCount, pDisplays);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ uint32_t *pPropertyCount,
+ VkDisplayModePropertiesKHR *pProperties) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetDisplayModePropertiesKHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ uint32_t *pPropertyCount,
+ VkDisplayModePropertiesKHR *pProperties) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_display_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_display extension not enabled. vkGetDisplayModePropertiesKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetDisplayModePropertiesKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetDisplayModePropertiesKHR!\n");
+ assert(false && "loader: null GetDisplayModePropertiesKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ const VkDisplayModeCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDisplayModeKHR *pMode) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->CreateDisplayModeKHR(unwrapped_phys_dev, display, pCreateInfo, pAllocator, pMode);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ const VkDisplayModeCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_display_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_display extension not enabled. vkCreateDisplayModeKHR not executed!\n");
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+
+ if (NULL == icd_term->dispatch.CreateDisplayModeKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkCreateDisplayModeKHR!\n");
+ assert(false && "loader: null CreateDisplayModeKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.CreateDisplayModeKHR(phys_dev_term->phys_dev, display, pCreateInfo, pAllocator, pMode);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
+ VkDisplayModeKHR mode, uint32_t planeIndex,
+ VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ VkResult res = disp->GetDisplayPlaneCapabilitiesKHR(unwrapped_phys_dev, mode, planeIndex, pCapabilities);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
+ uint32_t planeIndex,
+ VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
+ // First, check to ensure the appropriate extension was enabled:
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
+ if (!ptr_instance->wsi_display_enabled) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_display extension not enabled. vkGetDisplayPlaneCapabilitiesKHR not executed!\n");
+ return VK_SUCCESS;
+ }
+
+ if (NULL == icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR) {
+ loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD for selected physical device is not exporting vkGetDisplayPlaneCapabilitiesKHR!\n");
+ assert(false && "loader: null GetDisplayPlaneCapabilitiesKHR ICD pointer");
+ }
+
+ return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, mode, planeIndex, pCapabilities);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(VkInstance instance,
+ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ const VkLayerInstanceDispatchTable *disp;
+ disp = loader_get_instance_layer_dispatch(instance);
+ VkResult res;
+
+ res = disp->CreateDisplayPlaneSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
+ return res;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance,
+ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface) {
+ struct loader_instance *inst = loader_get_instance(instance);
+ VkIcdSurface *pIcdSurface = NULL;
+ VkResult vkRes = VK_SUCCESS;
+ uint32_t i = 0;
+
+ if (!inst->wsi_display_enabled) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "VK_KHR_surface extension not enabled. vkCreateDisplayPlaneSurfaceKHR not executed!\n");
+ vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto out;
+ }
+
+ // Next, if so, proceed with the implementation of this function:
+ pIcdSurface = AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base), sizeof(pIcdSurface->display_surf));
+ if (pIcdSurface == NULL) {
+ vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+
+ pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
+ pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
+ pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
+ pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
+ pIcdSurface->display_surf.transform = pCreateInfo->transform;
+ pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
+ pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
+ pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
+
+ // Loop through each ICD and determine if they need to create a surface
+ for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+ if (NULL != icd_term->dispatch.CreateDisplayPlaneSurfaceKHR) {
+ vkRes = icd_term->dispatch.CreateDisplayPlaneSurfaceKHR(icd_term->instance, pCreateInfo, pAllocator,
+ &pIcdSurface->real_icd_surfaces[i]);
+ if (VK_SUCCESS != vkRes) {
+ goto out;
+ }
+ }
+ }
+ }
+
+ *pSurface = (VkSurfaceKHR)pIcdSurface;
+
+out:
+
+ if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+ if (NULL != pIcdSurface->real_icd_surfaces) {
+ i = 0;
+ for (struct loader_icd_term *icd_term = inst->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
+ if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+ }
+ }
+ loader_instance_heap_free(inst, pIcdSurface->real_icd_surfaces);
+ }
+ loader_instance_heap_free(inst, pIcdSurface);
+ }
+
+ return vkRes;
+}
+
+// EXT_display_swapchain Extension command
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR *pCreateInfos,
+ const VkAllocationCallbacks *pAllocator,
+ VkSwapchainKHR *pSwapchains) {
+ const VkLayerDispatchTable *disp;
+ disp = loader_get_dispatch(device);
+ return disp->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR *pCreateInfos,
+ const VkAllocationCallbacks *pAllocator,
+ VkSwapchainKHR *pSwapchains) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.CreateSharedSwapchainsKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)pCreateInfos->surface;
+ if (NULL != icd_surface->real_icd_surfaces) {
+ if ((VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {
+ // We found the ICD, and there is an ICD KHR surface
+ // associated with it, so copy the CreateInfo struct
+ // and point it at the ICD's surface.
+ VkSwapchainCreateInfoKHR *pCreateCopy = loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
+ if (NULL == pCreateCopy) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memcpy(pCreateCopy, pCreateInfos, sizeof(VkSwapchainCreateInfoKHR) * swapchainCount);
+ for (uint32_t sc = 0; sc < swapchainCount; sc++) {
+ pCreateCopy[sc].surface = icd_surface->real_icd_surfaces[icd_index];
+ }
+ return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateCopy, pAllocator, pSwapchains);
+ }
+ }
+ return icd_term->dispatch.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+ }
+ return VK_SUCCESS;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR(
+ VkDevice device,
+ VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR(
+ VkDevice device,
+ VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHR* pModes) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(
+ VkDevice device,
+ VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHR* pModes) {
+ uint32_t icd_index = 0;
+ struct loader_device *dev;
+ struct loader_icd_term *icd_term = loader_get_icd_and_device(device, &dev, &icd_index);
+ if (NULL != icd_term && NULL != icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR) {
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(uintptr_t)surface;
+ if (NULL != icd_surface->real_icd_surfaces && (VkSurfaceKHR)NULL != icd_surface->real_icd_surfaces[icd_index]) {
+ return icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR(device, icd_surface->real_icd_surfaces[icd_index], pModes);
+ }
+ return icd_term->dispatch.GetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
+ }
+ return VK_SUCCESS;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pRectCount,
+ VkRect2D* pRects) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDevicePresentRectanglesKHR(unwrapped_phys_dev, surface, pRectCount, pRects);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDevicePresentRectanglesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pRectCount,
+ VkRect2D* pRects) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+ if (NULL == icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR) {
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "ICD associated with VkPhysicalDevice does not support GetPhysicalDevicePresentRectanglesKHX");
+ }
+ VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+ uint8_t icd_index = phys_dev_term->icd_index;
+ if (NULL != icd_surface->real_icd_surfaces && NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {
+ return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(phys_dev_term->phys_dev, icd_surface->real_icd_surfaces[icd_index], pRectCount, pRects);
+ }
+ return icd_term->dispatch.GetPhysicalDevicePresentRectanglesKHR(phys_dev_term->phys_dev, surface, pRectCount, pRects);
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR(
+ VkDevice device,
+ const VkAcquireNextImageInfoKHR* pAcquireInfo,
+ uint32_t* pImageIndex) {
+ const VkLayerDispatchTable *disp = loader_get_dispatch(device);
+ return disp->AcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
+}
+
+// ---- VK_KHR_get_display_properties2 extension trampoline/terminators
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayProperties2KHR *pProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceDisplayProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayProperties2KHR *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ // If the function is available in the driver, just call into it
+ if (icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR != NULL) {
+ return icd_term->dispatch.GetPhysicalDeviceDisplayProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
+ }
+
+ // We have to emulate the function.
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceDisplayProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
+
+ // If the icd doesn't support VK_KHR_display, then no properties are available
+ if (icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR == NULL) {
+ *pPropertyCount = 0;
+ return VK_SUCCESS;
+ }
+
+ // If we aren't writing to pProperties, then emulation is straightforward
+ if (pProperties == NULL || *pPropertyCount == 0) {
+ return icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
+ }
+
+ // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPropertiesKHR and copy it
+ VkDisplayPropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPropertiesKHR));
+ if (properties == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ VkResult res = icd_term->dispatch.GetPhysicalDeviceDisplayPropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
+ if (res < 0) {
+ return res;
+ }
+ for (uint32_t i = 0; i < *pPropertyCount; ++i) {
+ memcpy(&pProperties[i].displayProperties, &properties[i], sizeof(VkDisplayPropertiesKHR));
+ }
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
+ VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkDisplayPlaneProperties2KHR *pProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetPhysicalDeviceDisplayPlaneProperties2KHR(unwrapped_phys_dev, pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayPlaneProperties2KHR *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ // If the function is available in the driver, just call into it
+ if (icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR != NULL) {
+ return icd_term->dispatch.GetPhysicalDeviceDisplayPlaneProperties2KHR(phys_dev_term->phys_dev, pPropertyCount, pProperties);
+ }
+
+ // We have to emulate the function.
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetPhysicalDeviceDisplayPlaneProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
+
+ // If the icd doesn't support VK_KHR_display, then no properties are available
+ if (icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR == NULL) {
+ *pPropertyCount = 0;
+ return VK_SUCCESS;
+ }
+
+ // If we aren't writing to pProperties, then emulation is straightforward
+ if (pProperties == NULL || *pPropertyCount == 0) {
+ return icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, NULL);
+ }
+
+ // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayPlanePropertiesKHR and copy it
+ VkDisplayPlanePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayPlanePropertiesKHR));
+ if (properties == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ VkResult res =
+ icd_term->dispatch.GetPhysicalDeviceDisplayPlanePropertiesKHR(phys_dev_term->phys_dev, pPropertyCount, properties);
+ if (res < 0) {
+ return res;
+ }
+ for (uint32_t i = 0; i < *pPropertyCount; ++i) {
+ memcpy(&pProperties[i].displayPlaneProperties, &properties[i], sizeof(VkDisplayPlanePropertiesKHR));
+ }
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ uint32_t *pPropertyCount,
+ VkDisplayModeProperties2KHR *pProperties) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetDisplayModeProperties2KHR(unwrapped_phys_dev, display, pPropertyCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ uint32_t *pPropertyCount,
+ VkDisplayModeProperties2KHR *pProperties) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ // If the function is available in the driver, just call into it
+ if (icd_term->dispatch.GetDisplayModeProperties2KHR != NULL) {
+ return icd_term->dispatch.GetDisplayModeProperties2KHR(phys_dev_term->phys_dev, display, pPropertyCount, pProperties);
+ }
+
+ // We have to emulate the function.
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetDisplayModeProperties2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
+
+ // If the icd doesn't support VK_KHR_display, then no properties are available
+ if (icd_term->dispatch.GetDisplayModePropertiesKHR == NULL) {
+ *pPropertyCount = 0;
+ return VK_SUCCESS;
+ }
+
+ // If we aren't writing to pProperties, then emulation is straightforward
+ if (pProperties == NULL || *pPropertyCount == 0) {
+ return icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, NULL);
+ }
+
+ // If we do have to write to pProperties, then we need to write to a temporary array of VkDisplayModePropertiesKHR and copy it
+ VkDisplayModePropertiesKHR *properties = loader_stack_alloc(*pPropertyCount * sizeof(VkDisplayModePropertiesKHR));
+ if (properties == NULL) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ VkResult res = icd_term->dispatch.GetDisplayModePropertiesKHR(phys_dev_term->phys_dev, display, pPropertyCount, properties);
+ if (res < 0) {
+ return res;
+ }
+ for (uint32_t i = 0; i < *pPropertyCount; ++i) {
+ memcpy(&pProperties[i].displayModeProperties, &properties[i], sizeof(VkDisplayModePropertiesKHR));
+ }
+ return res;
+}
+
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
+ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
+ VkDisplayPlaneCapabilities2KHR *pCapabilities) {
+ const VkLayerInstanceDispatchTable *disp;
+ VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
+ disp = loader_get_instance_layer_dispatch(physicalDevice);
+ return disp->GetDisplayPlaneCapabilities2KHR(unwrapped_phys_dev, pDisplayPlaneInfo, pCapabilities);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
+ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
+ VkDisplayPlaneCapabilities2KHR *pCapabilities) {
+ struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
+ struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
+
+ // If the function is abailable in the driver, just call into it
+ if (icd_term->dispatch.GetDisplayPlaneCapabilities2KHR != NULL) {
+ return icd_term->dispatch.GetDisplayPlaneCapabilities2KHR(phys_dev_term->phys_dev, pDisplayPlaneInfo, pCapabilities);
+ }
+
+ // We have to emulate the function.
+ loader_log(icd_term->this_instance, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, 0,
+ "vkGetDisplayPlaneCapabilities2KHR: Emulating call in ICD \"%s\"", icd_term->scanned_icd->lib_name);
+
+ // Just call into the old version of the function.
+ // If the icd doesn't support VK_KHR_display, there are zero planes and this call is invalid (and will crash)
+ return icd_term->dispatch.GetDisplayPlaneCapabilitiesKHR(phys_dev_term->phys_dev, pDisplayPlaneInfo->mode,
+ pDisplayPlaneInfo->planeIndex, &pCapabilities->capabilities);
+}
+
+bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr) {
+ *addr = NULL;
+
+ // Functions for the VK_KHR_surface extension:
+ if (!strcmp("vkDestroySurfaceKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkDestroySurfaceKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceSupportKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceCapabilitiesKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfaceFormatsKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDeviceSurfacePresentModesKHR : NULL;
+ return true;
+ }
+
+ if (!strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetDeviceGroupPresentCapabilitiesKHR : NULL;
+ return true;
+ }
+
+ if (!strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetDeviceGroupSurfacePresentModesKHR : NULL;
+ return true;
+ }
+
+ if (!strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name)) {
+ *addr = ptr_instance->wsi_surface_enabled ? (void *)vkGetPhysicalDevicePresentRectanglesKHR : NULL;
+ return true;
+ }
+
+ // Functions for the VK_KHR_swapchain extension:
+
+ // Note: This is a device extension, and its functions are statically
+ // exported from the loader. Per Khronos decisions, the loader's GIPA
+ // function will return the trampoline function for such device-extension
+ // functions, regardless of whether the extension has been enabled.
+ if (!strcmp("vkCreateSwapchainKHR", name)) {
+ *addr = (void *)vkCreateSwapchainKHR;
+ return true;
+ }
+ if (!strcmp("vkDestroySwapchainKHR", name)) {
+ *addr = (void *)vkDestroySwapchainKHR;
+ return true;
+ }
+ if (!strcmp("vkGetSwapchainImagesKHR", name)) {
+ *addr = (void *)vkGetSwapchainImagesKHR;
+ return true;
+ }
+ if (!strcmp("vkAcquireNextImageKHR", name)) {
+ *addr = (void *)vkAcquireNextImageKHR;
+ return true;
+ }
+ if (!strcmp("vkQueuePresentKHR", name)) {
+ *addr = (void *)vkQueuePresentKHR;
+ return true;
+ }
+ if (!strcmp("vkAcquireNextImage2KHR", name)) {
+ *addr = (void *)vkAcquireNextImage2KHR;
+ return true;
+ }
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+
+ // Functions for the VK_KHR_win32_surface extension:
+ if (!strcmp("vkCreateWin32SurfaceKHR", name)) {
+ *addr = ptr_instance->wsi_win32_surface_enabled ? (void *)vkCreateWin32SurfaceKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceWin32PresentationSupportKHR", name)) {
+ *addr = ptr_instance->wsi_win32_surface_enabled ? (void *)vkGetPhysicalDeviceWin32PresentationSupportKHR : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+ // Functions for the VK_KHR_wayland_surface extension:
+ if (!strcmp("vkCreateWaylandSurfaceKHR", name)) {
+ *addr = ptr_instance->wsi_wayland_surface_enabled ? (void *)vkCreateWaylandSurfaceKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceWaylandPresentationSupportKHR", name)) {
+ *addr = ptr_instance->wsi_wayland_surface_enabled ? (void *)vkGetPhysicalDeviceWaylandPresentationSupportKHR : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+
+ // Functions for the VK_KHR_xcb_surface extension:
+ if (!strcmp("vkCreateXcbSurfaceKHR", name)) {
+ *addr = ptr_instance->wsi_xcb_surface_enabled ? (void *)vkCreateXcbSurfaceKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceXcbPresentationSupportKHR", name)) {
+ *addr = ptr_instance->wsi_xcb_surface_enabled ? (void *)vkGetPhysicalDeviceXcbPresentationSupportKHR : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+
+ // Functions for the VK_KHR_xlib_surface extension:
+ if (!strcmp("vkCreateXlibSurfaceKHR", name)) {
+ *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkCreateXlibSurfaceKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceXlibPresentationSupportKHR", name)) {
+ *addr = ptr_instance->wsi_xlib_surface_enabled ? (void *)vkGetPhysicalDeviceXlibPresentationSupportKHR : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+
+ // Functions for the VK_KHR_android_surface extension:
+ if (!strcmp("vkCreateAndroidSurfaceKHR", name)) {
+ *addr = ptr_instance->wsi_android_surface_enabled ? (void *)vkCreateAndroidSurfaceKHR : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+
+ // Functions for the VK_MVK_macos_surface extension:
+ if (!strcmp("vkCreateMacOSSurfaceMVK", name)) {
+ *addr = ptr_instance->wsi_macos_surface_enabled ? (void *)vkCreateMacOSSurfaceMVK : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_IOS_MVK
+
+ // Functions for the VK_MVK_ios_surface extension:
+ if (!strcmp("vkCreateIOSSurfaceMVK", name)) {
+ *addr = ptr_instance->wsi_ios_surface_enabled ? (void *)vkCreateIOSSurfaceMVK : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+ // Functions for the VK_EXT_headless_surface extension:
+ if (!strcmp("vkCreateHeadlessSurfaceEXT", name)) {
+ *addr = ptr_instance->wsi_headless_surface_enabled ? (void *)vkCreateHeadlessSurfaceEXT : NULL;
+ return true;
+ }
+
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+ // Functions for the VK_MVK_macos_surface extension:
+ if (!strcmp("vkCreateMetalSurfaceEXT", name)) {
+ *addr = ptr_instance->wsi_metal_surface_enabled ? (void *)vkCreateMetalSurfaceEXT : NULL;
+ return true;
+ }
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+ // Functions for VK_KHR_display extension:
+ if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
+ *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceDisplayPlanePropertiesKHR", name)) {
+ *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPlanePropertiesKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetDisplayPlaneSupportedDisplaysKHR", name)) {
+ *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayPlaneSupportedDisplaysKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetDisplayModePropertiesKHR", name)) {
+ *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayModePropertiesKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkCreateDisplayModeKHR", name)) {
+ *addr = ptr_instance->wsi_display_enabled ? (void *)vkCreateDisplayModeKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetDisplayPlaneCapabilitiesKHR", name)) {
+ *addr = ptr_instance->wsi_display_enabled ? (void *)vkGetDisplayPlaneCapabilitiesKHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkCreateDisplayPlaneSurfaceKHR", name)) {
+ *addr = ptr_instance->wsi_display_enabled ? (void *)vkCreateDisplayPlaneSurfaceKHR : NULL;
+ return true;
+ }
+
+ // Functions for KHR_display_swapchain extension:
+ if (!strcmp("vkCreateSharedSwapchainsKHR", name)) {
+ *addr = (void *)vkCreateSharedSwapchainsKHR;
+ return true;
+ }
+
+ // Functions for KHR_get_display_properties2
+ if (!strcmp("vkGetPhysicalDeviceDisplayProperties2KHR", name)) {
+ *addr = ptr_instance->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayProperties2KHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetPhysicalDeviceDisplayPlaneProperties2KHR", name)) {
+ *addr = ptr_instance->wsi_display_props2_enabled ? (void *)vkGetPhysicalDeviceDisplayPlaneProperties2KHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetDisplayModeProperties2KHR", name)) {
+ *addr = ptr_instance->wsi_display_props2_enabled ? (void *)vkGetDisplayModeProperties2KHR : NULL;
+ return true;
+ }
+ if (!strcmp("vkGetDisplayPlaneCapabilities2KHR", name)) {
+ *addr = ptr_instance->wsi_display_props2_enabled ? (void *)vkGetDisplayPlaneCapabilities2KHR : NULL;
+ return true;
+ }
+
+ return false;
+}
diff --git a/thirdparty/vulkan/loader/wsi.h b/thirdparty/vulkan/loader/wsi.h
new file mode 100644
index 0000000000..3e44efa9e9
--- /dev/null
+++ b/thirdparty/vulkan/loader/wsi.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Ian Elliott <ian@lunarg.com>
+ *
+ */
+
+#ifndef WSI_H
+#define WSI_H
+
+#include "vk_loader_platform.h"
+#include "loader.h"
+
+typedef struct {
+ union {
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ VkIcdSurfaceWayland wayland_surf;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+ VkIcdSurfaceWin32 win_surf;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+ VkIcdSurfaceXcb xcb_surf;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+ VkIcdSurfaceXlib xlib_surf;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+ VkIcdSurfaceMacOS macos_surf;
+#endif // VK_USE_PLATFORM_MACOS_MVK
+#ifdef VK_USE_PLATFORM_METAL_EXT
+ VkIcdSurfaceMetal metal_surf;
+#endif // VK_USE_PLATFORM_METAL_EXT
+ VkIcdSurfaceDisplay display_surf;
+ VkIcdSurfaceHeadless headless_surf;
+ };
+ uint32_t base_size; // Size of VkIcdSurfaceBase
+ uint32_t platform_size; // Size of corresponding VkIcdSurfaceXXX
+ uint32_t non_platform_offset; // Start offset to base_size
+ uint32_t entire_size; // Size of entire VkIcdSurface
+ VkSurfaceKHR *real_icd_surfaces;
+} VkIcdSurface;
+
+bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);
+
+void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);
+bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateHeadlessSurfaceEXT(VkInstance instance,
+ const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain);
+
+VKAPI_ATTR void VKAPI_CALL terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
+ const VkAllocationCallbacks *pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex, VkSurfaceKHR surface,
+ VkBool32 *pSupported);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+ uint32_t *pSurfaceFormatCount,
+ VkSurfaceFormatKHR *pSurfaceFormats);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface, uint32_t *pPresentModeCount,
+ VkPresentModeKHR *pPresentModes);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDeviceGroupSurfacePresentModesKHR(
+ VkDevice device,
+ VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHR* pModes);
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex);
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(VkInstance instance,
+ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ struct wl_display *display);
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ xcb_connection_t *connection,
+ xcb_visualid_t visual_id);
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex, Display *dpy,
+ VisualID visualID);
+#endif
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+#endif
+#ifdef VK_USE_PLATFORM_IOS_MVK
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+#endif
+#if defined(VK_USE_PLATFORM_METAL_EXT)
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+#endif
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayPropertiesKHR *pProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayPlanePropertiesKHR *pProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
+ uint32_t *pDisplayCount, VkDisplayKHR *pDisplays);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ uint32_t *pPropertyCount,
+ VkDisplayModePropertiesKHR *pProperties);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ const VkDisplayModeCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDisplayModeKHR *pMode);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode,
+ uint32_t planeIndex,
+ VkDisplayPlaneCapabilitiesKHR *pCapabilities);
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(VkInstance instance,
+ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkSurfaceKHR *pSurface);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR *pCreateInfos,
+ const VkAllocationCallbacks *pAllocator,
+ VkSwapchainKHR *pSwapchains);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pRectCount,
+ VkRect2D* pRects);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayProperties2KHR *pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice,
+ uint32_t *pPropertyCount,
+ VkDisplayPlaneProperties2KHR *pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+ uint32_t *pPropertyCount,
+ VkDisplayModeProperties2KHR *pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice,
+ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo,
+ VkDisplayPlaneCapabilities2KHR *pCapabilities);
+
+#endif // WSI_H