xref: /aosp_15_r20/external/mesa3d/src/asahi/vulkan/hk_instance.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2024 Valve Corporation
3  * Copyright 2024 Alyssa Rosenzweig
4  * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc.
5  * SPDX-License-Identifier: MIT
6  */
7 #include "hk_instance.h"
8 
9 #include "hk_entrypoints.h"
10 #include "hk_physical_device.h"
11 
12 #include "vulkan/wsi/wsi_common.h"
13 
14 #include "util/build_id.h"
15 #include "util/driconf.h"
16 #include "util/mesa-sha1.h"
17 
18 VKAPI_ATTR VkResult VKAPI_CALL
hk_EnumerateInstanceVersion(uint32_t * pApiVersion)19 hk_EnumerateInstanceVersion(uint32_t *pApiVersion)
20 {
21    uint32_t version_override = vk_get_version_override();
22    *pApiVersion = version_override ? version_override
23                                    : VK_MAKE_VERSION(1, 3, VK_HEADER_VERSION);
24 
25    return VK_SUCCESS;
26 }
27 
28 static const struct vk_instance_extension_table instance_extensions = {
29 #ifdef HK_USE_WSI_PLATFORM
30    .KHR_get_surface_capabilities2 = true,
31    .KHR_surface = true,
32    .KHR_surface_protected_capabilities = true,
33    .EXT_surface_maintenance1 = true,
34    .EXT_swapchain_colorspace = true,
35 #endif
36 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
37    .KHR_wayland_surface = true,
38 #endif
39 #ifdef VK_USE_PLATFORM_XCB_KHR
40    .KHR_xcb_surface = true,
41 #endif
42 #ifdef VK_USE_PLATFORM_XLIB_KHR
43    .KHR_xlib_surface = true,
44 #endif
45 #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
46    .EXT_acquire_xlib_display = true,
47 #endif
48 #ifdef VK_USE_PLATFORM_DISPLAY_KHR
49    .KHR_display = true,
50    .KHR_get_display_properties2 = true,
51    .EXT_direct_mode_display = true,
52    .EXT_display_surface_counter = true,
53    .EXT_acquire_drm_display = true,
54 #endif
55 #ifndef VK_USE_PLATFORM_WIN32_KHR
56    .EXT_headless_surface = true,
57 #endif
58    .KHR_device_group_creation = true,
59    .KHR_external_fence_capabilities = true,
60    .KHR_external_memory_capabilities = true,
61    .KHR_external_semaphore_capabilities = true,
62    .KHR_get_physical_device_properties2 = true,
63    .EXT_debug_report = true,
64    .EXT_debug_utils = true,
65 };
66 
67 VKAPI_ATTR VkResult VKAPI_CALL
hk_EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)68 hk_EnumerateInstanceExtensionProperties(const char *pLayerName,
69                                         uint32_t *pPropertyCount,
70                                         VkExtensionProperties *pProperties)
71 {
72    if (pLayerName)
73       return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
74 
75    return vk_enumerate_instance_extension_properties(
76       &instance_extensions, pPropertyCount, pProperties);
77 }
78 
79 static const driOptionDescription hk_dri_options[] = {
80    DRI_CONF_SECTION_PERFORMANCE DRI_CONF_ADAPTIVE_SYNC(true)
81       DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
82          DRI_CONF_VK_X11_STRICT_IMAGE_COUNT(false)
83             DRI_CONF_VK_X11_ENSURE_MIN_IMAGE_COUNT(false)
84                DRI_CONF_VK_KHR_PRESENT_WAIT(false)
85                   DRI_CONF_VK_XWAYLAND_WAIT_READY(false) DRI_CONF_SECTION_END
86 
87                      DRI_CONF_SECTION_DEBUG DRI_CONF_FORCE_VK_VENDOR()
88                         DRI_CONF_VK_WSI_FORCE_SWAPCHAIN_TO_CURRENT_EXTENT(false)
89                            DRI_CONF_VK_X11_IGNORE_SUBOPTIMAL(false)
90                               DRI_CONF_SECTION_END};
91 
92 static void
hk_init_dri_options(struct hk_instance * instance)93 hk_init_dri_options(struct hk_instance *instance)
94 {
95    driParseOptionInfo(&instance->available_dri_options, hk_dri_options,
96                       ARRAY_SIZE(hk_dri_options));
97    driParseConfigFiles(
98       &instance->dri_options, &instance->available_dri_options, 0, "hk", NULL,
99       NULL, instance->vk.app_info.app_name, instance->vk.app_info.app_version,
100       instance->vk.app_info.engine_name, instance->vk.app_info.engine_version);
101 
102    instance->force_vk_vendor =
103       driQueryOptioni(&instance->dri_options, "force_vk_vendor");
104 }
105 
106 VKAPI_ATTR VkResult VKAPI_CALL
hk_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)107 hk_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
108                   const VkAllocationCallbacks *pAllocator,
109                   VkInstance *pInstance)
110 {
111    struct hk_instance *instance;
112    VkResult result;
113 
114    if (pAllocator == NULL)
115       pAllocator = vk_default_allocator();
116 
117    instance = vk_alloc(pAllocator, sizeof(*instance), 8,
118                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
119    if (!instance)
120       return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
121 
122    struct vk_instance_dispatch_table dispatch_table;
123    vk_instance_dispatch_table_from_entrypoints(&dispatch_table,
124                                                &hk_instance_entrypoints, true);
125    vk_instance_dispatch_table_from_entrypoints(
126       &dispatch_table, &wsi_instance_entrypoints, false);
127 
128    result = vk_instance_init(&instance->vk, &instance_extensions,
129                              &dispatch_table, pCreateInfo, pAllocator);
130    if (result != VK_SUCCESS)
131       goto fail_alloc;
132 
133    hk_init_dri_options(instance);
134 
135    instance->vk.physical_devices.try_create_for_drm =
136       hk_create_drm_physical_device;
137    instance->vk.physical_devices.destroy = hk_physical_device_destroy;
138 
139    const struct build_id_note *note =
140       build_id_find_nhdr_for_addr(hk_CreateInstance);
141    if (!note) {
142       result = vk_errorf(NULL, VK_ERROR_INITIALIZATION_FAILED,
143                          "Failed to find build-id");
144       goto fail_init;
145    }
146 
147    unsigned build_id_len = build_id_length(note);
148    if (build_id_len < SHA1_DIGEST_LENGTH) {
149       result = vk_errorf(NULL, VK_ERROR_INITIALIZATION_FAILED,
150                          "build-id too short.  It needs to be a SHA");
151       goto fail_init;
152    }
153 
154    static_assert(sizeof(instance->driver_build_sha) == SHA1_DIGEST_LENGTH);
155    memcpy(instance->driver_build_sha, build_id_data(note), SHA1_DIGEST_LENGTH);
156 
157    *pInstance = hk_instance_to_handle(instance);
158    return VK_SUCCESS;
159 
160 fail_init:
161    vk_instance_finish(&instance->vk);
162 fail_alloc:
163    vk_free(pAllocator, instance);
164 
165    return result;
166 }
167 
168 VKAPI_ATTR void VKAPI_CALL
hk_DestroyInstance(VkInstance _instance,const VkAllocationCallbacks * pAllocator)169 hk_DestroyInstance(VkInstance _instance,
170                    const VkAllocationCallbacks *pAllocator)
171 {
172    VK_FROM_HANDLE(hk_instance, instance, _instance);
173 
174    if (!instance)
175       return;
176 
177    driDestroyOptionCache(&instance->dri_options);
178    driDestroyOptionInfo(&instance->available_dri_options);
179 
180    vk_instance_finish(&instance->vk);
181    vk_free(&instance->vk.alloc, instance);
182 }
183 
184 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
hk_GetInstanceProcAddr(VkInstance _instance,const char * pName)185 hk_GetInstanceProcAddr(VkInstance _instance, const char *pName)
186 {
187    VK_FROM_HANDLE(hk_instance, instance, _instance);
188    return vk_instance_get_proc_addr(&instance->vk, &hk_instance_entrypoints,
189                                     pName);
190 }
191 
192 PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vk_icdGetInstanceProcAddr(VkInstance instance,const char * pName)193 vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
194 {
195    return hk_GetInstanceProcAddr(instance, pName);
196 }
197