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 
58 static int
tu_device_get_cache_uuid(uint16_t family,void * uuid)59 tu_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 
76 VKAPI_ATTR VkResult VKAPI_CALL
tu_EnumerateInstanceVersion(uint32_t * pApiVersion)77 tu_EnumerateInstanceVersion(uint32_t *pApiVersion)
78 {
79     *pApiVersion = TU_API_VERSION;
80     return VK_SUCCESS;
81 }
82 
83 static 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 
112 static void
get_device_extensions(const struct tu_physical_device * device,struct vk_device_extension_table * ext)113 get_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 
202 VkResult
tu_physical_device_init(struct tu_physical_device * device,struct tu_instance * instance)203 tu_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 
285 fail_free_cache:
286    disk_cache_destroy(device->disk_cache);
287 fail_free_name:
288    vk_free(&instance->vk.alloc, (void *)device->name);
289    return result;
290 }
291 
292 static void
tu_physical_device_finish(struct tu_physical_device * device)293 tu_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 
309 static 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 
324 const char *
tu_get_debug_option_name(int id)325 tu_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 
331 VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)332 tu_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 
392 VKAPI_ATTR void VKAPI_CALL
tu_DestroyInstance(VkInstance _instance,const VkAllocationCallbacks * pAllocator)393 tu_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 
411 VKAPI_ATTR VkResult VKAPI_CALL
tu_EnumeratePhysicalDevices(VkInstance _instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)412 tu_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 
437 VKAPI_ATTR VkResult VKAPI_CALL
tu_EnumeratePhysicalDeviceGroups(VkInstance _instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)438 tu_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 
467 static void
tu_get_physical_device_features_1_1(struct tu_physical_device * pdevice,VkPhysicalDeviceVulkan11Features * features)468 tu_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 
485 static void
tu_get_physical_device_features_1_2(struct tu_physical_device * pdevice,VkPhysicalDeviceVulkan12Features * features)486 tu_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 
540 void
tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)541 tu_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 
758 static void
tu_get_physical_device_properties_1_1(struct tu_physical_device * pdevice,VkPhysicalDeviceVulkan11Properties * p)759 tu_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  */
797 static const size_t max_descriptor_set_size = (1 << 28) / A6XX_TEX_CONST_DWORDS;
798 static const VkSampleCountFlags sample_counts =
799    VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT;
800 
801 static void
tu_get_physical_device_properties_1_2(struct tu_physical_device * pdevice,VkPhysicalDeviceVulkan12Properties * p)802 tu_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 
883 VKAPI_ATTR void VKAPI_CALL
tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)884 tu_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 
1112 static 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 
1120 VKAPI_ATTR void VKAPI_CALL
tu_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)1121 tu_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 
1134 uint64_t
tu_get_system_heap_size()1135 tu_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 
1154 static VkDeviceSize
tu_get_budget_memory(struct tu_physical_device * physical_device)1155 tu_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 
1172 VKAPI_ATTR void VKAPI_CALL
tu_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice pdev,VkPhysicalDeviceMemoryProperties2 * props2)1173 tu_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 
1214 static VkResult
tu_queue_init(struct tu_device * device,struct tu_queue * queue,int idx,const VkDeviceQueueCreateInfo * create_info)1215 tu_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 
1238 static void
tu_queue_finish(struct tu_queue * queue)1239 tu_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 
1247 uint64_t
tu_device_ticks_to_ns(struct tu_device * dev,uint64_t ts)1248 tu_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 
1257 static void*
tu_trace_create_ts_buffer(struct u_trace_context * utctx,uint32_t size)1258 tu_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 
1269 static void
tu_trace_destroy_ts_buffer(struct u_trace_context * utctx,void * timestamps)1270 tu_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 
1280 static void
tu_trace_record_ts(struct u_trace * ut,void * cs,void * timestamps,unsigned idx)1281 tu_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 
1294 static uint64_t
tu_trace_read_ts(struct u_trace_context * utctx,void * timestamps,unsigned idx,void * flush_data)1295 tu_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 
1321 static void
tu_trace_delete_flush_data(struct u_trace_context * utctx,void * flush_data)1322 tu_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 
1334 void
tu_copy_timestamp_buffer(struct u_trace_context * utctx,void * cmdstream,void * ts_from,uint32_t from_offset,void * ts_to,uint32_t to_offset,uint32_t count)1335 tu_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 
1350 VkResult
tu_create_copy_timestamp_cs(struct tu_cmd_buffer * cmdbuf,struct tu_cs ** cs,struct u_trace ** trace_copy)1351 tu_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 
1389 void
tu_u_trace_cmd_data_finish(struct tu_device * device,struct tu_u_trace_cmd_data * trace_data,uint32_t entry_count)1390 tu_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 
1408 VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1409 tu_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 
1643 fail_timeline_cond:
1644 fail_prepare_perfcntrs_pass_cs:
1645    free(device->perfcntrs_pass_cs_entries);
1646    tu_cs_finish(device->perfcntrs_pass_cs);
1647 fail_perfcntrs_pass_entries_alloc:
1648    free(device->perfcntrs_pass_cs);
1649 fail_perfcntrs_pass_alloc:
1650    tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL);
1651 fail_pipeline_cache:
1652    tu_destroy_clear_blit_shaders(device);
1653 fail_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);
1657 fail_global_bo:
1658    ir3_compiler_destroy(device->compiler);
1659 
1660 fail_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 
1673 VKAPI_ATTR void VKAPI_CALL
tu_DestroyDevice(VkDevice _device,const VkAllocationCallbacks * pAllocator)1674 tu_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 
1715 VkResult
_tu_device_set_lost(struct tu_device * device,const char * msg,...)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 
1736 VkResult
tu_get_scratch_bo(struct tu_device * dev,uint64_t size,struct tu_bo ** bo)1737 tu_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 
1782 VKAPI_ATTR VkResult VKAPI_CALL
tu_EnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)1783 tu_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
1784                                     VkLayerProperties *pProperties)
1785 {
1786    *pPropertyCount = 0;
1787    return VK_SUCCESS;
1788 }
1789 
1790 VKAPI_ATTR VkResult VKAPI_CALL
tu_QueueWaitIdle(VkQueue _queue)1791 tu_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 
1829 VKAPI_ATTR VkResult VKAPI_CALL
tu_EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1830 tu_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 
1841 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
tu_GetInstanceProcAddr(VkInstance _instance,const char * pName)1842 tu_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  */
1853 PUBLIC
1854 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1855 vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName);
1856 
1857 PUBLIC
1858 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vk_icdGetInstanceProcAddr(VkInstance instance,const char * pName)1859 vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
1860 {
1861    return tu_GetInstanceProcAddr(instance, pName);
1862 }
1863 
1864 VKAPI_ATTR VkResult VKAPI_CALL
tu_AllocateMemory(VkDevice _device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMem)1865 tu_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 
1941 VKAPI_ATTR void VKAPI_CALL
tu_FreeMemory(VkDevice _device,VkDeviceMemory _mem,const VkAllocationCallbacks * pAllocator)1942 tu_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 
1957 VKAPI_ATTR VkResult VKAPI_CALL
tu_MapMemory(VkDevice _device,VkDeviceMemory _memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)1958 tu_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 
1984 VKAPI_ATTR void VKAPI_CALL
tu_UnmapMemory(VkDevice _device,VkDeviceMemory _memory)1985 tu_UnmapMemory(VkDevice _device, VkDeviceMemory _memory)
1986 {
1987    /* TODO: unmap here instead of waiting for FreeMemory */
1988 }
1989 
1990 VKAPI_ATTR VkResult VKAPI_CALL
tu_FlushMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)1991 tu_FlushMappedMemoryRanges(VkDevice _device,
1992                            uint32_t memoryRangeCount,
1993                            const VkMappedMemoryRange *pMemoryRanges)
1994 {
1995    return VK_SUCCESS;
1996 }
1997 
1998 VKAPI_ATTR VkResult VKAPI_CALL
tu_InvalidateMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)1999 tu_InvalidateMappedMemoryRanges(VkDevice _device,
2000                                 uint32_t memoryRangeCount,
2001                                 const VkMappedMemoryRange *pMemoryRanges)
2002 {
2003    return VK_SUCCESS;
2004 }
2005 
2006 VKAPI_ATTR void VKAPI_CALL
tu_GetBufferMemoryRequirements2(VkDevice device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)2007 tu_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 
2035 VKAPI_ATTR void VKAPI_CALL
tu_GetImageMemoryRequirements2(VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)2036 tu_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 
2063 VKAPI_ATTR void VKAPI_CALL
tu_GetImageSparseMemoryRequirements2(VkDevice device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)2064 tu_GetImageSparseMemoryRequirements2(
2065    VkDevice device,
2066    const VkImageSparseMemoryRequirementsInfo2 *pInfo,
2067    uint32_t *pSparseMemoryRequirementCount,
2068    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
2069 {
2070    tu_stub();
2071 }
2072 
2073 VKAPI_ATTR void VKAPI_CALL
tu_GetDeviceMemoryCommitment(VkDevice device,VkDeviceMemory memory,VkDeviceSize * pCommittedMemoryInBytes)2074 tu_GetDeviceMemoryCommitment(VkDevice device,
2075                              VkDeviceMemory memory,
2076                              VkDeviceSize *pCommittedMemoryInBytes)
2077 {
2078    *pCommittedMemoryInBytes = 0;
2079 }
2080 
2081 VKAPI_ATTR VkResult VKAPI_CALL
tu_BindBufferMemory2(VkDevice device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)2082 tu_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 
2100 VKAPI_ATTR VkResult VKAPI_CALL
tu_BindImageMemory2(VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)2101 tu_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 
2121 VKAPI_ATTR VkResult VKAPI_CALL
tu_QueueBindSparse(VkQueue _queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence _fence)2122 tu_QueueBindSparse(VkQueue _queue,
2123                    uint32_t bindInfoCount,
2124                    const VkBindSparseInfo *pBindInfo,
2125                    VkFence _fence)
2126 {
2127    return VK_SUCCESS;
2128 }
2129 
2130 VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateEvent(VkDevice _device,const VkEventCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkEvent * pEvent)2131 tu_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 
2157 fail_map:
2158    tu_bo_finish(device, &event->bo);
2159 fail_alloc:
2160    vk_object_free(&device->vk, pAllocator, event);
2161    return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2162 }
2163 
2164 VKAPI_ATTR void VKAPI_CALL
tu_DestroyEvent(VkDevice _device,VkEvent _event,const VkAllocationCallbacks * pAllocator)2165 tu_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 
2179 VKAPI_ATTR VkResult VKAPI_CALL
tu_GetEventStatus(VkDevice _device,VkEvent _event)2180 tu_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 
2189 VKAPI_ATTR VkResult VKAPI_CALL
tu_SetEvent(VkDevice _device,VkEvent _event)2190 tu_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 
2198 VKAPI_ATTR VkResult VKAPI_CALL
tu_ResetEvent(VkDevice _device,VkEvent _event)2199 tu_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 
2207 VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateBuffer(VkDevice _device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)2208 tu_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 
2232 VKAPI_ATTR void VKAPI_CALL
tu_DestroyBuffer(VkDevice _device,VkBuffer _buffer,const VkAllocationCallbacks * pAllocator)2233 tu_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 
2246 VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateFramebuffer(VkDevice _device,const VkFramebufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFramebuffer * pFramebuffer)2247 tu_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 
2287 VKAPI_ATTR void VKAPI_CALL
tu_DestroyFramebuffer(VkDevice _device,VkFramebuffer _fb,const VkAllocationCallbacks * pAllocator)2288 tu_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 
2301 static void
tu_init_sampler(struct tu_device * device,struct tu_sampler * sampler,const VkSamplerCreateInfo * pCreateInfo)2302 tu_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 
2372 VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateSampler(VkDevice _device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)2373 tu_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 
2394 VKAPI_ATTR void VKAPI_CALL
tu_DestroySampler(VkDevice _device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)2395 tu_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  */
2422 PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2423 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion);
2424 
2425 PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)2426 vk_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 
2464 VKAPI_ATTR VkResult VKAPI_CALL
tu_GetMemoryFdKHR(VkDevice _device,const VkMemoryGetFdInfoKHR * pGetFdInfo,int * pFd)2465 tu_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 
2488 VKAPI_ATTR VkResult VKAPI_CALL
tu_GetMemoryFdPropertiesKHR(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,int fd,VkMemoryFdPropertiesKHR * pMemoryFdProperties)2489 tu_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 
2499 VKAPI_ATTR void VKAPI_CALL
tu_GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties)2500 tu_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 
2510 VKAPI_ATTR void VKAPI_CALL
tu_GetDeviceGroupPeerMemoryFeatures(VkDevice device,uint32_t heapIndex,uint32_t localDeviceIndex,uint32_t remoteDeviceIndex,VkPeerMemoryFeatureFlags * pPeerMemoryFeatures)2511 tu_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 
2526 VKAPI_ATTR void VKAPI_CALL
tu_GetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice physicalDevice,VkSampleCountFlagBits samples,VkMultisamplePropertiesEXT * pMultisampleProperties)2527 tu_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