xref: /aosp_15_r20/external/mesa3d/src/panfrost/vulkan/panvk_instance.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2021 Collabora Ltd.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Derived from tu_device.c which is:
5*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
6*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
7*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
8*61046927SAndroid Build Coastguard Worker  *
9*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
10*61046927SAndroid Build Coastguard Worker  */
11*61046927SAndroid Build Coastguard Worker 
12*61046927SAndroid Build Coastguard Worker #include "util/build_id.h"
13*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
16*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker #include "panvk_entrypoints.h"
19*61046927SAndroid Build Coastguard Worker #include "panvk_instance.h"
20*61046927SAndroid Build Coastguard Worker #include "panvk_physical_device.h"
21*61046927SAndroid Build Coastguard Worker 
22*61046927SAndroid Build Coastguard Worker #ifdef HAVE_VALGRIND
23*61046927SAndroid Build Coastguard Worker #include <memcheck.h>
24*61046927SAndroid Build Coastguard Worker #include <valgrind.h>
25*61046927SAndroid Build Coastguard Worker #define VG(x) x
26*61046927SAndroid Build Coastguard Worker #else
27*61046927SAndroid Build Coastguard Worker #define VG(x)
28*61046927SAndroid Build Coastguard Worker #endif
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker static const struct debug_control panvk_debug_options[] = {
31*61046927SAndroid Build Coastguard Worker    {"startup", PANVK_DEBUG_STARTUP},
32*61046927SAndroid Build Coastguard Worker    {"nir", PANVK_DEBUG_NIR},
33*61046927SAndroid Build Coastguard Worker    {"trace", PANVK_DEBUG_TRACE},
34*61046927SAndroid Build Coastguard Worker    {"sync", PANVK_DEBUG_SYNC},
35*61046927SAndroid Build Coastguard Worker    {"afbc", PANVK_DEBUG_AFBC},
36*61046927SAndroid Build Coastguard Worker    {"linear", PANVK_DEBUG_LINEAR},
37*61046927SAndroid Build Coastguard Worker    {"dump", PANVK_DEBUG_DUMP},
38*61046927SAndroid Build Coastguard Worker    {"no_known_warn", PANVK_DEBUG_NO_KNOWN_WARN},
39*61046927SAndroid Build Coastguard Worker    {"cs", PANVK_DEBUG_CS},
40*61046927SAndroid Build Coastguard Worker    {NULL, 0}};
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
panvk_EnumerateInstanceVersion(uint32_t * pApiVersion)43*61046927SAndroid Build Coastguard Worker panvk_EnumerateInstanceVersion(uint32_t *pApiVersion)
44*61046927SAndroid Build Coastguard Worker {
45*61046927SAndroid Build Coastguard Worker    *pApiVersion = panvk_get_vk_version();
46*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
47*61046927SAndroid Build Coastguard Worker }
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker static const struct vk_instance_extension_table panvk_instance_extensions = {
50*61046927SAndroid Build Coastguard Worker    .KHR_device_group_creation = true,
51*61046927SAndroid Build Coastguard Worker    .KHR_get_physical_device_properties2 = true,
52*61046927SAndroid Build Coastguard Worker #ifdef PANVK_USE_WSI_PLATFORM
53*61046927SAndroid Build Coastguard Worker    .KHR_surface = true,
54*61046927SAndroid Build Coastguard Worker #endif
55*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WAYLAND_KHR
56*61046927SAndroid Build Coastguard Worker    .KHR_wayland_surface = true,
57*61046927SAndroid Build Coastguard Worker #endif
58*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_XCB_KHR
59*61046927SAndroid Build Coastguard Worker    .KHR_xcb_surface = true,
60*61046927SAndroid Build Coastguard Worker #endif
61*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_XLIB_KHR
62*61046927SAndroid Build Coastguard Worker    .KHR_xlib_surface = true,
63*61046927SAndroid Build Coastguard Worker #endif
64*61046927SAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
65*61046927SAndroid Build Coastguard Worker    .EXT_acquire_xlib_display = true,
66*61046927SAndroid Build Coastguard Worker #endif
67*61046927SAndroid Build Coastguard Worker    .EXT_debug_report = true,
68*61046927SAndroid Build Coastguard Worker    .EXT_debug_utils = true,
69*61046927SAndroid Build Coastguard Worker #ifndef VK_USE_PLATFORM_WIN32_KHR
70*61046927SAndroid Build Coastguard Worker    .EXT_headless_surface = true,
71*61046927SAndroid Build Coastguard Worker #endif
72*61046927SAndroid Build Coastguard Worker };
73*61046927SAndroid Build Coastguard Worker 
74*61046927SAndroid Build Coastguard Worker static VkResult
panvk_physical_device_try_create(struct vk_instance * vk_instance,struct _drmDevice * drm_device,struct vk_physical_device ** out)75*61046927SAndroid Build Coastguard Worker panvk_physical_device_try_create(struct vk_instance *vk_instance,
76*61046927SAndroid Build Coastguard Worker                                  struct _drmDevice *drm_device,
77*61046927SAndroid Build Coastguard Worker                                  struct vk_physical_device **out)
78*61046927SAndroid Build Coastguard Worker {
79*61046927SAndroid Build Coastguard Worker    struct panvk_instance *instance =
80*61046927SAndroid Build Coastguard Worker       container_of(vk_instance, struct panvk_instance, vk);
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker    if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)) ||
83*61046927SAndroid Build Coastguard Worker        drm_device->bustype != DRM_BUS_PLATFORM)
84*61046927SAndroid Build Coastguard Worker       return VK_ERROR_INCOMPATIBLE_DRIVER;
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker    struct panvk_physical_device *device =
87*61046927SAndroid Build Coastguard Worker       vk_zalloc(&instance->vk.alloc, sizeof(*device), 8,
88*61046927SAndroid Build Coastguard Worker                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
89*61046927SAndroid Build Coastguard Worker    if (!device)
90*61046927SAndroid Build Coastguard Worker       return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker    VkResult result = panvk_physical_device_init(device, instance, drm_device);
93*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
94*61046927SAndroid Build Coastguard Worker       vk_free(&instance->vk.alloc, device);
95*61046927SAndroid Build Coastguard Worker       return result;
96*61046927SAndroid Build Coastguard Worker    }
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    *out = &device->vk;
99*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker static void
panvk_destroy_physical_device(struct vk_physical_device * device)103*61046927SAndroid Build Coastguard Worker panvk_destroy_physical_device(struct vk_physical_device *device)
104*61046927SAndroid Build Coastguard Worker {
105*61046927SAndroid Build Coastguard Worker    panvk_physical_device_finish((struct panvk_physical_device *)device);
106*61046927SAndroid Build Coastguard Worker    vk_free(&device->instance->alloc, device);
107*61046927SAndroid Build Coastguard Worker }
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker static void *
panvk_kmod_zalloc(const struct pan_kmod_allocator * allocator,size_t size,bool transient)110*61046927SAndroid Build Coastguard Worker panvk_kmod_zalloc(const struct pan_kmod_allocator *allocator, size_t size,
111*61046927SAndroid Build Coastguard Worker                   bool transient)
112*61046927SAndroid Build Coastguard Worker {
113*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *vkalloc = allocator->priv;
114*61046927SAndroid Build Coastguard Worker 
115*61046927SAndroid Build Coastguard Worker    void *obj = vk_zalloc(vkalloc, size, 8,
116*61046927SAndroid Build Coastguard Worker                          transient ? VK_SYSTEM_ALLOCATION_SCOPE_COMMAND
117*61046927SAndroid Build Coastguard Worker                                    : VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    /* We force errno to -ENOMEM on host allocation failures so we can properly
120*61046927SAndroid Build Coastguard Worker     * report it back as VK_ERROR_OUT_OF_HOST_MEMORY. */
121*61046927SAndroid Build Coastguard Worker    errno = obj ? 0 : -ENOMEM;
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    return obj;
124*61046927SAndroid Build Coastguard Worker }
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker static void
panvk_kmod_free(const struct pan_kmod_allocator * allocator,void * data)127*61046927SAndroid Build Coastguard Worker panvk_kmod_free(const struct pan_kmod_allocator *allocator, void *data)
128*61046927SAndroid Build Coastguard Worker {
129*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *vkalloc = allocator->priv;
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker    return vk_free(vkalloc, data);
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
panvk_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)135*61046927SAndroid Build Coastguard Worker panvk_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
136*61046927SAndroid Build Coastguard Worker                      const VkAllocationCallbacks *pAllocator,
137*61046927SAndroid Build Coastguard Worker                      VkInstance *pInstance)
138*61046927SAndroid Build Coastguard Worker {
139*61046927SAndroid Build Coastguard Worker    struct panvk_instance *instance;
140*61046927SAndroid Build Coastguard Worker    VkResult result;
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker    const struct build_id_note *note =
145*61046927SAndroid Build Coastguard Worker       build_id_find_nhdr_for_addr(panvk_CreateInstance);
146*61046927SAndroid Build Coastguard Worker    if (!note) {
147*61046927SAndroid Build Coastguard Worker       return vk_errorf(NULL, VK_ERROR_INITIALIZATION_FAILED,
148*61046927SAndroid Build Coastguard Worker                        "Failed to find build-id");
149*61046927SAndroid Build Coastguard Worker    }
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker    unsigned build_id_len = build_id_length(note);
152*61046927SAndroid Build Coastguard Worker    if (build_id_len < SHA1_DIGEST_LENGTH) {
153*61046927SAndroid Build Coastguard Worker       return vk_errorf(NULL, VK_ERROR_INITIALIZATION_FAILED,
154*61046927SAndroid Build Coastguard Worker                        "build-id too short.  It needs to be a SHA");
155*61046927SAndroid Build Coastguard Worker    }
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker    pAllocator = pAllocator ?: vk_default_allocator();
158*61046927SAndroid Build Coastguard Worker    instance = vk_zalloc(pAllocator, sizeof(*instance), 8,
159*61046927SAndroid Build Coastguard Worker                         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
160*61046927SAndroid Build Coastguard Worker    if (!instance)
161*61046927SAndroid Build Coastguard Worker       return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker    struct vk_instance_dispatch_table dispatch_table;
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker    vk_instance_dispatch_table_from_entrypoints(
166*61046927SAndroid Build Coastguard Worker       &dispatch_table, &panvk_instance_entrypoints, true);
167*61046927SAndroid Build Coastguard Worker    vk_instance_dispatch_table_from_entrypoints(
168*61046927SAndroid Build Coastguard Worker       &dispatch_table, &wsi_instance_entrypoints, false);
169*61046927SAndroid Build Coastguard Worker    result = vk_instance_init(&instance->vk, &panvk_instance_extensions,
170*61046927SAndroid Build Coastguard Worker                              &dispatch_table, pCreateInfo, pAllocator);
171*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
172*61046927SAndroid Build Coastguard Worker       vk_free(pAllocator, instance);
173*61046927SAndroid Build Coastguard Worker       return vk_error(NULL, result);
174*61046927SAndroid Build Coastguard Worker    }
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker    instance->kmod.allocator = (struct pan_kmod_allocator){
177*61046927SAndroid Build Coastguard Worker       .zalloc = panvk_kmod_zalloc,
178*61046927SAndroid Build Coastguard Worker       .free = panvk_kmod_free,
179*61046927SAndroid Build Coastguard Worker       .priv = &instance->vk.alloc,
180*61046927SAndroid Build Coastguard Worker    };
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker    instance->vk.physical_devices.try_create_for_drm =
183*61046927SAndroid Build Coastguard Worker       panvk_physical_device_try_create;
184*61046927SAndroid Build Coastguard Worker    instance->vk.physical_devices.destroy = panvk_destroy_physical_device;
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker    instance->debug_flags =
187*61046927SAndroid Build Coastguard Worker       parse_debug_string(getenv("PANVK_DEBUG"), panvk_debug_options);
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker    if (instance->debug_flags & PANVK_DEBUG_STARTUP)
190*61046927SAndroid Build Coastguard Worker       vk_logi(VK_LOG_NO_OBJS(instance), "Created an instance");
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker    VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(sizeof(instance->driver_build_sha) == SHA1_DIGEST_LENGTH);
195*61046927SAndroid Build Coastguard Worker    memcpy(instance->driver_build_sha, build_id_data(note), SHA1_DIGEST_LENGTH);
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker    *pInstance = panvk_instance_to_handle(instance);
198*61046927SAndroid Build Coastguard Worker 
199*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
panvk_DestroyInstance(VkInstance _instance,const VkAllocationCallbacks * pAllocator)203*61046927SAndroid Build Coastguard Worker panvk_DestroyInstance(VkInstance _instance,
204*61046927SAndroid Build Coastguard Worker                       const VkAllocationCallbacks *pAllocator)
205*61046927SAndroid Build Coastguard Worker {
206*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_instance, instance, _instance);
207*61046927SAndroid Build Coastguard Worker 
208*61046927SAndroid Build Coastguard Worker    if (!instance)
209*61046927SAndroid Build Coastguard Worker       return;
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker    vk_instance_finish(&instance->vk);
212*61046927SAndroid Build Coastguard Worker    vk_free(&instance->vk.alloc, instance);
213*61046927SAndroid Build Coastguard Worker }
214*61046927SAndroid Build Coastguard Worker 
215*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
panvk_EnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)216*61046927SAndroid Build Coastguard Worker panvk_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
217*61046927SAndroid Build Coastguard Worker                                        VkLayerProperties *pProperties)
218*61046927SAndroid Build Coastguard Worker {
219*61046927SAndroid Build Coastguard Worker    *pPropertyCount = 0;
220*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
221*61046927SAndroid Build Coastguard Worker }
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
panvk_EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)224*61046927SAndroid Build Coastguard Worker panvk_EnumerateInstanceExtensionProperties(const char *pLayerName,
225*61046927SAndroid Build Coastguard Worker                                            uint32_t *pPropertyCount,
226*61046927SAndroid Build Coastguard Worker                                            VkExtensionProperties *pProperties)
227*61046927SAndroid Build Coastguard Worker {
228*61046927SAndroid Build Coastguard Worker    if (pLayerName)
229*61046927SAndroid Build Coastguard Worker       return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker    return vk_enumerate_instance_extension_properties(
232*61046927SAndroid Build Coastguard Worker       &panvk_instance_extensions, pPropertyCount, pProperties);
233*61046927SAndroid Build Coastguard Worker }
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker PFN_vkVoidFunction
panvk_GetInstanceProcAddr(VkInstance _instance,const char * pName)236*61046927SAndroid Build Coastguard Worker panvk_GetInstanceProcAddr(VkInstance _instance, const char *pName)
237*61046927SAndroid Build Coastguard Worker {
238*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_instance, instance, _instance);
239*61046927SAndroid Build Coastguard Worker    return vk_instance_get_proc_addr(&instance->vk, &panvk_instance_entrypoints,
240*61046927SAndroid Build Coastguard Worker                                     pName);
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker /* The loader wants us to expose a second GetInstanceProcAddr function
244*61046927SAndroid Build Coastguard Worker  * to work around certain LD_PRELOAD issues seen in apps.
245*61046927SAndroid Build Coastguard Worker  */
246*61046927SAndroid Build Coastguard Worker PUBLIC
247*61046927SAndroid Build Coastguard Worker VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vk_icdGetInstanceProcAddr(VkInstance instance,const char * pName)248*61046927SAndroid Build Coastguard Worker vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
249*61046927SAndroid Build Coastguard Worker {
250*61046927SAndroid Build Coastguard Worker    return panvk_GetInstanceProcAddr(instance, pName);
251*61046927SAndroid Build Coastguard Worker }
252