From be1575c625a09c6ef3fbc4e365e01794286b0488 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 27 Nov 2019 11:49:49 +0100 Subject: [PATCH] v3dv: implement vkCreateInstance Part-of: --- src/broadcom/vulkan/meson.build | 2 + src/broadcom/vulkan/v3dv_device.c | 144 ++++++++++++++++++++++++++++- src/broadcom/vulkan/v3dv_private.h | 2 + 3 files changed, 147 insertions(+), 1 deletion(-) diff --git a/src/broadcom/vulkan/meson.build b/src/broadcom/vulkan/meson.build index 19ac65f7c32..ed3d11b9939 100644 --- a/src/broadcom/vulkan/meson.build +++ b/src/broadcom/vulkan/meson.build @@ -77,6 +77,8 @@ libvulkan_broadcom = shared_library( ], link_with : [ libbroadcom_v3d, + # For glsl_type_singleton_init_or_ref: + libglsl, ], dependencies : v3dv_deps, c_args : v3dv_flags, diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 34038088e0e..dc9c5bbf7f2 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -31,6 +31,35 @@ #include "v3dv_private.h" #include "vk_util.h" +#include "compiler/glsl_types.h" + +static void * +default_alloc_func(void *pUserData, size_t size, size_t align, + VkSystemAllocationScope allocationScope) +{ + return malloc(size); +} + +static void * +default_realloc_func(void *pUserData, void *pOriginal, size_t size, + size_t align, VkSystemAllocationScope allocationScope) +{ + return realloc(pOriginal, size); +} + +static void +default_free_func(void *pUserData, void *pMemory) +{ + free(pMemory); +} + +static const VkAllocationCallbacks default_alloc = { + .pUserData = NULL, + .pfnAllocation = default_alloc_func, + .pfnReallocation = default_realloc_func, + .pfnFree = default_free_func, +}; + VkResult v3dv_EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount, @@ -54,7 +83,120 @@ v3dv_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { - /* FIXME: stub */ + struct v3dv_instance *instance; + VkResult result; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO); + + struct v3dv_instance_extension_table enabled_extensions = {}; + for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) { + int idx; + for (idx = 0; idx < V3DV_INSTANCE_EXTENSION_COUNT; idx++) { + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], + v3dv_instance_extensions[idx].extensionName) == 0) + break; + } + + if (idx >= V3DV_INSTANCE_EXTENSION_COUNT) + return vk_error(NULL, VK_ERROR_EXTENSION_NOT_PRESENT); + + if (!v3dv_instance_extensions_supported.extensions[idx]) + return vk_error(NULL, VK_ERROR_EXTENSION_NOT_PRESENT); + + enabled_extensions.extensions[idx] = true; + } + + instance = vk_alloc2(&default_alloc, pAllocator, sizeof(*instance), 8, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + if (!instance) + return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); + + instance->_loader_data.loaderMagic = ICD_LOADER_MAGIC; + + if (pAllocator) + instance->alloc = *pAllocator; + else + instance->alloc = default_alloc; + + instance->app_info = (struct v3dv_app_info) { .api_version = 0 }; + if (pCreateInfo->pApplicationInfo) { + const VkApplicationInfo *app = pCreateInfo->pApplicationInfo; + + instance->app_info.app_name = + vk_strdup(&instance->alloc, app->pApplicationName, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + instance->app_info.app_version = app->applicationVersion; + + instance->app_info.engine_name = + vk_strdup(&instance->alloc, app->pEngineName, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + instance->app_info.engine_version = app->engineVersion; + + instance->app_info.api_version = app->apiVersion; + } + + if (instance->app_info.api_version == 0) + instance->app_info.api_version = VK_API_VERSION_1_0; + + instance->enabled_extensions = enabled_extensions; + + for (unsigned i = 0; i < ARRAY_SIZE(instance->dispatch.entrypoints); i++) { + /* Vulkan requires that entrypoints for extensions which have not been + * enabled must not be advertised. + */ + if (!v3dv_instance_entrypoint_is_enabled(i, + instance->app_info.api_version, + &instance->enabled_extensions)) { + instance->dispatch.entrypoints[i] = NULL; + } else { + instance->dispatch.entrypoints[i] = + v3dv_instance_dispatch_table.entrypoints[i]; + } + } + + struct v3dv_physical_device *pdevice = &instance->physicalDevice; + for (unsigned i = 0; i < ARRAY_SIZE(pdevice->dispatch.entrypoints); i++) { + /* Vulkan requires that entrypoints for extensions which have not been + * enabled must not be advertised. + */ + if (!v3dv_physical_device_entrypoint_is_enabled(i, + instance->app_info.api_version, + &instance->enabled_extensions)) { + pdevice->dispatch.entrypoints[i] = NULL; + } else { + pdevice->dispatch.entrypoints[i] = + v3dv_physical_device_dispatch_table.entrypoints[i]; + } + } + + for (unsigned i = 0; i < ARRAY_SIZE(instance->device_dispatch.entrypoints); i++) { + /* Vulkan requires that entrypoints for extensions which have not been + * enabled must not be advertised. + */ + if (!v3dv_device_entrypoint_is_enabled(i, + instance->app_info.api_version, + &instance->enabled_extensions, + NULL)) { + instance->device_dispatch.entrypoints[i] = NULL; + } else { + instance->device_dispatch.entrypoints[i] = + v3dv_device_dispatch_table.entrypoints[i]; + } + } + + instance->physicalDeviceCount = -1; + + result = vk_debug_report_instance_init(&instance->debug_report_callbacks); + if (result != VK_SUCCESS) { + vk_free2(&default_alloc, pAllocator, instance); + return vk_error(NULL, result); + } + + glsl_type_singleton_init_or_ref(); + + VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false)); + + *pInstance = v3dv_instance_to_handle(instance); return VK_SUCCESS; } diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index c9edae676a0..f6ec1fe15d4 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -51,6 +51,8 @@ #include "v3dv_entrypoints.h" #include "v3dv_extensions.h" +#include "vk_alloc.h" + struct v3dv_instance; struct v3dv_device {