v3dv: implement vkCreateInstance
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
diff --git a/src/broadcom/vulkan/meson.build b/src/broadcom/vulkan/meson.build
index 19ac65f7..ed3d11b 100644
--- a/src/broadcom/vulkan/meson.build
+++ b/src/broadcom/vulkan/meson.build
@@ -77,6 +77,8 @@
],
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 3403808..dc9c5bb 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 @@
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 c9edae6..f6ec1fe 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 {