diff options
| author | Lenny Komow <lenny@lunarg.com> | 2018-02-13 15:58:47 -0700 |
|---|---|---|
| committer | Mike Schuchardt <mikes@lunarg.com> | 2018-03-09 13:54:31 -0700 |
| commit | bc9fdf492563939209b0758819caea3302c9c2cb (patch) | |
| tree | 3b5954fdd0f53f9a37ca93506d9fa7120f0864c3 /loader | |
| parent | 4c88179f99a2f6e6acd9b5574dd6fb22cde9037f (diff) | |
| download | usermoji-bc9fdf492563939209b0758819caea3302c9c2cb.tar.xz | |
loader: Extend pre-instance intercepts for 1.1
Add the ability to intercept vkEnumerateInstanceVersion through the
pre-instance intercept mechanism
Diffstat (limited to 'loader')
| -rw-r--r-- | loader/loader.c | 21 | ||||
| -rw-r--r-- | loader/loader.h | 1 | ||||
| -rw-r--r-- | loader/trampoline.c | 92 |
3 files changed, 107 insertions, 7 deletions
diff --git a/loader/loader.c b/loader/loader.c index ff777d5a..0b88f661 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -98,6 +98,10 @@ 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) @@ -2864,6 +2868,15 @@ static VkResult loader_read_json_layer(const struct loader_instance *inst, struc 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); + 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); + } } } @@ -6095,6 +6108,14 @@ VkStringErrorFlags vk_string_validate(const int max_length, const char *utf8) { } 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, 0); + 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; diff --git a/loader/loader.h b/loader/loader.h index 9342e21c..8abc034a 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -140,6 +140,7 @@ struct loader_layer_properties { 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; }; diff --git a/loader/trampoline.c b/loader/trampoline.c index dff1ccd3..51f1377c 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -33,9 +33,6 @@ #include "vk_loader_extensions.h" #include "gpa_helper.h" -// This loader only supports Vulkan API version 1.0 -uint32_t loader_major_version = 1; -uint32_t loader_minor_version = 1; // Trampoline entrypoints are in this file for core Vulkan commands @@ -273,10 +270,91 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( } LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(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, 0); - return VK_SUCCESS; + + 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)); + loader_implicit_layer_scan(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 (!loader_is_implicit_layer_enabled(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 + loader_delete_layer_properties(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, |
