diff options
Diffstat (limited to 'thirdparty/vulkan/loader')
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(¤t); + + 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, ®_size, LoaderPnpDriverRegistryWide()); + if (regHKR_result == VK_INCOMPLETE) { + regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, ®_size, LoaderPnpDriverRegistry()); + } + } else if (!strncmp(registry_location, VK_ELAYERS_INFO_REGISTRY_LOC, sizeof(VK_ELAYERS_INFO_REGISTRY_LOC))) { + regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, ®_size, LoaderPnpELayerRegistryWide()); + if (regHKR_result == VK_INCOMPLETE) { + regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, ®_size, LoaderPnpELayerRegistry()); + } + } else if (!strncmp(registry_location, VK_ILAYERS_INFO_REGISTRY_LOC, sizeof(VK_ILAYERS_INFO_REGISTRY_LOC))) { + regHKR_result = ReadManifestsFromD3DAdapters(inst, &search_path, ®_size, LoaderPnpILayerRegistryWide()); + if (regHKR_result == VK_INCOMPLETE) { + regHKR_result = loaderGetDeviceRegistryFiles(inst, &search_path, ®_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, ®_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 |