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