Path: blob/21.2-virgl/src/vulkan/util/vk_instance.c
7099 views
/*1* Copyright © 2021 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "vk_instance.h"2425#include "vk_alloc.h"26#include "vk_common_entrypoints.h"27#include "vk_util.h"2829#include "compiler/glsl_types.h"3031VkResult32vk_instance_init(struct vk_instance *instance,33const struct vk_instance_extension_table *supported_extensions,34const struct vk_instance_dispatch_table *dispatch_table,35const VkInstanceCreateInfo *pCreateInfo,36const VkAllocationCallbacks *alloc)37{38memset(instance, 0, sizeof(*instance));39vk_object_base_init(NULL, &instance->base, VK_OBJECT_TYPE_INSTANCE);40instance->alloc = *alloc;4142instance->app_info = (struct vk_app_info) { .api_version = 0 };43if (pCreateInfo->pApplicationInfo) {44const VkApplicationInfo *app = pCreateInfo->pApplicationInfo;4546instance->app_info.app_name =47vk_strdup(&instance->alloc, app->pApplicationName,48VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);49instance->app_info.app_version = app->applicationVersion;5051instance->app_info.engine_name =52vk_strdup(&instance->alloc, app->pEngineName,53VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);54instance->app_info.engine_version = app->engineVersion;5556instance->app_info.api_version = app->apiVersion;57}5859if (instance->app_info.api_version == 0)60instance->app_info.api_version = VK_API_VERSION_1_0;6162for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {63int idx;64for (idx = 0; idx < VK_INSTANCE_EXTENSION_COUNT; idx++) {65if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],66vk_instance_extensions[idx].extensionName) == 0)67break;68}6970if (idx >= VK_INSTANCE_EXTENSION_COUNT)71return VK_ERROR_EXTENSION_NOT_PRESENT;7273if (!supported_extensions->extensions[idx])74return VK_ERROR_EXTENSION_NOT_PRESENT;7576#ifdef ANDROID77if (!vk_android_allowed_instance_extensions.extensions[idx])78return VK_ERROR_EXTENSION_NOT_PRESENT;79#endif8081instance->enabled_extensions.extensions[idx] = true;82}8384instance->dispatch_table = *dispatch_table;8586/* Add common entrypoints without overwriting driver-provided ones. */87vk_instance_dispatch_table_from_entrypoints(88&instance->dispatch_table, &vk_common_instance_entrypoints, false);8990if (mtx_init(&instance->debug_report.callbacks_mutex, mtx_plain) != 0)91return VK_ERROR_INITIALIZATION_FAILED;9293list_inithead(&instance->debug_report.callbacks);9495glsl_type_singleton_init_or_ref();9697return VK_SUCCESS;98}99100void101vk_instance_finish(struct vk_instance *instance)102{103glsl_type_singleton_decref();104mtx_destroy(&instance->debug_report.callbacks_mutex);105vk_free(&instance->alloc, (char *)instance->app_info.app_name);106vk_free(&instance->alloc, (char *)instance->app_info.engine_name);107vk_object_base_finish(&instance->base);108}109110VkResult111vk_enumerate_instance_extension_properties(112const struct vk_instance_extension_table *supported_extensions,113uint32_t *pPropertyCount,114VkExtensionProperties *pProperties)115{116VK_OUTARRAY_MAKE_TYPED(VkExtensionProperties, out, pProperties, pPropertyCount);117118for (int i = 0; i < VK_INSTANCE_EXTENSION_COUNT; i++) {119if (!supported_extensions->extensions[i])120continue;121122#ifdef ANDROID123if (!vk_android_allowed_instance_extensions.extensions[i])124continue;125#endif126127vk_outarray_append_typed(VkExtensionProperties, &out, prop) {128*prop = vk_instance_extensions[i];129}130}131132return vk_outarray_status(&out);133}134135PFN_vkVoidFunction136vk_instance_get_proc_addr(const struct vk_instance *instance,137const struct vk_instance_entrypoint_table *entrypoints,138const char *name)139{140PFN_vkVoidFunction func;141142/* The Vulkan 1.0 spec for vkGetInstanceProcAddr has a table of exactly143* when we have to return valid function pointers, NULL, or it's left144* undefined. See the table for exact details.145*/146if (name == NULL)147return NULL;148149#define LOOKUP_VK_ENTRYPOINT(entrypoint) \150if (strcmp(name, "vk" #entrypoint) == 0) \151return (PFN_vkVoidFunction)entrypoints->entrypoint152153LOOKUP_VK_ENTRYPOINT(EnumerateInstanceExtensionProperties);154LOOKUP_VK_ENTRYPOINT(EnumerateInstanceLayerProperties);155LOOKUP_VK_ENTRYPOINT(EnumerateInstanceVersion);156LOOKUP_VK_ENTRYPOINT(CreateInstance);157158/* GetInstanceProcAddr() can also be called with a NULL instance.159* See https://gitlab.khronos.org/vulkan/vulkan/issues/2057160*/161LOOKUP_VK_ENTRYPOINT(GetInstanceProcAddr);162163#undef LOOKUP_VK_ENTRYPOINT164165if (instance == NULL)166return NULL;167168func = vk_instance_dispatch_table_get_if_supported(&instance->dispatch_table,169name,170instance->app_info.api_version,171&instance->enabled_extensions);172if (func != NULL)173return func;174175func = vk_physical_device_dispatch_table_get_if_supported(&vk_physical_device_trampolines,176name,177instance->app_info.api_version,178&instance->enabled_extensions);179if (func != NULL)180return func;181182func = vk_device_dispatch_table_get_if_supported(&vk_device_trampolines,183name,184instance->app_info.api_version,185&instance->enabled_extensions,186NULL);187if (func != NULL)188return func;189190return NULL;191}192193PFN_vkVoidFunction194vk_instance_get_proc_addr_unchecked(const struct vk_instance *instance,195const char *name)196{197PFN_vkVoidFunction func;198199if (instance == NULL || name == NULL)200return NULL;201202func = vk_instance_dispatch_table_get(&instance->dispatch_table, name);203if (func != NULL)204return func;205206func = vk_physical_device_dispatch_table_get(207&vk_physical_device_trampolines, name);208if (func != NULL)209return func;210211func = vk_device_dispatch_table_get(&vk_device_trampolines, name);212if (func != NULL)213return func;214215return NULL;216}217218PFN_vkVoidFunction219vk_instance_get_physical_device_proc_addr(const struct vk_instance *instance,220const char *name)221{222if (instance == NULL || name == NULL)223return NULL;224225return vk_physical_device_dispatch_table_get_if_supported(&vk_physical_device_trampolines,226name,227instance->app_info.api_version,228&instance->enabled_extensions);229}230231232