1/*
2 * Copyright © 2019 Raspberry Pi Ltd
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include <assert.h>
25#include <fcntl.h>
26#include <stdbool.h>
27#include <string.h>
28#include <sys/mman.h>
29#include <sys/sysinfo.h>
30#include <unistd.h>
31#include <xf86drm.h>
32
33#ifdef MAJOR_IN_MKDEV
34#include <sys/mkdev.h>
35#endif
36#ifdef MAJOR_IN_SYSMACROS
37#include <sys/sysmacros.h>
38#endif
39
40#include "v3dv_private.h"
41
42#include "common/v3d_debug.h"
43
44#include "compiler/v3d_compiler.h"
45
46#include "drm-uapi/v3d_drm.h"
47#include "format/u_format.h"
48#include "vk_drm_syncobj.h"
49#include "vk_util.h"
50#include "git_sha1.h"
51
52#include "util/build_id.h"
53#include "util/debug.h"
54
55#ifdef VK_USE_PLATFORM_XCB_KHR
56#include <xcb/xcb.h>
57#include <xcb/dri3.h>
58#include <X11/Xlib-xcb.h>
59#endif
60
61#ifdef VK_USE_PLATFORM_WAYLAND_KHR
62#include <wayland-client.h>
63#include "wayland-drm-client-protocol.h"
64#endif
65
66#ifndef ANDROID
67#   define V3DV_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION)
68#else
69/* Android CDD require additional extensions for API v1.1+ */
70#   define V3DV_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION)
71#endif
72
73VKAPI_ATTR VkResult VKAPI_CALL
74v3dv_EnumerateInstanceVersion(uint32_t *pApiVersion)
75{
76    *pApiVersion = V3DV_API_VERSION;
77    return VK_SUCCESS;
78}
79
80#if defined(VK_USE_PLATFORM_WIN32_KHR) ||   \
81    defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
82    defined(VK_USE_PLATFORM_XCB_KHR) ||     \
83    defined(VK_USE_PLATFORM_XLIB_KHR) ||    \
84    defined(VK_USE_PLATFORM_DISPLAY_KHR)
85#define V3DV_USE_WSI_PLATFORM
86#endif
87
88static const struct vk_instance_extension_table instance_extensions = {
89   .KHR_device_group_creation           = true,
90#ifdef VK_USE_PLATFORM_DISPLAY_KHR
91   .KHR_display                         = true,
92   .KHR_get_display_properties2         = true,
93#endif
94   .KHR_external_fence_capabilities     = true,
95   .KHR_external_memory_capabilities    = true,
96   .KHR_external_semaphore_capabilities = true,
97   .KHR_get_physical_device_properties2 = true,
98#ifdef V3DV_USE_WSI_PLATFORM
99   .KHR_get_surface_capabilities2       = true,
100   .KHR_surface                         = true,
101   .KHR_surface_protected_capabilities  = true,
102#endif
103#ifdef VK_USE_PLATFORM_WAYLAND_KHR
104   .KHR_wayland_surface                 = true,
105#endif
106#ifdef VK_USE_PLATFORM_XCB_KHR
107   .KHR_xcb_surface                     = true,
108#endif
109#ifdef VK_USE_PLATFORM_XLIB_KHR
110   .KHR_xlib_surface                    = true,
111#endif
112   .EXT_debug_report                    = true,
113   .EXT_debug_utils                     = true,
114};
115
116static void
117get_device_extensions(const struct v3dv_physical_device *device,
118                      struct vk_device_extension_table *ext)
119{
120   *ext = (struct vk_device_extension_table) {
121      .KHR_8bit_storage                    = true,
122      .KHR_16bit_storage                   = true,
123      .KHR_bind_memory2                    = true,
124      .KHR_buffer_device_address           = true,
125      .KHR_copy_commands2                  = true,
126      .KHR_create_renderpass2              = true,
127      .KHR_dedicated_allocation            = true,
128      .KHR_device_group                    = true,
129      .KHR_driver_properties               = true,
130      .KHR_descriptor_update_template      = true,
131      .KHR_depth_stencil_resolve           = true,
132      .KHR_external_fence                  = true,
133      .KHR_external_fence_fd               = true,
134      .KHR_external_memory                 = true,
135      .KHR_external_memory_fd              = true,
136      .KHR_external_semaphore              = true,
137      .KHR_external_semaphore_fd           = true,
138      .KHR_format_feature_flags2           = true,
139      .KHR_get_memory_requirements2        = true,
140      .KHR_image_format_list               = true,
141      .KHR_imageless_framebuffer           = true,
142      .KHR_performance_query               = device->caps.perfmon,
143      .KHR_relaxed_block_layout            = true,
144      .KHR_maintenance1                    = true,
145      .KHR_maintenance2                    = true,
146      .KHR_maintenance3                    = true,
147      .KHR_multiview                       = true,
148      .KHR_pipeline_executable_properties  = true,
149      .KHR_separate_depth_stencil_layouts  = true,
150      .KHR_shader_float_controls           = true,
151      .KHR_shader_non_semantic_info        = true,
152      .KHR_sampler_mirror_clamp_to_edge    = true,
153      .KHR_spirv_1_4                       = true,
154      .KHR_storage_buffer_storage_class    = true,
155      .KHR_timeline_semaphore              = true,
156      .KHR_uniform_buffer_standard_layout  = true,
157#ifdef V3DV_USE_WSI_PLATFORM
158      .KHR_swapchain                       = true,
159      .KHR_swapchain_mutable_format        = true,
160      .KHR_incremental_present             = true,
161#endif
162      .KHR_variable_pointers               = true,
163      .KHR_vulkan_memory_model             = true,
164      .EXT_4444_formats                    = true,
165      .EXT_color_write_enable              = true,
166      .EXT_custom_border_color             = true,
167      .EXT_inline_uniform_block            = true,
168      .EXT_external_memory_dma_buf         = true,
169      .EXT_host_query_reset                = true,
170      .EXT_image_drm_format_modifier       = true,
171      .EXT_index_type_uint8                = true,
172      .EXT_line_rasterization              = true,
173      .EXT_physical_device_drm             = true,
174      .EXT_pipeline_creation_cache_control = true,
175      .EXT_pipeline_creation_feedback      = true,
176      .EXT_private_data                    = true,
177      .EXT_provoking_vertex                = true,
178      .EXT_separate_stencil_usage          = true,
179      .EXT_vertex_attribute_divisor        = true,
180#ifdef ANDROID
181      .ANDROID_native_buffer               = true,
182#endif
183   };
184}
185
186VKAPI_ATTR VkResult VKAPI_CALL
187v3dv_EnumerateInstanceExtensionProperties(const char *pLayerName,
188                                          uint32_t *pPropertyCount,
189                                          VkExtensionProperties *pProperties)
190{
191   /* We don't support any layers  */
192   if (pLayerName)
193      return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
194
195   return vk_enumerate_instance_extension_properties(
196      &instance_extensions, pPropertyCount, pProperties);
197}
198
199VKAPI_ATTR VkResult VKAPI_CALL
200v3dv_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
201                    const VkAllocationCallbacks *pAllocator,
202                    VkInstance *pInstance)
203{
204   struct v3dv_instance *instance;
205   VkResult result;
206
207   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
208
209   if (pAllocator == NULL)
210      pAllocator = vk_default_allocator();
211
212   instance = vk_alloc(pAllocator, sizeof(*instance), 8,
213                       VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
214   if (!instance)
215      return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
216
217   struct vk_instance_dispatch_table dispatch_table;
218   vk_instance_dispatch_table_from_entrypoints(
219      &dispatch_table, &v3dv_instance_entrypoints, true);
220   vk_instance_dispatch_table_from_entrypoints(
221      &dispatch_table, &wsi_instance_entrypoints, false);
222
223   result = vk_instance_init(&instance->vk,
224                             &instance_extensions,
225                             &dispatch_table,
226                             pCreateInfo, pAllocator);
227
228   if (result != VK_SUCCESS) {
229      vk_free(pAllocator, instance);
230      return vk_error(NULL, result);
231   }
232
233   v3d_process_debug_variable();
234
235   instance->physicalDeviceCount = -1;
236
237   /* We start with the default values for the pipeline_cache envvars */
238   instance->pipeline_cache_enabled = true;
239   instance->default_pipeline_cache_enabled = true;
240   const char *pipeline_cache_str = getenv("V3DV_ENABLE_PIPELINE_CACHE");
241   if (pipeline_cache_str != NULL) {
242      if (strncmp(pipeline_cache_str, "full", 4) == 0) {
243         /* nothing to do, just to filter correct values */
244      } else if (strncmp(pipeline_cache_str, "no-default-cache", 16) == 0) {
245         instance->default_pipeline_cache_enabled = false;
246      } else if (strncmp(pipeline_cache_str, "off", 3) == 0) {
247         instance->pipeline_cache_enabled = false;
248         instance->default_pipeline_cache_enabled = false;
249      } else {
250         fprintf(stderr, "Wrong value for envvar V3DV_ENABLE_PIPELINE_CACHE. "
251                 "Allowed values are: full, no-default-cache, off\n");
252      }
253   }
254
255   if (instance->pipeline_cache_enabled == false) {
256      fprintf(stderr, "WARNING: v3dv pipeline cache is disabled. Performance "
257              "can be affected negatively\n");
258   } else {
259      if (instance->default_pipeline_cache_enabled == false) {
260        fprintf(stderr, "WARNING: default v3dv pipeline cache is disabled. "
261                "Performance can be affected negatively\n");
262      }
263   }
264
265   VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
266
267   *pInstance = v3dv_instance_to_handle(instance);
268
269   return VK_SUCCESS;
270}
271
272static void
273v3dv_physical_device_free_disk_cache(struct v3dv_physical_device *device)
274{
275#ifdef ENABLE_SHADER_CACHE
276   if (device->disk_cache)
277      disk_cache_destroy(device->disk_cache);
278#else
279   assert(device->disk_cache == NULL);
280#endif
281}
282
283static void
284physical_device_finish(struct v3dv_physical_device *device)
285{
286   v3dv_wsi_finish(device);
287   v3dv_physical_device_free_disk_cache(device);
288   v3d_compiler_free(device->compiler);
289
290   util_sparse_array_finish(&device->bo_map);
291
292   close(device->render_fd);
293   if (device->display_fd >= 0)
294      close(device->display_fd);
295   if (device->master_fd >= 0)
296      close(device->master_fd);
297
298   free(device->name);
299
300#if using_v3d_simulator
301   v3d_simulator_destroy(device->sim_file);
302#endif
303
304   vk_physical_device_finish(&device->vk);
305   mtx_destroy(&device->mutex);
306}
307
308VKAPI_ATTR void VKAPI_CALL
309v3dv_DestroyInstance(VkInstance _instance,
310                     const VkAllocationCallbacks *pAllocator)
311{
312   V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);
313
314   if (!instance)
315      return;
316
317   if (instance->physicalDeviceCount > 0) {
318      /* We support at most one physical device. */
319      assert(instance->physicalDeviceCount == 1);
320      physical_device_finish(&instance->physicalDevice);
321   }
322
323   VG(VALGRIND_DESTROY_MEMPOOL(instance));
324
325   vk_instance_finish(&instance->vk);
326   vk_free(&instance->vk.alloc, instance);
327}
328
329static uint64_t
330compute_heap_size()
331{
332#if !using_v3d_simulator
333   /* Query the total ram from the system */
334   struct sysinfo info;
335   sysinfo(&info);
336
337   uint64_t total_ram = (uint64_t)info.totalram * (uint64_t)info.mem_unit;
338#else
339   uint64_t total_ram = (uint64_t) v3d_simulator_get_mem_size();
340#endif
341
342   /* We don't want to burn too much ram with the GPU.  If the user has 4GiB
343    * or less, we use at most half.  If they have more than 4GiB, we use 3/4.
344    */
345   uint64_t available_ram;
346   if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
347      available_ram = total_ram / 2;
348   else
349      available_ram = total_ram * 3 / 4;
350
351   return available_ram;
352}
353
354#if !using_v3d_simulator
355#ifdef VK_USE_PLATFORM_XCB_KHR
356static int
357create_display_fd_xcb(VkIcdSurfaceBase *surface)
358{
359   int fd = -1;
360
361   xcb_connection_t *conn;
362   xcb_dri3_open_reply_t *reply = NULL;
363   if (surface) {
364      if (surface->platform == VK_ICD_WSI_PLATFORM_XLIB)
365         conn = XGetXCBConnection(((VkIcdSurfaceXlib *)surface)->dpy);
366      else
367         conn = ((VkIcdSurfaceXcb *)surface)->connection;
368   } else {
369      conn = xcb_connect(NULL, NULL);
370   }
371
372   if (xcb_connection_has_error(conn))
373      goto finish;
374
375   const xcb_setup_t *setup = xcb_get_setup(conn);
376   xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
377   xcb_screen_t *screen = iter.data;
378
379   xcb_dri3_open_cookie_t cookie;
380   cookie = xcb_dri3_open(conn, screen->root, None);
381   reply = xcb_dri3_open_reply(conn, cookie, NULL);
382   if (!reply)
383      goto finish;
384
385   if (reply->nfd != 1)
386      goto finish;
387
388   fd = xcb_dri3_open_reply_fds(conn, reply)[0];
389   fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
390
391finish:
392   if (!surface)
393      xcb_disconnect(conn);
394   if (reply)
395      free(reply);
396
397   return fd;
398}
399#endif
400
401#ifdef VK_USE_PLATFORM_WAYLAND_KHR
402struct v3dv_wayland_info {
403   struct wl_drm *wl_drm;
404   int fd;
405   bool is_set;
406   bool authenticated;
407};
408
409static void
410v3dv_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
411{
412   struct v3dv_wayland_info *info = data;
413   info->fd = open(device, O_RDWR | O_CLOEXEC);
414   info->is_set = info->fd != -1;
415   if (!info->is_set) {
416      fprintf(stderr, "v3dv_drm_handle_device: could not open %s (%s)\n",
417              device, strerror(errno));
418      return;
419   }
420
421   drm_magic_t magic;
422   if (drmGetMagic(info->fd, &magic)) {
423      fprintf(stderr, "v3dv_drm_handle_device: drmGetMagic failed\n");
424      close(info->fd);
425      info->fd = -1;
426      info->is_set = false;
427      return;
428   }
429   wl_drm_authenticate(info->wl_drm, magic);
430}
431
432static void
433v3dv_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
434{
435}
436
437static void
438v3dv_drm_handle_authenticated(void *data, struct wl_drm *drm)
439{
440   struct v3dv_wayland_info *info = data;
441   info->authenticated = true;
442}
443
444static void
445v3dv_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
446{
447}
448
449struct wl_drm_listener v3dv_drm_listener = {
450   .device = v3dv_drm_handle_device,
451   .format = v3dv_drm_handle_format,
452   .authenticated = v3dv_drm_handle_authenticated,
453   .capabilities = v3dv_drm_handle_capabilities
454};
455
456static void
457v3dv_registry_global(void *data,
458                     struct wl_registry *registry,
459                     uint32_t name,
460                     const char *interface,
461                     uint32_t version)
462{
463   struct v3dv_wayland_info *info = data;
464   if (strcmp(interface, "wl_drm") == 0) {
465      info->wl_drm = wl_registry_bind(registry, name, &wl_drm_interface,
466                                      MIN2(version, 2));
467      wl_drm_add_listener(info->wl_drm, &v3dv_drm_listener, data);
468   };
469}
470
471static void
472v3dv_registry_global_remove_cb(void *data,
473                               struct wl_registry *registry,
474                               uint32_t name)
475{
476}
477
478static int
479create_display_fd_wayland(VkIcdSurfaceBase *surface)
480{
481   struct wl_display *display;
482   struct wl_registry *registry = NULL;
483
484   struct v3dv_wayland_info info = {
485      .wl_drm = NULL,
486      .fd = -1,
487      .is_set = false,
488      .authenticated = false
489   };
490
491   if (surface)
492      display = ((VkIcdSurfaceWayland *) surface)->display;
493   else
494      display = wl_display_connect(NULL);
495
496   if (!display)
497      return -1;
498
499   registry = wl_display_get_registry(display);
500   if (!registry) {
501      if (!surface)
502         wl_display_disconnect(display);
503      return -1;
504   }
505
506   static const struct wl_registry_listener registry_listener = {
507      v3dv_registry_global,
508      v3dv_registry_global_remove_cb
509   };
510   wl_registry_add_listener(registry, &registry_listener, &info);
511
512   wl_display_roundtrip(display); /* For the registry advertisement */
513   wl_display_roundtrip(display); /* For the DRM device event */
514   wl_display_roundtrip(display); /* For the authentication event */
515
516   wl_drm_destroy(info.wl_drm);
517   wl_registry_destroy(registry);
518
519   if (!surface)
520      wl_display_disconnect(display);
521
522   if (!info.is_set)
523      return -1;
524
525   if (!info.authenticated)
526      return -1;
527
528   return info.fd;
529}
530#endif
531
532/* Acquire an authenticated display fd without a surface reference. This is the
533 * case where the application is making WSI allocations outside the Vulkan
534 * swapchain context (only Zink, for now). Since we lack information about the
535 * underlying surface we just try our best to figure out the correct display
536 * and platform to use. It should work in most cases.
537 */
538static void
539acquire_display_device_no_surface(struct v3dv_instance *instance,
540                                  struct v3dv_physical_device *pdevice)
541{
542#ifdef VK_USE_PLATFORM_WAYLAND_KHR
543   pdevice->display_fd = create_display_fd_wayland(NULL);
544#endif
545
546#ifdef VK_USE_PLATFORM_XCB_KHR
547   if (pdevice->display_fd == -1)
548      pdevice->display_fd = create_display_fd_xcb(NULL);
549#endif
550
551#ifdef VK_USE_PLATFORM_DISPLAY_KHR
552   if (pdevice->display_fd == - 1 && pdevice->master_fd >= 0)
553      pdevice->display_fd = dup(pdevice->master_fd);
554#endif
555}
556
557/* Acquire an authenticated display fd from the surface. This is the regular
558 * case where the application is using swapchains to create WSI allocations.
559 * In this case we use the surface information to figure out the correct
560 * display and platform combination.
561 */
562static void
563acquire_display_device_surface(struct v3dv_instance *instance,
564                               struct v3dv_physical_device *pdevice,
565                               VkIcdSurfaceBase *surface)
566{
567   /* Mesa will set both of VK_USE_PLATFORM_{XCB,XLIB} when building with
568    * platform X11, so only check for XCB and rely on XCB to get an
569    * authenticated device also for Xlib.
570    */
571#ifdef VK_USE_PLATFORM_XCB_KHR
572   if (surface->platform == VK_ICD_WSI_PLATFORM_XCB ||
573       surface->platform == VK_ICD_WSI_PLATFORM_XLIB) {
574      pdevice->display_fd = create_display_fd_xcb(surface);
575   }
576#endif
577
578#ifdef VK_USE_PLATFORM_WAYLAND_KHR
579   if (surface->platform == VK_ICD_WSI_PLATFORM_WAYLAND)
580      pdevice->display_fd = create_display_fd_wayland(surface);
581#endif
582
583#ifdef VK_USE_PLATFORM_DISPLAY_KHR
584   if (surface->platform == VK_ICD_WSI_PLATFORM_DISPLAY &&
585       pdevice->master_fd >= 0) {
586      pdevice->display_fd = dup(pdevice->master_fd);
587   }
588#endif
589}
590#endif /* !using_v3d_simulator */
591
592/* Attempts to get an authenticated display fd from the display server that
593 * we can use to allocate BOs for presentable images.
594 */
595VkResult
596v3dv_physical_device_acquire_display(struct v3dv_instance *instance,
597                                     struct v3dv_physical_device *pdevice,
598                                     VkIcdSurfaceBase *surface)
599{
600   VkResult result = VK_SUCCESS;
601   mtx_lock(&pdevice->mutex);
602
603   if (pdevice->display_fd != -1)
604      goto done;
605
606   /* When running on the simulator we do everything on a single render node so
607    * we don't need to get an authenticated display fd from the display server.
608    */
609#if !using_v3d_simulator
610   if (surface)
611      acquire_display_device_surface(instance, pdevice, surface);
612   else
613      acquire_display_device_no_surface(instance, pdevice);
614
615   if (pdevice->display_fd == -1)
616      result = VK_ERROR_INITIALIZATION_FAILED;
617#endif
618
619done:
620   mtx_unlock(&pdevice->mutex);
621   return result;
622}
623
624static bool
625v3d_has_feature(struct v3dv_physical_device *device, enum drm_v3d_param feature)
626{
627   struct drm_v3d_get_param p = {
628      .param = feature,
629   };
630   if (v3dv_ioctl(device->render_fd, DRM_IOCTL_V3D_GET_PARAM, &p) != 0)
631      return false;
632   return p.value;
633}
634
635static bool
636device_has_expected_features(struct v3dv_physical_device *device)
637{
638   return v3d_has_feature(device, DRM_V3D_PARAM_SUPPORTS_TFU) &&
639          v3d_has_feature(device, DRM_V3D_PARAM_SUPPORTS_CSD) &&
640          v3d_has_feature(device, DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH);
641}
642
643
644static VkResult
645init_uuids(struct v3dv_physical_device *device)
646{
647   const struct build_id_note *note =
648      build_id_find_nhdr_for_addr(init_uuids);
649   if (!note) {
650      return vk_errorf(device->vk.instance,
651                       VK_ERROR_INITIALIZATION_FAILED,
652                       "Failed to find build-id");
653   }
654
655   unsigned build_id_len = build_id_length(note);
656   if (build_id_len < 20) {
657      return vk_errorf(device->vk.instance,
658                       VK_ERROR_INITIALIZATION_FAILED,
659                       "build-id too short.  It needs to be a SHA");
660   }
661
662   memcpy(device->driver_build_sha1, build_id_data(note), 20);
663
664   uint32_t vendor_id = v3dv_physical_device_vendor_id(device);
665   uint32_t device_id = v3dv_physical_device_device_id(device);
666
667   struct mesa_sha1 sha1_ctx;
668   uint8_t sha1[20];
669   STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1));
670
671   /* The pipeline cache UUID is used for determining when a pipeline cache is
672    * invalid.  It needs both a driver build and the PCI ID of the device.
673    */
674   _mesa_sha1_init(&sha1_ctx);
675   _mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len);
676   _mesa_sha1_update(&sha1_ctx, &device_id, sizeof(device_id));
677   _mesa_sha1_final(&sha1_ctx, sha1);
678   memcpy(device->pipeline_cache_uuid, sha1, VK_UUID_SIZE);
679
680   /* The driver UUID is used for determining sharability of images and memory
681    * between two Vulkan instances in separate processes.  People who want to
682    * share memory need to also check the device UUID (below) so all this
683    * needs to be is the build-id.
684    */
685   memcpy(device->driver_uuid, build_id_data(note), VK_UUID_SIZE);
686
687   /* The device UUID uniquely identifies the given device within the machine.
688    * Since we never have more than one device, this doesn't need to be a real
689    * UUID.
690    */
691   _mesa_sha1_init(&sha1_ctx);
692   _mesa_sha1_update(&sha1_ctx, &vendor_id, sizeof(vendor_id));
693   _mesa_sha1_update(&sha1_ctx, &device_id, sizeof(device_id));
694   _mesa_sha1_final(&sha1_ctx, sha1);
695   memcpy(device->device_uuid, sha1, VK_UUID_SIZE);
696
697   return VK_SUCCESS;
698}
699
700static void
701v3dv_physical_device_init_disk_cache(struct v3dv_physical_device *device)
702{
703#ifdef ENABLE_SHADER_CACHE
704   char timestamp[41];
705   _mesa_sha1_format(timestamp, device->driver_build_sha1);
706
707   assert(device->name);
708   device->disk_cache = disk_cache_create(device->name, timestamp, 0);
709#else
710   device->disk_cache = NULL;
711#endif
712}
713
714static VkResult
715physical_device_init(struct v3dv_physical_device *device,
716                     struct v3dv_instance *instance,
717                     drmDevicePtr drm_render_device,
718                     drmDevicePtr drm_primary_device)
719{
720   VkResult result = VK_SUCCESS;
721   int32_t master_fd = -1;
722   int32_t render_fd = -1;
723
724   struct vk_physical_device_dispatch_table dispatch_table;
725   vk_physical_device_dispatch_table_from_entrypoints
726      (&dispatch_table, &v3dv_physical_device_entrypoints, true);
727   vk_physical_device_dispatch_table_from_entrypoints(
728      &dispatch_table, &wsi_physical_device_entrypoints, false);
729
730   result = vk_physical_device_init(&device->vk, &instance->vk, NULL,
731                                    &dispatch_table);
732
733   if (result != VK_SUCCESS)
734      goto fail;
735
736   assert(drm_render_device);
737   const char *path = drm_render_device->nodes[DRM_NODE_RENDER];
738   render_fd = open(path, O_RDWR | O_CLOEXEC);
739   if (render_fd < 0) {
740      fprintf(stderr, "Opening %s failed: %s\n", path, strerror(errno));
741      result = VK_ERROR_INCOMPATIBLE_DRIVER;
742      goto fail;
743   }
744
745   /* If we are running on VK_KHR_display we need to acquire the master
746    * display device now for the v3dv_wsi_init() call below. For anything else
747    * we postpone that until a swapchain is created.
748    */
749
750   const char *primary_path;
751#if !using_v3d_simulator
752   if (drm_primary_device)
753      primary_path = drm_primary_device->nodes[DRM_NODE_PRIMARY];
754   else
755      primary_path = NULL;
756#else
757   primary_path = drm_render_device->nodes[DRM_NODE_PRIMARY];
758#endif
759
760   struct stat primary_stat = {0}, render_stat = {0};
761
762   device->has_primary = primary_path;
763   if (device->has_primary) {
764      if (stat(primary_path, &primary_stat) != 0) {
765         result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
766                            "failed to stat DRM primary node %s",
767                            primary_path);
768         goto fail;
769      }
770
771      device->primary_devid = primary_stat.st_rdev;
772   }
773
774   if (fstat(render_fd, &render_stat) != 0) {
775      result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
776                         "failed to stat DRM render node %s",
777                         path);
778      goto fail;
779   }
780   device->has_render = true;
781   device->render_devid = render_stat.st_rdev;
782
783#if using_v3d_simulator
784   device->device_id = drm_render_device->deviceinfo.pci->device_id;
785#endif
786
787   if (instance->vk.enabled_extensions.KHR_display) {
788#if !using_v3d_simulator
789      /* Open the primary node on the vc4 display device */
790      assert(drm_primary_device);
791      master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
792#else
793      /* There is only one device with primary and render nodes.
794       * Open its primary node.
795       */
796      master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
797#endif
798   }
799
800#if using_v3d_simulator
801   device->sim_file = v3d_simulator_init(render_fd);
802#endif
803
804   device->render_fd = render_fd;    /* The v3d render node  */
805   device->display_fd = -1;          /* Authenticated vc4 primary node */
806   device->master_fd = master_fd;    /* Master vc4 primary node */
807
808   if (!v3d_get_device_info(device->render_fd, &device->devinfo, &v3dv_ioctl)) {
809      result = VK_ERROR_INCOMPATIBLE_DRIVER;
810      goto fail;
811   }
812
813   if (device->devinfo.ver < 42) {
814      result = VK_ERROR_INCOMPATIBLE_DRIVER;
815      goto fail;
816   }
817
818   if (!device_has_expected_features(device)) {
819      result = VK_ERROR_INCOMPATIBLE_DRIVER;
820      goto fail;
821   }
822
823   device->caps.multisync =
824      v3d_has_feature(device, DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT);
825
826   device->caps.perfmon =
827      v3d_has_feature(device, DRM_V3D_PARAM_SUPPORTS_PERFMON);
828
829   result = init_uuids(device);
830   if (result != VK_SUCCESS)
831      goto fail;
832
833   device->compiler = v3d_compiler_init(&device->devinfo,
834                                        MAX_INLINE_UNIFORM_BUFFERS);
835   device->next_program_id = 0;
836
837   ASSERTED int len =
838      asprintf(&device->name, "V3D %d.%d",
839               device->devinfo.ver / 10, device->devinfo.ver % 10);
840   assert(len != -1);
841
842   v3dv_physical_device_init_disk_cache(device);
843
844   /* Setup available memory heaps and types */
845   VkPhysicalDeviceMemoryProperties *mem = &device->memory;
846   mem->memoryHeapCount = 1;
847   mem->memoryHeaps[0].size = compute_heap_size();
848   mem->memoryHeaps[0].flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
849
850   /* This is the only combination required by the spec */
851   mem->memoryTypeCount = 1;
852   mem->memoryTypes[0].propertyFlags =
853      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
854      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
855      VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
856   mem->memoryTypes[0].heapIndex = 0;
857
858   /* Initialize sparse array for refcounting imported BOs */
859   util_sparse_array_init(&device->bo_map, sizeof(struct v3dv_bo), 512);
860
861   device->options.merge_jobs = !(V3D_DEBUG & V3D_DEBUG_NO_MERGE_JOBS);
862
863   device->drm_syncobj_type = vk_drm_syncobj_get_type(device->render_fd);
864
865   /* We don't support timelines in the uAPI yet and we don't want it getting
866    * suddenly turned on by vk_drm_syncobj_get_type() without us adding v3dv
867    * code for it first.
868    */
869   device->drm_syncobj_type.features &= ~VK_SYNC_FEATURE_TIMELINE;
870
871#ifndef ANDROID
872   /* Sync file export is incompatible with the current model of execution
873    * where some jobs may run on the CPU.  There are CTS tests which do the
874    * following:
875    *
876    *  1. Create a command buffer with a vkCmdWaitEvents()
877    *  2. Submit the command buffer
878    *  3. vkGetSemaphoreFdKHR() to try to get a sync_file
879    *  4. vkSetEvent()
880    *
881    * This deadlocks because we have to wait for the syncobj to get a real
882    * fence in vkGetSemaphoreFdKHR() which only happens after all the work
883    * from the command buffer is complete which only happens after
884    * vkSetEvent().  No amount of CPU threading in userspace will ever fix
885    * this.  Sadly, this is pretty explicitly allowed by the Vulkan spec:
886    *
887    *    VUID-vkCmdWaitEvents-pEvents-01163
888    *
889    *    "If pEvents includes one or more events that will be signaled by
890    *    vkSetEvent after commandBuffer has been submitted to a queue, then
891    *    vkCmdWaitEvents must not be called inside a render pass instance"
892    *
893    * Disable sync file support for now.
894    */
895   device->drm_syncobj_type.import_sync_file = NULL;
896   device->drm_syncobj_type.export_sync_file = NULL;
897#endif
898
899   /* Multiwait is required for emulated timeline semaphores and is supported
900    * by the v3d kernel interface.
901    */
902   device->drm_syncobj_type.features |= VK_SYNC_FEATURE_GPU_MULTI_WAIT;
903
904   device->sync_timeline_type =
905      vk_sync_timeline_get_type(&device->drm_syncobj_type);
906
907   device->sync_types[0] = &device->drm_syncobj_type;
908   device->sync_types[1] = &device->sync_timeline_type.sync;
909   device->sync_types[2] = NULL;
910   device->vk.supported_sync_types = device->sync_types;
911
912   result = v3dv_wsi_init(device);
913   if (result != VK_SUCCESS) {
914      vk_error(instance, result);
915      goto fail;
916   }
917
918   get_device_extensions(device, &device->vk.supported_extensions);
919
920   mtx_init(&device->mutex, mtx_plain);
921
922   return VK_SUCCESS;
923
924fail:
925   vk_physical_device_finish(&device->vk);
926
927   if (render_fd >= 0)
928      close(render_fd);
929   if (master_fd >= 0)
930      close(master_fd);
931
932   return result;
933}
934
935static VkResult
936enumerate_devices(struct v3dv_instance *instance)
937{
938   /* TODO: Check for more devices? */
939   drmDevicePtr devices[8];
940   VkResult result = VK_ERROR_INCOMPATIBLE_DRIVER;
941   int max_devices;
942
943   instance->physicalDeviceCount = 0;
944
945   max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
946   if (max_devices < 1)
947      return VK_ERROR_INCOMPATIBLE_DRIVER;
948
949#if !using_v3d_simulator
950   int32_t v3d_idx = -1;
951   int32_t vc4_idx = -1;
952#endif
953   for (unsigned i = 0; i < (unsigned)max_devices; i++) {
954#if using_v3d_simulator
955      /* In the simulator, we look for an Intel/AMD render node */
956      const int required_nodes = (1 << DRM_NODE_RENDER) | (1 << DRM_NODE_PRIMARY);
957      if ((devices[i]->available_nodes & required_nodes) == required_nodes &&
958           devices[i]->bustype == DRM_BUS_PCI &&
959          (devices[i]->deviceinfo.pci->vendor_id == 0x8086 ||
960           devices[i]->deviceinfo.pci->vendor_id == 0x1002)) {
961         result = physical_device_init(&instance->physicalDevice, instance,
962                                       devices[i], NULL);
963         if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
964            break;
965      }
966#else
967      /* On actual hardware, we should have a render node (v3d)
968       * and a primary node (vc4). We will need to use the primary
969       * to allocate WSI buffers and share them with the render node
970       * via prime, but that is a privileged operation so we need the
971       * primary node to be authenticated, and for that we need the
972       * display server to provide the device fd (with DRI3), so we
973       * here we only check that the device is present but we don't
974       * try to open it.
975       */
976      if (devices[i]->bustype != DRM_BUS_PLATFORM)
977         continue;
978
979      if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER) {
980         char **compat = devices[i]->deviceinfo.platform->compatible;
981         while (*compat) {
982            if (strncmp(*compat, "brcm,2711-v3d", 13) == 0) {
983               v3d_idx = i;
984               break;
985            }
986            compat++;
987         }
988      } else if (devices[i]->available_nodes & 1 << DRM_NODE_PRIMARY) {
989         char **compat = devices[i]->deviceinfo.platform->compatible;
990         while (*compat) {
991            if (strncmp(*compat, "brcm,bcm2711-vc5", 16) == 0 ||
992                strncmp(*compat, "brcm,bcm2835-vc4", 16) == 0 ) {
993               vc4_idx = i;
994               break;
995            }
996            compat++;
997         }
998      }
999#endif
1000   }
1001
1002#if !using_v3d_simulator
1003   if (v3d_idx == -1 || vc4_idx == -1)
1004      result = VK_ERROR_INCOMPATIBLE_DRIVER;
1005   else
1006      result = physical_device_init(&instance->physicalDevice, instance,
1007                                    devices[v3d_idx], devices[vc4_idx]);
1008#endif
1009
1010   drmFreeDevices(devices, max_devices);
1011
1012   if (result == VK_SUCCESS)
1013      instance->physicalDeviceCount = 1;
1014
1015   return result;
1016}
1017
1018static VkResult
1019instance_ensure_physical_device(struct v3dv_instance *instance)
1020{
1021   if (instance->physicalDeviceCount < 0) {
1022      VkResult result = enumerate_devices(instance);
1023      if (result != VK_SUCCESS &&
1024          result != VK_ERROR_INCOMPATIBLE_DRIVER)
1025         return result;
1026   }
1027
1028   return VK_SUCCESS;
1029}
1030
1031VKAPI_ATTR VkResult  VKAPI_CALL
1032v3dv_EnumeratePhysicalDevices(VkInstance _instance,
1033                              uint32_t *pPhysicalDeviceCount,
1034                              VkPhysicalDevice *pPhysicalDevices)
1035{
1036   V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);
1037   VK_OUTARRAY_MAKE_TYPED(VkPhysicalDevice, out,
1038                          pPhysicalDevices, pPhysicalDeviceCount);
1039
1040   VkResult result = instance_ensure_physical_device(instance);
1041   if (result != VK_SUCCESS)
1042      return result;
1043
1044   if (instance->physicalDeviceCount == 0)
1045      return VK_SUCCESS;
1046
1047   assert(instance->physicalDeviceCount == 1);
1048   vk_outarray_append_typed(VkPhysicalDevice, &out, i) {
1049      *i = v3dv_physical_device_to_handle(&instance->physicalDevice);
1050   }
1051
1052   return vk_outarray_status(&out);
1053}
1054
1055VKAPI_ATTR VkResult VKAPI_CALL
1056v3dv_EnumeratePhysicalDeviceGroups(
1057    VkInstance _instance,
1058    uint32_t *pPhysicalDeviceGroupCount,
1059    VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
1060{
1061   V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);
1062   VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceGroupProperties, out,
1063                          pPhysicalDeviceGroupProperties,
1064                          pPhysicalDeviceGroupCount);
1065
1066   VkResult result = instance_ensure_physical_device(instance);
1067   if (result != VK_SUCCESS)
1068      return result;
1069
1070   assert(instance->physicalDeviceCount == 1);
1071
1072   vk_outarray_append_typed(VkPhysicalDeviceGroupProperties, &out, p) {
1073      p->physicalDeviceCount = 1;
1074      memset(p->physicalDevices, 0, sizeof(p->physicalDevices));
1075      p->physicalDevices[0] =
1076         v3dv_physical_device_to_handle(&instance->physicalDevice);
1077      p->subsetAllocation = false;
1078
1079      vk_foreach_struct(ext, p->pNext)
1080         v3dv_debug_ignored_stype(ext->sType);
1081   }
1082
1083   return vk_outarray_status(&out);
1084}
1085
1086VKAPI_ATTR void VKAPI_CALL
1087v3dv_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
1088                               VkPhysicalDeviceFeatures *pFeatures)
1089{
1090   memset(pFeatures, 0, sizeof(*pFeatures));
1091
1092   *pFeatures = (VkPhysicalDeviceFeatures) {
1093      .robustBufferAccess = true, /* This feature is mandatory */
1094      .fullDrawIndexUint32 = false, /* Only available since V3D 4.4.9.1 */
1095      .imageCubeArray = true,
1096      .independentBlend = true,
1097      .geometryShader = true,
1098      .tessellationShader = false,
1099      .sampleRateShading = true,
1100      .dualSrcBlend = false,
1101      .logicOp = true,
1102      .multiDrawIndirect = false,
1103      .drawIndirectFirstInstance = true,
1104      .depthClamp = false, /* Only available since V3D 4.5.1.1 */
1105      .depthBiasClamp = true,
1106      .fillModeNonSolid = true,
1107      .depthBounds = false, /* Only available since V3D 4.3.16.2 */
1108      .wideLines = true,
1109      .largePoints = true,
1110      .alphaToOne = true,
1111      .multiViewport = false,
1112      .samplerAnisotropy = true,
1113      .textureCompressionETC2 = true,
1114      .textureCompressionASTC_LDR = true,
1115      /* Note that textureCompressionBC requires that the driver support all
1116       * the BC formats. V3D 4.2 only support the BC1-3, so we can't claim
1117       * that we support it.
1118       */
1119      .textureCompressionBC = false,
1120      .occlusionQueryPrecise = true,
1121      .pipelineStatisticsQuery = false,
1122      .vertexPipelineStoresAndAtomics = true,
1123      .fragmentStoresAndAtomics = true,
1124      .shaderTessellationAndGeometryPointSize = true,
1125      .shaderImageGatherExtended = false,
1126      .shaderStorageImageExtendedFormats = true,
1127      .shaderStorageImageMultisample = false,
1128      .shaderStorageImageReadWithoutFormat = false,
1129      .shaderStorageImageWriteWithoutFormat = false,
1130      .shaderUniformBufferArrayDynamicIndexing = false,
1131      .shaderSampledImageArrayDynamicIndexing = false,
1132      .shaderStorageBufferArrayDynamicIndexing = false,
1133      .shaderStorageImageArrayDynamicIndexing = false,
1134      .shaderClipDistance = true,
1135      .shaderCullDistance = false,
1136      .shaderFloat64 = false,
1137      .shaderInt64 = false,
1138      .shaderInt16 = false,
1139      .shaderResourceResidency = false,
1140      .shaderResourceMinLod = false,
1141      .sparseBinding = false,
1142      .sparseResidencyBuffer = false,
1143      .sparseResidencyImage2D = false,
1144      .sparseResidencyImage3D = false,
1145      .sparseResidency2Samples = false,
1146      .sparseResidency4Samples = false,
1147      .sparseResidency8Samples = false,
1148      .sparseResidency16Samples = false,
1149      .sparseResidencyAliased = false,
1150      .variableMultisampleRate = false,
1151      .inheritedQueries = true,
1152   };
1153}
1154
1155VKAPI_ATTR void VKAPI_CALL
1156v3dv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
1157                                VkPhysicalDeviceFeatures2 *pFeatures)
1158{
1159   V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice);
1160   v3dv_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
1161
1162   VkPhysicalDeviceVulkan13Features vk13 = {
1163      .inlineUniformBlock  = true,
1164      /* Inline buffers work like push constants, so after their are bound
1165       * some of their contents may be copied into the uniform stream as soon
1166       * as the next draw/dispatch is recorded in the command buffer. This means
1167       * that if the client updates the buffer contents after binding it to
1168       * a command buffer, the next queue submit of that command buffer may
1169       * not use the latest update to the buffer contents, but the data that
1170       * was present in the buffer at the time it was bound to the command
1171       * buffer.
1172       */
1173      .descriptorBindingInlineUniformBlockUpdateAfterBind = false,
1174      .pipelineCreationCacheControl = true,
1175      .privateData = true,
1176   };
1177
1178   VkPhysicalDeviceVulkan12Features vk12 = {
1179      .hostQueryReset = true,
1180      .uniformAndStorageBuffer8BitAccess = true,
1181      .uniformBufferStandardLayout = true,
1182      /* V3D 4.2 wraps TMU vector accesses to 16-byte boundaries, so loads and
1183       * stores of vectors that cross these boundaries would not work correcly
1184       * with scalarBlockLayout and would need to be split into smaller vectors
1185       * (and/or scalars) that don't cross these boundaries. For load/stores
1186       * with dynamic offsets where we can't identify if the offset is
1187       * problematic, we would always have to scalarize. Overall, this would
1188       * not lead to best performance so let's just not support it.
1189       */
1190      .scalarBlockLayout = false,
1191      /* This tells applications 2 things:
1192       *
1193       * 1. If they can select just one aspect for barriers. For us barriers
1194       *    decide if we need to split a job and we don't care if it is only
1195       *    for one of the aspects of the image or both, so we don't really
1196       *    benefit from seeing barriers that select just one aspect.
1197       *
1198       * 2. If they can program different layouts for each aspect. We
1199       *    generally don't care about layouts, so again, we don't get any
1200       *    benefits from this to limit the scope of image layout transitions.
1201       *
1202       * Still, Vulkan 1.2 requires this feature to be supported so we
1203       * advertise it even though we don't really take advantage of it.
1204       */
1205      .separateDepthStencilLayouts = true,
1206      .storageBuffer8BitAccess = true,
1207      .storagePushConstant8 = true,
1208      .imagelessFramebuffer = true,
1209      .timelineSemaphore = true,
1210
1211      .samplerMirrorClampToEdge = true,
1212
1213      /* These are mandatory by Vulkan 1.2, however, we don't support any of
1214       * the optional features affected by them (non 32-bit types for
1215       * shaderSubgroupExtendedTypes and additional subgroup ballot for
1216       * subgroupBroadcastDynamicId), so in practice setting them to true
1217       * doesn't have any implications for us until we implement any of these
1218       * optional features.
1219       */
1220      .shaderSubgroupExtendedTypes = true,
1221      .subgroupBroadcastDynamicId = true,
1222
1223      .vulkanMemoryModel = true,
1224      .vulkanMemoryModelDeviceScope = true,
1225      .vulkanMemoryModelAvailabilityVisibilityChains = true,
1226
1227      .bufferDeviceAddress = true,
1228      .bufferDeviceAddressCaptureReplay = false,
1229      .bufferDeviceAddressMultiDevice = false,
1230   };
1231
1232   VkPhysicalDeviceVulkan11Features vk11 = {
1233      .storageBuffer16BitAccess = true,
1234      .uniformAndStorageBuffer16BitAccess = true,
1235      .storagePushConstant16 = true,
1236      .storageInputOutput16 = false,
1237      .multiview = true,
1238      .multiviewGeometryShader = false,
1239      .multiviewTessellationShader = false,
1240      .variablePointersStorageBuffer = true,
1241      /* FIXME: this needs support for non-constant index on UBO/SSBO */
1242      .variablePointers = false,
1243      .protectedMemory = false,
1244      .samplerYcbcrConversion = false,
1245      .shaderDrawParameters = false,
1246   };
1247
1248   vk_foreach_struct(ext, pFeatures->pNext) {
1249      if (vk_get_physical_device_core_1_1_feature_ext(ext, &vk11))
1250         continue;
1251      if (vk_get_physical_device_core_1_2_feature_ext(ext, &vk12))
1252         continue;
1253      if (vk_get_physical_device_core_1_3_feature_ext(ext, &vk13))
1254         continue;
1255
1256      switch (ext->sType) {
1257      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: {
1258         VkPhysicalDevice4444FormatsFeaturesEXT *features =
1259            (VkPhysicalDevice4444FormatsFeaturesEXT *)ext;
1260         features->formatA4R4G4B4 = true;
1261         features->formatA4B4G4R4 = true;
1262         break;
1263      }
1264
1265      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
1266         VkPhysicalDeviceCustomBorderColorFeaturesEXT *features =
1267            (VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext;
1268         features->customBorderColors = true;
1269         features->customBorderColorWithoutFormat = false;
1270         break;
1271      }
1272
1273      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {
1274         VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =
1275            (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;
1276         features->indexTypeUint8 = true;
1277         break;
1278      }
1279
1280      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
1281         VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
1282            (VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
1283         features->rectangularLines = true;
1284         features->bresenhamLines = true;
1285         features->smoothLines = false;
1286         features->stippledRectangularLines = false;
1287         features->stippledBresenhamLines = false;
1288         features->stippledSmoothLines = false;
1289         break;
1290      }
1291
1292      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: {
1293          VkPhysicalDeviceColorWriteEnableFeaturesEXT *features = (void *) ext;
1294          features->colorWriteEnable = true;
1295          break;
1296      }
1297
1298      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR: {
1299         VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *features =
1300            (VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *) ext;
1301         features->pipelineExecutableInfo = true;
1302         break;
1303      }
1304
1305      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {
1306         VkPhysicalDeviceProvokingVertexFeaturesEXT *features = (void *) ext;
1307         features->provokingVertexLast = true;
1308         /* FIXME: update when supporting EXT_transform_feedback */
1309         features->transformFeedbackPreservesProvokingVertex = false;
1310         break;
1311      }
1312
1313      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
1314         VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
1315            (void *) ext;
1316         features->vertexAttributeInstanceRateDivisor = true;
1317         features->vertexAttributeInstanceRateZeroDivisor = false;
1318         break;
1319      }
1320
1321      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {
1322         VkPhysicalDevicePerformanceQueryFeaturesKHR *features =
1323            (void *) ext;
1324
1325         features->performanceCounterQueryPools =
1326            physical_device->caps.perfmon;
1327         features->performanceCounterMultipleQueryPools = false;
1328         break;
1329      }
1330
1331      default:
1332         v3dv_debug_ignored_stype(ext->sType);
1333         break;
1334      }
1335   }
1336}
1337
1338VKAPI_ATTR void VKAPI_CALL
1339v3dv_GetDeviceGroupPeerMemoryFeatures(VkDevice device,
1340                                      uint32_t heapIndex,
1341                                      uint32_t localDeviceIndex,
1342                                      uint32_t remoteDeviceIndex,
1343                                      VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
1344{
1345   assert(localDeviceIndex == 0 && remoteDeviceIndex == 0);
1346   *pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT |
1347                          VK_PEER_MEMORY_FEATURE_COPY_DST_BIT |
1348                          VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
1349                          VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
1350}
1351
1352uint32_t
1353v3dv_physical_device_vendor_id(struct v3dv_physical_device *dev)
1354{
1355   return 0x14E4; /* Broadcom */
1356}
1357
1358uint32_t
1359v3dv_physical_device_device_id(struct v3dv_physical_device *dev)
1360{
1361#if using_v3d_simulator
1362   return dev->device_id;
1363#else
1364   switch (dev->devinfo.ver) {
1365   case 42:
1366      return 0xBE485FD3; /* Broadcom deviceID for 2711 */
1367   default:
1368      unreachable("Unsupported V3D version");
1369   }
1370#endif
1371}
1372
1373VKAPI_ATTR void VKAPI_CALL
1374v3dv_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1375                                 VkPhysicalDeviceProperties *pProperties)
1376{
1377   V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
1378
1379   STATIC_ASSERT(MAX_SAMPLED_IMAGES + MAX_STORAGE_IMAGES + MAX_INPUT_ATTACHMENTS
1380                 <= V3D_MAX_TEXTURE_SAMPLERS);
1381   STATIC_ASSERT(MAX_UNIFORM_BUFFERS >= MAX_DYNAMIC_UNIFORM_BUFFERS);
1382   STATIC_ASSERT(MAX_STORAGE_BUFFERS >= MAX_DYNAMIC_STORAGE_BUFFERS);
1383
1384   const uint32_t page_size = 4096;
1385   const uint32_t mem_size = compute_heap_size();
1386
1387   const uint32_t max_varying_components = 16 * 4;
1388
1389   const float v3d_point_line_granularity = 2.0f / (1 << V3D_COORD_SHIFT);
1390   const uint32_t max_fb_size = V3D_MAX_IMAGE_DIMENSION;
1391
1392   const VkSampleCountFlags supported_sample_counts =
1393      VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
1394
1395   struct timespec clock_res;
1396   clock_getres(CLOCK_MONOTONIC, &clock_res);
1397   const float timestamp_period =
1398      clock_res.tv_sec * 1000000000.0f + clock_res.tv_nsec;
1399
1400   /* FIXME: this will probably require an in-depth review */
1401   VkPhysicalDeviceLimits limits = {
1402      .maxImageDimension1D                      = V3D_MAX_IMAGE_DIMENSION,
1403      .maxImageDimension2D                      = V3D_MAX_IMAGE_DIMENSION,
1404      .maxImageDimension3D                      = V3D_MAX_IMAGE_DIMENSION,
1405      .maxImageDimensionCube                    = V3D_MAX_IMAGE_DIMENSION,
1406      .maxImageArrayLayers                      = V3D_MAX_ARRAY_LAYERS,
1407      .maxTexelBufferElements                   = (1ul << 28),
1408      .maxUniformBufferRange                    = V3D_MAX_BUFFER_RANGE,
1409      .maxStorageBufferRange                    = V3D_MAX_BUFFER_RANGE,
1410      .maxPushConstantsSize                     = MAX_PUSH_CONSTANTS_SIZE,
1411      .maxMemoryAllocationCount                 = mem_size / page_size,
1412      .maxSamplerAllocationCount                = 64 * 1024,
1413      .bufferImageGranularity                   = V3D_NON_COHERENT_ATOM_SIZE,
1414      .sparseAddressSpaceSize                   = 0,
1415      .maxBoundDescriptorSets                   = MAX_SETS,
1416      .maxPerStageDescriptorSamplers            = V3D_MAX_TEXTURE_SAMPLERS,
1417      .maxPerStageDescriptorUniformBuffers      = MAX_UNIFORM_BUFFERS,
1418      .maxPerStageDescriptorStorageBuffers      = MAX_STORAGE_BUFFERS,
1419      .maxPerStageDescriptorSampledImages       = MAX_SAMPLED_IMAGES,
1420      .maxPerStageDescriptorStorageImages       = MAX_STORAGE_IMAGES,
1421      .maxPerStageDescriptorInputAttachments    = MAX_INPUT_ATTACHMENTS,
1422      .maxPerStageResources                     = 128,
1423
1424      /* Some of these limits are multiplied by 6 because they need to
1425       * include all possible shader stages (even if not supported). See
1426       * 'Required Limits' table in the Vulkan spec.
1427       */
1428      .maxDescriptorSetSamplers                 = 6 * V3D_MAX_TEXTURE_SAMPLERS,
1429      .maxDescriptorSetUniformBuffers           = 6 * MAX_UNIFORM_BUFFERS,
1430      .maxDescriptorSetUniformBuffersDynamic    = MAX_DYNAMIC_UNIFORM_BUFFERS,
1431      .maxDescriptorSetStorageBuffers           = 6 * MAX_STORAGE_BUFFERS,
1432      .maxDescriptorSetStorageBuffersDynamic    = MAX_DYNAMIC_STORAGE_BUFFERS,
1433      .maxDescriptorSetSampledImages            = 6 * MAX_SAMPLED_IMAGES,
1434      .maxDescriptorSetStorageImages            = 6 * MAX_STORAGE_IMAGES,
1435      .maxDescriptorSetInputAttachments         = MAX_INPUT_ATTACHMENTS,
1436
1437      /* Vertex limits */
1438      .maxVertexInputAttributes                 = MAX_VERTEX_ATTRIBS,
1439      .maxVertexInputBindings                   = MAX_VBS,
1440      .maxVertexInputAttributeOffset            = 0xffffffff,
1441      .maxVertexInputBindingStride              = 0xffffffff,
1442      .maxVertexOutputComponents                = max_varying_components,
1443
1444      /* Tessellation limits */
1445      .maxTessellationGenerationLevel           = 0,
1446      .maxTessellationPatchSize                 = 0,
1447      .maxTessellationControlPerVertexInputComponents = 0,
1448      .maxTessellationControlPerVertexOutputComponents = 0,
1449      .maxTessellationControlPerPatchOutputComponents = 0,
1450      .maxTessellationControlTotalOutputComponents = 0,
1451      .maxTessellationEvaluationInputComponents = 0,
1452      .maxTessellationEvaluationOutputComponents = 0,
1453
1454      /* Geometry limits */
1455      .maxGeometryShaderInvocations             = 32,
1456      .maxGeometryInputComponents               = 64,
1457      .maxGeometryOutputComponents              = 64,
1458      .maxGeometryOutputVertices                = 256,
1459      .maxGeometryTotalOutputComponents         = 1024,
1460
1461      /* Fragment limits */
1462      .maxFragmentInputComponents               = max_varying_components,
1463      .maxFragmentOutputAttachments             = 4,
1464      .maxFragmentDualSrcAttachments            = 0,
1465      .maxFragmentCombinedOutputResources       = MAX_RENDER_TARGETS +
1466                                                  MAX_STORAGE_BUFFERS +
1467                                                  MAX_STORAGE_IMAGES,
1468
1469      /* Compute limits */
1470      .maxComputeSharedMemorySize               = 16384,
1471      .maxComputeWorkGroupCount                 = { 65535, 65535, 65535 },
1472      .maxComputeWorkGroupInvocations           = 256,
1473      .maxComputeWorkGroupSize                  = { 256, 256, 256 },
1474
1475      .subPixelPrecisionBits                    = V3D_COORD_SHIFT,
1476      .subTexelPrecisionBits                    = 8,
1477      .mipmapPrecisionBits                      = 8,
1478      .maxDrawIndexedIndexValue                 = 0x00ffffff,
1479      .maxDrawIndirectCount                     = 0x7fffffff,
1480      .maxSamplerLodBias                        = 14.0f,
1481      .maxSamplerAnisotropy                     = 16.0f,
1482      .maxViewports                             = MAX_VIEWPORTS,
1483      .maxViewportDimensions                    = { max_fb_size, max_fb_size },
1484      .viewportBoundsRange                      = { -2.0 * max_fb_size,
1485                                                    2.0 * max_fb_size - 1 },
1486      .viewportSubPixelBits                     = 0,
1487      .minMemoryMapAlignment                    = page_size,
1488      .minTexelBufferOffsetAlignment            = V3D_UIFBLOCK_SIZE,
1489      .minUniformBufferOffsetAlignment          = 32,
1490      .minStorageBufferOffsetAlignment          = 32,
1491      .minTexelOffset                           = -8,
1492      .maxTexelOffset                           = 7,
1493      .minTexelGatherOffset                     = -8,
1494      .maxTexelGatherOffset                     = 7,
1495      .minInterpolationOffset                   = -0.5,
1496      .maxInterpolationOffset                   = 0.5,
1497      .subPixelInterpolationOffsetBits          = V3D_COORD_SHIFT,
1498      .maxFramebufferWidth                      = max_fb_size,
1499      .maxFramebufferHeight                     = max_fb_size,
1500      .maxFramebufferLayers                     = 256,
1501      .framebufferColorSampleCounts             = supported_sample_counts,
1502      .framebufferDepthSampleCounts             = supported_sample_counts,
1503      .framebufferStencilSampleCounts           = supported_sample_counts,
1504      .framebufferNoAttachmentsSampleCounts     = supported_sample_counts,
1505      .maxColorAttachments                      = MAX_RENDER_TARGETS,
1506      .sampledImageColorSampleCounts            = supported_sample_counts,
1507      .sampledImageIntegerSampleCounts          = supported_sample_counts,
1508      .sampledImageDepthSampleCounts            = supported_sample_counts,
1509      .sampledImageStencilSampleCounts          = supported_sample_counts,
1510      .storageImageSampleCounts                 = VK_SAMPLE_COUNT_1_BIT,
1511      .maxSampleMaskWords                       = 1,
1512      .timestampComputeAndGraphics              = true,
1513      .timestampPeriod                          = timestamp_period,
1514      .maxClipDistances                         = 8,
1515      .maxCullDistances                         = 0,
1516      .maxCombinedClipAndCullDistances          = 8,
1517      .discreteQueuePriorities                  = 2,
1518      .pointSizeRange                           = { v3d_point_line_granularity,
1519                                                    V3D_MAX_POINT_SIZE },
1520      .lineWidthRange                           = { 1.0f, V3D_MAX_LINE_WIDTH },
1521      .pointSizeGranularity                     = v3d_point_line_granularity,
1522      .lineWidthGranularity                     = v3d_point_line_granularity,
1523      .strictLines                              = true,
1524      .standardSampleLocations                  = false,
1525      .optimalBufferCopyOffsetAlignment         = 32,
1526      .optimalBufferCopyRowPitchAlignment       = 32,
1527      .nonCoherentAtomSize                      = V3D_NON_COHERENT_ATOM_SIZE,
1528   };
1529
1530   *pProperties = (VkPhysicalDeviceProperties) {
1531      .apiVersion = V3DV_API_VERSION,
1532      .driverVersion = vk_get_driver_version(),
1533      .vendorID = v3dv_physical_device_vendor_id(pdevice),
1534      .deviceID = v3dv_physical_device_device_id(pdevice),
1535      .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
1536      .limits = limits,
1537      .sparseProperties = { 0 },
1538   };
1539
1540   snprintf(pProperties->deviceName, sizeof(pProperties->deviceName),
1541            "%s", pdevice->name);
1542   memcpy(pProperties->pipelineCacheUUID,
1543          pdevice->pipeline_cache_uuid, VK_UUID_SIZE);
1544}
1545
1546VKAPI_ATTR void VKAPI_CALL
1547v3dv_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1548                                  VkPhysicalDeviceProperties2 *pProperties)
1549{
1550   V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
1551
1552   v3dv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
1553
1554   /* We don't really have special restrictions for the maximum
1555    * descriptors per set, other than maybe not exceeding the limits
1556    * of addressable memory in a single allocation on either the host
1557    * or the GPU. This will be a much larger limit than any of the
1558    * per-stage limits already available in Vulkan though, so in practice,
1559    * it is not expected to limit anything beyond what is already
1560    * constrained through per-stage limits.
1561    */
1562   const uint32_t max_host_descriptors =
1563      (UINT32_MAX - sizeof(struct v3dv_descriptor_set)) /
1564      sizeof(struct v3dv_descriptor);
1565   const uint32_t max_gpu_descriptors =
1566      (UINT32_MAX / v3dv_X(pdevice, max_descriptor_bo_size)());
1567
1568   VkPhysicalDeviceVulkan13Properties vk13 = {
1569      .maxInlineUniformBlockSize = 4096,
1570      .maxPerStageDescriptorInlineUniformBlocks = MAX_INLINE_UNIFORM_BUFFERS,
1571      .maxDescriptorSetInlineUniformBlocks = MAX_INLINE_UNIFORM_BUFFERS,
1572      .maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks =
1573         MAX_INLINE_UNIFORM_BUFFERS,
1574      .maxDescriptorSetUpdateAfterBindInlineUniformBlocks =
1575         MAX_INLINE_UNIFORM_BUFFERS,
1576   };
1577
1578   VkPhysicalDeviceVulkan12Properties vk12 = {
1579      .driverID = VK_DRIVER_ID_MESA_V3DV,
1580      .conformanceVersion = {
1581         .major = 1,
1582         .minor = 2,
1583         .subminor = 7,
1584         .patch = 1,
1585      },
1586      .supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1587      .supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1588      /* FIXME: if we want to support independentResolveNone then we would
1589       * need to honor attachment load operations on resolve attachments,
1590       * which we currently ignore because the resolve makes them irrelevant,
1591       * as it unconditionally writes all pixels in the render area. However,
1592       * with independentResolveNone, it is possible to have one aspect of a
1593       * D/S resolve attachment stay unresolved, in which case the attachment
1594       * load operation is relevant.
1595       *
1596       * NOTE: implementing attachment load for resolve attachments isn't
1597       * immediately trivial because these attachments are not part of the
1598       * framebuffer and therefore we can't use the same mechanism we use
1599       * for framebuffer attachments. Instead, we should probably have to
1600       * emit a meta operation for that right at the start of the render
1601       * pass (or subpass).
1602       */
1603      .independentResolveNone = false,
1604      .independentResolve = false,
1605      .maxTimelineSemaphoreValueDifference = UINT64_MAX,
1606
1607      .denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
1608      .roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
1609      .shaderSignedZeroInfNanPreserveFloat16 = true,
1610      .shaderSignedZeroInfNanPreserveFloat32 = true,
1611      .shaderSignedZeroInfNanPreserveFloat64 = false,
1612      .shaderDenormPreserveFloat16 = true,
1613      .shaderDenormPreserveFloat32 = true,
1614      .shaderDenormPreserveFloat64 = false,
1615      .shaderDenormFlushToZeroFloat16 = false,
1616      .shaderDenormFlushToZeroFloat32 = false,
1617      .shaderDenormFlushToZeroFloat64 = false,
1618      .shaderRoundingModeRTEFloat16 = true,
1619      .shaderRoundingModeRTEFloat32 = true,
1620      .shaderRoundingModeRTEFloat64 = false,
1621      .shaderRoundingModeRTZFloat16 = false,
1622      .shaderRoundingModeRTZFloat32 = false,
1623      .shaderRoundingModeRTZFloat64 = false,
1624
1625      /* V3D doesn't support min/max filtering */
1626      .filterMinmaxSingleComponentFormats = false,
1627      .filterMinmaxImageComponentMapping = false,
1628
1629      .framebufferIntegerColorSampleCounts =
1630         VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT,
1631   };
1632   memset(vk12.driverName, 0, VK_MAX_DRIVER_NAME_SIZE);
1633   snprintf(vk12.driverName, VK_MAX_DRIVER_NAME_SIZE, "V3DV Mesa");
1634   memset(vk12.driverInfo, 0, VK_MAX_DRIVER_INFO_SIZE);
1635   snprintf(vk12.driverInfo, VK_MAX_DRIVER_INFO_SIZE,
1636            "Mesa " PACKAGE_VERSION MESA_GIT_SHA1);
1637
1638   VkPhysicalDeviceVulkan11Properties vk11 = {
1639      .deviceLUIDValid = false,
1640      .subgroupSize = V3D_CHANNELS,
1641      .subgroupSupportedStages = VK_SHADER_STAGE_COMPUTE_BIT,
1642      .subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT,
1643      .subgroupQuadOperationsInAllStages = false,
1644      .pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES,
1645      .maxMultiviewViewCount = MAX_MULTIVIEW_VIEW_COUNT,
1646      .maxMultiviewInstanceIndex = UINT32_MAX - 1,
1647      .protectedNoFault = false,
1648      .maxPerSetDescriptors = MIN2(max_host_descriptors, max_gpu_descriptors),
1649      /* Minimum required by the spec */
1650      .maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE,
1651   };
1652   memcpy(vk11.deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
1653   memcpy(vk11.driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
1654
1655
1656   vk_foreach_struct(ext, pProperties->pNext) {
1657      if (vk_get_physical_device_core_1_1_property_ext(ext, &vk11))
1658         continue;
1659      if (vk_get_physical_device_core_1_2_property_ext(ext, &vk12))
1660         continue;
1661      if (vk_get_physical_device_core_1_3_property_ext(ext, &vk13))
1662         continue;
1663
1664      switch (ext->sType) {
1665      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
1666         VkPhysicalDeviceCustomBorderColorPropertiesEXT *props =
1667            (VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;
1668         props->maxCustomBorderColorSamplers = V3D_MAX_TEXTURE_SAMPLERS;
1669         break;
1670      }
1671      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {
1672         VkPhysicalDeviceProvokingVertexPropertiesEXT *props =
1673            (VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext;
1674         props->provokingVertexModePerPipeline = true;
1675         /* FIXME: update when supporting EXT_transform_feedback */
1676         props->transformFeedbackPreservesTriangleFanProvokingVertex = false;
1677         break;
1678      }
1679      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
1680         VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
1681            (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
1682         props->maxVertexAttribDivisor = 0xffff;
1683         break;
1684      }
1685      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR : {
1686         VkPhysicalDevicePerformanceQueryPropertiesKHR *props =
1687            (VkPhysicalDevicePerformanceQueryPropertiesKHR *)ext;
1688
1689         props->allowCommandBufferQueryCopies = true;
1690         break;
1691      }
1692      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT: {
1693         VkPhysicalDeviceDrmPropertiesEXT *props =
1694            (VkPhysicalDeviceDrmPropertiesEXT *)ext;
1695         props->hasPrimary = pdevice->has_primary;
1696         if (props->hasPrimary) {
1697            props->primaryMajor = (int64_t) major(pdevice->primary_devid);
1698            props->primaryMinor = (int64_t) minor(pdevice->primary_devid);
1699         }
1700         props->hasRender = pdevice->has_render;
1701         if (props->hasRender) {
1702            props->renderMajor = (int64_t) major(pdevice->render_devid);
1703            props->renderMinor = (int64_t) minor(pdevice->render_devid);
1704         }
1705         break;
1706      }
1707      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
1708         VkPhysicalDeviceLineRasterizationPropertiesEXT *props =
1709            (VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
1710         props->lineSubPixelPrecisionBits = V3D_COORD_SHIFT;
1711         break;
1712      }
1713      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT:
1714         /* Do nothing, not even logging. This is a non-PCI device, so we will
1715          * never provide this extension.
1716          */
1717         break;
1718      default:
1719         v3dv_debug_ignored_stype(ext->sType);
1720         break;
1721      }
1722   }
1723}
1724
1725/* We support exactly one queue family. */
1726static const VkQueueFamilyProperties
1727v3dv_queue_family_properties = {
1728   .queueFlags = VK_QUEUE_GRAPHICS_BIT |
1729                 VK_QUEUE_COMPUTE_BIT |
1730                 VK_QUEUE_TRANSFER_BIT,
1731   .queueCount = 1,
1732   .timestampValidBits = 64,
1733   .minImageTransferGranularity = { 1, 1, 1 },
1734};
1735
1736VKAPI_ATTR void VKAPI_CALL
1737v3dv_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,
1738                                             uint32_t *pQueueFamilyPropertyCount,
1739                                             VkQueueFamilyProperties2 *pQueueFamilyProperties)
1740{
1741   VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out,
1742                          pQueueFamilyProperties, pQueueFamilyPropertyCount);
1743
1744   vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) {
1745      p->queueFamilyProperties = v3dv_queue_family_properties;
1746
1747      vk_foreach_struct(s, p->pNext) {
1748         v3dv_debug_ignored_stype(s->sType);
1749      }
1750   }
1751}
1752
1753VKAPI_ATTR void VKAPI_CALL
1754v3dv_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
1755                                       VkPhysicalDeviceMemoryProperties *pMemoryProperties)
1756{
1757   V3DV_FROM_HANDLE(v3dv_physical_device, device, physicalDevice);
1758   *pMemoryProperties = device->memory;
1759}
1760
1761VKAPI_ATTR void VKAPI_CALL
1762v3dv_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,
1763                                        VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
1764{
1765   v3dv_GetPhysicalDeviceMemoryProperties(physicalDevice,
1766                                          &pMemoryProperties->memoryProperties);
1767
1768   vk_foreach_struct(ext, pMemoryProperties->pNext) {
1769      switch (ext->sType) {
1770      default:
1771         v3dv_debug_ignored_stype(ext->sType);
1772         break;
1773      }
1774   }
1775}
1776
1777VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1778v3dv_GetInstanceProcAddr(VkInstance _instance,
1779                         const char *pName)
1780{
1781   V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);
1782   return vk_instance_get_proc_addr(&instance->vk,
1783                                    &v3dv_instance_entrypoints,
1784                                    pName);
1785}
1786
1787/* With version 1+ of the loader interface the ICD should expose
1788 * vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in apps.
1789 */
1790PUBLIC
1791VKAPI_ATTR PFN_vkVoidFunction
1792VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance,
1793                                     const char *pName);
1794
1795PUBLIC
1796VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1797vk_icdGetInstanceProcAddr(VkInstance instance,
1798                          const char*                                 pName)
1799{
1800   return v3dv_GetInstanceProcAddr(instance, pName);
1801}
1802
1803/* With version 4+ of the loader interface the ICD should expose
1804 * vk_icdGetPhysicalDeviceProcAddr()
1805 */
1806PUBLIC
1807VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1808vk_icdGetPhysicalDeviceProcAddr(VkInstance  _instance,
1809                                const char* pName);
1810
1811PFN_vkVoidFunction
1812vk_icdGetPhysicalDeviceProcAddr(VkInstance  _instance,
1813                                const char* pName)
1814{
1815   V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);
1816
1817   return vk_instance_get_physical_device_proc_addr(&instance->vk, pName);
1818}
1819
1820VKAPI_ATTR VkResult VKAPI_CALL
1821v3dv_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
1822                                      VkLayerProperties *pProperties)
1823{
1824   if (pProperties == NULL) {
1825      *pPropertyCount = 0;
1826      return VK_SUCCESS;
1827   }
1828
1829   return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1830}
1831
1832VKAPI_ATTR VkResult VKAPI_CALL
1833v3dv_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1834                                    uint32_t *pPropertyCount,
1835                                    VkLayerProperties *pProperties)
1836{
1837   V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice);
1838
1839   if (pProperties == NULL) {
1840      *pPropertyCount = 0;
1841      return VK_SUCCESS;
1842   }
1843
1844   return vk_error(physical_device, VK_ERROR_LAYER_NOT_PRESENT);
1845}
1846
1847static void
1848destroy_queue_syncs(struct v3dv_queue *queue)
1849{
1850   for (int i = 0; i < V3DV_QUEUE_COUNT; i++) {
1851      if (queue->last_job_syncs.syncs[i]) {
1852         drmSyncobjDestroy(queue->device->pdevice->render_fd,
1853                           queue->last_job_syncs.syncs[i]);
1854      }
1855   }
1856}
1857
1858static VkResult
1859queue_init(struct v3dv_device *device, struct v3dv_queue *queue,
1860           const VkDeviceQueueCreateInfo *create_info,
1861           uint32_t index_in_family)
1862{
1863   VkResult result = vk_queue_init(&queue->vk, &device->vk, create_info,
1864                                   index_in_family);
1865   if (result != VK_SUCCESS)
1866      return result;
1867
1868   result = vk_queue_enable_submit_thread(&queue->vk);
1869   if (result != VK_SUCCESS)
1870      goto fail_submit_thread;
1871
1872   queue->device = device;
1873   queue->vk.driver_submit = v3dv_queue_driver_submit;
1874
1875   for (int i = 0; i < V3DV_QUEUE_COUNT; i++) {
1876      queue->last_job_syncs.first[i] = true;
1877      int ret = drmSyncobjCreate(device->pdevice->render_fd,
1878                                 DRM_SYNCOBJ_CREATE_SIGNALED,
1879                                 &queue->last_job_syncs.syncs[i]);
1880      if (ret) {
1881         result = vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED,
1882                            "syncobj create failed: %m");
1883         goto fail_last_job_syncs;
1884      }
1885   }
1886
1887   queue->noop_job = NULL;
1888   return VK_SUCCESS;
1889
1890fail_last_job_syncs:
1891   destroy_queue_syncs(queue);
1892fail_submit_thread:
1893   vk_queue_finish(&queue->vk);
1894   return result;
1895}
1896
1897static void
1898queue_finish(struct v3dv_queue *queue)
1899{
1900   if (queue->noop_job)
1901      v3dv_job_destroy(queue->noop_job);
1902   destroy_queue_syncs(queue);
1903   vk_queue_finish(&queue->vk);
1904}
1905
1906static void
1907init_device_meta(struct v3dv_device *device)
1908{
1909   mtx_init(&device->meta.mtx, mtx_plain);
1910   v3dv_meta_clear_init(device);
1911   v3dv_meta_blit_init(device);
1912   v3dv_meta_texel_buffer_copy_init(device);
1913}
1914
1915static void
1916destroy_device_meta(struct v3dv_device *device)
1917{
1918   mtx_destroy(&device->meta.mtx);
1919   v3dv_meta_clear_finish(device);
1920   v3dv_meta_blit_finish(device);
1921   v3dv_meta_texel_buffer_copy_finish(device);
1922}
1923
1924VKAPI_ATTR VkResult VKAPI_CALL
1925v3dv_CreateDevice(VkPhysicalDevice physicalDevice,
1926                  const VkDeviceCreateInfo *pCreateInfo,
1927                  const VkAllocationCallbacks *pAllocator,
1928                  VkDevice *pDevice)
1929{
1930   V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice);
1931   struct v3dv_instance *instance = (struct v3dv_instance*) physical_device->vk.instance;
1932   VkResult result;
1933   struct v3dv_device *device;
1934
1935   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
1936
1937   /* Check requested queues (we only expose one queue ) */
1938   assert(pCreateInfo->queueCreateInfoCount == 1);
1939   for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
1940      assert(pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex == 0);
1941      assert(pCreateInfo->pQueueCreateInfos[i].queueCount == 1);
1942      if (pCreateInfo->pQueueCreateInfos[i].flags != 0)
1943         return vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
1944   }
1945
1946   device = vk_zalloc2(&physical_device->vk.instance->alloc, pAllocator,
1947                       sizeof(*device), 8,
1948                       VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1949   if (!device)
1950      return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1951
1952   struct vk_device_dispatch_table dispatch_table;
1953   vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1954                                             &v3dv_device_entrypoints, true);
1955   vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1956                                             &wsi_device_entrypoints, false);
1957   result = vk_device_init(&device->vk, &physical_device->vk,
1958                           &dispatch_table, pCreateInfo, pAllocator);
1959   if (result != VK_SUCCESS) {
1960      vk_free(&device->vk.alloc, device);
1961      return vk_error(NULL, result);
1962   }
1963
1964   device->instance = instance;
1965   device->pdevice = physical_device;
1966
1967   mtx_init(&device->query_mutex, mtx_plain);
1968   cnd_init(&device->query_ended);
1969
1970   vk_device_set_drm_fd(&device->vk, physical_device->render_fd);
1971   vk_device_enable_threaded_submit(&device->vk);
1972
1973   result = queue_init(device, &device->queue,
1974                       pCreateInfo->pQueueCreateInfos, 0);
1975   if (result != VK_SUCCESS)
1976      goto fail;
1977
1978   device->devinfo = physical_device->devinfo;
1979
1980   /* Vulkan 1.1 and VK_KHR_get_physical_device_properties2 added
1981    * VkPhysicalDeviceFeatures2 which can be used in the pNext chain of
1982    * vkDeviceCreateInfo, in which case it should be used instead of
1983    * pEnabledFeatures.
1984    */
1985   const VkPhysicalDeviceFeatures2 *features2 =
1986      vk_find_struct_const(pCreateInfo->pNext, PHYSICAL_DEVICE_FEATURES_2);
1987   if (features2) {
1988      memcpy(&device->features, &features2->features,
1989             sizeof(device->features));
1990   } else  if (pCreateInfo->pEnabledFeatures) {
1991      memcpy(&device->features, pCreateInfo->pEnabledFeatures,
1992             sizeof(device->features));
1993   }
1994
1995   if (device->features.robustBufferAccess)
1996      perf_debug("Device created with Robust Buffer Access enabled.\n");
1997
1998#ifdef DEBUG
1999   v3dv_X(device, device_check_prepacked_sizes)();
2000#endif
2001   init_device_meta(device);
2002   v3dv_bo_cache_init(device);
2003   v3dv_pipeline_cache_init(&device->default_pipeline_cache, device, 0,
2004                            device->instance->default_pipeline_cache_enabled);
2005   device->default_attribute_float =
2006      v3dv_pipeline_create_default_attribute_values(device, NULL);
2007
2008   device->device_address_mem_ctx = ralloc_context(NULL);
2009   util_dynarray_init(&device->device_address_bo_list,
2010                      device->device_address_mem_ctx);
2011
2012   *pDevice = v3dv_device_to_handle(device);
2013
2014   return VK_SUCCESS;
2015
2016fail:
2017   cnd_destroy(&device->query_ended);
2018   mtx_destroy(&device->query_mutex);
2019   queue_finish(&device->queue);
2020   destroy_device_meta(device);
2021   v3dv_pipeline_cache_finish(&device->default_pipeline_cache);
2022   vk_device_finish(&device->vk);
2023   vk_free(&device->vk.alloc, device);
2024
2025   return result;
2026}
2027
2028VKAPI_ATTR void VKAPI_CALL
2029v3dv_DestroyDevice(VkDevice _device,
2030                   const VkAllocationCallbacks *pAllocator)
2031{
2032   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2033
2034   device->vk.dispatch_table.DeviceWaitIdle(_device);
2035   queue_finish(&device->queue);
2036   destroy_device_meta(device);
2037   v3dv_pipeline_cache_finish(&device->default_pipeline_cache);
2038
2039   if (device->default_attribute_float) {
2040      v3dv_bo_free(device, device->default_attribute_float);
2041      device->default_attribute_float = NULL;
2042   }
2043
2044   ralloc_free(device->device_address_mem_ctx);
2045
2046   /* Bo cache should be removed the last, as any other object could be
2047    * freeing their private bos
2048    */
2049   v3dv_bo_cache_destroy(device);
2050
2051   cnd_destroy(&device->query_ended);
2052   mtx_destroy(&device->query_mutex);
2053
2054   vk_device_finish(&device->vk);
2055   vk_free2(&device->vk.alloc, pAllocator, device);
2056}
2057
2058static VkResult
2059device_alloc(struct v3dv_device *device,
2060             struct v3dv_device_memory *mem,
2061             VkDeviceSize size)
2062{
2063   /* Our kernel interface is 32-bit */
2064   assert(size <= UINT32_MAX);
2065
2066   mem->bo = v3dv_bo_alloc(device, size, "device_alloc", false);
2067   if (!mem->bo)
2068      return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2069
2070   return VK_SUCCESS;
2071}
2072
2073static void
2074device_free_wsi_dumb(int32_t display_fd, int32_t dumb_handle)
2075{
2076   assert(display_fd != -1);
2077   if (dumb_handle < 0)
2078      return;
2079
2080   struct drm_mode_destroy_dumb destroy_dumb = {
2081      .handle = dumb_handle,
2082   };
2083   if (v3dv_ioctl(display_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb)) {
2084      fprintf(stderr, "destroy dumb object %d: %s\n", dumb_handle, strerror(errno));
2085   }
2086}
2087
2088static void
2089device_free(struct v3dv_device *device, struct v3dv_device_memory *mem)
2090{
2091   /* If this memory allocation was for WSI, then we need to use the
2092    * display device to free the allocated dumb BO.
2093    */
2094   if (mem->is_for_wsi) {
2095      device_free_wsi_dumb(device->instance->physicalDevice.display_fd,
2096                           mem->bo->dumb_handle);
2097   }
2098
2099   v3dv_bo_free(device, mem->bo);
2100}
2101
2102static void
2103device_unmap(struct v3dv_device *device, struct v3dv_device_memory *mem)
2104{
2105   assert(mem && mem->bo->map && mem->bo->map_size > 0);
2106   v3dv_bo_unmap(device, mem->bo);
2107}
2108
2109static VkResult
2110device_map(struct v3dv_device *device, struct v3dv_device_memory *mem)
2111{
2112   assert(mem && mem->bo);
2113
2114   /* From the spec:
2115    *
2116    *   "After a successful call to vkMapMemory the memory object memory is
2117    *   considered to be currently host mapped. It is an application error to
2118    *   call vkMapMemory on a memory object that is already host mapped."
2119    *
2120    * We are not concerned with this ourselves (validation layers should
2121    * catch these errors and warn users), however, the driver may internally
2122    * map things (for example for debug CLIF dumps or some CPU-side operations)
2123    * so by the time the user calls here the buffer might already been mapped
2124    * internally by the driver.
2125    */
2126   if (mem->bo->map) {
2127      assert(mem->bo->map_size == mem->bo->size);
2128      return VK_SUCCESS;
2129   }
2130
2131   bool ok = v3dv_bo_map(device, mem->bo, mem->bo->size);
2132   if (!ok)
2133      return VK_ERROR_MEMORY_MAP_FAILED;
2134
2135   return VK_SUCCESS;
2136}
2137
2138static VkResult
2139device_import_bo(struct v3dv_device *device,
2140                 const VkAllocationCallbacks *pAllocator,
2141                 int fd, uint64_t size,
2142                 struct v3dv_bo **bo)
2143{
2144   *bo = NULL;
2145
2146   off_t real_size = lseek(fd, 0, SEEK_END);
2147   lseek(fd, 0, SEEK_SET);
2148   if (real_size < 0 || (uint64_t) real_size < size)
2149      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
2150
2151   int render_fd = device->pdevice->render_fd;
2152   assert(render_fd >= 0);
2153
2154   int ret;
2155   uint32_t handle;
2156   ret = drmPrimeFDToHandle(render_fd, fd, &handle);
2157   if (ret)
2158      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
2159
2160   struct drm_v3d_get_bo_offset get_offset = {
2161      .handle = handle,
2162   };
2163   ret = v3dv_ioctl(render_fd, DRM_IOCTL_V3D_GET_BO_OFFSET, &get_offset);
2164   if (ret)
2165      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
2166   assert(get_offset.offset != 0);
2167
2168   *bo = v3dv_device_lookup_bo(device->pdevice, handle);
2169   assert(*bo);
2170
2171   if ((*bo)->refcnt == 0)
2172      v3dv_bo_init(*bo, handle, size, get_offset.offset, "import", false);
2173   else
2174      p_atomic_inc(&(*bo)->refcnt);
2175
2176   return VK_SUCCESS;
2177}
2178
2179static VkResult
2180device_alloc_for_wsi(struct v3dv_device *device,
2181                     const VkAllocationCallbacks *pAllocator,
2182                     struct v3dv_device_memory *mem,
2183                     VkDeviceSize size)
2184{
2185   /* In the simulator we can get away with a regular allocation since both
2186    * allocation and rendering happen in the same DRM render node. On actual
2187    * hardware we need to allocate our winsys BOs on the vc4 display device
2188    * and import them into v3d.
2189    */
2190#if using_v3d_simulator
2191      return device_alloc(device, mem, size);
2192#else
2193   /* If we are allocating for WSI we should have a swapchain and thus,
2194    * we should've initialized the display device. However, Zink doesn't
2195    * use swapchains, so in that case we can get here without acquiring the
2196    * display device and we need to do it now.
2197    */
2198   VkResult result;
2199   struct v3dv_instance *instance = device->instance;
2200   struct v3dv_physical_device *pdevice = &device->instance->physicalDevice;
2201   if (unlikely(pdevice->display_fd < 0)) {
2202      result = v3dv_physical_device_acquire_display(instance, pdevice, NULL);
2203      if (result != VK_SUCCESS)
2204         return result;
2205   }
2206   assert(pdevice->display_fd != -1);
2207
2208   mem->is_for_wsi = true;
2209
2210   int display_fd = pdevice->display_fd;
2211   struct drm_mode_create_dumb create_dumb = {
2212      .width = 1024, /* one page */
2213      .height = align(size, 4096) / 4096,
2214      .bpp = util_format_get_blocksizebits(PIPE_FORMAT_RGBA8888_UNORM),
2215   };
2216
2217   int err;
2218   err = v3dv_ioctl(display_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
2219   if (err < 0)
2220      goto fail_create;
2221
2222   int fd;
2223   err =
2224      drmPrimeHandleToFD(display_fd, create_dumb.handle, O_CLOEXEC, &fd);
2225   if (err < 0)
2226      goto fail_export;
2227
2228   result = device_import_bo(device, pAllocator, fd, size, &mem->bo);
2229   close(fd);
2230   if (result != VK_SUCCESS)
2231      goto fail_import;
2232
2233   mem->bo->dumb_handle = create_dumb.handle;
2234   return VK_SUCCESS;
2235
2236fail_import:
2237fail_export:
2238   device_free_wsi_dumb(display_fd, create_dumb.handle);
2239
2240fail_create:
2241   return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2242#endif
2243}
2244
2245static void
2246device_add_device_address_bo(struct v3dv_device *device,
2247                                  struct v3dv_bo *bo)
2248{
2249   util_dynarray_append(&device->device_address_bo_list,
2250                        struct v3dv_bo *,
2251                        bo);
2252}
2253
2254static void
2255device_remove_device_address_bo(struct v3dv_device *device,
2256                                struct v3dv_bo *bo)
2257{
2258   util_dynarray_delete_unordered(&device->device_address_bo_list,
2259                                  struct v3dv_bo *,
2260                                  bo);
2261}
2262
2263VKAPI_ATTR VkResult VKAPI_CALL
2264v3dv_AllocateMemory(VkDevice _device,
2265                    const VkMemoryAllocateInfo *pAllocateInfo,
2266                    const VkAllocationCallbacks *pAllocator,
2267                    VkDeviceMemory *pMem)
2268{
2269   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2270   struct v3dv_device_memory *mem;
2271   struct v3dv_physical_device *pdevice = &device->instance->physicalDevice;
2272
2273   assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
2274
2275   /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */
2276   assert(pAllocateInfo->allocationSize > 0);
2277
2278   mem = vk_object_zalloc(&device->vk, pAllocator, sizeof(*mem),
2279                          VK_OBJECT_TYPE_DEVICE_MEMORY);
2280   if (mem == NULL)
2281      return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
2282
2283   assert(pAllocateInfo->memoryTypeIndex < pdevice->memory.memoryTypeCount);
2284   mem->type = &pdevice->memory.memoryTypes[pAllocateInfo->memoryTypeIndex];
2285   mem->is_for_wsi = false;
2286
2287   const struct wsi_memory_allocate_info *wsi_info = NULL;
2288   const VkImportMemoryFdInfoKHR *fd_info = NULL;
2289   const VkMemoryAllocateFlagsInfo *flags_info = NULL;
2290   vk_foreach_struct_const(ext, pAllocateInfo->pNext) {
2291      switch ((unsigned)ext->sType) {
2292      case VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA:
2293         wsi_info = (void *)ext;
2294         break;
2295      case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:
2296         fd_info = (void *)ext;
2297         break;
2298      case VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO:
2299         flags_info = (void *)ext;
2300         break;
2301      case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:
2302         /* We don't have particular optimizations associated with memory
2303          * allocations that won't be suballocated to multiple resources.
2304          */
2305         break;
2306      case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
2307         /* The mask of handle types specified here must be supported
2308          * according to VkExternalImageFormatProperties, so it must be
2309          * fd or dmabuf, which don't have special requirements for us.
2310          */
2311         break;
2312      default:
2313         v3dv_debug_ignored_stype(ext->sType);
2314         break;
2315      }
2316   }
2317
2318   VkResult result = VK_SUCCESS;
2319
2320   /* We always allocate device memory in multiples of a page, so round up
2321    * requested size to that.
2322    */
2323   VkDeviceSize alloc_size = ALIGN(pAllocateInfo->allocationSize, 4096);
2324
2325   if (unlikely(alloc_size > MAX_MEMORY_ALLOCATION_SIZE)) {
2326      result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
2327   } else {
2328      if (wsi_info) {
2329         result = device_alloc_for_wsi(device, pAllocator, mem, alloc_size);
2330      } else if (fd_info && fd_info->handleType) {
2331         assert(fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
2332                fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2333         result = device_import_bo(device, pAllocator,
2334                                   fd_info->fd, alloc_size, &mem->bo);
2335         if (result == VK_SUCCESS)
2336            close(fd_info->fd);
2337      } else {
2338         result = device_alloc(device, mem, alloc_size);
2339      }
2340   }
2341
2342   if (result != VK_SUCCESS) {
2343      vk_object_free(&device->vk, pAllocator, mem);
2344      return vk_error(device, result);
2345   }
2346
2347   /* If this memory can be used via VK_KHR_buffer_device_address then we
2348    * will need to manually add the BO to any job submit that makes use of
2349    * VK_KHR_buffer_device_address, since such jobs may produde buffer
2350    * load/store operations that may access any buffer memory allocated with
2351    * this flag and we don't have any means to tell which buffers will be
2352    * accessed through this mechanism since they don't even have to be bound
2353    * through descriptor state.
2354    */
2355   if (flags_info &&
2356       (flags_info->flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR)) {
2357      mem->is_for_device_address = true;
2358      device_add_device_address_bo(device, mem->bo);
2359   }
2360
2361   *pMem = v3dv_device_memory_to_handle(mem);
2362   return result;
2363}
2364
2365VKAPI_ATTR void VKAPI_CALL
2366v3dv_FreeMemory(VkDevice _device,
2367                VkDeviceMemory _mem,
2368                const VkAllocationCallbacks *pAllocator)
2369{
2370   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2371   V3DV_FROM_HANDLE(v3dv_device_memory, mem, _mem);
2372
2373   if (mem == NULL)
2374      return;
2375
2376   if (mem->bo->map)
2377      v3dv_UnmapMemory(_device, _mem);
2378
2379   if (mem->is_for_device_address)
2380      device_remove_device_address_bo(device, mem->bo);
2381
2382   device_free(device, mem);
2383
2384   vk_object_free(&device->vk, pAllocator, mem);
2385}
2386
2387VKAPI_ATTR VkResult VKAPI_CALL
2388v3dv_MapMemory(VkDevice _device,
2389               VkDeviceMemory _memory,
2390               VkDeviceSize offset,
2391               VkDeviceSize size,
2392               VkMemoryMapFlags flags,
2393               void **ppData)
2394{
2395   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2396   V3DV_FROM_HANDLE(v3dv_device_memory, mem, _memory);
2397
2398   if (mem == NULL) {
2399      *ppData = NULL;
2400      return VK_SUCCESS;
2401   }
2402
2403   assert(offset < mem->bo->size);
2404
2405   /* Since the driver can map BOs internally as well and the mapped range
2406    * required by the user or the driver might not be the same, we always map
2407    * the entire BO and then add the requested offset to the start address
2408    * of the mapped region.
2409    */
2410   VkResult result = device_map(device, mem);
2411   if (result != VK_SUCCESS)
2412      return vk_error(device, result);
2413
2414   *ppData = ((uint8_t *) mem->bo->map) + offset;
2415   return VK_SUCCESS;
2416}
2417
2418VKAPI_ATTR void VKAPI_CALL
2419v3dv_UnmapMemory(VkDevice _device,
2420                 VkDeviceMemory _memory)
2421{
2422   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2423   V3DV_FROM_HANDLE(v3dv_device_memory, mem, _memory);
2424
2425   if (mem == NULL)
2426      return;
2427
2428   device_unmap(device, mem);
2429}
2430
2431VKAPI_ATTR VkResult VKAPI_CALL
2432v3dv_FlushMappedMemoryRanges(VkDevice _device,
2433                             uint32_t memoryRangeCount,
2434                             const VkMappedMemoryRange *pMemoryRanges)
2435{
2436   return VK_SUCCESS;
2437}
2438
2439VKAPI_ATTR VkResult VKAPI_CALL
2440v3dv_InvalidateMappedMemoryRanges(VkDevice _device,
2441                                  uint32_t memoryRangeCount,
2442                                  const VkMappedMemoryRange *pMemoryRanges)
2443{
2444   return VK_SUCCESS;
2445}
2446
2447VKAPI_ATTR void VKAPI_CALL
2448v3dv_GetImageMemoryRequirements2(VkDevice device,
2449                                 const VkImageMemoryRequirementsInfo2 *pInfo,
2450                                 VkMemoryRequirements2 *pMemoryRequirements)
2451{
2452   V3DV_FROM_HANDLE(v3dv_image, image, pInfo->image);
2453
2454   pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
2455      .memoryTypeBits = 0x1,
2456      .alignment = image->alignment,
2457      .size = image->size
2458   };
2459
2460   vk_foreach_struct(ext, pMemoryRequirements->pNext) {
2461      switch (ext->sType) {
2462      case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
2463         VkMemoryDedicatedRequirements *req =
2464            (VkMemoryDedicatedRequirements *) ext;
2465         req->requiresDedicatedAllocation = image->vk.external_handle_types != 0;
2466         req->prefersDedicatedAllocation = image->vk.external_handle_types != 0;
2467         break;
2468      }
2469      default:
2470         v3dv_debug_ignored_stype(ext->sType);
2471         break;
2472      }
2473   }
2474}
2475
2476static void
2477bind_image_memory(const VkBindImageMemoryInfo *info)
2478{
2479   V3DV_FROM_HANDLE(v3dv_image, image, info->image);
2480   V3DV_FROM_HANDLE(v3dv_device_memory, mem, info->memory);
2481
2482   /* Valid usage:
2483    *
2484    *   "memoryOffset must be an integer multiple of the alignment member of
2485    *    the VkMemoryRequirements structure returned from a call to
2486    *    vkGetImageMemoryRequirements with image"
2487    */
2488   assert(info->memoryOffset % image->alignment == 0);
2489   assert(info->memoryOffset < mem->bo->size);
2490
2491   image->mem = mem;
2492   image->mem_offset = info->memoryOffset;
2493}
2494
2495VKAPI_ATTR VkResult VKAPI_CALL
2496v3dv_BindImageMemory2(VkDevice _device,
2497                      uint32_t bindInfoCount,
2498                      const VkBindImageMemoryInfo *pBindInfos)
2499{
2500   for (uint32_t i = 0; i < bindInfoCount; i++) {
2501      const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
2502         vk_find_struct_const(pBindInfos->pNext,
2503                              BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
2504      if (swapchain_info && swapchain_info->swapchain) {
2505         struct v3dv_image *swapchain_image =
2506            v3dv_wsi_get_image_from_swapchain(swapchain_info->swapchain,
2507                                              swapchain_info->imageIndex);
2508         VkBindImageMemoryInfo swapchain_bind = {
2509            .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
2510            .image = pBindInfos[i].image,
2511            .memory = v3dv_device_memory_to_handle(swapchain_image->mem),
2512            .memoryOffset = swapchain_image->mem_offset,
2513         };
2514         bind_image_memory(&swapchain_bind);
2515      } else {
2516         bind_image_memory(&pBindInfos[i]);
2517      }
2518   }
2519
2520   return VK_SUCCESS;
2521}
2522
2523VKAPI_ATTR void VKAPI_CALL
2524v3dv_GetBufferMemoryRequirements2(VkDevice device,
2525                                  const VkBufferMemoryRequirementsInfo2 *pInfo,
2526                                  VkMemoryRequirements2 *pMemoryRequirements)
2527{
2528   V3DV_FROM_HANDLE(v3dv_buffer, buffer, pInfo->buffer);
2529
2530   pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
2531      .memoryTypeBits = 0x1,
2532      .alignment = buffer->alignment,
2533      .size = align64(buffer->size, buffer->alignment),
2534   };
2535
2536   vk_foreach_struct(ext, pMemoryRequirements->pNext) {
2537      switch (ext->sType) {
2538      case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
2539         VkMemoryDedicatedRequirements *req =
2540            (VkMemoryDedicatedRequirements *) ext;
2541         req->requiresDedicatedAllocation = false;
2542         req->prefersDedicatedAllocation = false;
2543         break;
2544      }
2545      default:
2546         v3dv_debug_ignored_stype(ext->sType);
2547         break;
2548      }
2549   }
2550}
2551
2552static void
2553bind_buffer_memory(const VkBindBufferMemoryInfo *info)
2554{
2555   V3DV_FROM_HANDLE(v3dv_buffer, buffer, info->buffer);
2556   V3DV_FROM_HANDLE(v3dv_device_memory, mem, info->memory);
2557
2558   /* Valid usage:
2559    *
2560    *   "memoryOffset must be an integer multiple of the alignment member of
2561    *    the VkMemoryRequirements structure returned from a call to
2562    *    vkGetBufferMemoryRequirements with buffer"
2563    */
2564   assert(info->memoryOffset % buffer->alignment == 0);
2565   assert(info->memoryOffset < mem->bo->size);
2566
2567   buffer->mem = mem;
2568   buffer->mem_offset = info->memoryOffset;
2569}
2570
2571
2572VKAPI_ATTR VkResult VKAPI_CALL
2573v3dv_BindBufferMemory2(VkDevice device,
2574                       uint32_t bindInfoCount,
2575                       const VkBindBufferMemoryInfo *pBindInfos)
2576{
2577   for (uint32_t i = 0; i < bindInfoCount; i++)
2578      bind_buffer_memory(&pBindInfos[i]);
2579
2580   return VK_SUCCESS;
2581}
2582
2583VKAPI_ATTR VkResult VKAPI_CALL
2584v3dv_CreateBuffer(VkDevice  _device,
2585                  const VkBufferCreateInfo *pCreateInfo,
2586                  const VkAllocationCallbacks *pAllocator,
2587                  VkBuffer *pBuffer)
2588{
2589   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2590   struct v3dv_buffer *buffer;
2591
2592   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
2593   assert(pCreateInfo->usage != 0);
2594
2595   /* We don't support any flags for now */
2596   assert(pCreateInfo->flags == 0);
2597
2598   buffer = vk_object_zalloc(&device->vk, pAllocator, sizeof(*buffer),
2599                             VK_OBJECT_TYPE_BUFFER);
2600   if (buffer == NULL)
2601      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2602
2603   buffer->size = pCreateInfo->size;
2604   buffer->usage = pCreateInfo->usage;
2605   buffer->alignment = V3D_NON_COHERENT_ATOM_SIZE;
2606
2607   /* Limit allocations to 32-bit */
2608   const VkDeviceSize aligned_size = align64(buffer->size, buffer->alignment);
2609   if (aligned_size > UINT32_MAX || aligned_size < buffer->size) {
2610      vk_free(&device->vk.alloc, buffer);
2611      return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2612   }
2613
2614   *pBuffer = v3dv_buffer_to_handle(buffer);
2615
2616   return VK_SUCCESS;
2617}
2618
2619VKAPI_ATTR void VKAPI_CALL
2620v3dv_DestroyBuffer(VkDevice _device,
2621                   VkBuffer _buffer,
2622                   const VkAllocationCallbacks *pAllocator)
2623{
2624   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2625   V3DV_FROM_HANDLE(v3dv_buffer, buffer, _buffer);
2626
2627   if (!buffer)
2628      return;
2629
2630   vk_object_free(&device->vk, pAllocator, buffer);
2631}
2632
2633VKAPI_ATTR VkResult VKAPI_CALL
2634v3dv_CreateFramebuffer(VkDevice _device,
2635                       const VkFramebufferCreateInfo *pCreateInfo,
2636                       const VkAllocationCallbacks *pAllocator,
2637                       VkFramebuffer *pFramebuffer)
2638{
2639   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2640   struct v3dv_framebuffer *framebuffer;
2641
2642   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
2643
2644   size_t size = sizeof(*framebuffer) +
2645                 sizeof(struct v3dv_image_view *) * pCreateInfo->attachmentCount;
2646   framebuffer = vk_object_zalloc(&device->vk, pAllocator, size,
2647                                  VK_OBJECT_TYPE_FRAMEBUFFER);
2648   if (framebuffer == NULL)
2649      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2650
2651   framebuffer->width = pCreateInfo->width;
2652   framebuffer->height = pCreateInfo->height;
2653   framebuffer->layers = pCreateInfo->layers;
2654   framebuffer->has_edge_padding = true;
2655
2656   const VkFramebufferAttachmentsCreateInfo *imageless =
2657      vk_find_struct_const(pCreateInfo->pNext,
2658      FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
2659
2660   framebuffer->attachment_count = pCreateInfo->attachmentCount;
2661   framebuffer->color_attachment_count = 0;
2662   for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
2663      if (!imageless) {
2664         framebuffer->attachments[i] =
2665            v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]);
2666         if (framebuffer->attachments[i]->vk.aspects & VK_IMAGE_ASPECT_COLOR_BIT)
2667            framebuffer->color_attachment_count++;
2668      } else {
2669         assert(i < imageless->attachmentImageInfoCount);
2670         if (imageless->pAttachmentImageInfos[i].usage &
2671             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
2672            framebuffer->color_attachment_count++;
2673         }
2674      }
2675   }
2676
2677   *pFramebuffer = v3dv_framebuffer_to_handle(framebuffer);
2678
2679   return VK_SUCCESS;
2680}
2681
2682VKAPI_ATTR void VKAPI_CALL
2683v3dv_DestroyFramebuffer(VkDevice _device,
2684                        VkFramebuffer _fb,
2685                        const VkAllocationCallbacks *pAllocator)
2686{
2687   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2688   V3DV_FROM_HANDLE(v3dv_framebuffer, fb, _fb);
2689
2690   if (!fb)
2691      return;
2692
2693   vk_object_free(&device->vk, pAllocator, fb);
2694}
2695
2696VKAPI_ATTR VkResult VKAPI_CALL
2697v3dv_GetMemoryFdPropertiesKHR(VkDevice _device,
2698                              VkExternalMemoryHandleTypeFlagBits handleType,
2699                              int fd,
2700                              VkMemoryFdPropertiesKHR *pMemoryFdProperties)
2701{
2702   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2703   struct v3dv_physical_device *pdevice = &device->instance->physicalDevice;
2704
2705   switch (handleType) {
2706   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
2707      pMemoryFdProperties->memoryTypeBits =
2708         (1 << pdevice->memory.memoryTypeCount) - 1;
2709      return VK_SUCCESS;
2710   default:
2711      return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
2712   }
2713}
2714
2715VKAPI_ATTR VkResult VKAPI_CALL
2716v3dv_GetMemoryFdKHR(VkDevice _device,
2717                    const VkMemoryGetFdInfoKHR *pGetFdInfo,
2718                    int *pFd)
2719{
2720   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2721   V3DV_FROM_HANDLE(v3dv_device_memory, mem, pGetFdInfo->memory);
2722
2723   assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
2724   assert(pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
2725          pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2726
2727   int fd, ret;
2728   ret = drmPrimeHandleToFD(device->pdevice->render_fd,
2729                            mem->bo->handle,
2730                            DRM_CLOEXEC, &fd);
2731   if (ret)
2732      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2733
2734   *pFd = fd;
2735
2736   return VK_SUCCESS;
2737}
2738
2739VKAPI_ATTR VkResult VKAPI_CALL
2740v3dv_CreateEvent(VkDevice _device,
2741                 const VkEventCreateInfo *pCreateInfo,
2742                 const VkAllocationCallbacks *pAllocator,
2743                 VkEvent *pEvent)
2744{
2745   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2746   struct v3dv_event *event =
2747      vk_object_zalloc(&device->vk, pAllocator, sizeof(*event),
2748                       VK_OBJECT_TYPE_EVENT);
2749   if (!event)
2750      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2751
2752   /* Events are created in the unsignaled state */
2753   event->state = false;
2754   *pEvent = v3dv_event_to_handle(event);
2755
2756   return VK_SUCCESS;
2757}
2758
2759VKAPI_ATTR void VKAPI_CALL
2760v3dv_DestroyEvent(VkDevice _device,
2761                  VkEvent _event,
2762                  const VkAllocationCallbacks *pAllocator)
2763{
2764   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2765   V3DV_FROM_HANDLE(v3dv_event, event, _event);
2766
2767   if (!event)
2768      return;
2769
2770   vk_object_free(&device->vk, pAllocator, event);
2771}
2772
2773VKAPI_ATTR VkResult VKAPI_CALL
2774v3dv_GetEventStatus(VkDevice _device, VkEvent _event)
2775{
2776   V3DV_FROM_HANDLE(v3dv_event, event, _event);
2777   return p_atomic_read(&event->state) ? VK_EVENT_SET : VK_EVENT_RESET;
2778}
2779
2780VKAPI_ATTR VkResult VKAPI_CALL
2781v3dv_SetEvent(VkDevice _device, VkEvent _event)
2782{
2783   V3DV_FROM_HANDLE(v3dv_event, event, _event);
2784   p_atomic_set(&event->state, 1);
2785   return VK_SUCCESS;
2786}
2787
2788VKAPI_ATTR VkResult VKAPI_CALL
2789v3dv_ResetEvent(VkDevice _device, VkEvent _event)
2790{
2791   V3DV_FROM_HANDLE(v3dv_event, event, _event);
2792   p_atomic_set(&event->state, 0);
2793   return VK_SUCCESS;
2794}
2795
2796VKAPI_ATTR VkResult VKAPI_CALL
2797v3dv_CreateSampler(VkDevice _device,
2798                 const VkSamplerCreateInfo *pCreateInfo,
2799                 const VkAllocationCallbacks *pAllocator,
2800                 VkSampler *pSampler)
2801{
2802   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2803   struct v3dv_sampler *sampler;
2804
2805   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
2806
2807   sampler = vk_object_zalloc(&device->vk, pAllocator, sizeof(*sampler),
2808                              VK_OBJECT_TYPE_SAMPLER);
2809   if (!sampler)
2810      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2811
2812   sampler->compare_enable = pCreateInfo->compareEnable;
2813   sampler->unnormalized_coordinates = pCreateInfo->unnormalizedCoordinates;
2814
2815   const VkSamplerCustomBorderColorCreateInfoEXT *bc_info =
2816      vk_find_struct_const(pCreateInfo->pNext,
2817                           SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
2818
2819   v3dv_X(device, pack_sampler_state)(sampler, pCreateInfo, bc_info);
2820
2821   *pSampler = v3dv_sampler_to_handle(sampler);
2822
2823   return VK_SUCCESS;
2824}
2825
2826VKAPI_ATTR void VKAPI_CALL
2827v3dv_DestroySampler(VkDevice _device,
2828                  VkSampler _sampler,
2829                  const VkAllocationCallbacks *pAllocator)
2830{
2831   V3DV_FROM_HANDLE(v3dv_device, device, _device);
2832   V3DV_FROM_HANDLE(v3dv_sampler, sampler, _sampler);
2833
2834   if (!sampler)
2835      return;
2836
2837   vk_object_free(&device->vk, pAllocator, sampler);
2838}
2839
2840VKAPI_ATTR void VKAPI_CALL
2841v3dv_GetDeviceMemoryCommitment(VkDevice device,
2842                               VkDeviceMemory memory,
2843                               VkDeviceSize *pCommittedMemoryInBytes)
2844{
2845   *pCommittedMemoryInBytes = 0;
2846}
2847
2848VKAPI_ATTR void VKAPI_CALL
2849v3dv_GetImageSparseMemoryRequirements(
2850    VkDevice device,
2851    VkImage image,
2852    uint32_t *pSparseMemoryRequirementCount,
2853    VkSparseImageMemoryRequirements *pSparseMemoryRequirements)
2854{
2855   *pSparseMemoryRequirementCount = 0;
2856}
2857
2858VKAPI_ATTR void VKAPI_CALL
2859v3dv_GetImageSparseMemoryRequirements2(
2860   VkDevice device,
2861   const VkImageSparseMemoryRequirementsInfo2 *pInfo,
2862   uint32_t *pSparseMemoryRequirementCount,
2863   VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
2864{
2865   *pSparseMemoryRequirementCount = 0;
2866}
2867
2868/* vk_icd.h does not declare this function, so we declare it here to
2869 * suppress Wmissing-prototypes.
2870 */
2871PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2872vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);
2873
2874PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2875vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)
2876{
2877   /* For the full details on loader interface versioning, see
2878    * <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
2879    * What follows is a condensed summary, to help you navigate the large and
2880    * confusing official doc.
2881    *
2882    *   - Loader interface v0 is incompatible with later versions. We don't
2883    *     support it.
2884    *
2885    *   - In loader interface v1:
2886    *       - The first ICD entrypoint called by the loader is
2887    *         vk_icdGetInstanceProcAddr(). The ICD must statically expose this
2888    *         entrypoint.
2889    *       - The ICD must statically expose no other Vulkan symbol unless it is
2890    *         linked with -Bsymbolic.
2891    *       - Each dispatchable Vulkan handle created by the ICD must be
2892    *         a pointer to a struct whose first member is VK_LOADER_DATA. The
2893    *         ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC.
2894    *       - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
2895    *         vkDestroySurfaceKHR(). The ICD must be capable of working with
2896    *         such loader-managed surfaces.
2897    *
2898    *    - Loader interface v2 differs from v1 in:
2899    *       - The first ICD entrypoint called by the loader is
2900    *         vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
2901    *         statically expose this entrypoint.
2902    *
2903    *    - Loader interface v3 differs from v2 in:
2904    *        - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
2905    *          vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
2906    *          because the loader no longer does so.
2907    *
2908    *    - Loader interface v4 differs from v3 in:
2909    *        - The ICD must implement vk_icdGetPhysicalDeviceProcAddr().
2910    *
2911    *    - Loader interface v5 differs from v4 in:
2912    *        - The ICD must support Vulkan API version 1.1 and must not return
2913    *          VK_ERROR_INCOMPATIBLE_DRIVER from vkCreateInstance() unless a
2914    *          Vulkan Loader with interface v4 or smaller is being used and the
2915    *          application provides an API version that is greater than 1.0.
2916    */
2917   *pSupportedVersion = MIN2(*pSupportedVersion, 5u);
2918   return VK_SUCCESS;
2919}
2920
2921VkDeviceAddress
2922v3dv_GetBufferDeviceAddress(VkDevice device,
2923                            const VkBufferDeviceAddressInfoKHR *pInfo)
2924{
2925   V3DV_FROM_HANDLE(v3dv_buffer, buffer, pInfo->buffer);
2926   return buffer->mem_offset + buffer->mem->bo->offset;
2927}
2928
2929uint64_t
2930v3dv_GetBufferOpaqueCaptureAddress(VkDevice device,
2931                                   const VkBufferDeviceAddressInfoKHR *pInfo)
2932{
2933   /* Not implemented */
2934   return 0;
2935}
2936
2937uint64_t
2938v3dv_GetDeviceMemoryOpaqueCaptureAddress(
2939    VkDevice device,
2940    const VkDeviceMemoryOpaqueCaptureAddressInfoKHR *pInfo)
2941{
2942   /* Not implemented */
2943   return 0;
2944}
2945