1/*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28#include "tu_private.h"
29#include "tu_cs.h"
30#include "git_sha1.h"
31
32#include <fcntl.h>
33#include <poll.h>
34#include <stdbool.h>
35#include <string.h>
36#include <sys/sysinfo.h>
37#include <unistd.h>
38
39#include "util/debug.h"
40#include "util/disk_cache.h"
41#include "util/u_atomic.h"
42#include "vk_format.h"
43#include "vk_util.h"
44
45/* for fd_get_driver/device_uuid() */
46#include "freedreno/common/freedreno_uuid.h"
47
48#if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
49     defined(VK_USE_PLATFORM_XCB_KHR) || \
50     defined(VK_USE_PLATFORM_XLIB_KHR) || \
51     defined(VK_USE_PLATFORM_DISPLAY_KHR)
52#define TU_HAS_SURFACE 1
53#else
54#define TU_HAS_SURFACE 0
55#endif
56
57
58static int
59tu_device_get_cache_uuid(uint16_t family, void *uuid)
60{
61   uint32_t mesa_timestamp;
62   uint16_t f = family;
63   memset(uuid, 0, VK_UUID_SIZE);
64   if (!disk_cache_get_function_timestamp(tu_device_get_cache_uuid,
65                                          &mesa_timestamp))
66      return -1;
67
68   memcpy(uuid, &mesa_timestamp, 4);
69   memcpy((char *) uuid + 4, &f, 2);
70   snprintf((char *) uuid + 6, VK_UUID_SIZE - 10, "tu");
71   return 0;
72}
73
74#define TU_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
75
76VKAPI_ATTR VkResult VKAPI_CALL
77tu_EnumerateInstanceVersion(uint32_t *pApiVersion)
78{
79    *pApiVersion = TU_API_VERSION;
80    return VK_SUCCESS;
81}
82
83static const struct vk_instance_extension_table tu_instance_extensions_supported = {
84   .KHR_device_group_creation           = true,
85   .KHR_external_fence_capabilities     = true,
86   .KHR_external_memory_capabilities    = true,
87   .KHR_external_semaphore_capabilities = true,
88   .KHR_get_physical_device_properties2 = true,
89   .KHR_surface                         = TU_HAS_SURFACE,
90   .KHR_get_surface_capabilities2       = TU_HAS_SURFACE,
91   .EXT_debug_report                    = true,
92#ifdef VK_USE_PLATFORM_WAYLAND_KHR
93   .KHR_wayland_surface                 = true,
94#endif
95#ifdef VK_USE_PLATFORM_XCB_KHR
96   .KHR_xcb_surface                     = true,
97#endif
98#ifdef VK_USE_PLATFORM_XLIB_KHR
99   .KHR_xlib_surface                    = true,
100#endif
101#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
102   .EXT_acquire_xlib_display            = true,
103#endif
104#ifdef VK_USE_PLATFORM_DISPLAY_KHR
105   .KHR_display                         = true,
106   .KHR_get_display_properties2         = true,
107   .EXT_direct_mode_display             = true,
108   .EXT_display_surface_counter         = true,
109#endif
110};
111
112static void
113get_device_extensions(const struct tu_physical_device *device,
114                      struct vk_device_extension_table *ext)
115{
116   *ext = (struct vk_device_extension_table) {
117      .KHR_16bit_storage = device->info->a6xx.storage_16bit,
118      .KHR_bind_memory2 = true,
119      .KHR_create_renderpass2 = true,
120      .KHR_dedicated_allocation = true,
121      .KHR_depth_stencil_resolve = true,
122      .KHR_descriptor_update_template = true,
123      .KHR_device_group = true,
124      .KHR_draw_indirect_count = true,
125      .KHR_external_fence = true,
126      .KHR_external_fence_fd = true,
127      .KHR_external_memory = true,
128      .KHR_external_memory_fd = true,
129      .KHR_external_semaphore = true,
130      .KHR_external_semaphore_fd = true,
131      .KHR_get_memory_requirements2 = true,
132      .KHR_imageless_framebuffer = true,
133      .KHR_incremental_present = TU_HAS_SURFACE,
134      .KHR_image_format_list = true,
135      .KHR_maintenance1 = true,
136      .KHR_maintenance2 = true,
137      .KHR_maintenance3 = true,
138      .KHR_multiview = true,
139      .KHR_performance_query = device->instance->debug_flags & TU_DEBUG_PERFC,
140      .KHR_pipeline_executable_properties = true,
141      .KHR_push_descriptor = true,
142      .KHR_relaxed_block_layout = true,
143      .KHR_sampler_mirror_clamp_to_edge = true,
144      .KHR_sampler_ycbcr_conversion = true,
145      .KHR_shader_draw_parameters = true,
146      .KHR_shader_float_controls = true,
147      .KHR_shader_float16_int8 = true,
148      .KHR_shader_subgroup_extended_types = true,
149      .KHR_shader_terminate_invocation = true,
150      .KHR_spirv_1_4 = true,
151      .KHR_storage_buffer_storage_class = true,
152      .KHR_swapchain = TU_HAS_SURFACE,
153      .KHR_uniform_buffer_standard_layout = true,
154      .KHR_variable_pointers = true,
155      .KHR_vulkan_memory_model = true,
156#ifndef TU_USE_KGSL
157      .KHR_timeline_semaphore = true,
158#endif
159#ifdef VK_USE_PLATFORM_DISPLAY_KHR
160      /* This extension is supported by common code across drivers, but it is
161       * missing some core functionality and fails
162       * dEQP-VK.wsi.display_control.register_device_event. Once some variant of
163       * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12305 lands,
164       * then we can re-enable it.
165       */
166      /* .EXT_display_control = true, */
167#endif
168      .EXT_external_memory_dma_buf = true,
169      .EXT_image_drm_format_modifier = true,
170      .EXT_sample_locations = device->info->a6xx.has_sample_locations,
171      .EXT_sampler_filter_minmax = true,
172      .EXT_transform_feedback = true,
173      .EXT_4444_formats = true,
174      .EXT_conditional_rendering = true,
175      .EXT_custom_border_color = true,
176      .EXT_depth_clip_enable = true,
177      .EXT_descriptor_indexing = true,
178      .EXT_extended_dynamic_state = true,
179      .EXT_extended_dynamic_state2 = true,
180      .EXT_filter_cubic = device->info->a6xx.has_tex_filter_cubic,
181      .EXT_host_query_reset = true,
182      .EXT_index_type_uint8 = true,
183      .EXT_memory_budget = true,
184      .EXT_private_data = true,
185      .EXT_robustness2 = true,
186      .EXT_scalar_block_layout = true,
187      .EXT_separate_stencil_usage = true,
188      .EXT_shader_demote_to_helper_invocation = true,
189      .EXT_shader_stencil_export = true,
190      .EXT_shader_viewport_index_layer = true,
191      .EXT_vertex_attribute_divisor = true,
192      .EXT_provoking_vertex = true,
193      .EXT_line_rasterization = true,
194#ifdef ANDROID
195      .ANDROID_native_buffer = true,
196#endif
197      .IMG_filter_cubic = device->info->a6xx.has_tex_filter_cubic,
198      .VALVE_mutable_descriptor_type = true,
199   };
200}
201
202VkResult
203tu_physical_device_init(struct tu_physical_device *device,
204                        struct tu_instance *instance)
205{
206   VkResult result = VK_SUCCESS;
207
208   const char *fd_name = fd_dev_name(&device->dev_id);
209   if (strncmp(fd_name, "FD", 2) == 0) {
210      device->name = vk_asprintf(&instance->vk.alloc,
211                                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE,
212                                 "Turnip Adreno (TM) %s", &fd_name[2]);
213   } else {
214      device->name = vk_strdup(&instance->vk.alloc, fd_name,
215                               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
216
217   }
218   if (!device->name) {
219      return vk_startup_errorf(instance, VK_ERROR_OUT_OF_HOST_MEMORY,
220                               "device name alloc fail");
221   }
222
223   const struct fd_dev_info *info = fd_dev_info(&device->dev_id);
224   if (!info) {
225      result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
226                                 "device %s is unsupported", device->name);
227      goto fail_free_name;
228   }
229   switch (fd_dev_gen(&device->dev_id)) {
230   case 6:
231      device->info = info;
232      device->ccu_offset_bypass = device->info->num_ccu * A6XX_CCU_DEPTH_SIZE;
233      device->ccu_offset_gmem = (device->gmem_size -
234         device->info->num_ccu * A6XX_CCU_GMEM_COLOR_SIZE);
235      break;
236   default:
237      result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
238                                 "device %s is unsupported", device->name);
239      goto fail_free_name;
240   }
241   if (tu_device_get_cache_uuid(fd_dev_gpu_id(&device->dev_id), device->cache_uuid)) {
242      result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
243                                 "cannot generate UUID");
244      goto fail_free_name;
245   }
246
247   /* The gpu id is already embedded in the uuid so we just pass "tu"
248    * when creating the cache.
249    */
250   char buf[VK_UUID_SIZE * 2 + 1];
251   disk_cache_format_hex_id(buf, device->cache_uuid, VK_UUID_SIZE * 2);
252   device->disk_cache = disk_cache_create(device->name, buf, 0);
253
254   vk_warn_non_conformant_implementation("tu");
255
256   fd_get_driver_uuid(device->driver_uuid);
257   fd_get_device_uuid(device->device_uuid, &device->dev_id);
258
259   struct vk_device_extension_table supported_extensions;
260   get_device_extensions(device, &supported_extensions);
261
262   struct vk_physical_device_dispatch_table dispatch_table;
263   vk_physical_device_dispatch_table_from_entrypoints(
264      &dispatch_table, &tu_physical_device_entrypoints, true);
265   vk_physical_device_dispatch_table_from_entrypoints(
266      &dispatch_table, &wsi_physical_device_entrypoints, false);
267
268   result = vk_physical_device_init(&device->vk, &instance->vk,
269                                    &supported_extensions,
270                                    &dispatch_table);
271   if (result != VK_SUCCESS)
272      goto fail_free_cache;
273
274#if TU_HAS_SURFACE
275   result = tu_wsi_init(device);
276   if (result != VK_SUCCESS) {
277      vk_startup_errorf(instance, result, "WSI init failure");
278      vk_physical_device_finish(&device->vk);
279      goto fail_free_cache;
280   }
281#endif
282
283   return VK_SUCCESS;
284
285fail_free_cache:
286   disk_cache_destroy(device->disk_cache);
287fail_free_name:
288   vk_free(&instance->vk.alloc, (void *)device->name);
289   return result;
290}
291
292static void
293tu_physical_device_finish(struct tu_physical_device *device)
294{
295#if TU_HAS_SURFACE
296   tu_wsi_finish(device);
297#endif
298
299   disk_cache_destroy(device->disk_cache);
300   close(device->local_fd);
301   if (device->master_fd != -1)
302      close(device->master_fd);
303
304   vk_free(&device->instance->vk.alloc, (void *)device->name);
305
306   vk_physical_device_finish(&device->vk);
307}
308
309static const struct debug_control tu_debug_options[] = {
310   { "startup", TU_DEBUG_STARTUP },
311   { "nir", TU_DEBUG_NIR },
312   { "nobin", TU_DEBUG_NOBIN },
313   { "sysmem", TU_DEBUG_SYSMEM },
314   { "forcebin", TU_DEBUG_FORCEBIN },
315   { "noubwc", TU_DEBUG_NOUBWC },
316   { "nomultipos", TU_DEBUG_NOMULTIPOS },
317   { "nolrz", TU_DEBUG_NOLRZ },
318   { "perfc", TU_DEBUG_PERFC },
319   { "flushall", TU_DEBUG_FLUSHALL },
320   { "syncdraw", TU_DEBUG_SYNCDRAW },
321   { NULL, 0 }
322};
323
324const char *
325tu_get_debug_option_name(int id)
326{
327   assert(id < ARRAY_SIZE(tu_debug_options) - 1);
328   return tu_debug_options[id].string;
329}
330
331VKAPI_ATTR VkResult VKAPI_CALL
332tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
333                  const VkAllocationCallbacks *pAllocator,
334                  VkInstance *pInstance)
335{
336   struct tu_instance *instance;
337   VkResult result;
338
339   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
340
341   if (pAllocator == NULL)
342      pAllocator = vk_default_allocator();
343
344   instance = vk_zalloc(pAllocator, sizeof(*instance), 8,
345                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
346
347   if (!instance)
348      return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
349
350   struct vk_instance_dispatch_table dispatch_table;
351   vk_instance_dispatch_table_from_entrypoints(
352      &dispatch_table, &tu_instance_entrypoints, true);
353   vk_instance_dispatch_table_from_entrypoints(
354      &dispatch_table, &wsi_instance_entrypoints, false);
355
356   result = vk_instance_init(&instance->vk,
357                             &tu_instance_extensions_supported,
358                             &dispatch_table,
359                             pCreateInfo, pAllocator);
360   if (result != VK_SUCCESS) {
361      vk_free(pAllocator, instance);
362      return vk_error(NULL, result);
363   }
364
365   instance->physical_device_count = -1;
366
367   instance->debug_flags =
368      parse_debug_string(getenv("TU_DEBUG"), tu_debug_options);
369
370#ifdef DEBUG
371   /* Enable startup debugging by default on debug drivers.  You almost always
372    * want to see your startup failures in that case, and it's hard to set
373    * this env var on android.
374    */
375   instance->debug_flags |= TU_DEBUG_STARTUP;
376#endif
377
378   if (instance->debug_flags & TU_DEBUG_STARTUP)
379      mesa_logi("Created an instance");
380
381   VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
382
383   *pInstance = tu_instance_to_handle(instance);
384
385#ifdef HAVE_PERFETTO
386   tu_perfetto_init();
387#endif
388
389   return VK_SUCCESS;
390}
391
392VKAPI_ATTR void VKAPI_CALL
393tu_DestroyInstance(VkInstance _instance,
394                   const VkAllocationCallbacks *pAllocator)
395{
396   TU_FROM_HANDLE(tu_instance, instance, _instance);
397
398   if (!instance)
399      return;
400
401   for (int i = 0; i < instance->physical_device_count; ++i) {
402      tu_physical_device_finish(instance->physical_devices + i);
403   }
404
405   VG(VALGRIND_DESTROY_MEMPOOL(instance));
406
407   vk_instance_finish(&instance->vk);
408   vk_free(&instance->vk.alloc, instance);
409}
410
411VKAPI_ATTR VkResult VKAPI_CALL
412tu_EnumeratePhysicalDevices(VkInstance _instance,
413                            uint32_t *pPhysicalDeviceCount,
414                            VkPhysicalDevice *pPhysicalDevices)
415{
416   TU_FROM_HANDLE(tu_instance, instance, _instance);
417   VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
418
419   VkResult result;
420
421   if (instance->physical_device_count < 0) {
422      result = tu_enumerate_devices(instance);
423      if (result != VK_SUCCESS && result != VK_ERROR_INCOMPATIBLE_DRIVER)
424         return result;
425   }
426
427   for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
428      vk_outarray_append(&out, p)
429      {
430         *p = tu_physical_device_to_handle(instance->physical_devices + i);
431      }
432   }
433
434   return vk_outarray_status(&out);
435}
436
437VKAPI_ATTR VkResult VKAPI_CALL
438tu_EnumeratePhysicalDeviceGroups(
439   VkInstance _instance,
440   uint32_t *pPhysicalDeviceGroupCount,
441   VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
442{
443   TU_FROM_HANDLE(tu_instance, instance, _instance);
444   VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,
445                    pPhysicalDeviceGroupCount);
446   VkResult result;
447
448   if (instance->physical_device_count < 0) {
449      result = tu_enumerate_devices(instance);
450      if (result != VK_SUCCESS && result != VK_ERROR_INCOMPATIBLE_DRIVER)
451         return result;
452   }
453
454   for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
455      vk_outarray_append(&out, p)
456      {
457         p->physicalDeviceCount = 1;
458         p->physicalDevices[0] =
459            tu_physical_device_to_handle(instance->physical_devices + i);
460         p->subsetAllocation = false;
461      }
462   }
463
464   return vk_outarray_status(&out);
465}
466
467static void
468tu_get_physical_device_features_1_1(struct tu_physical_device *pdevice,
469                                    VkPhysicalDeviceVulkan11Features *features)
470{
471   features->storageBuffer16BitAccess            = pdevice->info->a6xx.storage_16bit;
472   features->uniformAndStorageBuffer16BitAccess  = false;
473   features->storagePushConstant16               = false;
474   features->storageInputOutput16                = false;
475   features->multiview                           = true;
476   features->multiviewGeometryShader             = false;
477   features->multiviewTessellationShader         = false;
478   features->variablePointersStorageBuffer       = true;
479   features->variablePointers                    = true;
480   features->protectedMemory                     = false;
481   features->samplerYcbcrConversion              = true;
482   features->shaderDrawParameters                = true;
483}
484
485static void
486tu_get_physical_device_features_1_2(struct tu_physical_device *pdevice,
487                                    VkPhysicalDeviceVulkan12Features *features)
488{
489   features->samplerMirrorClampToEdge            = true;
490   features->drawIndirectCount                   = true;
491   features->storageBuffer8BitAccess             = false;
492   features->uniformAndStorageBuffer8BitAccess   = false;
493   features->storagePushConstant8                = false;
494   features->shaderBufferInt64Atomics            = false;
495   features->shaderSharedInt64Atomics            = false;
496   features->shaderFloat16                       = true;
497   features->shaderInt8                          = false;
498
499   features->descriptorIndexing                                 = true;
500   features->shaderInputAttachmentArrayDynamicIndexing          = false;
501   features->shaderUniformTexelBufferArrayDynamicIndexing       = true;
502   features->shaderStorageTexelBufferArrayDynamicIndexing       = true;
503   features->shaderUniformBufferArrayNonUniformIndexing         = true;
504   features->shaderSampledImageArrayNonUniformIndexing          = true;
505   features->shaderStorageBufferArrayNonUniformIndexing         = true;
506   features->shaderStorageImageArrayNonUniformIndexing          = true;
507   features->shaderInputAttachmentArrayNonUniformIndexing       = false;
508   features->shaderUniformTexelBufferArrayNonUniformIndexing    = true;
509   features->shaderStorageTexelBufferArrayNonUniformIndexing    = true;
510   features->descriptorBindingUniformBufferUpdateAfterBind      = false;
511   features->descriptorBindingSampledImageUpdateAfterBind       = true;
512   features->descriptorBindingStorageImageUpdateAfterBind       = true;
513   features->descriptorBindingStorageBufferUpdateAfterBind      = true;
514   features->descriptorBindingUniformTexelBufferUpdateAfterBind = true;
515   features->descriptorBindingStorageTexelBufferUpdateAfterBind = true;
516   features->descriptorBindingUpdateUnusedWhilePending          = true;
517   features->descriptorBindingPartiallyBound                    = true;
518   features->descriptorBindingVariableDescriptorCount           = true;
519   features->runtimeDescriptorArray                             = true;
520
521   features->samplerFilterMinmax                 = true;
522   features->scalarBlockLayout                   = true;
523   features->imagelessFramebuffer                = true;
524   features->uniformBufferStandardLayout         = true;
525   features->shaderSubgroupExtendedTypes         = true;
526   features->separateDepthStencilLayouts         = false;
527   features->hostQueryReset                      = true;
528   features->timelineSemaphore                   = true;
529   features->bufferDeviceAddress                 = false;
530   features->bufferDeviceAddressCaptureReplay    = false;
531   features->bufferDeviceAddressMultiDevice      = false;
532   features->vulkanMemoryModel                   = true;
533   features->vulkanMemoryModelDeviceScope        = true;
534   features->vulkanMemoryModelAvailabilityVisibilityChains = true;
535   features->shaderOutputViewportIndex           = true;
536   features->shaderOutputLayer                   = true;
537   features->subgroupBroadcastDynamicId          = false;
538}
539
540void
541tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
542                              VkPhysicalDeviceFeatures2 *pFeatures)
543{
544   TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
545
546   pFeatures->features = (VkPhysicalDeviceFeatures) {
547      .robustBufferAccess = true,
548      .fullDrawIndexUint32 = true,
549      .imageCubeArray = true,
550      .independentBlend = true,
551      .geometryShader = true,
552      .tessellationShader = true,
553      .sampleRateShading = true,
554      .dualSrcBlend = true,
555      .logicOp = true,
556      .multiDrawIndirect = true,
557      .drawIndirectFirstInstance = true,
558      .depthClamp = true,
559      .depthBiasClamp = true,
560      .fillModeNonSolid = true,
561      .depthBounds = true,
562      .wideLines = false,
563      .largePoints = true,
564      .alphaToOne = true,
565      .multiViewport = true,
566      .samplerAnisotropy = true,
567      .textureCompressionETC2 = true,
568      .textureCompressionASTC_LDR = true,
569      .textureCompressionBC = true,
570      .occlusionQueryPrecise = true,
571      .pipelineStatisticsQuery = true,
572      .vertexPipelineStoresAndAtomics = true,
573      .fragmentStoresAndAtomics = true,
574      .shaderTessellationAndGeometryPointSize = false,
575      .shaderImageGatherExtended = true,
576      .shaderStorageImageExtendedFormats = true,
577      .shaderStorageImageMultisample = false,
578      .shaderUniformBufferArrayDynamicIndexing = true,
579      .shaderSampledImageArrayDynamicIndexing = true,
580      .shaderStorageBufferArrayDynamicIndexing = true,
581      .shaderStorageImageArrayDynamicIndexing = true,
582      .shaderStorageImageReadWithoutFormat = true,
583      .shaderStorageImageWriteWithoutFormat = true,
584      .shaderClipDistance = true,
585      .shaderCullDistance = true,
586      .shaderFloat64 = false,
587      .shaderInt64 = false,
588      .shaderInt16 = true,
589      .sparseBinding = false,
590      .variableMultisampleRate = true,
591      .inheritedQueries = true,
592   };
593
594   VkPhysicalDeviceVulkan11Features core_1_1 = {
595      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
596   };
597   tu_get_physical_device_features_1_1(pdevice, &core_1_1);
598
599   VkPhysicalDeviceVulkan12Features core_1_2 = {
600      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
601   };
602   tu_get_physical_device_features_1_2(pdevice, &core_1_2);
603
604   vk_foreach_struct(ext, pFeatures->pNext)
605   {
606      if (vk_get_physical_device_core_1_1_feature_ext(ext, &core_1_1))
607         continue;
608      if (vk_get_physical_device_core_1_2_feature_ext(ext, &core_1_2))
609         continue;
610
611      switch (ext->sType) {
612      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
613         VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
614            (VkPhysicalDeviceConditionalRenderingFeaturesEXT *) ext;
615         features->conditionalRendering = true;
616         features->inheritedConditionalRendering = true;
617         break;
618      }
619      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
620         VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
621            (VkPhysicalDeviceTransformFeedbackFeaturesEXT *) ext;
622         features->transformFeedback = true;
623         features->geometryStreams = true;
624         break;
625      }
626      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {
627         VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =
628            (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;
629         features->indexTypeUint8 = true;
630         break;
631      }
632      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
633         VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
634            (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
635         features->vertexAttributeInstanceRateDivisor = true;
636         features->vertexAttributeInstanceRateZeroDivisor = true;
637         break;
638      }
639      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {
640         VkPhysicalDevicePrivateDataFeaturesEXT *features =
641            (VkPhysicalDevicePrivateDataFeaturesEXT *)ext;
642         features->privateData = true;
643         break;
644      }
645      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
646         VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =
647            (VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;
648         features->depthClipEnable = true;
649         break;
650      }
651      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: {
652         VkPhysicalDevice4444FormatsFeaturesEXT *features = (void *)ext;
653         features->formatA4R4G4B4 = true;
654         features->formatA4B4G4R4 = true;
655         break;
656      }
657      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
658         VkPhysicalDeviceCustomBorderColorFeaturesEXT *features = (void *) ext;
659         features->customBorderColors = true;
660         features->customBorderColorWithoutFormat = true;
661         break;
662      }
663      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {
664         VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features = (void *)ext;
665         features->extendedDynamicState = true;
666         break;
667      }
668      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: {
669         VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features =
670            (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;
671         features->extendedDynamicState2 = true;
672         features->extendedDynamicState2LogicOp = false;
673         features->extendedDynamicState2PatchControlPoints = false;
674         break;
675      }
676      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {
677         VkPhysicalDevicePerformanceQueryFeaturesKHR *feature =
678            (VkPhysicalDevicePerformanceQueryFeaturesKHR *)ext;
679         feature->performanceCounterQueryPools = true;
680         feature->performanceCounterMultipleQueryPools = false;
681         break;
682      }
683      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR: {
684         VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *features =
685            (VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *)ext;
686         features->pipelineExecutableInfo = true;
687         break;
688      }
689      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES: {
690         VkPhysicalDeviceShaderFloat16Int8Features *features =
691            (VkPhysicalDeviceShaderFloat16Int8Features *) ext;
692         features->shaderFloat16 = true;
693         features->shaderInt8 = false;
694         break;
695      }
696      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
697         VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features = (void *)ext;
698         features->scalarBlockLayout = true;
699         break;
700      }
701      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
702         VkPhysicalDeviceRobustness2FeaturesEXT *features = (void *)ext;
703         features->robustBufferAccess2 = true;
704         features->robustImageAccess2 = true;
705         features->nullDescriptor = true;
706         break;
707      }
708      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT: {
709         VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *features =
710            (VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *)ext;
711         features->shaderDemoteToHelperInvocation = true;
712         break;
713      }
714      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR: {
715         VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *features =
716            (VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *)ext;
717         features->shaderTerminateInvocation = true;
718         break;
719      }
720      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES: {
721         VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *features =
722            (VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *) ext;
723         features->timelineSemaphore = true;
724         break;
725      }
726      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {
727         VkPhysicalDeviceProvokingVertexFeaturesEXT *features =
728            (VkPhysicalDeviceProvokingVertexFeaturesEXT *)ext;
729         features->provokingVertexLast = true;
730         features->transformFeedbackPreservesProvokingVertex = true;
731         break;
732      }
733      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE: {
734         VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *features =
735            (VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *)ext;
736         features->mutableDescriptorType = true;
737         break;
738      }
739      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
740         VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
741            (VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
742         features->rectangularLines = true;
743         features->bresenhamLines = true;
744         features->smoothLines = false;
745         features->stippledRectangularLines = false;
746         features->stippledBresenhamLines = false;
747         features->stippledSmoothLines = false;
748         break;
749      }
750
751      default:
752         break;
753      }
754   }
755}
756
757
758static void
759tu_get_physical_device_properties_1_1(struct tu_physical_device *pdevice,
760                                       VkPhysicalDeviceVulkan11Properties *p)
761{
762   assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES);
763
764   memcpy(p->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
765   memcpy(p->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
766   memset(p->deviceLUID, 0, VK_LUID_SIZE);
767   p->deviceNodeMask = 0;
768   p->deviceLUIDValid = false;
769
770   p->subgroupSize = 128;
771   p->subgroupSupportedStages = VK_SHADER_STAGE_COMPUTE_BIT;
772   p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT |
773                                    VK_SUBGROUP_FEATURE_VOTE_BIT |
774                                    VK_SUBGROUP_FEATURE_BALLOT_BIT;
775   p->subgroupQuadOperationsInAllStages = false;
776
777   p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
778   p->maxMultiviewViewCount = MAX_VIEWS;
779   p->maxMultiviewInstanceIndex = INT_MAX;
780   p->protectedNoFault = false;
781   /* Make sure everything is addressable by a signed 32-bit int, and
782    * our largest descriptors are 96 bytes.
783    */
784   p->maxPerSetDescriptors = (1ull << 31) / 96;
785   /* Our buffer size fields allow only this much */
786   p->maxMemoryAllocationSize = 0xFFFFFFFFull;
787
788}
789
790
791/* I have no idea what the maximum size is, but the hardware supports very
792 * large numbers of descriptors (at least 2^16). This limit is based on
793 * CP_LOAD_STATE6, which has a 28-bit field for the DWORD offset, so that
794 * we don't have to think about what to do if that overflows, but really
795 * nothing is likely to get close to this.
796 */
797static const size_t max_descriptor_set_size = (1 << 28) / A6XX_TEX_CONST_DWORDS;
798static const VkSampleCountFlags sample_counts =
799   VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT;
800
801static void
802tu_get_physical_device_properties_1_2(struct tu_physical_device *pdevice,
803                                       VkPhysicalDeviceVulkan12Properties *p)
804{
805   assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES);
806
807   p->driverID = VK_DRIVER_ID_MESA_TURNIP;
808   memset(p->driverName, 0, sizeof(p->driverName));
809   snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE_KHR,
810            "turnip Mesa driver");
811   memset(p->driverInfo, 0, sizeof(p->driverInfo));
812   snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR,
813            "Mesa " PACKAGE_VERSION MESA_GIT_SHA1);
814   /* XXX: VK 1.2: Need to pass conformance. */
815   p->conformanceVersion = (VkConformanceVersionKHR) {
816      .major = 0,
817      .minor = 0,
818      .subminor = 0,
819      .patch = 0,
820   };
821
822   p->denormBehaviorIndependence =
823      VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
824   p->roundingModeIndependence =
825      VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
826
827   p->shaderDenormFlushToZeroFloat16         = true;
828   p->shaderDenormPreserveFloat16            = false;
829   p->shaderRoundingModeRTEFloat16           = true;
830   p->shaderRoundingModeRTZFloat16           = false;
831   p->shaderSignedZeroInfNanPreserveFloat16  = true;
832
833   p->shaderDenormFlushToZeroFloat32         = true;
834   p->shaderDenormPreserveFloat32            = false;
835   p->shaderRoundingModeRTEFloat32           = true;
836   p->shaderRoundingModeRTZFloat32           = false;
837   p->shaderSignedZeroInfNanPreserveFloat32  = true;
838
839   p->shaderDenormFlushToZeroFloat64         = false;
840   p->shaderDenormPreserveFloat64            = false;
841   p->shaderRoundingModeRTEFloat64           = false;
842   p->shaderRoundingModeRTZFloat64           = false;
843   p->shaderSignedZeroInfNanPreserveFloat64  = false;
844
845   p->shaderUniformBufferArrayNonUniformIndexingNative   = true;
846   p->shaderSampledImageArrayNonUniformIndexingNative    = true;
847   p->shaderStorageBufferArrayNonUniformIndexingNative   = true;
848   p->shaderStorageImageArrayNonUniformIndexingNative    = true;
849   p->shaderInputAttachmentArrayNonUniformIndexingNative = false;
850   p->robustBufferAccessUpdateAfterBind                  = false;
851   p->quadDivergentImplicitLod                           = false;
852
853   p->maxUpdateAfterBindDescriptorsInAllPools            = max_descriptor_set_size;
854   p->maxPerStageDescriptorUpdateAfterBindSamplers       = max_descriptor_set_size;
855   p->maxPerStageDescriptorUpdateAfterBindUniformBuffers = max_descriptor_set_size;
856   p->maxPerStageDescriptorUpdateAfterBindStorageBuffers = max_descriptor_set_size;
857   p->maxPerStageDescriptorUpdateAfterBindSampledImages  = max_descriptor_set_size;
858   p->maxPerStageDescriptorUpdateAfterBindStorageImages  = max_descriptor_set_size;
859   p->maxPerStageDescriptorUpdateAfterBindInputAttachments = max_descriptor_set_size;
860   p->maxPerStageUpdateAfterBindResources                = max_descriptor_set_size;
861   p->maxDescriptorSetUpdateAfterBindSamplers            = max_descriptor_set_size;
862   p->maxDescriptorSetUpdateAfterBindUniformBuffers      = max_descriptor_set_size;
863   p->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS;
864   p->maxDescriptorSetUpdateAfterBindStorageBuffers      = max_descriptor_set_size;
865   p->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS;
866   p->maxDescriptorSetUpdateAfterBindSampledImages       = max_descriptor_set_size;
867   p->maxDescriptorSetUpdateAfterBindStorageImages       = max_descriptor_set_size;
868   p->maxDescriptorSetUpdateAfterBindInputAttachments    = max_descriptor_set_size;
869
870   p->supportedDepthResolveModes    = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
871   p->supportedStencilResolveModes  = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
872   p->independentResolveNone  = false;
873   p->independentResolve      = false;
874
875   p->filterMinmaxSingleComponentFormats  = true;
876   p->filterMinmaxImageComponentMapping   = true;
877
878   p->maxTimelineSemaphoreValueDifference = UINT64_MAX;
879
880   p->framebufferIntegerColorSampleCounts = sample_counts;
881}
882
883VKAPI_ATTR void VKAPI_CALL
884tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
885                                VkPhysicalDeviceProperties2 *pProperties)
886{
887   TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
888
889   VkPhysicalDeviceLimits limits = {
890      .maxImageDimension1D = (1 << 14),
891      .maxImageDimension2D = (1 << 14),
892      .maxImageDimension3D = (1 << 11),
893      .maxImageDimensionCube = (1 << 14),
894      .maxImageArrayLayers = (1 << 11),
895      .maxTexelBufferElements = 128 * 1024 * 1024,
896      .maxUniformBufferRange = MAX_UNIFORM_BUFFER_RANGE,
897      .maxStorageBufferRange = MAX_STORAGE_BUFFER_RANGE,
898      .maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
899      .maxMemoryAllocationCount = UINT32_MAX,
900      .maxSamplerAllocationCount = 64 * 1024,
901      .bufferImageGranularity = 64,          /* A cache line */
902      .sparseAddressSpaceSize = 0,
903      .maxBoundDescriptorSets = MAX_SETS,
904      .maxPerStageDescriptorSamplers = max_descriptor_set_size,
905      .maxPerStageDescriptorUniformBuffers = max_descriptor_set_size,
906      .maxPerStageDescriptorStorageBuffers = max_descriptor_set_size,
907      .maxPerStageDescriptorSampledImages = max_descriptor_set_size,
908      .maxPerStageDescriptorStorageImages = max_descriptor_set_size,
909      .maxPerStageDescriptorInputAttachments = MAX_RTS,
910      .maxPerStageResources = max_descriptor_set_size,
911      .maxDescriptorSetSamplers = max_descriptor_set_size,
912      .maxDescriptorSetUniformBuffers = max_descriptor_set_size,
913      .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS,
914      .maxDescriptorSetStorageBuffers = max_descriptor_set_size,
915      .maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS,
916      .maxDescriptorSetSampledImages = max_descriptor_set_size,
917      .maxDescriptorSetStorageImages = max_descriptor_set_size,
918      .maxDescriptorSetInputAttachments = MAX_RTS,
919      .maxVertexInputAttributes = 32,
920      .maxVertexInputBindings = 32,
921      .maxVertexInputAttributeOffset = 4095,
922      .maxVertexInputBindingStride = 2048,
923      .maxVertexOutputComponents = 128,
924      .maxTessellationGenerationLevel = 64,
925      .maxTessellationPatchSize = 32,
926      .maxTessellationControlPerVertexInputComponents = 128,
927      .maxTessellationControlPerVertexOutputComponents = 128,
928      .maxTessellationControlPerPatchOutputComponents = 120,
929      .maxTessellationControlTotalOutputComponents = 4096,
930      .maxTessellationEvaluationInputComponents = 128,
931      .maxTessellationEvaluationOutputComponents = 128,
932      .maxGeometryShaderInvocations = 32,
933      .maxGeometryInputComponents = 64,
934      .maxGeometryOutputComponents = 128,
935      .maxGeometryOutputVertices = 256,
936      .maxGeometryTotalOutputComponents = 1024,
937      .maxFragmentInputComponents = 124,
938      .maxFragmentOutputAttachments = 8,
939      .maxFragmentDualSrcAttachments = 1,
940      .maxFragmentCombinedOutputResources = 8,
941      .maxComputeSharedMemorySize = 32768,
942      .maxComputeWorkGroupCount = { 65535, 65535, 65535 },
943      .maxComputeWorkGroupInvocations = 2048,
944      .maxComputeWorkGroupSize = { 1024, 1024, 1024 },
945      .subPixelPrecisionBits = 8,
946      .subTexelPrecisionBits = 8,
947      .mipmapPrecisionBits = 8,
948      .maxDrawIndexedIndexValue = UINT32_MAX,
949      .maxDrawIndirectCount = UINT32_MAX,
950      .maxSamplerLodBias = 4095.0 / 256.0, /* [-16, 15.99609375] */
951      .maxSamplerAnisotropy = 16,
952      .maxViewports = MAX_VIEWPORTS,
953      .maxViewportDimensions = { MAX_VIEWPORT_SIZE, MAX_VIEWPORT_SIZE },
954      .viewportBoundsRange = { INT16_MIN, INT16_MAX },
955      .viewportSubPixelBits = 8,
956      .minMemoryMapAlignment = 4096, /* A page */
957      .minTexelBufferOffsetAlignment = 64,
958      .minUniformBufferOffsetAlignment = 64,
959      .minStorageBufferOffsetAlignment = 64,
960      .minTexelOffset = -16,
961      .maxTexelOffset = 15,
962      .minTexelGatherOffset = -32,
963      .maxTexelGatherOffset = 31,
964      .minInterpolationOffset = -0.5,
965      .maxInterpolationOffset = 0.4375,
966      .subPixelInterpolationOffsetBits = 4,
967      .maxFramebufferWidth = (1 << 14),
968      .maxFramebufferHeight = (1 << 14),
969      .maxFramebufferLayers = (1 << 10),
970      .framebufferColorSampleCounts = sample_counts,
971      .framebufferDepthSampleCounts = sample_counts,
972      .framebufferStencilSampleCounts = sample_counts,
973      .framebufferNoAttachmentsSampleCounts = sample_counts,
974      .maxColorAttachments = MAX_RTS,
975      .sampledImageColorSampleCounts = sample_counts,
976      .sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT,
977      .sampledImageDepthSampleCounts = sample_counts,
978      .sampledImageStencilSampleCounts = sample_counts,
979      .storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
980      .maxSampleMaskWords = 1,
981      .timestampComputeAndGraphics = true,
982      .timestampPeriod = 1000000000.0 / 19200000.0, /* CP_ALWAYS_ON_COUNTER is fixed 19.2MHz */
983      .maxClipDistances = 8,
984      .maxCullDistances = 8,
985      .maxCombinedClipAndCullDistances = 8,
986      .discreteQueuePriorities = 2,
987      .pointSizeRange = { 1, 4092 },
988      .lineWidthRange = { 1.0, 1.0 },
989      .pointSizeGranularity = 	0.0625,
990      .lineWidthGranularity = 0.0,
991      .strictLines = true,
992      .standardSampleLocations = true,
993      .optimalBufferCopyOffsetAlignment = 128,
994      .optimalBufferCopyRowPitchAlignment = 128,
995      .nonCoherentAtomSize = 64,
996   };
997
998   pProperties->properties = (VkPhysicalDeviceProperties) {
999      .apiVersion = TU_API_VERSION,
1000      .driverVersion = vk_get_driver_version(),
1001      .vendorID = 0x5143,
1002      .deviceID = pdevice->dev_id.chip_id,
1003      .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
1004      .limits = limits,
1005      .sparseProperties = { 0 },
1006   };
1007
1008   strcpy(pProperties->properties.deviceName, pdevice->name);
1009   memcpy(pProperties->properties.pipelineCacheUUID, pdevice->cache_uuid, VK_UUID_SIZE);
1010
1011   VkPhysicalDeviceVulkan11Properties core_1_1 = {
1012      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
1013   };
1014   tu_get_physical_device_properties_1_1(pdevice, &core_1_1);
1015
1016   VkPhysicalDeviceVulkan12Properties core_1_2 = {
1017      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES,
1018   };
1019   tu_get_physical_device_properties_1_2(pdevice, &core_1_2);
1020
1021   vk_foreach_struct(ext, pProperties->pNext)
1022   {
1023      if (vk_get_physical_device_core_1_1_property_ext(ext, &core_1_1))
1024         continue;
1025      if (vk_get_physical_device_core_1_2_property_ext(ext, &core_1_2))
1026         continue;
1027
1028      switch (ext->sType) {
1029      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
1030         VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
1031            (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
1032         properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
1033         break;
1034      }
1035      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
1036         VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =
1037            (VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext;
1038
1039         properties->maxTransformFeedbackStreams = IR3_MAX_SO_STREAMS;
1040         properties->maxTransformFeedbackBuffers = IR3_MAX_SO_BUFFERS;
1041         properties->maxTransformFeedbackBufferSize = UINT32_MAX;
1042         properties->maxTransformFeedbackStreamDataSize = 512;
1043         properties->maxTransformFeedbackBufferDataSize = 512;
1044         properties->maxTransformFeedbackBufferDataStride = 512;
1045         properties->transformFeedbackQueries = true;
1046         properties->transformFeedbackStreamsLinesTriangles = true;
1047         properties->transformFeedbackRasterizationStreamSelect = true;
1048         properties->transformFeedbackDraw = true;
1049         break;
1050      }
1051      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT: {
1052         VkPhysicalDeviceSampleLocationsPropertiesEXT *properties =
1053            (VkPhysicalDeviceSampleLocationsPropertiesEXT *)ext;
1054         properties->sampleLocationSampleCounts = 0;
1055         if (pdevice->vk.supported_extensions.EXT_sample_locations) {
1056            properties->sampleLocationSampleCounts =
1057               VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT;
1058         }
1059         properties->maxSampleLocationGridSize = (VkExtent2D) { 1 , 1 };
1060         properties->sampleLocationCoordinateRange[0] = 0.0f;
1061         properties->sampleLocationCoordinateRange[1] = 0.9375f;
1062         properties->sampleLocationSubPixelBits = 4;
1063         properties->variableSampleLocations = true;
1064         break;
1065      }
1066      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
1067         VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
1068            (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
1069         props->maxVertexAttribDivisor = UINT32_MAX;
1070         break;
1071      }
1072      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
1073         VkPhysicalDeviceCustomBorderColorPropertiesEXT *props = (void *)ext;
1074         props->maxCustomBorderColorSamplers = TU_BORDER_COLOR_COUNT;
1075         break;
1076      }
1077      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR: {
1078         VkPhysicalDevicePerformanceQueryPropertiesKHR *properties =
1079            (VkPhysicalDevicePerformanceQueryPropertiesKHR *)ext;
1080         properties->allowCommandBufferQueryCopies = false;
1081         break;
1082      }
1083      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: {
1084         VkPhysicalDeviceRobustness2PropertiesEXT *props = (void *)ext;
1085         /* see write_buffer_descriptor() */
1086         props->robustStorageBufferAccessSizeAlignment = 4;
1087         /* see write_ubo_descriptor() */
1088         props->robustUniformBufferAccessSizeAlignment = 16;
1089         break;
1090      }
1091
1092      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {
1093         VkPhysicalDeviceProvokingVertexPropertiesEXT *properties =
1094            (VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext;
1095         properties->provokingVertexModePerPipeline = true;
1096         properties->transformFeedbackPreservesTriangleFanProvokingVertex = false;
1097         break;
1098      }
1099      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
1100         VkPhysicalDeviceLineRasterizationPropertiesEXT *props =
1101            (VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
1102         props->lineSubPixelPrecisionBits = 8;
1103         break;
1104      }
1105
1106      default:
1107         break;
1108      }
1109   }
1110}
1111
1112static const VkQueueFamilyProperties tu_queue_family_properties = {
1113   .queueFlags =
1114      VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT,
1115   .queueCount = 1,
1116   .timestampValidBits = 48,
1117   .minImageTransferGranularity = { 1, 1, 1 },
1118};
1119
1120VKAPI_ATTR void VKAPI_CALL
1121tu_GetPhysicalDeviceQueueFamilyProperties2(
1122   VkPhysicalDevice physicalDevice,
1123   uint32_t *pQueueFamilyPropertyCount,
1124   VkQueueFamilyProperties2 *pQueueFamilyProperties)
1125{
1126   VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
1127
1128   vk_outarray_append(&out, p)
1129   {
1130      p->queueFamilyProperties = tu_queue_family_properties;
1131   }
1132}
1133
1134uint64_t
1135tu_get_system_heap_size()
1136{
1137   struct sysinfo info;
1138   sysinfo(&info);
1139
1140   uint64_t total_ram = (uint64_t) info.totalram * (uint64_t) info.mem_unit;
1141
1142   /* We don't want to burn too much ram with the GPU.  If the user has 4GiB
1143    * or less, we use at most half.  If they have more than 4GiB, we use 3/4.
1144    */
1145   uint64_t available_ram;
1146   if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
1147      available_ram = total_ram / 2;
1148   else
1149      available_ram = total_ram * 3 / 4;
1150
1151   return available_ram;
1152}
1153
1154static VkDeviceSize
1155tu_get_budget_memory(struct tu_physical_device *physical_device)
1156{
1157   uint64_t heap_size = physical_device->heap.size;
1158   uint64_t heap_used = physical_device->heap.used;
1159   uint64_t sys_available;
1160   ASSERTED bool has_available_memory =
1161      os_get_available_system_memory(&sys_available);
1162   assert(has_available_memory);
1163
1164   /*
1165    * Let's not incite the app to starve the system: report at most 90% of
1166    * available system memory.
1167    */
1168   uint64_t heap_available = sys_available * 9 / 10;
1169   return MIN2(heap_size, heap_used + heap_available);
1170}
1171
1172VKAPI_ATTR void VKAPI_CALL
1173tu_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice pdev,
1174                                      VkPhysicalDeviceMemoryProperties2 *props2)
1175{
1176   TU_FROM_HANDLE(tu_physical_device, physical_device, pdev);
1177
1178   VkPhysicalDeviceMemoryProperties *props = &props2->memoryProperties;
1179   props->memoryHeapCount = 1;
1180   props->memoryHeaps[0].size = physical_device->heap.size;
1181   props->memoryHeaps[0].flags = physical_device->heap.flags;
1182
1183   props->memoryTypeCount = 1;
1184   props->memoryTypes[0].propertyFlags =
1185      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1186      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
1187      VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
1188   props->memoryTypes[0].heapIndex = 0;
1189
1190   vk_foreach_struct(ext, props2->pNext)
1191   {
1192      switch (ext->sType) {
1193      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: {
1194         VkPhysicalDeviceMemoryBudgetPropertiesEXT *memory_budget_props =
1195            (VkPhysicalDeviceMemoryBudgetPropertiesEXT *) ext;
1196         memory_budget_props->heapUsage[0] = physical_device->heap.used;
1197         memory_budget_props->heapBudget[0] = tu_get_budget_memory(physical_device);
1198
1199         /* The heapBudget and heapUsage values must be zero for array elements
1200          * greater than or equal to VkPhysicalDeviceMemoryProperties::memoryHeapCount
1201          */
1202         for (unsigned i = 1; i < VK_MAX_MEMORY_HEAPS; i++) {
1203            memory_budget_props->heapBudget[i] = 0u;
1204            memory_budget_props->heapUsage[i] = 0u;
1205         }
1206         break;
1207      }
1208      default:
1209         break;
1210      }
1211   }
1212}
1213
1214static VkResult
1215tu_queue_init(struct tu_device *device,
1216              struct tu_queue *queue,
1217              int idx,
1218              const VkDeviceQueueCreateInfo *create_info)
1219{
1220   VkResult result = vk_queue_init(&queue->vk, &device->vk, create_info, idx);
1221   if (result != VK_SUCCESS)
1222      return result;
1223
1224   queue->device = device;
1225
1226   list_inithead(&queue->queued_submits);
1227
1228   int ret = tu_drm_submitqueue_new(device, 0, &queue->msm_queue_id);
1229   if (ret)
1230      return vk_startup_errorf(device->instance, VK_ERROR_INITIALIZATION_FAILED,
1231                               "submitqueue create failed");
1232
1233   queue->fence = -1;
1234
1235   return VK_SUCCESS;
1236}
1237
1238static void
1239tu_queue_finish(struct tu_queue *queue)
1240{
1241   vk_queue_finish(&queue->vk);
1242   if (queue->fence >= 0)
1243      close(queue->fence);
1244   tu_drm_submitqueue_close(queue->device, queue->msm_queue_id);
1245}
1246
1247uint64_t
1248tu_device_ticks_to_ns(struct tu_device *dev, uint64_t ts)
1249{
1250   /* This is based on the 19.2MHz always-on rbbm timer.
1251    *
1252    * TODO we should probably query this value from kernel..
1253    */
1254   return ts * (1000000000 / 19200000);
1255}
1256
1257static void*
1258tu_trace_create_ts_buffer(struct u_trace_context *utctx, uint32_t size)
1259{
1260   struct tu_device *device =
1261      container_of(utctx, struct tu_device, trace_context);
1262
1263   struct tu_bo *bo = ralloc(NULL, struct tu_bo);
1264   tu_bo_init_new(device, bo, size, false);
1265
1266   return bo;
1267}
1268
1269static void
1270tu_trace_destroy_ts_buffer(struct u_trace_context *utctx, void *timestamps)
1271{
1272   struct tu_device *device =
1273      container_of(utctx, struct tu_device, trace_context);
1274   struct tu_bo *bo = timestamps;
1275
1276   tu_bo_finish(device, bo);
1277   ralloc_free(bo);
1278}
1279
1280static void
1281tu_trace_record_ts(struct u_trace *ut, void *cs, void *timestamps,
1282                   unsigned idx)
1283{
1284   struct tu_bo *bo = timestamps;
1285   struct tu_cs *ts_cs = cs;
1286
1287   unsigned ts_offset = idx * sizeof(uint64_t);
1288   tu_cs_emit_pkt7(ts_cs, CP_EVENT_WRITE, 4);
1289   tu_cs_emit(ts_cs, CP_EVENT_WRITE_0_EVENT(RB_DONE_TS) | CP_EVENT_WRITE_0_TIMESTAMP);
1290   tu_cs_emit_qw(ts_cs, bo->iova + ts_offset);
1291   tu_cs_emit(ts_cs, 0x00000000);
1292}
1293
1294static uint64_t
1295tu_trace_read_ts(struct u_trace_context *utctx,
1296                 void *timestamps, unsigned idx, void *flush_data)
1297{
1298   struct tu_device *device =
1299      container_of(utctx, struct tu_device, trace_context);
1300   struct tu_bo *bo = timestamps;
1301   struct tu_u_trace_flush_data *trace_flush_data = flush_data;
1302
1303   /* Only need to stall on results for the first entry: */
1304   if (idx == 0) {
1305      tu_device_wait_u_trace(device, trace_flush_data->syncobj);
1306   }
1307
1308   if (tu_bo_map(device, bo) != VK_SUCCESS) {
1309      return U_TRACE_NO_TIMESTAMP;
1310   }
1311
1312   uint64_t *ts = bo->map;
1313
1314   /* Don't translate the no-timestamp marker: */
1315   if (ts[idx] == U_TRACE_NO_TIMESTAMP)
1316      return U_TRACE_NO_TIMESTAMP;
1317
1318   return tu_device_ticks_to_ns(device, ts[idx]);
1319}
1320
1321static void
1322tu_trace_delete_flush_data(struct u_trace_context *utctx, void *flush_data)
1323{
1324   struct tu_device *device =
1325      container_of(utctx, struct tu_device, trace_context);
1326   struct tu_u_trace_flush_data *trace_flush_data = flush_data;
1327
1328   tu_u_trace_cmd_data_finish(device, trace_flush_data->cmd_trace_data,
1329                              trace_flush_data->trace_count);
1330   vk_free(&device->vk.alloc, trace_flush_data->syncobj);
1331   vk_free(&device->vk.alloc, trace_flush_data);
1332}
1333
1334void
1335tu_copy_timestamp_buffer(struct u_trace_context *utctx, void *cmdstream,
1336                         void *ts_from, uint32_t from_offset,
1337                         void *ts_to, uint32_t to_offset,
1338                         uint32_t count)
1339{
1340   struct tu_cs *cs = cmdstream;
1341   struct tu_bo *bo_from = ts_from;
1342   struct tu_bo *bo_to = ts_to;
1343
1344   tu_cs_emit_pkt7(cs, CP_MEMCPY, 5);
1345   tu_cs_emit(cs, count * sizeof(uint64_t) / sizeof(uint32_t));
1346   tu_cs_emit_qw(cs, bo_from->iova + from_offset * sizeof(uint64_t));
1347   tu_cs_emit_qw(cs, bo_to->iova + to_offset * sizeof(uint64_t));
1348}
1349
1350VkResult
1351tu_create_copy_timestamp_cs(struct tu_cmd_buffer *cmdbuf, struct tu_cs** cs,
1352                            struct u_trace **trace_copy)
1353{
1354   *cs = vk_zalloc(&cmdbuf->device->vk.alloc, sizeof(struct tu_cs), 8,
1355                   VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1356
1357   if (*cs == NULL) {
1358      return VK_ERROR_OUT_OF_HOST_MEMORY;
1359   }
1360
1361   tu_cs_init(*cs, cmdbuf->device, TU_CS_MODE_GROW,
1362              list_length(&cmdbuf->trace.trace_chunks) * 6 + 3);
1363
1364   tu_cs_begin(*cs);
1365
1366   tu_cs_emit_wfi(*cs);
1367   tu_cs_emit_pkt7(*cs, CP_WAIT_FOR_ME, 0);
1368
1369   *trace_copy = vk_zalloc(&cmdbuf->device->vk.alloc, sizeof(struct u_trace), 8,
1370                           VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1371
1372   if (*trace_copy == NULL) {
1373      return VK_ERROR_OUT_OF_HOST_MEMORY;
1374   }
1375
1376   u_trace_init(*trace_copy, cmdbuf->trace.utctx);
1377   u_trace_clone_append(u_trace_begin_iterator(&cmdbuf->trace),
1378                        u_trace_end_iterator(&cmdbuf->trace),
1379                        *trace_copy, *cs,
1380                        tu_copy_timestamp_buffer);
1381
1382   tu_cs_emit_wfi(*cs);
1383
1384   tu_cs_end(*cs);
1385
1386   return VK_SUCCESS;
1387}
1388
1389void
1390tu_u_trace_cmd_data_finish(struct tu_device *device,
1391                           struct tu_u_trace_cmd_data *trace_data,
1392                           uint32_t entry_count)
1393{
1394   for (uint32_t i = 0; i < entry_count; ++i) {
1395      /* Only if we had to create a copy of trace we should free it */
1396      if (trace_data[i].timestamp_copy_cs != NULL) {
1397         tu_cs_finish(trace_data[i].timestamp_copy_cs);
1398         vk_free(&device->vk.alloc, trace_data[i].timestamp_copy_cs);
1399
1400         u_trace_fini(trace_data[i].trace);
1401         vk_free(&device->vk.alloc, trace_data[i].trace);
1402      }
1403   }
1404
1405   vk_free(&device->vk.alloc, trace_data);
1406}
1407
1408VKAPI_ATTR VkResult VKAPI_CALL
1409tu_CreateDevice(VkPhysicalDevice physicalDevice,
1410                const VkDeviceCreateInfo *pCreateInfo,
1411                const VkAllocationCallbacks *pAllocator,
1412                VkDevice *pDevice)
1413{
1414   TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
1415   VkResult result;
1416   struct tu_device *device;
1417   bool custom_border_colors = false;
1418   bool perf_query_pools = false;
1419   bool robust_buffer_access2 = false;
1420
1421   vk_foreach_struct_const(ext, pCreateInfo->pNext) {
1422      switch (ext->sType) {
1423      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
1424         const VkPhysicalDeviceCustomBorderColorFeaturesEXT *border_color_features = (const void *)ext;
1425         custom_border_colors = border_color_features->customBorderColors;
1426         break;
1427      }
1428      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {
1429         const VkPhysicalDevicePerformanceQueryFeaturesKHR *feature =
1430            (VkPhysicalDevicePerformanceQueryFeaturesKHR *)ext;
1431         perf_query_pools = feature->performanceCounterQueryPools;
1432         break;
1433      }
1434      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
1435         VkPhysicalDeviceRobustness2FeaturesEXT *features = (void *)ext;
1436         robust_buffer_access2 = features->robustBufferAccess2;
1437         break;
1438      }
1439      default:
1440         break;
1441      }
1442   }
1443
1444   device = vk_zalloc2(&physical_device->instance->vk.alloc, pAllocator,
1445                       sizeof(*device), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1446   if (!device)
1447      return vk_startup_errorf(physical_device->instance, VK_ERROR_OUT_OF_HOST_MEMORY, "OOM");
1448
1449   struct vk_device_dispatch_table dispatch_table;
1450   vk_device_dispatch_table_from_entrypoints(
1451      &dispatch_table, &tu_device_entrypoints, true);
1452   vk_device_dispatch_table_from_entrypoints(
1453      &dispatch_table, &wsi_device_entrypoints, false);
1454
1455   result = vk_device_init(&device->vk, &physical_device->vk,
1456                           &dispatch_table, pCreateInfo, pAllocator);
1457   if (result != VK_SUCCESS) {
1458      vk_free(&device->vk.alloc, device);
1459      return vk_startup_errorf(physical_device->instance, result,
1460                               "vk_device_init failed");
1461   }
1462
1463   device->instance = physical_device->instance;
1464   device->physical_device = physical_device;
1465   device->fd = physical_device->local_fd;
1466   device->_lost = false;
1467
1468   mtx_init(&device->bo_mutex, mtx_plain);
1469   pthread_mutex_init(&device->submit_mutex, NULL);
1470
1471   for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
1472      const VkDeviceQueueCreateInfo *queue_create =
1473         &pCreateInfo->pQueueCreateInfos[i];
1474      uint32_t qfi = queue_create->queueFamilyIndex;
1475      device->queues[qfi] = vk_alloc(
1476         &device->vk.alloc, queue_create->queueCount * sizeof(struct tu_queue),
1477         8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1478      if (!device->queues[qfi]) {
1479         result = vk_startup_errorf(physical_device->instance,
1480                                    VK_ERROR_OUT_OF_HOST_MEMORY,
1481                                    "OOM");
1482         goto fail_queues;
1483      }
1484
1485      memset(device->queues[qfi], 0,
1486             queue_create->queueCount * sizeof(struct tu_queue));
1487
1488      device->queue_count[qfi] = queue_create->queueCount;
1489
1490      for (unsigned q = 0; q < queue_create->queueCount; q++) {
1491         result = tu_queue_init(device, &device->queues[qfi][q], q,
1492                                queue_create);
1493         if (result != VK_SUCCESS)
1494            goto fail_queues;
1495      }
1496   }
1497
1498   device->compiler = ir3_compiler_create(NULL, &physical_device->dev_id,
1499                                          robust_buffer_access2);
1500   if (!device->compiler) {
1501      result = vk_startup_errorf(physical_device->instance,
1502                                 VK_ERROR_INITIALIZATION_FAILED,
1503                                 "failed to initialize ir3 compiler");
1504      goto fail_queues;
1505   }
1506
1507   /* initial sizes, these will increase if there is overflow */
1508   device->vsc_draw_strm_pitch = 0x1000 + VSC_PAD;
1509   device->vsc_prim_strm_pitch = 0x4000 + VSC_PAD;
1510
1511   uint32_t global_size = sizeof(struct tu6_global);
1512   if (custom_border_colors)
1513      global_size += TU_BORDER_COLOR_COUNT * sizeof(struct bcolor_entry);
1514
1515   result = tu_bo_init_new(device, &device->global_bo, global_size,
1516                           TU_BO_ALLOC_ALLOW_DUMP);
1517   if (result != VK_SUCCESS) {
1518      vk_startup_errorf(device->instance, result, "BO init");
1519      goto fail_global_bo;
1520   }
1521
1522   result = tu_bo_map(device, &device->global_bo);
1523   if (result != VK_SUCCESS) {
1524      vk_startup_errorf(device->instance, result, "BO map");
1525      goto fail_global_bo_map;
1526   }
1527
1528   struct tu6_global *global = device->global_bo.map;
1529   tu_init_clear_blit_shaders(device);
1530   global->predicate = 0;
1531   tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK],
1532                         &(VkClearColorValue) {}, false);
1533   tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_TRANSPARENT_BLACK],
1534                         &(VkClearColorValue) {}, true);
1535   tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK],
1536                         &(VkClearColorValue) { .float32[3] = 1.0f }, false);
1537   tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_OPAQUE_BLACK],
1538                         &(VkClearColorValue) { .int32[3] = 1 }, true);
1539   tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE],
1540                         &(VkClearColorValue) { .float32[0 ... 3] = 1.0f }, false);
1541   tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_OPAQUE_WHITE],
1542                         &(VkClearColorValue) { .int32[0 ... 3] = 1 }, true);
1543
1544   /* initialize to ones so ffs can be used to find unused slots */
1545   BITSET_ONES(device->custom_border_color);
1546
1547   VkPipelineCacheCreateInfo ci;
1548   ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
1549   ci.pNext = NULL;
1550   ci.flags = 0;
1551   ci.pInitialData = NULL;
1552   ci.initialDataSize = 0;
1553   VkPipelineCache pc;
1554   result =
1555      tu_CreatePipelineCache(tu_device_to_handle(device), &ci, NULL, &pc);
1556   if (result != VK_SUCCESS) {
1557      vk_startup_errorf(device->instance, result, "create pipeline cache failed");
1558      goto fail_pipeline_cache;
1559   }
1560
1561   if (perf_query_pools) {
1562      /* Prepare command streams setting pass index to the PERF_CNTRS_REG
1563       * from 0 to 31. One of these will be picked up at cmd submit time
1564       * when the perf query is executed.
1565       */
1566      struct tu_cs *cs;
1567
1568      if (!(device->perfcntrs_pass_cs = calloc(1, sizeof(struct tu_cs)))) {
1569         result = vk_startup_errorf(device->instance,
1570               VK_ERROR_OUT_OF_HOST_MEMORY, "OOM");
1571         goto fail_perfcntrs_pass_alloc;
1572      }
1573
1574      device->perfcntrs_pass_cs_entries = calloc(32, sizeof(struct tu_cs_entry));
1575      if (!device->perfcntrs_pass_cs_entries) {
1576         result = vk_startup_errorf(device->instance,
1577               VK_ERROR_OUT_OF_HOST_MEMORY, "OOM");
1578         goto fail_perfcntrs_pass_entries_alloc;
1579      }
1580
1581      cs = device->perfcntrs_pass_cs;
1582      tu_cs_init(cs, device, TU_CS_MODE_SUB_STREAM, 96);
1583
1584      for (unsigned i = 0; i < 32; i++) {
1585         struct tu_cs sub_cs;
1586
1587         result = tu_cs_begin_sub_stream(cs, 3, &sub_cs);
1588         if (result != VK_SUCCESS) {
1589            vk_startup_errorf(device->instance, result,
1590                  "failed to allocate commands streams");
1591            goto fail_prepare_perfcntrs_pass_cs;
1592         }
1593
1594         tu_cs_emit_regs(&sub_cs, A6XX_CP_SCRATCH_REG(PERF_CNTRS_REG, 1 << i));
1595         tu_cs_emit_pkt7(&sub_cs, CP_WAIT_FOR_ME, 0);
1596
1597         device->perfcntrs_pass_cs_entries[i] = tu_cs_end_sub_stream(cs, &sub_cs);
1598      }
1599   }
1600
1601   /* Initialize a condition variable for timeline semaphore */
1602   pthread_condattr_t condattr;
1603   if (pthread_condattr_init(&condattr) != 0) {
1604      result = vk_startup_errorf(physical_device->instance,
1605                                 VK_ERROR_INITIALIZATION_FAILED,
1606                                 "pthread condattr init");
1607      goto fail_timeline_cond;
1608   }
1609   if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) != 0) {
1610      pthread_condattr_destroy(&condattr);
1611      result = vk_startup_errorf(physical_device->instance,
1612                                 VK_ERROR_INITIALIZATION_FAILED,
1613                                 "pthread condattr clock setup");
1614      goto fail_timeline_cond;
1615   }
1616   if (pthread_cond_init(&device->timeline_cond, &condattr) != 0) {
1617      pthread_condattr_destroy(&condattr);
1618      result = vk_startup_errorf(physical_device->instance,
1619                                 VK_ERROR_INITIALIZATION_FAILED,
1620                                 "pthread cond init");
1621      goto fail_timeline_cond;
1622   }
1623   pthread_condattr_destroy(&condattr);
1624
1625   device->mem_cache = tu_pipeline_cache_from_handle(pc);
1626
1627   for (unsigned i = 0; i < ARRAY_SIZE(device->scratch_bos); i++)
1628      mtx_init(&device->scratch_bos[i].construct_mtx, mtx_plain);
1629
1630   mtx_init(&device->mutex, mtx_plain);
1631
1632   device->submit_count = 0;
1633   u_trace_context_init(&device->trace_context, device,
1634                     tu_trace_create_ts_buffer,
1635                     tu_trace_destroy_ts_buffer,
1636                     tu_trace_record_ts,
1637                     tu_trace_read_ts,
1638                     tu_trace_delete_flush_data);
1639
1640   *pDevice = tu_device_to_handle(device);
1641   return VK_SUCCESS;
1642
1643fail_timeline_cond:
1644fail_prepare_perfcntrs_pass_cs:
1645   free(device->perfcntrs_pass_cs_entries);
1646   tu_cs_finish(device->perfcntrs_pass_cs);
1647fail_perfcntrs_pass_entries_alloc:
1648   free(device->perfcntrs_pass_cs);
1649fail_perfcntrs_pass_alloc:
1650   tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL);
1651fail_pipeline_cache:
1652   tu_destroy_clear_blit_shaders(device);
1653fail_global_bo_map:
1654   tu_bo_finish(device, &device->global_bo);
1655   vk_free(&device->vk.alloc, device->bo_idx);
1656   vk_free(&device->vk.alloc, device->bo_list);
1657fail_global_bo:
1658   ir3_compiler_destroy(device->compiler);
1659
1660fail_queues:
1661   for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
1662      for (unsigned q = 0; q < device->queue_count[i]; q++)
1663         tu_queue_finish(&device->queues[i][q]);
1664      if (device->queue_count[i])
1665         vk_free(&device->vk.alloc, device->queues[i]);
1666   }
1667
1668   vk_device_finish(&device->vk);
1669   vk_free(&device->vk.alloc, device);
1670   return result;
1671}
1672
1673VKAPI_ATTR void VKAPI_CALL
1674tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
1675{
1676   TU_FROM_HANDLE(tu_device, device, _device);
1677
1678   if (!device)
1679      return;
1680
1681   u_trace_context_fini(&device->trace_context);
1682
1683   for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
1684      for (unsigned q = 0; q < device->queue_count[i]; q++)
1685         tu_queue_finish(&device->queues[i][q]);
1686      if (device->queue_count[i])
1687         vk_free(&device->vk.alloc, device->queues[i]);
1688   }
1689
1690   for (unsigned i = 0; i < ARRAY_SIZE(device->scratch_bos); i++) {
1691      if (device->scratch_bos[i].initialized)
1692         tu_bo_finish(device, &device->scratch_bos[i].bo);
1693   }
1694
1695   tu_destroy_clear_blit_shaders(device);
1696
1697   ir3_compiler_destroy(device->compiler);
1698
1699   VkPipelineCache pc = tu_pipeline_cache_to_handle(device->mem_cache);
1700   tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL);
1701
1702   if (device->perfcntrs_pass_cs) {
1703      free(device->perfcntrs_pass_cs_entries);
1704      tu_cs_finish(device->perfcntrs_pass_cs);
1705      free(device->perfcntrs_pass_cs);
1706   }
1707
1708   pthread_cond_destroy(&device->timeline_cond);
1709   vk_free(&device->vk.alloc, device->bo_list);
1710   vk_free(&device->vk.alloc, device->bo_idx);
1711   vk_device_finish(&device->vk);
1712   vk_free(&device->vk.alloc, device);
1713}
1714
1715VkResult
1716_tu_device_set_lost(struct tu_device *device,
1717                    const char *msg, ...)
1718{
1719   /* Set the flag indicating that waits should return in finite time even
1720    * after device loss.
1721    */
1722   p_atomic_inc(&device->_lost);
1723
1724   /* TODO: Report the log message through VkDebugReportCallbackEXT instead */
1725   va_list ap;
1726   va_start(ap, msg);
1727   mesa_loge_v(msg, ap);
1728   va_end(ap);
1729
1730   if (env_var_as_boolean("TU_ABORT_ON_DEVICE_LOSS", false))
1731      abort();
1732
1733   return VK_ERROR_DEVICE_LOST;
1734}
1735
1736VkResult
1737tu_get_scratch_bo(struct tu_device *dev, uint64_t size, struct tu_bo **bo)
1738{
1739   unsigned size_log2 = MAX2(util_logbase2_ceil64(size), MIN_SCRATCH_BO_SIZE_LOG2);
1740   unsigned index = size_log2 - MIN_SCRATCH_BO_SIZE_LOG2;
1741   assert(index < ARRAY_SIZE(dev->scratch_bos));
1742
1743   for (unsigned i = index; i < ARRAY_SIZE(dev->scratch_bos); i++) {
1744      if (p_atomic_read(&dev->scratch_bos[i].initialized)) {
1745         /* Fast path: just return the already-allocated BO. */
1746         *bo = &dev->scratch_bos[i].bo;
1747         return VK_SUCCESS;
1748      }
1749   }
1750
1751   /* Slow path: actually allocate the BO. We take a lock because the process
1752    * of allocating it is slow, and we don't want to block the CPU while it
1753    * finishes.
1754   */
1755   mtx_lock(&dev->scratch_bos[index].construct_mtx);
1756
1757   /* Another thread may have allocated it already while we were waiting on
1758    * the lock. We need to check this in order to avoid double-allocating.
1759    */
1760   if (dev->scratch_bos[index].initialized) {
1761      mtx_unlock(&dev->scratch_bos[index].construct_mtx);
1762      *bo = &dev->scratch_bos[index].bo;
1763      return VK_SUCCESS;
1764   }
1765
1766   unsigned bo_size = 1ull << size_log2;
1767   VkResult result = tu_bo_init_new(dev, &dev->scratch_bos[index].bo, bo_size,
1768                                    TU_BO_ALLOC_NO_FLAGS);
1769   if (result != VK_SUCCESS) {
1770      mtx_unlock(&dev->scratch_bos[index].construct_mtx);
1771      return result;
1772   }
1773
1774   p_atomic_set(&dev->scratch_bos[index].initialized, true);
1775
1776   mtx_unlock(&dev->scratch_bos[index].construct_mtx);
1777
1778   *bo = &dev->scratch_bos[index].bo;
1779   return VK_SUCCESS;
1780}
1781
1782VKAPI_ATTR VkResult VKAPI_CALL
1783tu_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
1784                                    VkLayerProperties *pProperties)
1785{
1786   *pPropertyCount = 0;
1787   return VK_SUCCESS;
1788}
1789
1790VKAPI_ATTR VkResult VKAPI_CALL
1791tu_QueueWaitIdle(VkQueue _queue)
1792{
1793   TU_FROM_HANDLE(tu_queue, queue, _queue);
1794
1795   if (tu_device_is_lost(queue->device))
1796      return VK_ERROR_DEVICE_LOST;
1797
1798   if (queue->fence < 0)
1799      return VK_SUCCESS;
1800
1801   pthread_mutex_lock(&queue->device->submit_mutex);
1802
1803   do {
1804      tu_device_submit_deferred_locked(queue->device);
1805
1806      if (list_is_empty(&queue->queued_submits))
1807         break;
1808
1809      pthread_cond_wait(&queue->device->timeline_cond,
1810            &queue->device->submit_mutex);
1811   } while (!list_is_empty(&queue->queued_submits));
1812
1813   pthread_mutex_unlock(&queue->device->submit_mutex);
1814
1815   struct pollfd fds = { .fd = queue->fence, .events = POLLIN };
1816   int ret;
1817   do {
1818      ret = poll(&fds, 1, -1);
1819   } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1820
1821   /* TODO: otherwise set device lost ? */
1822   assert(ret == 1 && !(fds.revents & (POLLERR | POLLNVAL)));
1823
1824   close(queue->fence);
1825   queue->fence = -1;
1826   return VK_SUCCESS;
1827}
1828
1829VKAPI_ATTR VkResult VKAPI_CALL
1830tu_EnumerateInstanceExtensionProperties(const char *pLayerName,
1831                                        uint32_t *pPropertyCount,
1832                                        VkExtensionProperties *pProperties)
1833{
1834   if (pLayerName)
1835      return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1836
1837   return vk_enumerate_instance_extension_properties(
1838      &tu_instance_extensions_supported, pPropertyCount, pProperties);
1839}
1840
1841VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1842tu_GetInstanceProcAddr(VkInstance _instance, const char *pName)
1843{
1844   TU_FROM_HANDLE(tu_instance, instance, _instance);
1845   return vk_instance_get_proc_addr(&instance->vk,
1846                                    &tu_instance_entrypoints,
1847                                    pName);
1848}
1849
1850/* The loader wants us to expose a second GetInstanceProcAddr function
1851 * to work around certain LD_PRELOAD issues seen in apps.
1852 */
1853PUBLIC
1854VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1855vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName);
1856
1857PUBLIC
1858VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1859vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
1860{
1861   return tu_GetInstanceProcAddr(instance, pName);
1862}
1863
1864VKAPI_ATTR VkResult VKAPI_CALL
1865tu_AllocateMemory(VkDevice _device,
1866                  const VkMemoryAllocateInfo *pAllocateInfo,
1867                  const VkAllocationCallbacks *pAllocator,
1868                  VkDeviceMemory *pMem)
1869{
1870   TU_FROM_HANDLE(tu_device, device, _device);
1871   struct tu_device_memory *mem;
1872   VkResult result;
1873
1874   assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
1875
1876   if (pAllocateInfo->allocationSize == 0) {
1877      /* Apparently, this is allowed */
1878      *pMem = VK_NULL_HANDLE;
1879      return VK_SUCCESS;
1880   }
1881
1882   struct tu_memory_heap *mem_heap = &device->physical_device->heap;
1883   uint64_t mem_heap_used = p_atomic_read(&mem_heap->used);
1884   if (mem_heap_used > mem_heap->size)
1885      return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
1886
1887   mem = vk_object_alloc(&device->vk, pAllocator, sizeof(*mem),
1888                         VK_OBJECT_TYPE_DEVICE_MEMORY);
1889   if (mem == NULL)
1890      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1891
1892   const VkImportMemoryFdInfoKHR *fd_info =
1893      vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
1894   if (fd_info && !fd_info->handleType)
1895      fd_info = NULL;
1896
1897   if (fd_info) {
1898      assert(fd_info->handleType ==
1899                VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
1900             fd_info->handleType ==
1901                VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
1902
1903      /*
1904       * TODO Importing the same fd twice gives us the same handle without
1905       * reference counting.  We need to maintain a per-instance handle-to-bo
1906       * table and add reference count to tu_bo.
1907       */
1908      result = tu_bo_init_dmabuf(device, &mem->bo,
1909                                 pAllocateInfo->allocationSize, fd_info->fd);
1910      if (result == VK_SUCCESS) {
1911         /* take ownership and close the fd */
1912         close(fd_info->fd);
1913      }
1914   } else {
1915      result =
1916         tu_bo_init_new(device, &mem->bo, pAllocateInfo->allocationSize,
1917                        TU_BO_ALLOC_NO_FLAGS);
1918   }
1919
1920
1921   if (result == VK_SUCCESS) {
1922      mem_heap_used = p_atomic_add_return(&mem_heap->used, mem->bo.size);
1923      if (mem_heap_used > mem_heap->size) {
1924         p_atomic_add(&mem_heap->used, -mem->bo.size);
1925         tu_bo_finish(device, &mem->bo);
1926         result = vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY,
1927                            "Out of heap memory");
1928      }
1929   }
1930
1931   if (result != VK_SUCCESS) {
1932      vk_object_free(&device->vk, pAllocator, mem);
1933      return result;
1934   }
1935
1936   *pMem = tu_device_memory_to_handle(mem);
1937
1938   return VK_SUCCESS;
1939}
1940
1941VKAPI_ATTR void VKAPI_CALL
1942tu_FreeMemory(VkDevice _device,
1943              VkDeviceMemory _mem,
1944              const VkAllocationCallbacks *pAllocator)
1945{
1946   TU_FROM_HANDLE(tu_device, device, _device);
1947   TU_FROM_HANDLE(tu_device_memory, mem, _mem);
1948
1949   if (mem == NULL)
1950      return;
1951
1952   p_atomic_add(&device->physical_device->heap.used, -mem->bo.size);
1953   tu_bo_finish(device, &mem->bo);
1954   vk_object_free(&device->vk, pAllocator, mem);
1955}
1956
1957VKAPI_ATTR VkResult VKAPI_CALL
1958tu_MapMemory(VkDevice _device,
1959             VkDeviceMemory _memory,
1960             VkDeviceSize offset,
1961             VkDeviceSize size,
1962             VkMemoryMapFlags flags,
1963             void **ppData)
1964{
1965   TU_FROM_HANDLE(tu_device, device, _device);
1966   TU_FROM_HANDLE(tu_device_memory, mem, _memory);
1967   VkResult result;
1968
1969   if (mem == NULL) {
1970      *ppData = NULL;
1971      return VK_SUCCESS;
1972   }
1973
1974   if (!mem->bo.map) {
1975      result = tu_bo_map(device, &mem->bo);
1976      if (result != VK_SUCCESS)
1977         return result;
1978   }
1979
1980   *ppData = mem->bo.map + offset;
1981   return VK_SUCCESS;
1982}
1983
1984VKAPI_ATTR void VKAPI_CALL
1985tu_UnmapMemory(VkDevice _device, VkDeviceMemory _memory)
1986{
1987   /* TODO: unmap here instead of waiting for FreeMemory */
1988}
1989
1990VKAPI_ATTR VkResult VKAPI_CALL
1991tu_FlushMappedMemoryRanges(VkDevice _device,
1992                           uint32_t memoryRangeCount,
1993                           const VkMappedMemoryRange *pMemoryRanges)
1994{
1995   return VK_SUCCESS;
1996}
1997
1998VKAPI_ATTR VkResult VKAPI_CALL
1999tu_InvalidateMappedMemoryRanges(VkDevice _device,
2000                                uint32_t memoryRangeCount,
2001                                const VkMappedMemoryRange *pMemoryRanges)
2002{
2003   return VK_SUCCESS;
2004}
2005
2006VKAPI_ATTR void VKAPI_CALL
2007tu_GetBufferMemoryRequirements2(
2008   VkDevice device,
2009   const VkBufferMemoryRequirementsInfo2 *pInfo,
2010   VkMemoryRequirements2 *pMemoryRequirements)
2011{
2012   TU_FROM_HANDLE(tu_buffer, buffer, pInfo->buffer);
2013
2014   pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
2015      .memoryTypeBits = 1,
2016      .alignment = 64,
2017      .size = MAX2(align64(buffer->size, 64), buffer->size),
2018   };
2019
2020   vk_foreach_struct(ext, pMemoryRequirements->pNext) {
2021      switch (ext->sType) {
2022      case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
2023         VkMemoryDedicatedRequirements *req =
2024            (VkMemoryDedicatedRequirements *) ext;
2025         req->requiresDedicatedAllocation = false;
2026         req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
2027         break;
2028      }
2029      default:
2030         break;
2031      }
2032   }
2033}
2034
2035VKAPI_ATTR void VKAPI_CALL
2036tu_GetImageMemoryRequirements2(VkDevice device,
2037                               const VkImageMemoryRequirementsInfo2 *pInfo,
2038                               VkMemoryRequirements2 *pMemoryRequirements)
2039{
2040   TU_FROM_HANDLE(tu_image, image, pInfo->image);
2041
2042   pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
2043      .memoryTypeBits = 1,
2044      .alignment = image->layout[0].base_align,
2045      .size = image->total_size
2046   };
2047
2048   vk_foreach_struct(ext, pMemoryRequirements->pNext) {
2049      switch (ext->sType) {
2050      case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
2051         VkMemoryDedicatedRequirements *req =
2052            (VkMemoryDedicatedRequirements *) ext;
2053         req->requiresDedicatedAllocation = image->shareable;
2054         req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
2055         break;
2056      }
2057      default:
2058         break;
2059      }
2060   }
2061}
2062
2063VKAPI_ATTR void VKAPI_CALL
2064tu_GetImageSparseMemoryRequirements2(
2065   VkDevice device,
2066   const VkImageSparseMemoryRequirementsInfo2 *pInfo,
2067   uint32_t *pSparseMemoryRequirementCount,
2068   VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
2069{
2070   tu_stub();
2071}
2072
2073VKAPI_ATTR void VKAPI_CALL
2074tu_GetDeviceMemoryCommitment(VkDevice device,
2075                             VkDeviceMemory memory,
2076                             VkDeviceSize *pCommittedMemoryInBytes)
2077{
2078   *pCommittedMemoryInBytes = 0;
2079}
2080
2081VKAPI_ATTR VkResult VKAPI_CALL
2082tu_BindBufferMemory2(VkDevice device,
2083                     uint32_t bindInfoCount,
2084                     const VkBindBufferMemoryInfo *pBindInfos)
2085{
2086   for (uint32_t i = 0; i < bindInfoCount; ++i) {
2087      TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory);
2088      TU_FROM_HANDLE(tu_buffer, buffer, pBindInfos[i].buffer);
2089
2090      if (mem) {
2091         buffer->bo = &mem->bo;
2092         buffer->bo_offset = pBindInfos[i].memoryOffset;
2093      } else {
2094         buffer->bo = NULL;
2095      }
2096   }
2097   return VK_SUCCESS;
2098}
2099
2100VKAPI_ATTR VkResult VKAPI_CALL
2101tu_BindImageMemory2(VkDevice device,
2102                    uint32_t bindInfoCount,
2103                    const VkBindImageMemoryInfo *pBindInfos)
2104{
2105   for (uint32_t i = 0; i < bindInfoCount; ++i) {
2106      TU_FROM_HANDLE(tu_image, image, pBindInfos[i].image);
2107      TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory);
2108
2109      if (mem) {
2110         image->bo = &mem->bo;
2111         image->bo_offset = pBindInfos[i].memoryOffset;
2112      } else {
2113         image->bo = NULL;
2114         image->bo_offset = 0;
2115      }
2116   }
2117
2118   return VK_SUCCESS;
2119}
2120
2121VKAPI_ATTR VkResult VKAPI_CALL
2122tu_QueueBindSparse(VkQueue _queue,
2123                   uint32_t bindInfoCount,
2124                   const VkBindSparseInfo *pBindInfo,
2125                   VkFence _fence)
2126{
2127   return VK_SUCCESS;
2128}
2129
2130VKAPI_ATTR VkResult VKAPI_CALL
2131tu_CreateEvent(VkDevice _device,
2132               const VkEventCreateInfo *pCreateInfo,
2133               const VkAllocationCallbacks *pAllocator,
2134               VkEvent *pEvent)
2135{
2136   TU_FROM_HANDLE(tu_device, device, _device);
2137
2138   struct tu_event *event =
2139         vk_object_alloc(&device->vk, pAllocator, sizeof(*event),
2140                         VK_OBJECT_TYPE_EVENT);
2141   if (!event)
2142      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2143
2144   VkResult result = tu_bo_init_new(device, &event->bo, 0x1000,
2145                                    TU_BO_ALLOC_NO_FLAGS);
2146   if (result != VK_SUCCESS)
2147      goto fail_alloc;
2148
2149   result = tu_bo_map(device, &event->bo);
2150   if (result != VK_SUCCESS)
2151      goto fail_map;
2152
2153   *pEvent = tu_event_to_handle(event);
2154
2155   return VK_SUCCESS;
2156
2157fail_map:
2158   tu_bo_finish(device, &event->bo);
2159fail_alloc:
2160   vk_object_free(&device->vk, pAllocator, event);
2161   return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2162}
2163
2164VKAPI_ATTR void VKAPI_CALL
2165tu_DestroyEvent(VkDevice _device,
2166                VkEvent _event,
2167                const VkAllocationCallbacks *pAllocator)
2168{
2169   TU_FROM_HANDLE(tu_device, device, _device);
2170   TU_FROM_HANDLE(tu_event, event, _event);
2171
2172   if (!event)
2173      return;
2174
2175   tu_bo_finish(device, &event->bo);
2176   vk_object_free(&device->vk, pAllocator, event);
2177}
2178
2179VKAPI_ATTR VkResult VKAPI_CALL
2180tu_GetEventStatus(VkDevice _device, VkEvent _event)
2181{
2182   TU_FROM_HANDLE(tu_event, event, _event);
2183
2184   if (*(uint64_t*) event->bo.map == 1)
2185      return VK_EVENT_SET;
2186   return VK_EVENT_RESET;
2187}
2188
2189VKAPI_ATTR VkResult VKAPI_CALL
2190tu_SetEvent(VkDevice _device, VkEvent _event)
2191{
2192   TU_FROM_HANDLE(tu_event, event, _event);
2193   *(uint64_t*) event->bo.map = 1;
2194
2195   return VK_SUCCESS;
2196}
2197
2198VKAPI_ATTR VkResult VKAPI_CALL
2199tu_ResetEvent(VkDevice _device, VkEvent _event)
2200{
2201   TU_FROM_HANDLE(tu_event, event, _event);
2202   *(uint64_t*) event->bo.map = 0;
2203
2204   return VK_SUCCESS;
2205}
2206
2207VKAPI_ATTR VkResult VKAPI_CALL
2208tu_CreateBuffer(VkDevice _device,
2209                const VkBufferCreateInfo *pCreateInfo,
2210                const VkAllocationCallbacks *pAllocator,
2211                VkBuffer *pBuffer)
2212{
2213   TU_FROM_HANDLE(tu_device, device, _device);
2214   struct tu_buffer *buffer;
2215
2216   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
2217
2218   buffer = vk_object_alloc(&device->vk, pAllocator, sizeof(*buffer),
2219                            VK_OBJECT_TYPE_BUFFER);
2220   if (buffer == NULL)
2221      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2222
2223   buffer->size = pCreateInfo->size;
2224   buffer->usage = pCreateInfo->usage;
2225   buffer->flags = pCreateInfo->flags;
2226
2227   *pBuffer = tu_buffer_to_handle(buffer);
2228
2229   return VK_SUCCESS;
2230}
2231
2232VKAPI_ATTR void VKAPI_CALL
2233tu_DestroyBuffer(VkDevice _device,
2234                 VkBuffer _buffer,
2235                 const VkAllocationCallbacks *pAllocator)
2236{
2237   TU_FROM_HANDLE(tu_device, device, _device);
2238   TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
2239
2240   if (!buffer)
2241      return;
2242
2243   vk_object_free(&device->vk, pAllocator, buffer);
2244}
2245
2246VKAPI_ATTR VkResult VKAPI_CALL
2247tu_CreateFramebuffer(VkDevice _device,
2248                     const VkFramebufferCreateInfo *pCreateInfo,
2249                     const VkAllocationCallbacks *pAllocator,
2250                     VkFramebuffer *pFramebuffer)
2251{
2252   TU_FROM_HANDLE(tu_device, device, _device);
2253   TU_FROM_HANDLE(tu_render_pass, pass, pCreateInfo->renderPass);
2254   struct tu_framebuffer *framebuffer;
2255
2256   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
2257
2258   bool imageless = pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT;
2259
2260   size_t size = sizeof(*framebuffer);
2261   if (!imageless)
2262      size += sizeof(struct tu_attachment_info) * pCreateInfo->attachmentCount;
2263   framebuffer = vk_object_alloc(&device->vk, pAllocator, size,
2264                                 VK_OBJECT_TYPE_FRAMEBUFFER);
2265   if (framebuffer == NULL)
2266      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2267
2268   framebuffer->attachment_count = pCreateInfo->attachmentCount;
2269   framebuffer->width = pCreateInfo->width;
2270   framebuffer->height = pCreateInfo->height;
2271   framebuffer->layers = pCreateInfo->layers;
2272
2273   if (!imageless) {
2274      for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
2275         VkImageView _iview = pCreateInfo->pAttachments[i];
2276         struct tu_image_view *iview = tu_image_view_from_handle(_iview);
2277         framebuffer->attachments[i].attachment = iview;
2278      }
2279   }
2280
2281   tu_framebuffer_tiling_config(framebuffer, device, pass);
2282
2283   *pFramebuffer = tu_framebuffer_to_handle(framebuffer);
2284   return VK_SUCCESS;
2285}
2286
2287VKAPI_ATTR void VKAPI_CALL
2288tu_DestroyFramebuffer(VkDevice _device,
2289                      VkFramebuffer _fb,
2290                      const VkAllocationCallbacks *pAllocator)
2291{
2292   TU_FROM_HANDLE(tu_device, device, _device);
2293   TU_FROM_HANDLE(tu_framebuffer, fb, _fb);
2294
2295   if (!fb)
2296      return;
2297
2298   vk_object_free(&device->vk, pAllocator, fb);
2299}
2300
2301static void
2302tu_init_sampler(struct tu_device *device,
2303                struct tu_sampler *sampler,
2304                const VkSamplerCreateInfo *pCreateInfo)
2305{
2306   const struct VkSamplerReductionModeCreateInfo *reduction =
2307      vk_find_struct_const(pCreateInfo->pNext, SAMPLER_REDUCTION_MODE_CREATE_INFO);
2308   const struct VkSamplerYcbcrConversionInfo *ycbcr_conversion =
2309      vk_find_struct_const(pCreateInfo->pNext,  SAMPLER_YCBCR_CONVERSION_INFO);
2310   const VkSamplerCustomBorderColorCreateInfoEXT *custom_border_color =
2311      vk_find_struct_const(pCreateInfo->pNext, SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
2312   /* for non-custom border colors, the VK enum is translated directly to an offset in
2313    * the border color buffer. custom border colors are located immediately after the
2314    * builtin colors, and thus an offset of TU_BORDER_COLOR_BUILTIN is added.
2315    */
2316   uint32_t border_color = (unsigned) pCreateInfo->borderColor;
2317   if (pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT ||
2318       pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT) {
2319      mtx_lock(&device->mutex);
2320      border_color = BITSET_FFS(device->custom_border_color);
2321      BITSET_CLEAR(device->custom_border_color, border_color);
2322      mtx_unlock(&device->mutex);
2323      tu6_pack_border_color(device->global_bo.map + gb_offset(bcolor[border_color]),
2324                            &custom_border_color->customBorderColor,
2325                            pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
2326      border_color += TU_BORDER_COLOR_BUILTIN;
2327   }
2328
2329   unsigned aniso = pCreateInfo->anisotropyEnable ?
2330      util_last_bit(MIN2((uint32_t)pCreateInfo->maxAnisotropy >> 1, 8)) : 0;
2331   bool miplinear = (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR);
2332   float min_lod = CLAMP(pCreateInfo->minLod, 0.0f, 4095.0f / 256.0f);
2333   float max_lod = CLAMP(pCreateInfo->maxLod, 0.0f, 4095.0f / 256.0f);
2334
2335   sampler->descriptor[0] =
2336      COND(miplinear, A6XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) |
2337      A6XX_TEX_SAMP_0_XY_MAG(tu6_tex_filter(pCreateInfo->magFilter, aniso)) |
2338      A6XX_TEX_SAMP_0_XY_MIN(tu6_tex_filter(pCreateInfo->minFilter, aniso)) |
2339      A6XX_TEX_SAMP_0_ANISO(aniso) |
2340      A6XX_TEX_SAMP_0_WRAP_S(tu6_tex_wrap(pCreateInfo->addressModeU)) |
2341      A6XX_TEX_SAMP_0_WRAP_T(tu6_tex_wrap(pCreateInfo->addressModeV)) |
2342      A6XX_TEX_SAMP_0_WRAP_R(tu6_tex_wrap(pCreateInfo->addressModeW)) |
2343      A6XX_TEX_SAMP_0_LOD_BIAS(pCreateInfo->mipLodBias);
2344   sampler->descriptor[1] =
2345      /* COND(!cso->seamless_cube_map, A6XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF) | */
2346      COND(pCreateInfo->unnormalizedCoordinates, A6XX_TEX_SAMP_1_UNNORM_COORDS) |
2347      A6XX_TEX_SAMP_1_MIN_LOD(min_lod) |
2348      A6XX_TEX_SAMP_1_MAX_LOD(max_lod) |
2349      COND(pCreateInfo->compareEnable,
2350           A6XX_TEX_SAMP_1_COMPARE_FUNC(tu6_compare_func(pCreateInfo->compareOp)));
2351   sampler->descriptor[2] = A6XX_TEX_SAMP_2_BCOLOR(border_color);
2352   sampler->descriptor[3] = 0;
2353
2354   if (reduction) {
2355      sampler->descriptor[2] |= A6XX_TEX_SAMP_2_REDUCTION_MODE(
2356         tu6_reduction_mode(reduction->reductionMode));
2357   }
2358
2359   sampler->ycbcr_sampler = ycbcr_conversion ?
2360      tu_sampler_ycbcr_conversion_from_handle(ycbcr_conversion->conversion) : NULL;
2361
2362   if (sampler->ycbcr_sampler &&
2363       sampler->ycbcr_sampler->chroma_filter == VK_FILTER_LINEAR) {
2364      sampler->descriptor[2] |= A6XX_TEX_SAMP_2_CHROMA_LINEAR;
2365   }
2366
2367   /* TODO:
2368    * A6XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR disables mipmapping, but vk has no NONE mipfilter?
2369    */
2370}
2371
2372VKAPI_ATTR VkResult VKAPI_CALL
2373tu_CreateSampler(VkDevice _device,
2374                 const VkSamplerCreateInfo *pCreateInfo,
2375                 const VkAllocationCallbacks *pAllocator,
2376                 VkSampler *pSampler)
2377{
2378   TU_FROM_HANDLE(tu_device, device, _device);
2379   struct tu_sampler *sampler;
2380
2381   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
2382
2383   sampler = vk_object_alloc(&device->vk, pAllocator, sizeof(*sampler),
2384                             VK_OBJECT_TYPE_SAMPLER);
2385   if (!sampler)
2386      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2387
2388   tu_init_sampler(device, sampler, pCreateInfo);
2389   *pSampler = tu_sampler_to_handle(sampler);
2390
2391   return VK_SUCCESS;
2392}
2393
2394VKAPI_ATTR void VKAPI_CALL
2395tu_DestroySampler(VkDevice _device,
2396                  VkSampler _sampler,
2397                  const VkAllocationCallbacks *pAllocator)
2398{
2399   TU_FROM_HANDLE(tu_device, device, _device);
2400   TU_FROM_HANDLE(tu_sampler, sampler, _sampler);
2401   uint32_t border_color;
2402
2403   if (!sampler)
2404      return;
2405
2406   border_color = (sampler->descriptor[2] & A6XX_TEX_SAMP_2_BCOLOR__MASK) >> A6XX_TEX_SAMP_2_BCOLOR__SHIFT;
2407   if (border_color >= TU_BORDER_COLOR_BUILTIN) {
2408      border_color -= TU_BORDER_COLOR_BUILTIN;
2409      /* if the sampler had a custom border color, free it. TODO: no lock */
2410      mtx_lock(&device->mutex);
2411      assert(!BITSET_TEST(device->custom_border_color, border_color));
2412      BITSET_SET(device->custom_border_color, border_color);
2413      mtx_unlock(&device->mutex);
2414   }
2415
2416   vk_object_free(&device->vk, pAllocator, sampler);
2417}
2418
2419/* vk_icd.h does not declare this function, so we declare it here to
2420 * suppress Wmissing-prototypes.
2421 */
2422PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2423vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion);
2424
2425PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2426vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion)
2427{
2428   /* For the full details on loader interface versioning, see
2429    * <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
2430    * What follows is a condensed summary, to help you navigate the large and
2431    * confusing official doc.
2432    *
2433    *   - Loader interface v0 is incompatible with later versions. We don't
2434    *     support it.
2435    *
2436    *   - In loader interface v1:
2437    *       - The first ICD entrypoint called by the loader is
2438    *         vk_icdGetInstanceProcAddr(). The ICD must statically expose this
2439    *         entrypoint.
2440    *       - The ICD must statically expose no other Vulkan symbol unless it
2441    * is linked with -Bsymbolic.
2442    *       - Each dispatchable Vulkan handle created by the ICD must be
2443    *         a pointer to a struct whose first member is VK_LOADER_DATA. The
2444    *         ICD must initialize VK_LOADER_DATA.loadMagic to
2445    * ICD_LOADER_MAGIC.
2446    *       - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
2447    *         vkDestroySurfaceKHR(). The ICD must be capable of working with
2448    *         such loader-managed surfaces.
2449    *
2450    *    - Loader interface v2 differs from v1 in:
2451    *       - The first ICD entrypoint called by the loader is
2452    *         vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
2453    *         statically expose this entrypoint.
2454    *
2455    *    - Loader interface v3 differs from v2 in:
2456    *        - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
2457    *          vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
2458    *          because the loader no longer does so.
2459    */
2460   *pSupportedVersion = MIN2(*pSupportedVersion, 3u);
2461   return VK_SUCCESS;
2462}
2463
2464VKAPI_ATTR VkResult VKAPI_CALL
2465tu_GetMemoryFdKHR(VkDevice _device,
2466                  const VkMemoryGetFdInfoKHR *pGetFdInfo,
2467                  int *pFd)
2468{
2469   TU_FROM_HANDLE(tu_device, device, _device);
2470   TU_FROM_HANDLE(tu_device_memory, memory, pGetFdInfo->memory);
2471
2472   assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
2473
2474   /* At the moment, we support only the below handle types. */
2475   assert(pGetFdInfo->handleType ==
2476             VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
2477          pGetFdInfo->handleType ==
2478             VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2479
2480   int prime_fd = tu_bo_export_dmabuf(device, &memory->bo);
2481   if (prime_fd < 0)
2482      return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
2483
2484   *pFd = prime_fd;
2485   return VK_SUCCESS;
2486}
2487
2488VKAPI_ATTR VkResult VKAPI_CALL
2489tu_GetMemoryFdPropertiesKHR(VkDevice _device,
2490                            VkExternalMemoryHandleTypeFlagBits handleType,
2491                            int fd,
2492                            VkMemoryFdPropertiesKHR *pMemoryFdProperties)
2493{
2494   assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2495   pMemoryFdProperties->memoryTypeBits = 1;
2496   return VK_SUCCESS;
2497}
2498
2499VKAPI_ATTR void VKAPI_CALL
2500tu_GetPhysicalDeviceExternalFenceProperties(
2501   VkPhysicalDevice physicalDevice,
2502   const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
2503   VkExternalFenceProperties *pExternalFenceProperties)
2504{
2505   pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2506   pExternalFenceProperties->compatibleHandleTypes = 0;
2507   pExternalFenceProperties->externalFenceFeatures = 0;
2508}
2509
2510VKAPI_ATTR void VKAPI_CALL
2511tu_GetDeviceGroupPeerMemoryFeatures(
2512   VkDevice device,
2513   uint32_t heapIndex,
2514   uint32_t localDeviceIndex,
2515   uint32_t remoteDeviceIndex,
2516   VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
2517{
2518   assert(localDeviceIndex == remoteDeviceIndex);
2519
2520   *pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT |
2521                          VK_PEER_MEMORY_FEATURE_COPY_DST_BIT |
2522                          VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
2523                          VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
2524}
2525
2526VKAPI_ATTR void VKAPI_CALL
2527tu_GetPhysicalDeviceMultisamplePropertiesEXT(
2528   VkPhysicalDevice                            physicalDevice,
2529   VkSampleCountFlagBits                       samples,
2530   VkMultisamplePropertiesEXT*                 pMultisampleProperties)
2531{
2532   TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
2533
2534   if (samples <= VK_SAMPLE_COUNT_4_BIT && pdevice->vk.supported_extensions.EXT_sample_locations)
2535      pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 1, 1 };
2536   else
2537      pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 0, 0 };
2538}
2539