Home | History | Annotate | Line # | Download | only in vulkan
      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
     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
     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
    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
    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
    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 *
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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*
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   1859 vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
   1860 {
   1861    return tu_GetInstanceProcAddr(instance, pName);
   1862 }
   1863 
   1864 VKAPI_ATTR VkResult VKAPI_CALL
   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
   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
   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
   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
   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
   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
   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
   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
   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
   2074 tu_GetDeviceMemoryCommitment(VkDevice device,
   2075                              VkDeviceMemory memory,
   2076                              VkDeviceSize *pCommittedMemoryInBytes)
   2077 {
   2078    *pCommittedMemoryInBytes = 0;
   2079 }
   2080 
   2081 VKAPI_ATTR VkResult VKAPI_CALL
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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
   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