• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
30 #include <fcntl.h>
31 #include <poll.h>
32 #include <stdbool.h>
33 #include <string.h>
34 #include <sys/sysinfo.h>
35 #include <unistd.h>
36 
37 #include "compiler/glsl_types.h"
38 #include "util/debug.h"
39 #include "util/disk_cache.h"
40 #include "util/u_atomic.h"
41 #include "vk_format.h"
42 #include "vk_util.h"
43 
44 /* for fd_get_driver/device_uuid() */
45 #include "freedreno/common/freedreno_uuid.h"
46 
47 #define TU_HAS_SURFACE \
48    (VK_USE_PLATFORM_WAYLAND_KHR || \
49     VK_USE_PLATFORM_XCB_KHR || \
50     VK_USE_PLATFORM_XLIB_KHR || \
51     VK_USE_PLATFORM_DISPLAY_KHR)
52 
53 static int
tu_device_get_cache_uuid(uint16_t family,void * uuid)54 tu_device_get_cache_uuid(uint16_t family, void *uuid)
55 {
56    uint32_t mesa_timestamp;
57    uint16_t f = family;
58    memset(uuid, 0, VK_UUID_SIZE);
59    if (!disk_cache_get_function_timestamp(tu_device_get_cache_uuid,
60                                           &mesa_timestamp))
61       return -1;
62 
63    memcpy(uuid, &mesa_timestamp, 4);
64    memcpy((char *) uuid + 4, &f, 2);
65    snprintf((char *) uuid + 6, VK_UUID_SIZE - 10, "tu");
66    return 0;
67 }
68 
69 VkResult
tu_physical_device_init(struct tu_physical_device * device,struct tu_instance * instance)70 tu_physical_device_init(struct tu_physical_device *device,
71                         struct tu_instance *instance)
72 {
73    VkResult result = VK_SUCCESS;
74 
75    memset(device->name, 0, sizeof(device->name));
76    sprintf(device->name, "FD%d", device->gpu_id);
77 
78    device->limited_z24s8 = (device->gpu_id == 630);
79 
80    switch (device->gpu_id) {
81    case 615:
82    case 618:
83    case 630:
84    case 640:
85    case 650:
86       freedreno_dev_info_init(&device->info, device->gpu_id);
87       break;
88    default:
89       result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
90                                  "device %s is unsupported", device->name);
91       goto fail;
92    }
93    if (tu_device_get_cache_uuid(device->gpu_id, device->cache_uuid)) {
94       result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
95                                  "cannot generate UUID");
96       goto fail;
97    }
98 
99    /* The gpu id is already embedded in the uuid so we just pass "tu"
100     * when creating the cache.
101     */
102    char buf[VK_UUID_SIZE * 2 + 1];
103    disk_cache_format_hex_id(buf, device->cache_uuid, VK_UUID_SIZE * 2);
104    device->disk_cache = disk_cache_create(device->name, buf, 0);
105 
106    fprintf(stderr, "WARNING: tu is not a conformant vulkan implementation, "
107                    "testing use only.\n");
108 
109    fd_get_driver_uuid(device->driver_uuid);
110    fd_get_device_uuid(device->device_uuid, device->gpu_id);
111 
112    tu_physical_device_get_supported_extensions(device, &device->supported_extensions);
113 
114 #if TU_HAS_SURFACE
115    result = tu_wsi_init(device);
116    if (result != VK_SUCCESS) {
117       vk_startup_errorf(instance, result, "WSI init failure");
118       goto fail;
119    }
120 #endif
121 
122    return VK_SUCCESS;
123 
124 fail:
125    close(device->local_fd);
126    if (device->master_fd != -1)
127       close(device->master_fd);
128    return result;
129 }
130 
131 static void
tu_physical_device_finish(struct tu_physical_device * device)132 tu_physical_device_finish(struct tu_physical_device *device)
133 {
134 #if TU_HAS_SURFACE
135    tu_wsi_finish(device);
136 #endif
137 
138    disk_cache_destroy(device->disk_cache);
139    close(device->local_fd);
140    if (device->master_fd != -1)
141       close(device->master_fd);
142 
143    vk_object_base_finish(&device->base);
144 }
145 
146 static VKAPI_ATTR void *
default_alloc_func(void * pUserData,size_t size,size_t align,VkSystemAllocationScope allocationScope)147 default_alloc_func(void *pUserData,
148                    size_t size,
149                    size_t align,
150                    VkSystemAllocationScope allocationScope)
151 {
152    return malloc(size);
153 }
154 
155 static VKAPI_ATTR void *
default_realloc_func(void * pUserData,void * pOriginal,size_t size,size_t align,VkSystemAllocationScope allocationScope)156 default_realloc_func(void *pUserData,
157                      void *pOriginal,
158                      size_t size,
159                      size_t align,
160                      VkSystemAllocationScope allocationScope)
161 {
162    return realloc(pOriginal, size);
163 }
164 
165 static VKAPI_ATTR void
default_free_func(void * pUserData,void * pMemory)166 default_free_func(void *pUserData, void *pMemory)
167 {
168    free(pMemory);
169 }
170 
171 static const VkAllocationCallbacks default_alloc = {
172    .pUserData = NULL,
173    .pfnAllocation = default_alloc_func,
174    .pfnReallocation = default_realloc_func,
175    .pfnFree = default_free_func,
176 };
177 
178 static const struct debug_control tu_debug_options[] = {
179    { "startup", TU_DEBUG_STARTUP },
180    { "nir", TU_DEBUG_NIR },
181    { "ir3", TU_DEBUG_IR3 },
182    { "nobin", TU_DEBUG_NOBIN },
183    { "sysmem", TU_DEBUG_SYSMEM },
184    { "forcebin", TU_DEBUG_FORCEBIN },
185    { "noubwc", TU_DEBUG_NOUBWC },
186    { "nomultipos", TU_DEBUG_NOMULTIPOS },
187    { "nolrz", TU_DEBUG_NOLRZ },
188    { NULL, 0 }
189 };
190 
191 const char *
tu_get_debug_option_name(int id)192 tu_get_debug_option_name(int id)
193 {
194    assert(id < ARRAY_SIZE(tu_debug_options) - 1);
195    return tu_debug_options[id].string;
196 }
197 
198 static int
tu_get_instance_extension_index(const char * name)199 tu_get_instance_extension_index(const char *name)
200 {
201    for (unsigned i = 0; i < TU_INSTANCE_EXTENSION_COUNT; ++i) {
202       if (strcmp(name, tu_instance_extensions[i].extensionName) == 0)
203          return i;
204    }
205    return -1;
206 }
207 
208 VkResult
tu_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)209 tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
210                   const VkAllocationCallbacks *pAllocator,
211                   VkInstance *pInstance)
212 {
213    struct tu_instance *instance;
214    VkResult result;
215 
216    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
217 
218    uint32_t client_version;
219    if (pCreateInfo->pApplicationInfo &&
220        pCreateInfo->pApplicationInfo->apiVersion != 0) {
221       client_version = pCreateInfo->pApplicationInfo->apiVersion;
222    } else {
223       tu_EnumerateInstanceVersion(&client_version);
224    }
225 
226    instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
227                          VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
228 
229    if (!instance)
230       return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
231 
232    vk_object_base_init(NULL, &instance->base, VK_OBJECT_TYPE_INSTANCE);
233 
234    if (pAllocator)
235       instance->alloc = *pAllocator;
236    else
237       instance->alloc = default_alloc;
238 
239    instance->api_version = client_version;
240    instance->physical_device_count = -1;
241 
242    instance->debug_flags =
243       parse_debug_string(getenv("TU_DEBUG"), tu_debug_options);
244 
245 #ifdef DEBUG
246    /* Enable startup debugging by default on debug drivers.  You almost always
247     * want to see your startup failures in that case, and it's hard to set
248     * this env var on android.
249     */
250    instance->debug_flags |= TU_DEBUG_STARTUP;
251 #endif
252 
253    if (instance->debug_flags & TU_DEBUG_STARTUP)
254       mesa_logi("Created an instance");
255 
256    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
257       const char *ext_name = pCreateInfo->ppEnabledExtensionNames[i];
258       int index = tu_get_instance_extension_index(ext_name);
259 
260       if (index < 0 || !tu_instance_extensions_supported.extensions[index]) {
261          vk_object_base_finish(&instance->base);
262          vk_free2(&default_alloc, pAllocator, instance);
263          return vk_startup_errorf(instance, VK_ERROR_EXTENSION_NOT_PRESENT,
264                                   "Missing %s", ext_name);
265       }
266 
267       instance->enabled_extensions.extensions[index] = true;
268    }
269 
270    result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
271    if (result != VK_SUCCESS) {
272       vk_object_base_finish(&instance->base);
273       vk_free2(&default_alloc, pAllocator, instance);
274       return vk_startup_errorf(instance, result, "debug_report setup failure");
275    }
276 
277    glsl_type_singleton_init_or_ref();
278 
279    VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
280 
281    *pInstance = tu_instance_to_handle(instance);
282 
283    return VK_SUCCESS;
284 }
285 
286 void
tu_DestroyInstance(VkInstance _instance,const VkAllocationCallbacks * pAllocator)287 tu_DestroyInstance(VkInstance _instance,
288                    const VkAllocationCallbacks *pAllocator)
289 {
290    TU_FROM_HANDLE(tu_instance, instance, _instance);
291 
292    if (!instance)
293       return;
294 
295    for (int i = 0; i < instance->physical_device_count; ++i) {
296       tu_physical_device_finish(instance->physical_devices + i);
297    }
298 
299    VG(VALGRIND_DESTROY_MEMPOOL(instance));
300 
301    glsl_type_singleton_decref();
302 
303    vk_debug_report_instance_destroy(&instance->debug_report_callbacks);
304 
305    vk_object_base_finish(&instance->base);
306    vk_free(&instance->alloc, instance);
307 }
308 
309 VkResult
tu_EnumeratePhysicalDevices(VkInstance _instance,uint32_t * pPhysicalDeviceCount,VkPhysicalDevice * pPhysicalDevices)310 tu_EnumeratePhysicalDevices(VkInstance _instance,
311                             uint32_t *pPhysicalDeviceCount,
312                             VkPhysicalDevice *pPhysicalDevices)
313 {
314    TU_FROM_HANDLE(tu_instance, instance, _instance);
315    VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
316 
317    VkResult result;
318 
319    if (instance->physical_device_count < 0) {
320       result = tu_enumerate_devices(instance);
321       if (result != VK_SUCCESS && result != VK_ERROR_INCOMPATIBLE_DRIVER)
322          return result;
323    }
324 
325    for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
326       vk_outarray_append(&out, p)
327       {
328          *p = tu_physical_device_to_handle(instance->physical_devices + i);
329       }
330    }
331 
332    return vk_outarray_status(&out);
333 }
334 
335 VkResult
tu_EnumeratePhysicalDeviceGroups(VkInstance _instance,uint32_t * pPhysicalDeviceGroupCount,VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties)336 tu_EnumeratePhysicalDeviceGroups(
337    VkInstance _instance,
338    uint32_t *pPhysicalDeviceGroupCount,
339    VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
340 {
341    TU_FROM_HANDLE(tu_instance, instance, _instance);
342    VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,
343                     pPhysicalDeviceGroupCount);
344    VkResult result;
345 
346    if (instance->physical_device_count < 0) {
347       result = tu_enumerate_devices(instance);
348       if (result != VK_SUCCESS && result != VK_ERROR_INCOMPATIBLE_DRIVER)
349          return result;
350    }
351 
352    for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
353       vk_outarray_append(&out, p)
354       {
355          p->physicalDeviceCount = 1;
356          p->physicalDevices[0] =
357             tu_physical_device_to_handle(instance->physical_devices + i);
358          p->subsetAllocation = false;
359       }
360    }
361 
362    return vk_outarray_status(&out);
363 }
364 
365 void
tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2 * pFeatures)366 tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
367                               VkPhysicalDeviceFeatures2 *pFeatures)
368 {
369    pFeatures->features = (VkPhysicalDeviceFeatures) {
370       .robustBufferAccess = true,
371       .fullDrawIndexUint32 = true,
372       .imageCubeArray = true,
373       .independentBlend = true,
374       .geometryShader = true,
375       .tessellationShader = true,
376       .sampleRateShading = true,
377       .dualSrcBlend = true,
378       .logicOp = true,
379       .multiDrawIndirect = true,
380       .drawIndirectFirstInstance = true,
381       .depthClamp = true,
382       .depthBiasClamp = true,
383       .fillModeNonSolid = true,
384       .depthBounds = true,
385       .wideLines = false,
386       .largePoints = true,
387       .alphaToOne = true,
388       .multiViewport = true,
389       .samplerAnisotropy = true,
390       .textureCompressionETC2 = true,
391       .textureCompressionASTC_LDR = true,
392       .textureCompressionBC = true,
393       .occlusionQueryPrecise = true,
394       .pipelineStatisticsQuery = true,
395       .vertexPipelineStoresAndAtomics = true,
396       .fragmentStoresAndAtomics = true,
397       .shaderTessellationAndGeometryPointSize = false,
398       .shaderImageGatherExtended = true,
399       .shaderStorageImageExtendedFormats = true,
400       .shaderStorageImageMultisample = false,
401       .shaderUniformBufferArrayDynamicIndexing = true,
402       .shaderSampledImageArrayDynamicIndexing = true,
403       .shaderStorageBufferArrayDynamicIndexing = true,
404       .shaderStorageImageArrayDynamicIndexing = true,
405       .shaderStorageImageReadWithoutFormat = true,
406       .shaderStorageImageWriteWithoutFormat = true,
407       .shaderClipDistance = true,
408       .shaderCullDistance = true,
409       .shaderFloat64 = false,
410       .shaderInt64 = false,
411       .shaderInt16 = false,
412       .sparseBinding = false,
413       .variableMultisampleRate = false,
414       .inheritedQueries = false,
415    };
416 
417    vk_foreach_struct(ext, pFeatures->pNext)
418    {
419       switch (ext->sType) {
420       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
421          VkPhysicalDeviceVulkan11Features *features = (void *) ext;
422          features->storageBuffer16BitAccess            = false;
423          features->uniformAndStorageBuffer16BitAccess  = false;
424          features->storagePushConstant16               = false;
425          features->storageInputOutput16                = false;
426          features->multiview                           = true;
427          features->multiviewGeometryShader             = false;
428          features->multiviewTessellationShader         = false;
429          features->variablePointersStorageBuffer       = true;
430          features->variablePointers                    = true;
431          features->protectedMemory                     = false;
432          features->samplerYcbcrConversion              = true;
433          features->shaderDrawParameters                = true;
434          break;
435       }
436       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: {
437          VkPhysicalDeviceVulkan12Features *features = (void *) ext;
438          features->samplerMirrorClampToEdge            = true;
439          features->drawIndirectCount                   = true;
440          features->storageBuffer8BitAccess             = false;
441          features->uniformAndStorageBuffer8BitAccess   = false;
442          features->storagePushConstant8                = false;
443          features->shaderBufferInt64Atomics            = false;
444          features->shaderSharedInt64Atomics            = false;
445          features->shaderFloat16                       = false;
446          features->shaderInt8                          = false;
447 
448          features->descriptorIndexing                                 = false;
449          features->shaderInputAttachmentArrayDynamicIndexing          = false;
450          features->shaderUniformTexelBufferArrayDynamicIndexing       = false;
451          features->shaderStorageTexelBufferArrayDynamicIndexing       = false;
452          features->shaderUniformBufferArrayNonUniformIndexing         = false;
453          features->shaderSampledImageArrayNonUniformIndexing          = false;
454          features->shaderStorageBufferArrayNonUniformIndexing         = false;
455          features->shaderStorageImageArrayNonUniformIndexing          = false;
456          features->shaderInputAttachmentArrayNonUniformIndexing       = false;
457          features->shaderUniformTexelBufferArrayNonUniformIndexing    = false;
458          features->shaderStorageTexelBufferArrayNonUniformIndexing    = false;
459          features->descriptorBindingUniformBufferUpdateAfterBind      = false;
460          features->descriptorBindingSampledImageUpdateAfterBind       = false;
461          features->descriptorBindingStorageImageUpdateAfterBind       = false;
462          features->descriptorBindingStorageBufferUpdateAfterBind      = false;
463          features->descriptorBindingUniformTexelBufferUpdateAfterBind = false;
464          features->descriptorBindingStorageTexelBufferUpdateAfterBind = false;
465          features->descriptorBindingUpdateUnusedWhilePending          = false;
466          features->descriptorBindingPartiallyBound                    = false;
467          features->descriptorBindingVariableDescriptorCount           = false;
468          features->runtimeDescriptorArray                             = false;
469 
470          features->samplerFilterMinmax                 = true;
471          features->scalarBlockLayout                   = false;
472          features->imagelessFramebuffer                = false;
473          features->uniformBufferStandardLayout         = false;
474          features->shaderSubgroupExtendedTypes         = false;
475          features->separateDepthStencilLayouts         = false;
476          features->hostQueryReset                      = true;
477          features->timelineSemaphore                   = false;
478          features->bufferDeviceAddress                 = false;
479          features->bufferDeviceAddressCaptureReplay    = false;
480          features->bufferDeviceAddressMultiDevice      = false;
481          features->vulkanMemoryModel                   = false;
482          features->vulkanMemoryModelDeviceScope        = false;
483          features->vulkanMemoryModelAvailabilityVisibilityChains = false;
484          features->shaderOutputViewportIndex           = true;
485          features->shaderOutputLayer                   = true;
486          features->subgroupBroadcastDynamicId          = false;
487          break;
488       }
489       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: {
490          VkPhysicalDeviceVariablePointersFeatures *features = (void *) ext;
491          features->variablePointersStorageBuffer = true;
492          features->variablePointers = true;
493          break;
494       }
495       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
496          VkPhysicalDeviceMultiviewFeatures *features =
497             (VkPhysicalDeviceMultiviewFeatures *) ext;
498          features->multiview = true;
499          features->multiviewGeometryShader = false;
500          features->multiviewTessellationShader = false;
501          break;
502       }
503       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
504          VkPhysicalDeviceShaderDrawParametersFeatures *features =
505             (VkPhysicalDeviceShaderDrawParametersFeatures *) ext;
506          features->shaderDrawParameters = true;
507          break;
508       }
509       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
510          VkPhysicalDeviceProtectedMemoryFeatures *features =
511             (VkPhysicalDeviceProtectedMemoryFeatures *) ext;
512          features->protectedMemory = false;
513          break;
514       }
515       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
516          VkPhysicalDevice16BitStorageFeatures *features =
517             (VkPhysicalDevice16BitStorageFeatures *) ext;
518          features->storageBuffer16BitAccess = false;
519          features->uniformAndStorageBuffer16BitAccess = false;
520          features->storagePushConstant16 = false;
521          features->storageInputOutput16 = false;
522          break;
523       }
524       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
525          VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =
526             (VkPhysicalDeviceSamplerYcbcrConversionFeatures *) ext;
527          features->samplerYcbcrConversion = true;
528          break;
529       }
530       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
531          VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features =
532             (VkPhysicalDeviceDescriptorIndexingFeaturesEXT *) ext;
533          features->shaderInputAttachmentArrayDynamicIndexing = false;
534          features->shaderUniformTexelBufferArrayDynamicIndexing = false;
535          features->shaderStorageTexelBufferArrayDynamicIndexing = false;
536          features->shaderUniformBufferArrayNonUniformIndexing = false;
537          features->shaderSampledImageArrayNonUniformIndexing = false;
538          features->shaderStorageBufferArrayNonUniformIndexing = false;
539          features->shaderStorageImageArrayNonUniformIndexing = false;
540          features->shaderInputAttachmentArrayNonUniformIndexing = false;
541          features->shaderUniformTexelBufferArrayNonUniformIndexing = false;
542          features->shaderStorageTexelBufferArrayNonUniformIndexing = false;
543          features->descriptorBindingUniformBufferUpdateAfterBind = false;
544          features->descriptorBindingSampledImageUpdateAfterBind = false;
545          features->descriptorBindingStorageImageUpdateAfterBind = false;
546          features->descriptorBindingStorageBufferUpdateAfterBind = false;
547          features->descriptorBindingUniformTexelBufferUpdateAfterBind = false;
548          features->descriptorBindingStorageTexelBufferUpdateAfterBind = false;
549          features->descriptorBindingUpdateUnusedWhilePending = false;
550          features->descriptorBindingPartiallyBound = false;
551          features->descriptorBindingVariableDescriptorCount = false;
552          features->runtimeDescriptorArray = false;
553          break;
554       }
555       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
556          VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
557             (VkPhysicalDeviceConditionalRenderingFeaturesEXT *) ext;
558          features->conditionalRendering = true;
559          features->inheritedConditionalRendering = true;
560          break;
561       }
562       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
563          VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
564             (VkPhysicalDeviceTransformFeedbackFeaturesEXT *) ext;
565          features->transformFeedback = true;
566          features->geometryStreams = true;
567          break;
568       }
569       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {
570          VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =
571             (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;
572          features->indexTypeUint8 = true;
573          break;
574       }
575       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
576          VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
577             (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
578          features->vertexAttributeInstanceRateDivisor = true;
579          features->vertexAttributeInstanceRateZeroDivisor = true;
580          break;
581       }
582       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {
583          VkPhysicalDevicePrivateDataFeaturesEXT *features =
584             (VkPhysicalDevicePrivateDataFeaturesEXT *)ext;
585          features->privateData = true;
586          break;
587       }
588       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
589          VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =
590             (VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;
591          features->depthClipEnable = true;
592          break;
593       }
594       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: {
595          VkPhysicalDevice4444FormatsFeaturesEXT *features = (void *)ext;
596          features->formatA4R4G4B4 = true;
597          features->formatA4B4G4R4 = true;
598          break;
599       }
600       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
601          VkPhysicalDeviceCustomBorderColorFeaturesEXT *features = (void *) ext;
602          features->customBorderColors = true;
603          features->customBorderColorWithoutFormat = true;
604          break;
605       }
606       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
607          VkPhysicalDeviceHostQueryResetFeaturesEXT *features =
608             (VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;
609          features->hostQueryReset = true;
610          break;
611       }
612       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {
613          VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features = (void *)ext;
614          features->extendedDynamicState = true;
615          break;
616       }
617       default:
618          break;
619       }
620    }
621 }
622 
623 void
tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2 * pProperties)624 tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
625                                 VkPhysicalDeviceProperties2 *pProperties)
626 {
627    TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
628    VkSampleCountFlags sample_counts =
629       VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT;
630 
631    /* I have no idea what the maximum size is, but the hardware supports very
632     * large numbers of descriptors (at least 2^16). This limit is based on
633     * CP_LOAD_STATE6, which has a 28-bit field for the DWORD offset, so that
634     * we don't have to think about what to do if that overflows, but really
635     * nothing is likely to get close to this.
636     */
637    const size_t max_descriptor_set_size = (1 << 28) / A6XX_TEX_CONST_DWORDS;
638 
639    VkPhysicalDeviceLimits limits = {
640       .maxImageDimension1D = (1 << 14),
641       .maxImageDimension2D = (1 << 14),
642       .maxImageDimension3D = (1 << 11),
643       .maxImageDimensionCube = (1 << 14),
644       .maxImageArrayLayers = (1 << 11),
645       .maxTexelBufferElements = 128 * 1024 * 1024,
646       .maxUniformBufferRange = MAX_UNIFORM_BUFFER_RANGE,
647       .maxStorageBufferRange = MAX_STORAGE_BUFFER_RANGE,
648       .maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
649       .maxMemoryAllocationCount = UINT32_MAX,
650       .maxSamplerAllocationCount = 64 * 1024,
651       .bufferImageGranularity = 64,          /* A cache line */
652       .sparseAddressSpaceSize = 0xffffffffu, /* buffer max size */
653       .maxBoundDescriptorSets = MAX_SETS,
654       .maxPerStageDescriptorSamplers = max_descriptor_set_size,
655       .maxPerStageDescriptorUniformBuffers = max_descriptor_set_size,
656       .maxPerStageDescriptorStorageBuffers = max_descriptor_set_size,
657       .maxPerStageDescriptorSampledImages = max_descriptor_set_size,
658       .maxPerStageDescriptorStorageImages = max_descriptor_set_size,
659       .maxPerStageDescriptorInputAttachments = MAX_RTS,
660       .maxPerStageResources = max_descriptor_set_size,
661       .maxDescriptorSetSamplers = max_descriptor_set_size,
662       .maxDescriptorSetUniformBuffers = max_descriptor_set_size,
663       .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS,
664       .maxDescriptorSetStorageBuffers = max_descriptor_set_size,
665       .maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS,
666       .maxDescriptorSetSampledImages = max_descriptor_set_size,
667       .maxDescriptorSetStorageImages = max_descriptor_set_size,
668       .maxDescriptorSetInputAttachments = MAX_RTS,
669       .maxVertexInputAttributes = 32,
670       .maxVertexInputBindings = 32,
671       .maxVertexInputAttributeOffset = 4095,
672       .maxVertexInputBindingStride = 2048,
673       .maxVertexOutputComponents = 128,
674       .maxTessellationGenerationLevel = 64,
675       .maxTessellationPatchSize = 32,
676       .maxTessellationControlPerVertexInputComponents = 128,
677       .maxTessellationControlPerVertexOutputComponents = 128,
678       .maxTessellationControlPerPatchOutputComponents = 120,
679       .maxTessellationControlTotalOutputComponents = 4096,
680       .maxTessellationEvaluationInputComponents = 128,
681       .maxTessellationEvaluationOutputComponents = 128,
682       .maxGeometryShaderInvocations = 32,
683       .maxGeometryInputComponents = 64,
684       .maxGeometryOutputComponents = 128,
685       .maxGeometryOutputVertices = 256,
686       .maxGeometryTotalOutputComponents = 1024,
687       .maxFragmentInputComponents = 124,
688       .maxFragmentOutputAttachments = 8,
689       .maxFragmentDualSrcAttachments = 1,
690       .maxFragmentCombinedOutputResources = 8,
691       .maxComputeSharedMemorySize = 32768,
692       .maxComputeWorkGroupCount = { 65535, 65535, 65535 },
693       .maxComputeWorkGroupInvocations = 2048,
694       .maxComputeWorkGroupSize = { 2048, 2048, 2048 },
695       .subPixelPrecisionBits = 8,
696       .subTexelPrecisionBits = 8,
697       .mipmapPrecisionBits = 8,
698       .maxDrawIndexedIndexValue = UINT32_MAX,
699       .maxDrawIndirectCount = UINT32_MAX,
700       .maxSamplerLodBias = 4095.0 / 256.0, /* [-16, 15.99609375] */
701       .maxSamplerAnisotropy = 16,
702       .maxViewports = MAX_VIEWPORTS,
703       .maxViewportDimensions = { (1 << 14), (1 << 14) },
704       .viewportBoundsRange = { INT16_MIN, INT16_MAX },
705       .viewportSubPixelBits = 8,
706       .minMemoryMapAlignment = 4096, /* A page */
707       .minTexelBufferOffsetAlignment = 64,
708       .minUniformBufferOffsetAlignment = 64,
709       .minStorageBufferOffsetAlignment = 64,
710       .minTexelOffset = -16,
711       .maxTexelOffset = 15,
712       .minTexelGatherOffset = -32,
713       .maxTexelGatherOffset = 31,
714       .minInterpolationOffset = -0.5,
715       .maxInterpolationOffset = 0.4375,
716       .subPixelInterpolationOffsetBits = 4,
717       .maxFramebufferWidth = (1 << 14),
718       .maxFramebufferHeight = (1 << 14),
719       .maxFramebufferLayers = (1 << 10),
720       .framebufferColorSampleCounts = sample_counts,
721       .framebufferDepthSampleCounts = sample_counts,
722       .framebufferStencilSampleCounts = sample_counts,
723       .framebufferNoAttachmentsSampleCounts = sample_counts,
724       .maxColorAttachments = MAX_RTS,
725       .sampledImageColorSampleCounts = sample_counts,
726       .sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT,
727       .sampledImageDepthSampleCounts = sample_counts,
728       .sampledImageStencilSampleCounts = sample_counts,
729       .storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
730       .maxSampleMaskWords = 1,
731       .timestampComputeAndGraphics = true,
732       .timestampPeriod = 1000000000.0 / 19200000.0, /* CP_ALWAYS_ON_COUNTER is fixed 19.2MHz */
733       .maxClipDistances = 8,
734       .maxCullDistances = 8,
735       .maxCombinedClipAndCullDistances = 8,
736       .discreteQueuePriorities = 1,
737       .pointSizeRange = { 1, 4092 },
738       .lineWidthRange = { 0.0, 7.9921875 },
739       .pointSizeGranularity = 	0.0625,
740       .lineWidthGranularity = (1.0 / 128.0),
741       .strictLines = false, /* FINISHME */
742       .standardSampleLocations = true,
743       .optimalBufferCopyOffsetAlignment = 128,
744       .optimalBufferCopyRowPitchAlignment = 128,
745       .nonCoherentAtomSize = 64,
746    };
747 
748    pProperties->properties = (VkPhysicalDeviceProperties) {
749       .apiVersion = tu_physical_device_api_version(pdevice),
750       .driverVersion = vk_get_driver_version(),
751       .vendorID = 0, /* TODO */
752       .deviceID = 0,
753       .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
754       .limits = limits,
755       .sparseProperties = { 0 },
756    };
757 
758    strcpy(pProperties->properties.deviceName, pdevice->name);
759    memcpy(pProperties->properties.pipelineCacheUUID, pdevice->cache_uuid, VK_UUID_SIZE);
760 
761    vk_foreach_struct(ext, pProperties->pNext)
762    {
763       switch (ext->sType) {
764       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
765          VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
766             (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
767          properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
768          break;
769       }
770       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
771          VkPhysicalDeviceIDProperties *properties =
772             (VkPhysicalDeviceIDProperties *) ext;
773          memcpy(properties->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
774          memcpy(properties->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
775          properties->deviceLUIDValid = false;
776          break;
777       }
778       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {
779          VkPhysicalDeviceMultiviewProperties *properties =
780             (VkPhysicalDeviceMultiviewProperties *) ext;
781          properties->maxMultiviewViewCount = MAX_VIEWS;
782          properties->maxMultiviewInstanceIndex = INT_MAX;
783          break;
784       }
785       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
786          VkPhysicalDevicePointClippingProperties *properties =
787             (VkPhysicalDevicePointClippingProperties *) ext;
788          properties->pointClippingBehavior =
789             VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
790          break;
791       }
792       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
793          VkPhysicalDeviceMaintenance3Properties *properties =
794             (VkPhysicalDeviceMaintenance3Properties *) ext;
795          /* Make sure everything is addressable by a signed 32-bit int, and
796           * our largest descriptors are 96 bytes. */
797          properties->maxPerSetDescriptors = (1ull << 31) / 96;
798          /* Our buffer size fields allow only this much */
799          properties->maxMemoryAllocationSize = 0xFFFFFFFFull;
800          break;
801       }
802       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
803          VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =
804             (VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext;
805 
806          properties->maxTransformFeedbackStreams = IR3_MAX_SO_STREAMS;
807          properties->maxTransformFeedbackBuffers = IR3_MAX_SO_BUFFERS;
808          properties->maxTransformFeedbackBufferSize = UINT32_MAX;
809          properties->maxTransformFeedbackStreamDataSize = 512;
810          properties->maxTransformFeedbackBufferDataSize = 512;
811          properties->maxTransformFeedbackBufferDataStride = 512;
812          properties->transformFeedbackQueries = true;
813          properties->transformFeedbackStreamsLinesTriangles = true;
814          properties->transformFeedbackRasterizationStreamSelect = true;
815          properties->transformFeedbackDraw = true;
816          break;
817       }
818       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT: {
819          VkPhysicalDeviceSampleLocationsPropertiesEXT *properties =
820             (VkPhysicalDeviceSampleLocationsPropertiesEXT *)ext;
821          properties->sampleLocationSampleCounts = 0;
822          if (pdevice->supported_extensions.EXT_sample_locations) {
823             properties->sampleLocationSampleCounts =
824                VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT;
825          }
826          properties->maxSampleLocationGridSize = (VkExtent2D) { 1 , 1 };
827          properties->sampleLocationCoordinateRange[0] = 0.0f;
828          properties->sampleLocationCoordinateRange[1] = 0.9375f;
829          properties->sampleLocationSubPixelBits = 4;
830          properties->variableSampleLocations = true;
831          break;
832       }
833       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES: {
834          VkPhysicalDeviceSamplerFilterMinmaxProperties *properties =
835             (VkPhysicalDeviceSamplerFilterMinmaxProperties *)ext;
836          properties->filterMinmaxImageComponentMapping = true;
837          properties->filterMinmaxSingleComponentFormats = true;
838          break;
839       }
840       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {
841          VkPhysicalDeviceSubgroupProperties *properties =
842             (VkPhysicalDeviceSubgroupProperties *)ext;
843          properties->subgroupSize = 64;
844          properties->supportedStages = VK_SHADER_STAGE_COMPUTE_BIT;
845          properties->supportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT |
846                                            VK_SUBGROUP_FEATURE_VOTE_BIT;
847          properties->quadOperationsInAllStages = false;
848          break;
849       }
850       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
851          VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
852             (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
853          props->maxVertexAttribDivisor = UINT32_MAX;
854          break;
855       }
856       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
857          VkPhysicalDeviceCustomBorderColorPropertiesEXT *props = (void *)ext;
858          props->maxCustomBorderColorSamplers = TU_BORDER_COLOR_COUNT;
859          break;
860       }
861       default:
862          break;
863       }
864    }
865 }
866 
867 static const VkQueueFamilyProperties tu_queue_family_properties = {
868    .queueFlags =
869       VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT,
870    .queueCount = 1,
871    .timestampValidBits = 48,
872    .minImageTransferGranularity = { 1, 1, 1 },
873 };
874 
875 void
tu_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)876 tu_GetPhysicalDeviceQueueFamilyProperties2(
877    VkPhysicalDevice physicalDevice,
878    uint32_t *pQueueFamilyPropertyCount,
879    VkQueueFamilyProperties2 *pQueueFamilyProperties)
880 {
881    VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
882 
883    vk_outarray_append(&out, p)
884    {
885       p->queueFamilyProperties = tu_queue_family_properties;
886    }
887 }
888 
889 static uint64_t
tu_get_system_heap_size()890 tu_get_system_heap_size()
891 {
892    struct sysinfo info;
893    sysinfo(&info);
894 
895    uint64_t total_ram = (uint64_t) info.totalram * (uint64_t) info.mem_unit;
896 
897    /* We don't want to burn too much ram with the GPU.  If the user has 4GiB
898     * or less, we use at most half.  If they have more than 4GiB, we use 3/4.
899     */
900    uint64_t available_ram;
901    if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
902       available_ram = total_ram / 2;
903    else
904       available_ram = total_ram * 3 / 4;
905 
906    return available_ram;
907 }
908 
909 void
tu_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice pdev,VkPhysicalDeviceMemoryProperties2 * props2)910 tu_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice pdev,
911                                       VkPhysicalDeviceMemoryProperties2 *props2)
912 {
913    VkPhysicalDeviceMemoryProperties *props = &props2->memoryProperties;
914 
915    props->memoryHeapCount = 1;
916    props->memoryHeaps[0].size = tu_get_system_heap_size();
917    props->memoryHeaps[0].flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
918 
919    props->memoryTypeCount = 1;
920    props->memoryTypes[0].propertyFlags =
921       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
922       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
923       VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
924    props->memoryTypes[0].heapIndex = 0;
925 }
926 
927 static VkResult
tu_queue_init(struct tu_device * device,struct tu_queue * queue,uint32_t queue_family_index,int idx,VkDeviceQueueCreateFlags flags)928 tu_queue_init(struct tu_device *device,
929               struct tu_queue *queue,
930               uint32_t queue_family_index,
931               int idx,
932               VkDeviceQueueCreateFlags flags)
933 {
934    vk_object_base_init(&device->vk, &queue->base, VK_OBJECT_TYPE_QUEUE);
935 
936    queue->device = device;
937    queue->queue_family_index = queue_family_index;
938    queue->queue_idx = idx;
939    queue->flags = flags;
940 
941    int ret = tu_drm_submitqueue_new(device, 0, &queue->msm_queue_id);
942    if (ret)
943       return vk_startup_errorf(device->instance, VK_ERROR_INITIALIZATION_FAILED,
944                                "submitqueue create failed");
945 
946    queue->fence = -1;
947 
948    return VK_SUCCESS;
949 }
950 
951 static void
tu_queue_finish(struct tu_queue * queue)952 tu_queue_finish(struct tu_queue *queue)
953 {
954    if (queue->fence >= 0)
955       close(queue->fence);
956    tu_drm_submitqueue_close(queue->device, queue->msm_queue_id);
957 }
958 
959 static int
tu_get_device_extension_index(const char * name)960 tu_get_device_extension_index(const char *name)
961 {
962    for (unsigned i = 0; i < TU_DEVICE_EXTENSION_COUNT; ++i) {
963       if (strcmp(name, tu_device_extensions[i].extensionName) == 0)
964          return i;
965    }
966    return -1;
967 }
968 
969 VkResult
tu_CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)970 tu_CreateDevice(VkPhysicalDevice physicalDevice,
971                 const VkDeviceCreateInfo *pCreateInfo,
972                 const VkAllocationCallbacks *pAllocator,
973                 VkDevice *pDevice)
974 {
975    TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
976    VkResult result;
977    struct tu_device *device;
978    bool custom_border_colors = false;
979 
980    /* Check enabled features */
981    if (pCreateInfo->pEnabledFeatures) {
982       VkPhysicalDeviceFeatures supported_features;
983       tu_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);
984       VkBool32 *supported_feature = (VkBool32 *) &supported_features;
985       VkBool32 *enabled_feature = (VkBool32 *) pCreateInfo->pEnabledFeatures;
986       unsigned num_features =
987          sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
988       for (uint32_t i = 0; i < num_features; i++) {
989          if (enabled_feature[i] && !supported_feature[i])
990             return vk_startup_errorf(physical_device->instance,
991                                      VK_ERROR_FEATURE_NOT_PRESENT,
992                                      "Missing feature bit %d\n", i);
993       }
994    }
995 
996    vk_foreach_struct_const(ext, pCreateInfo->pNext) {
997       switch (ext->sType) {
998       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
999          const VkPhysicalDeviceCustomBorderColorFeaturesEXT *border_color_features = (const void *)ext;
1000          custom_border_colors = border_color_features->customBorderColors;
1001          break;
1002       }
1003       default:
1004          break;
1005       }
1006    }
1007 
1008    device = vk_zalloc2(&physical_device->instance->alloc, pAllocator,
1009                        sizeof(*device), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1010    if (!device)
1011       return vk_startup_errorf(physical_device->instance, VK_ERROR_OUT_OF_HOST_MEMORY, "OOM");
1012 
1013    vk_device_init(&device->vk, pCreateInfo,
1014          &physical_device->instance->alloc, pAllocator);
1015 
1016    device->instance = physical_device->instance;
1017    device->physical_device = physical_device;
1018    device->fd = physical_device->local_fd;
1019    device->_lost = false;
1020 
1021    mtx_init(&device->bo_mutex, mtx_plain);
1022 
1023    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
1024       const char *ext_name = pCreateInfo->ppEnabledExtensionNames[i];
1025       int index = tu_get_device_extension_index(ext_name);
1026       if (index < 0 ||
1027           !physical_device->supported_extensions.extensions[index]) {
1028          vk_free(&device->vk.alloc, device);
1029          return vk_startup_errorf(physical_device->instance,
1030                                   VK_ERROR_EXTENSION_NOT_PRESENT,
1031                                   "Missing device extension '%s'", ext_name);
1032       }
1033 
1034       device->enabled_extensions.extensions[index] = true;
1035    }
1036 
1037    for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
1038       const VkDeviceQueueCreateInfo *queue_create =
1039          &pCreateInfo->pQueueCreateInfos[i];
1040       uint32_t qfi = queue_create->queueFamilyIndex;
1041       device->queues[qfi] = vk_alloc(
1042          &device->vk.alloc, queue_create->queueCount * sizeof(struct tu_queue),
1043          8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1044       if (!device->queues[qfi]) {
1045          result = vk_startup_errorf(physical_device->instance,
1046                                     VK_ERROR_OUT_OF_HOST_MEMORY,
1047                                     "OOM");
1048          goto fail_queues;
1049       }
1050 
1051       memset(device->queues[qfi], 0,
1052              queue_create->queueCount * sizeof(struct tu_queue));
1053 
1054       device->queue_count[qfi] = queue_create->queueCount;
1055 
1056       for (unsigned q = 0; q < queue_create->queueCount; q++) {
1057          result = tu_queue_init(device, &device->queues[qfi][q], qfi, q,
1058                                 queue_create->flags);
1059          if (result != VK_SUCCESS)
1060             goto fail_queues;
1061       }
1062    }
1063 
1064    device->compiler = ir3_compiler_create(NULL, physical_device->gpu_id);
1065    if (!device->compiler) {
1066       result = vk_startup_errorf(physical_device->instance,
1067                                  VK_ERROR_INITIALIZATION_FAILED,
1068                                  "failed to initialize ir3 compiler");
1069       goto fail_queues;
1070    }
1071 
1072    /* initial sizes, these will increase if there is overflow */
1073    device->vsc_draw_strm_pitch = 0x1000 + VSC_PAD;
1074    device->vsc_prim_strm_pitch = 0x4000 + VSC_PAD;
1075 
1076    uint32_t global_size = sizeof(struct tu6_global);
1077    if (custom_border_colors)
1078       global_size += TU_BORDER_COLOR_COUNT * sizeof(struct bcolor_entry);
1079 
1080    result = tu_bo_init_new(device, &device->global_bo, global_size, false);
1081    if (result != VK_SUCCESS) {
1082       vk_startup_errorf(device->instance, result, "BO init");
1083       goto fail_global_bo;
1084    }
1085 
1086    result = tu_bo_map(device, &device->global_bo);
1087    if (result != VK_SUCCESS) {
1088       vk_startup_errorf(device->instance, result, "BO map");
1089       goto fail_global_bo_map;
1090    }
1091 
1092    struct tu6_global *global = device->global_bo.map;
1093    tu_init_clear_blit_shaders(device->global_bo.map);
1094    global->predicate = 0;
1095    tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK],
1096                          &(VkClearColorValue) {}, false);
1097    tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_TRANSPARENT_BLACK],
1098                          &(VkClearColorValue) {}, true);
1099    tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK],
1100                          &(VkClearColorValue) { .float32[3] = 1.0f }, false);
1101    tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_OPAQUE_BLACK],
1102                          &(VkClearColorValue) { .int32[3] = 1 }, true);
1103    tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE],
1104                          &(VkClearColorValue) { .float32[0 ... 3] = 1.0f }, false);
1105    tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_OPAQUE_WHITE],
1106                          &(VkClearColorValue) { .int32[0 ... 3] = 1 }, true);
1107 
1108    /* initialize to ones so ffs can be used to find unused slots */
1109    BITSET_ONES(device->custom_border_color);
1110 
1111    VkPipelineCacheCreateInfo ci;
1112    ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
1113    ci.pNext = NULL;
1114    ci.flags = 0;
1115    ci.pInitialData = NULL;
1116    ci.initialDataSize = 0;
1117    VkPipelineCache pc;
1118    result =
1119       tu_CreatePipelineCache(tu_device_to_handle(device), &ci, NULL, &pc);
1120    if (result != VK_SUCCESS) {
1121       vk_startup_errorf(device->instance, result, "create pipeline cache failed");
1122       goto fail_pipeline_cache;
1123    }
1124 
1125    device->mem_cache = tu_pipeline_cache_from_handle(pc);
1126 
1127    for (unsigned i = 0; i < ARRAY_SIZE(device->scratch_bos); i++)
1128       mtx_init(&device->scratch_bos[i].construct_mtx, mtx_plain);
1129 
1130    mtx_init(&device->mutex, mtx_plain);
1131 
1132    *pDevice = tu_device_to_handle(device);
1133    return VK_SUCCESS;
1134 
1135 fail_pipeline_cache:
1136 fail_global_bo_map:
1137    tu_bo_finish(device, &device->global_bo);
1138 
1139 fail_global_bo:
1140    ir3_compiler_destroy(device->compiler);
1141 
1142 fail_queues:
1143    for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
1144       for (unsigned q = 0; q < device->queue_count[i]; q++)
1145          tu_queue_finish(&device->queues[i][q]);
1146       if (device->queue_count[i])
1147          vk_object_free(&device->vk, NULL, device->queues[i]);
1148    }
1149 
1150    vk_free(&device->vk.alloc, device);
1151    return result;
1152 }
1153 
1154 void
tu_DestroyDevice(VkDevice _device,const VkAllocationCallbacks * pAllocator)1155 tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
1156 {
1157    TU_FROM_HANDLE(tu_device, device, _device);
1158 
1159    if (!device)
1160       return;
1161 
1162    for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
1163       for (unsigned q = 0; q < device->queue_count[i]; q++)
1164          tu_queue_finish(&device->queues[i][q]);
1165       if (device->queue_count[i])
1166          vk_object_free(&device->vk, NULL, device->queues[i]);
1167    }
1168 
1169    for (unsigned i = 0; i < ARRAY_SIZE(device->scratch_bos); i++) {
1170       if (device->scratch_bos[i].initialized)
1171          tu_bo_finish(device, &device->scratch_bos[i].bo);
1172    }
1173 
1174    ir3_compiler_destroy(device->compiler);
1175 
1176    VkPipelineCache pc = tu_pipeline_cache_to_handle(device->mem_cache);
1177    tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL);
1178 
1179    vk_free(&device->vk.alloc, device->bo_list);
1180    vk_free(&device->vk.alloc, device->bo_idx);
1181    vk_free(&device->vk.alloc, device);
1182 }
1183 
1184 VkResult
_tu_device_set_lost(struct tu_device * device,const char * msg,...)1185 _tu_device_set_lost(struct tu_device *device,
1186                     const char *msg, ...)
1187 {
1188    /* Set the flag indicating that waits should return in finite time even
1189     * after device loss.
1190     */
1191    p_atomic_inc(&device->_lost);
1192 
1193    /* TODO: Report the log message through VkDebugReportCallbackEXT instead */
1194    va_list ap;
1195    va_start(ap, msg);
1196    mesa_loge_v(msg, ap);
1197    va_end(ap);
1198 
1199    if (env_var_as_boolean("TU_ABORT_ON_DEVICE_LOSS", false))
1200       abort();
1201 
1202    return VK_ERROR_DEVICE_LOST;
1203 }
1204 
1205 VkResult
tu_get_scratch_bo(struct tu_device * dev,uint64_t size,struct tu_bo ** bo)1206 tu_get_scratch_bo(struct tu_device *dev, uint64_t size, struct tu_bo **bo)
1207 {
1208    unsigned size_log2 = MAX2(util_logbase2_ceil64(size), MIN_SCRATCH_BO_SIZE_LOG2);
1209    unsigned index = size_log2 - MIN_SCRATCH_BO_SIZE_LOG2;
1210    assert(index < ARRAY_SIZE(dev->scratch_bos));
1211 
1212    for (unsigned i = index; i < ARRAY_SIZE(dev->scratch_bos); i++) {
1213       if (p_atomic_read(&dev->scratch_bos[i].initialized)) {
1214          /* Fast path: just return the already-allocated BO. */
1215          *bo = &dev->scratch_bos[i].bo;
1216          return VK_SUCCESS;
1217       }
1218    }
1219 
1220    /* Slow path: actually allocate the BO. We take a lock because the process
1221     * of allocating it is slow, and we don't want to block the CPU while it
1222     * finishes.
1223    */
1224    mtx_lock(&dev->scratch_bos[index].construct_mtx);
1225 
1226    /* Another thread may have allocated it already while we were waiting on
1227     * the lock. We need to check this in order to avoid double-allocating.
1228     */
1229    if (dev->scratch_bos[index].initialized) {
1230       mtx_unlock(&dev->scratch_bos[index].construct_mtx);
1231       *bo = &dev->scratch_bos[index].bo;
1232       return VK_SUCCESS;
1233    }
1234 
1235    unsigned bo_size = 1ull << size_log2;
1236    VkResult result = tu_bo_init_new(dev, &dev->scratch_bos[index].bo, bo_size, false);
1237    if (result != VK_SUCCESS) {
1238       mtx_unlock(&dev->scratch_bos[index].construct_mtx);
1239       return result;
1240    }
1241 
1242    p_atomic_set(&dev->scratch_bos[index].initialized, true);
1243 
1244    mtx_unlock(&dev->scratch_bos[index].construct_mtx);
1245 
1246    *bo = &dev->scratch_bos[index].bo;
1247    return VK_SUCCESS;
1248 }
1249 
1250 VkResult
tu_EnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)1251 tu_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
1252                                     VkLayerProperties *pProperties)
1253 {
1254    *pPropertyCount = 0;
1255    return VK_SUCCESS;
1256 }
1257 
1258 VkResult
tu_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pPropertyCount,VkLayerProperties * pProperties)1259 tu_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1260                                   uint32_t *pPropertyCount,
1261                                   VkLayerProperties *pProperties)
1262 {
1263    *pPropertyCount = 0;
1264    return VK_SUCCESS;
1265 }
1266 
1267 void
tu_GetDeviceQueue2(VkDevice _device,const VkDeviceQueueInfo2 * pQueueInfo,VkQueue * pQueue)1268 tu_GetDeviceQueue2(VkDevice _device,
1269                    const VkDeviceQueueInfo2 *pQueueInfo,
1270                    VkQueue *pQueue)
1271 {
1272    TU_FROM_HANDLE(tu_device, device, _device);
1273    struct tu_queue *queue;
1274 
1275    queue =
1276       &device->queues[pQueueInfo->queueFamilyIndex][pQueueInfo->queueIndex];
1277    if (pQueueInfo->flags != queue->flags) {
1278       /* From the Vulkan 1.1.70 spec:
1279        *
1280        * "The queue returned by vkGetDeviceQueue2 must have the same
1281        * flags value from this structure as that used at device
1282        * creation time in a VkDeviceQueueCreateInfo instance. If no
1283        * matching flags were specified at device creation time then
1284        * pQueue will return VK_NULL_HANDLE."
1285        */
1286       *pQueue = VK_NULL_HANDLE;
1287       return;
1288    }
1289 
1290    *pQueue = tu_queue_to_handle(queue);
1291 }
1292 
1293 VkResult
tu_QueueWaitIdle(VkQueue _queue)1294 tu_QueueWaitIdle(VkQueue _queue)
1295 {
1296    TU_FROM_HANDLE(tu_queue, queue, _queue);
1297 
1298    if (tu_device_is_lost(queue->device))
1299       return VK_ERROR_DEVICE_LOST;
1300 
1301    if (queue->fence < 0)
1302       return VK_SUCCESS;
1303 
1304    struct pollfd fds = { .fd = queue->fence, .events = POLLIN };
1305    int ret;
1306    do {
1307       ret = poll(&fds, 1, -1);
1308    } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1309 
1310    /* TODO: otherwise set device lost ? */
1311    assert(ret == 1 && !(fds.revents & (POLLERR | POLLNVAL)));
1312 
1313    close(queue->fence);
1314    queue->fence = -1;
1315    return VK_SUCCESS;
1316 }
1317 
1318 VkResult
tu_DeviceWaitIdle(VkDevice _device)1319 tu_DeviceWaitIdle(VkDevice _device)
1320 {
1321    TU_FROM_HANDLE(tu_device, device, _device);
1322 
1323    if (tu_device_is_lost(device))
1324       return VK_ERROR_DEVICE_LOST;
1325 
1326    for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
1327       for (unsigned q = 0; q < device->queue_count[i]; q++) {
1328          tu_QueueWaitIdle(tu_queue_to_handle(&device->queues[i][q]));
1329       }
1330    }
1331    return VK_SUCCESS;
1332 }
1333 
1334 VkResult
tu_EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1335 tu_EnumerateInstanceExtensionProperties(const char *pLayerName,
1336                                         uint32_t *pPropertyCount,
1337                                         VkExtensionProperties *pProperties)
1338 {
1339    VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
1340 
1341    /* We spport no lyaers */
1342    if (pLayerName)
1343       return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1344 
1345    for (int i = 0; i < TU_INSTANCE_EXTENSION_COUNT; i++) {
1346       if (tu_instance_extensions_supported.extensions[i]) {
1347          vk_outarray_append(&out, prop) { *prop = tu_instance_extensions[i]; }
1348       }
1349    }
1350 
1351    return vk_outarray_status(&out);
1352 }
1353 
1354 VkResult
tu_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)1355 tu_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
1356                                       const char *pLayerName,
1357                                       uint32_t *pPropertyCount,
1358                                       VkExtensionProperties *pProperties)
1359 {
1360    /* We spport no lyaers */
1361    TU_FROM_HANDLE(tu_physical_device, device, physicalDevice);
1362    VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
1363 
1364    /* We spport no lyaers */
1365    if (pLayerName)
1366       return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1367 
1368    for (int i = 0; i < TU_DEVICE_EXTENSION_COUNT; i++) {
1369       if (device->supported_extensions.extensions[i]) {
1370          vk_outarray_append(&out, prop) { *prop = tu_device_extensions[i]; }
1371       }
1372    }
1373 
1374    return vk_outarray_status(&out);
1375 }
1376 
1377 PFN_vkVoidFunction
tu_GetInstanceProcAddr(VkInstance _instance,const char * pName)1378 tu_GetInstanceProcAddr(VkInstance _instance, const char *pName)
1379 {
1380    TU_FROM_HANDLE(tu_instance, instance, _instance);
1381 
1382    return tu_lookup_entrypoint_checked(
1383       pName, instance ? instance->api_version : 0,
1384       instance ? &instance->enabled_extensions : NULL, NULL);
1385 }
1386 
1387 /* The loader wants us to expose a second GetInstanceProcAddr function
1388  * to work around certain LD_PRELOAD issues seen in apps.
1389  */
1390 PUBLIC
1391 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
1392 vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName);
1393 
1394 PUBLIC
1395 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vk_icdGetInstanceProcAddr(VkInstance instance,const char * pName)1396 vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
1397 {
1398    return tu_GetInstanceProcAddr(instance, pName);
1399 }
1400 
1401 PFN_vkVoidFunction
tu_GetDeviceProcAddr(VkDevice _device,const char * pName)1402 tu_GetDeviceProcAddr(VkDevice _device, const char *pName)
1403 {
1404    TU_FROM_HANDLE(tu_device, device, _device);
1405 
1406    return tu_lookup_entrypoint_checked(pName, device->instance->api_version,
1407                                        &device->instance->enabled_extensions,
1408                                        &device->enabled_extensions);
1409 }
1410 
1411 VkResult
tu_AllocateMemory(VkDevice _device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMem)1412 tu_AllocateMemory(VkDevice _device,
1413                   const VkMemoryAllocateInfo *pAllocateInfo,
1414                   const VkAllocationCallbacks *pAllocator,
1415                   VkDeviceMemory *pMem)
1416 {
1417    TU_FROM_HANDLE(tu_device, device, _device);
1418    struct tu_device_memory *mem;
1419    VkResult result;
1420 
1421    assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
1422 
1423    if (pAllocateInfo->allocationSize == 0) {
1424       /* Apparently, this is allowed */
1425       *pMem = VK_NULL_HANDLE;
1426       return VK_SUCCESS;
1427    }
1428 
1429    mem = vk_object_alloc(&device->vk, pAllocator, sizeof(*mem),
1430                          VK_OBJECT_TYPE_DEVICE_MEMORY);
1431    if (mem == NULL)
1432       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1433 
1434    const VkImportMemoryFdInfoKHR *fd_info =
1435       vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
1436    if (fd_info && !fd_info->handleType)
1437       fd_info = NULL;
1438 
1439    if (fd_info) {
1440       assert(fd_info->handleType ==
1441                 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
1442              fd_info->handleType ==
1443                 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
1444 
1445       /*
1446        * TODO Importing the same fd twice gives us the same handle without
1447        * reference counting.  We need to maintain a per-instance handle-to-bo
1448        * table and add reference count to tu_bo.
1449        */
1450       result = tu_bo_init_dmabuf(device, &mem->bo,
1451                                  pAllocateInfo->allocationSize, fd_info->fd);
1452       if (result == VK_SUCCESS) {
1453          /* take ownership and close the fd */
1454          close(fd_info->fd);
1455       }
1456    } else {
1457       result =
1458          tu_bo_init_new(device, &mem->bo, pAllocateInfo->allocationSize, false);
1459    }
1460 
1461    if (result != VK_SUCCESS) {
1462       vk_object_free(&device->vk, pAllocator, mem);
1463       return result;
1464    }
1465 
1466    *pMem = tu_device_memory_to_handle(mem);
1467 
1468    return VK_SUCCESS;
1469 }
1470 
1471 void
tu_FreeMemory(VkDevice _device,VkDeviceMemory _mem,const VkAllocationCallbacks * pAllocator)1472 tu_FreeMemory(VkDevice _device,
1473               VkDeviceMemory _mem,
1474               const VkAllocationCallbacks *pAllocator)
1475 {
1476    TU_FROM_HANDLE(tu_device, device, _device);
1477    TU_FROM_HANDLE(tu_device_memory, mem, _mem);
1478 
1479    if (mem == NULL)
1480       return;
1481 
1482    tu_bo_finish(device, &mem->bo);
1483    vk_object_free(&device->vk, pAllocator, mem);
1484 }
1485 
1486 VkResult
tu_MapMemory(VkDevice _device,VkDeviceMemory _memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)1487 tu_MapMemory(VkDevice _device,
1488              VkDeviceMemory _memory,
1489              VkDeviceSize offset,
1490              VkDeviceSize size,
1491              VkMemoryMapFlags flags,
1492              void **ppData)
1493 {
1494    TU_FROM_HANDLE(tu_device, device, _device);
1495    TU_FROM_HANDLE(tu_device_memory, mem, _memory);
1496    VkResult result;
1497 
1498    if (mem == NULL) {
1499       *ppData = NULL;
1500       return VK_SUCCESS;
1501    }
1502 
1503    if (!mem->bo.map) {
1504       result = tu_bo_map(device, &mem->bo);
1505       if (result != VK_SUCCESS)
1506          return result;
1507    }
1508 
1509    *ppData = mem->bo.map + offset;
1510    return VK_SUCCESS;
1511 }
1512 
1513 void
tu_UnmapMemory(VkDevice _device,VkDeviceMemory _memory)1514 tu_UnmapMemory(VkDevice _device, VkDeviceMemory _memory)
1515 {
1516    /* TODO: unmap here instead of waiting for FreeMemory */
1517 }
1518 
1519 VkResult
tu_FlushMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)1520 tu_FlushMappedMemoryRanges(VkDevice _device,
1521                            uint32_t memoryRangeCount,
1522                            const VkMappedMemoryRange *pMemoryRanges)
1523 {
1524    return VK_SUCCESS;
1525 }
1526 
1527 VkResult
tu_InvalidateMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)1528 tu_InvalidateMappedMemoryRanges(VkDevice _device,
1529                                 uint32_t memoryRangeCount,
1530                                 const VkMappedMemoryRange *pMemoryRanges)
1531 {
1532    return VK_SUCCESS;
1533 }
1534 
1535 void
tu_GetBufferMemoryRequirements2(VkDevice device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1536 tu_GetBufferMemoryRequirements2(
1537    VkDevice device,
1538    const VkBufferMemoryRequirementsInfo2 *pInfo,
1539    VkMemoryRequirements2 *pMemoryRequirements)
1540 {
1541    TU_FROM_HANDLE(tu_buffer, buffer, pInfo->buffer);
1542 
1543    pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
1544       .memoryTypeBits = 1,
1545       .alignment = 64,
1546       .size = align64(buffer->size, 64),
1547    };
1548 }
1549 
1550 void
tu_GetImageMemoryRequirements2(VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1551 tu_GetImageMemoryRequirements2(VkDevice device,
1552                                const VkImageMemoryRequirementsInfo2 *pInfo,
1553                                VkMemoryRequirements2 *pMemoryRequirements)
1554 {
1555    TU_FROM_HANDLE(tu_image, image, pInfo->image);
1556 
1557    pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
1558       .memoryTypeBits = 1,
1559       .alignment = image->layout[0].base_align,
1560       .size = image->total_size
1561    };
1562 }
1563 
1564 void
tu_GetImageSparseMemoryRequirements2(VkDevice device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1565 tu_GetImageSparseMemoryRequirements2(
1566    VkDevice device,
1567    const VkImageSparseMemoryRequirementsInfo2 *pInfo,
1568    uint32_t *pSparseMemoryRequirementCount,
1569    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
1570 {
1571    tu_stub();
1572 }
1573 
1574 void
tu_GetDeviceMemoryCommitment(VkDevice device,VkDeviceMemory memory,VkDeviceSize * pCommittedMemoryInBytes)1575 tu_GetDeviceMemoryCommitment(VkDevice device,
1576                              VkDeviceMemory memory,
1577                              VkDeviceSize *pCommittedMemoryInBytes)
1578 {
1579    *pCommittedMemoryInBytes = 0;
1580 }
1581 
1582 VkResult
tu_BindBufferMemory2(VkDevice device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)1583 tu_BindBufferMemory2(VkDevice device,
1584                      uint32_t bindInfoCount,
1585                      const VkBindBufferMemoryInfo *pBindInfos)
1586 {
1587    for (uint32_t i = 0; i < bindInfoCount; ++i) {
1588       TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory);
1589       TU_FROM_HANDLE(tu_buffer, buffer, pBindInfos[i].buffer);
1590 
1591       if (mem) {
1592          buffer->bo = &mem->bo;
1593          buffer->bo_offset = pBindInfos[i].memoryOffset;
1594       } else {
1595          buffer->bo = NULL;
1596       }
1597    }
1598    return VK_SUCCESS;
1599 }
1600 
1601 VkResult
tu_BindImageMemory2(VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)1602 tu_BindImageMemory2(VkDevice device,
1603                     uint32_t bindInfoCount,
1604                     const VkBindImageMemoryInfo *pBindInfos)
1605 {
1606    for (uint32_t i = 0; i < bindInfoCount; ++i) {
1607       TU_FROM_HANDLE(tu_image, image, pBindInfos[i].image);
1608       TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory);
1609 
1610       if (mem) {
1611          image->bo = &mem->bo;
1612          image->bo_offset = pBindInfos[i].memoryOffset;
1613       } else {
1614          image->bo = NULL;
1615          image->bo_offset = 0;
1616       }
1617    }
1618 
1619    return VK_SUCCESS;
1620 }
1621 
1622 VkResult
tu_QueueBindSparse(VkQueue _queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence _fence)1623 tu_QueueBindSparse(VkQueue _queue,
1624                    uint32_t bindInfoCount,
1625                    const VkBindSparseInfo *pBindInfo,
1626                    VkFence _fence)
1627 {
1628    return VK_SUCCESS;
1629 }
1630 
1631 VkResult
tu_CreateEvent(VkDevice _device,const VkEventCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkEvent * pEvent)1632 tu_CreateEvent(VkDevice _device,
1633                const VkEventCreateInfo *pCreateInfo,
1634                const VkAllocationCallbacks *pAllocator,
1635                VkEvent *pEvent)
1636 {
1637    TU_FROM_HANDLE(tu_device, device, _device);
1638 
1639    struct tu_event *event =
1640          vk_object_alloc(&device->vk, pAllocator, sizeof(*event),
1641                          VK_OBJECT_TYPE_EVENT);
1642    if (!event)
1643       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1644 
1645    VkResult result = tu_bo_init_new(device, &event->bo, 0x1000, false);
1646    if (result != VK_SUCCESS)
1647       goto fail_alloc;
1648 
1649    result = tu_bo_map(device, &event->bo);
1650    if (result != VK_SUCCESS)
1651       goto fail_map;
1652 
1653    *pEvent = tu_event_to_handle(event);
1654 
1655    return VK_SUCCESS;
1656 
1657 fail_map:
1658    tu_bo_finish(device, &event->bo);
1659 fail_alloc:
1660    vk_object_free(&device->vk, pAllocator, event);
1661    return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1662 }
1663 
1664 void
tu_DestroyEvent(VkDevice _device,VkEvent _event,const VkAllocationCallbacks * pAllocator)1665 tu_DestroyEvent(VkDevice _device,
1666                 VkEvent _event,
1667                 const VkAllocationCallbacks *pAllocator)
1668 {
1669    TU_FROM_HANDLE(tu_device, device, _device);
1670    TU_FROM_HANDLE(tu_event, event, _event);
1671 
1672    if (!event)
1673       return;
1674 
1675    tu_bo_finish(device, &event->bo);
1676    vk_object_free(&device->vk, pAllocator, event);
1677 }
1678 
1679 VkResult
tu_GetEventStatus(VkDevice _device,VkEvent _event)1680 tu_GetEventStatus(VkDevice _device, VkEvent _event)
1681 {
1682    TU_FROM_HANDLE(tu_event, event, _event);
1683 
1684    if (*(uint64_t*) event->bo.map == 1)
1685       return VK_EVENT_SET;
1686    return VK_EVENT_RESET;
1687 }
1688 
1689 VkResult
tu_SetEvent(VkDevice _device,VkEvent _event)1690 tu_SetEvent(VkDevice _device, VkEvent _event)
1691 {
1692    TU_FROM_HANDLE(tu_event, event, _event);
1693    *(uint64_t*) event->bo.map = 1;
1694 
1695    return VK_SUCCESS;
1696 }
1697 
1698 VkResult
tu_ResetEvent(VkDevice _device,VkEvent _event)1699 tu_ResetEvent(VkDevice _device, VkEvent _event)
1700 {
1701    TU_FROM_HANDLE(tu_event, event, _event);
1702    *(uint64_t*) event->bo.map = 0;
1703 
1704    return VK_SUCCESS;
1705 }
1706 
1707 VkResult
tu_CreateBuffer(VkDevice _device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)1708 tu_CreateBuffer(VkDevice _device,
1709                 const VkBufferCreateInfo *pCreateInfo,
1710                 const VkAllocationCallbacks *pAllocator,
1711                 VkBuffer *pBuffer)
1712 {
1713    TU_FROM_HANDLE(tu_device, device, _device);
1714    struct tu_buffer *buffer;
1715 
1716    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
1717 
1718    buffer = vk_object_alloc(&device->vk, pAllocator, sizeof(*buffer),
1719                             VK_OBJECT_TYPE_BUFFER);
1720    if (buffer == NULL)
1721       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1722 
1723    buffer->size = pCreateInfo->size;
1724    buffer->usage = pCreateInfo->usage;
1725    buffer->flags = pCreateInfo->flags;
1726 
1727    *pBuffer = tu_buffer_to_handle(buffer);
1728 
1729    return VK_SUCCESS;
1730 }
1731 
1732 void
tu_DestroyBuffer(VkDevice _device,VkBuffer _buffer,const VkAllocationCallbacks * pAllocator)1733 tu_DestroyBuffer(VkDevice _device,
1734                  VkBuffer _buffer,
1735                  const VkAllocationCallbacks *pAllocator)
1736 {
1737    TU_FROM_HANDLE(tu_device, device, _device);
1738    TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
1739 
1740    if (!buffer)
1741       return;
1742 
1743    vk_object_free(&device->vk, pAllocator, buffer);
1744 }
1745 
1746 VkResult
tu_CreateFramebuffer(VkDevice _device,const VkFramebufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFramebuffer * pFramebuffer)1747 tu_CreateFramebuffer(VkDevice _device,
1748                      const VkFramebufferCreateInfo *pCreateInfo,
1749                      const VkAllocationCallbacks *pAllocator,
1750                      VkFramebuffer *pFramebuffer)
1751 {
1752    TU_FROM_HANDLE(tu_device, device, _device);
1753    TU_FROM_HANDLE(tu_render_pass, pass, pCreateInfo->renderPass);
1754    struct tu_framebuffer *framebuffer;
1755 
1756    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
1757 
1758    size_t size = sizeof(*framebuffer) + sizeof(struct tu_attachment_info) *
1759                                            pCreateInfo->attachmentCount;
1760    framebuffer = vk_object_alloc(&device->vk, pAllocator, size,
1761                                  VK_OBJECT_TYPE_FRAMEBUFFER);
1762    if (framebuffer == NULL)
1763       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1764 
1765    framebuffer->attachment_count = pCreateInfo->attachmentCount;
1766    framebuffer->width = pCreateInfo->width;
1767    framebuffer->height = pCreateInfo->height;
1768    framebuffer->layers = pCreateInfo->layers;
1769    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
1770       VkImageView _iview = pCreateInfo->pAttachments[i];
1771       struct tu_image_view *iview = tu_image_view_from_handle(_iview);
1772       framebuffer->attachments[i].attachment = iview;
1773    }
1774 
1775    tu_framebuffer_tiling_config(framebuffer, device, pass);
1776 
1777    *pFramebuffer = tu_framebuffer_to_handle(framebuffer);
1778    return VK_SUCCESS;
1779 }
1780 
1781 void
tu_DestroyFramebuffer(VkDevice _device,VkFramebuffer _fb,const VkAllocationCallbacks * pAllocator)1782 tu_DestroyFramebuffer(VkDevice _device,
1783                       VkFramebuffer _fb,
1784                       const VkAllocationCallbacks *pAllocator)
1785 {
1786    TU_FROM_HANDLE(tu_device, device, _device);
1787    TU_FROM_HANDLE(tu_framebuffer, fb, _fb);
1788 
1789    if (!fb)
1790       return;
1791 
1792    vk_object_free(&device->vk, pAllocator, fb);
1793 }
1794 
1795 static void
tu_init_sampler(struct tu_device * device,struct tu_sampler * sampler,const VkSamplerCreateInfo * pCreateInfo)1796 tu_init_sampler(struct tu_device *device,
1797                 struct tu_sampler *sampler,
1798                 const VkSamplerCreateInfo *pCreateInfo)
1799 {
1800    const struct VkSamplerReductionModeCreateInfo *reduction =
1801       vk_find_struct_const(pCreateInfo->pNext, SAMPLER_REDUCTION_MODE_CREATE_INFO);
1802    const struct VkSamplerYcbcrConversionInfo *ycbcr_conversion =
1803       vk_find_struct_const(pCreateInfo->pNext,  SAMPLER_YCBCR_CONVERSION_INFO);
1804    const VkSamplerCustomBorderColorCreateInfoEXT *custom_border_color =
1805       vk_find_struct_const(pCreateInfo->pNext, SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
1806    /* for non-custom border colors, the VK enum is translated directly to an offset in
1807     * the border color buffer. custom border colors are located immediately after the
1808     * builtin colors, and thus an offset of TU_BORDER_COLOR_BUILTIN is added.
1809     */
1810    uint32_t border_color = (unsigned) pCreateInfo->borderColor;
1811    if (pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT ||
1812        pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT) {
1813       mtx_lock(&device->mutex);
1814       border_color = BITSET_FFS(device->custom_border_color);
1815       BITSET_CLEAR(device->custom_border_color, border_color);
1816       mtx_unlock(&device->mutex);
1817       tu6_pack_border_color(device->global_bo.map + gb_offset(bcolor[border_color]),
1818                             &custom_border_color->customBorderColor,
1819                             pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
1820       border_color += TU_BORDER_COLOR_BUILTIN;
1821    }
1822 
1823    unsigned aniso = pCreateInfo->anisotropyEnable ?
1824       util_last_bit(MIN2((uint32_t)pCreateInfo->maxAnisotropy >> 1, 8)) : 0;
1825    bool miplinear = (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR);
1826    float min_lod = CLAMP(pCreateInfo->minLod, 0.0f, 4095.0f / 256.0f);
1827    float max_lod = CLAMP(pCreateInfo->maxLod, 0.0f, 4095.0f / 256.0f);
1828 
1829    sampler->descriptor[0] =
1830       COND(miplinear, A6XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) |
1831       A6XX_TEX_SAMP_0_XY_MAG(tu6_tex_filter(pCreateInfo->magFilter, aniso)) |
1832       A6XX_TEX_SAMP_0_XY_MIN(tu6_tex_filter(pCreateInfo->minFilter, aniso)) |
1833       A6XX_TEX_SAMP_0_ANISO(aniso) |
1834       A6XX_TEX_SAMP_0_WRAP_S(tu6_tex_wrap(pCreateInfo->addressModeU)) |
1835       A6XX_TEX_SAMP_0_WRAP_T(tu6_tex_wrap(pCreateInfo->addressModeV)) |
1836       A6XX_TEX_SAMP_0_WRAP_R(tu6_tex_wrap(pCreateInfo->addressModeW)) |
1837       A6XX_TEX_SAMP_0_LOD_BIAS(pCreateInfo->mipLodBias);
1838    sampler->descriptor[1] =
1839       /* COND(!cso->seamless_cube_map, A6XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF) | */
1840       COND(pCreateInfo->unnormalizedCoordinates, A6XX_TEX_SAMP_1_UNNORM_COORDS) |
1841       A6XX_TEX_SAMP_1_MIN_LOD(min_lod) |
1842       A6XX_TEX_SAMP_1_MAX_LOD(max_lod) |
1843       COND(pCreateInfo->compareEnable,
1844            A6XX_TEX_SAMP_1_COMPARE_FUNC(tu6_compare_func(pCreateInfo->compareOp)));
1845    sampler->descriptor[2] = A6XX_TEX_SAMP_2_BCOLOR(border_color);
1846    sampler->descriptor[3] = 0;
1847 
1848    if (reduction) {
1849       sampler->descriptor[2] |= A6XX_TEX_SAMP_2_REDUCTION_MODE(
1850          tu6_reduction_mode(reduction->reductionMode));
1851    }
1852 
1853    sampler->ycbcr_sampler = ycbcr_conversion ?
1854       tu_sampler_ycbcr_conversion_from_handle(ycbcr_conversion->conversion) : NULL;
1855 
1856    if (sampler->ycbcr_sampler &&
1857        sampler->ycbcr_sampler->chroma_filter == VK_FILTER_LINEAR) {
1858       sampler->descriptor[2] |= A6XX_TEX_SAMP_2_CHROMA_LINEAR;
1859    }
1860 
1861    /* TODO:
1862     * A6XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR disables mipmapping, but vk has no NONE mipfilter?
1863     */
1864 }
1865 
1866 VkResult
tu_CreateSampler(VkDevice _device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)1867 tu_CreateSampler(VkDevice _device,
1868                  const VkSamplerCreateInfo *pCreateInfo,
1869                  const VkAllocationCallbacks *pAllocator,
1870                  VkSampler *pSampler)
1871 {
1872    TU_FROM_HANDLE(tu_device, device, _device);
1873    struct tu_sampler *sampler;
1874 
1875    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
1876 
1877    sampler = vk_object_alloc(&device->vk, pAllocator, sizeof(*sampler),
1878                              VK_OBJECT_TYPE_SAMPLER);
1879    if (!sampler)
1880       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1881 
1882    tu_init_sampler(device, sampler, pCreateInfo);
1883    *pSampler = tu_sampler_to_handle(sampler);
1884 
1885    return VK_SUCCESS;
1886 }
1887 
1888 void
tu_DestroySampler(VkDevice _device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)1889 tu_DestroySampler(VkDevice _device,
1890                   VkSampler _sampler,
1891                   const VkAllocationCallbacks *pAllocator)
1892 {
1893    TU_FROM_HANDLE(tu_device, device, _device);
1894    TU_FROM_HANDLE(tu_sampler, sampler, _sampler);
1895    uint32_t border_color;
1896 
1897    if (!sampler)
1898       return;
1899 
1900    border_color = (sampler->descriptor[2] & A6XX_TEX_SAMP_2_BCOLOR__MASK) >> A6XX_TEX_SAMP_2_BCOLOR__SHIFT;
1901    if (border_color >= TU_BORDER_COLOR_BUILTIN) {
1902       border_color -= TU_BORDER_COLOR_BUILTIN;
1903       /* if the sampler had a custom border color, free it. TODO: no lock */
1904       mtx_lock(&device->mutex);
1905       assert(!BITSET_TEST(device->custom_border_color, border_color));
1906       BITSET_SET(device->custom_border_color, border_color);
1907       mtx_unlock(&device->mutex);
1908    }
1909 
1910    vk_object_free(&device->vk, pAllocator, sampler);
1911 }
1912 
1913 /* vk_icd.h does not declare this function, so we declare it here to
1914  * suppress Wmissing-prototypes.
1915  */
1916 PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
1917 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion);
1918 
1919 PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t * pSupportedVersion)1920 vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion)
1921 {
1922    /* For the full details on loader interface versioning, see
1923     * <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
1924     * What follows is a condensed summary, to help you navigate the large and
1925     * confusing official doc.
1926     *
1927     *   - Loader interface v0 is incompatible with later versions. We don't
1928     *     support it.
1929     *
1930     *   - In loader interface v1:
1931     *       - The first ICD entrypoint called by the loader is
1932     *         vk_icdGetInstanceProcAddr(). The ICD must statically expose this
1933     *         entrypoint.
1934     *       - The ICD must statically expose no other Vulkan symbol unless it
1935     * is linked with -Bsymbolic.
1936     *       - Each dispatchable Vulkan handle created by the ICD must be
1937     *         a pointer to a struct whose first member is VK_LOADER_DATA. The
1938     *         ICD must initialize VK_LOADER_DATA.loadMagic to
1939     * ICD_LOADER_MAGIC.
1940     *       - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
1941     *         vkDestroySurfaceKHR(). The ICD must be capable of working with
1942     *         such loader-managed surfaces.
1943     *
1944     *    - Loader interface v2 differs from v1 in:
1945     *       - The first ICD entrypoint called by the loader is
1946     *         vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
1947     *         statically expose this entrypoint.
1948     *
1949     *    - Loader interface v3 differs from v2 in:
1950     *        - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
1951     *          vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
1952     *          because the loader no longer does so.
1953     */
1954    *pSupportedVersion = MIN2(*pSupportedVersion, 3u);
1955    return VK_SUCCESS;
1956 }
1957 
1958 VkResult
tu_GetMemoryFdKHR(VkDevice _device,const VkMemoryGetFdInfoKHR * pGetFdInfo,int * pFd)1959 tu_GetMemoryFdKHR(VkDevice _device,
1960                   const VkMemoryGetFdInfoKHR *pGetFdInfo,
1961                   int *pFd)
1962 {
1963    TU_FROM_HANDLE(tu_device, device, _device);
1964    TU_FROM_HANDLE(tu_device_memory, memory, pGetFdInfo->memory);
1965 
1966    assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
1967 
1968    /* At the moment, we support only the below handle types. */
1969    assert(pGetFdInfo->handleType ==
1970              VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
1971           pGetFdInfo->handleType ==
1972              VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
1973 
1974    int prime_fd = tu_bo_export_dmabuf(device, &memory->bo);
1975    if (prime_fd < 0)
1976       return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
1977 
1978    *pFd = prime_fd;
1979    return VK_SUCCESS;
1980 }
1981 
1982 VkResult
tu_GetMemoryFdPropertiesKHR(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,int fd,VkMemoryFdPropertiesKHR * pMemoryFdProperties)1983 tu_GetMemoryFdPropertiesKHR(VkDevice _device,
1984                             VkExternalMemoryHandleTypeFlagBits handleType,
1985                             int fd,
1986                             VkMemoryFdPropertiesKHR *pMemoryFdProperties)
1987 {
1988    assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
1989    pMemoryFdProperties->memoryTypeBits = 1;
1990    return VK_SUCCESS;
1991 }
1992 
1993 void
tu_GetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,VkExternalFenceProperties * pExternalFenceProperties)1994 tu_GetPhysicalDeviceExternalFenceProperties(
1995    VkPhysicalDevice physicalDevice,
1996    const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
1997    VkExternalFenceProperties *pExternalFenceProperties)
1998 {
1999    pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2000    pExternalFenceProperties->compatibleHandleTypes = 0;
2001    pExternalFenceProperties->externalFenceFeatures = 0;
2002 }
2003 
2004 VkResult
tu_CreateDebugReportCallbackEXT(VkInstance _instance,const VkDebugReportCallbackCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugReportCallbackEXT * pCallback)2005 tu_CreateDebugReportCallbackEXT(
2006    VkInstance _instance,
2007    const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
2008    const VkAllocationCallbacks *pAllocator,
2009    VkDebugReportCallbackEXT *pCallback)
2010 {
2011    TU_FROM_HANDLE(tu_instance, instance, _instance);
2012    return vk_create_debug_report_callback(&instance->debug_report_callbacks,
2013                                           pCreateInfo, pAllocator,
2014                                           &instance->alloc, pCallback);
2015 }
2016 
2017 void
tu_DestroyDebugReportCallbackEXT(VkInstance _instance,VkDebugReportCallbackEXT _callback,const VkAllocationCallbacks * pAllocator)2018 tu_DestroyDebugReportCallbackEXT(VkInstance _instance,
2019                                  VkDebugReportCallbackEXT _callback,
2020                                  const VkAllocationCallbacks *pAllocator)
2021 {
2022    TU_FROM_HANDLE(tu_instance, instance, _instance);
2023    vk_destroy_debug_report_callback(&instance->debug_report_callbacks,
2024                                     _callback, pAllocator, &instance->alloc);
2025 }
2026 
2027 void
tu_DebugReportMessageEXT(VkInstance _instance,VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT objectType,uint64_t object,size_t location,int32_t messageCode,const char * pLayerPrefix,const char * pMessage)2028 tu_DebugReportMessageEXT(VkInstance _instance,
2029                          VkDebugReportFlagsEXT flags,
2030                          VkDebugReportObjectTypeEXT objectType,
2031                          uint64_t object,
2032                          size_t location,
2033                          int32_t messageCode,
2034                          const char *pLayerPrefix,
2035                          const char *pMessage)
2036 {
2037    TU_FROM_HANDLE(tu_instance, instance, _instance);
2038    vk_debug_report(&instance->debug_report_callbacks, flags, objectType,
2039                    object, location, messageCode, pLayerPrefix, pMessage);
2040 }
2041 
2042 void
tu_GetDeviceGroupPeerMemoryFeatures(VkDevice device,uint32_t heapIndex,uint32_t localDeviceIndex,uint32_t remoteDeviceIndex,VkPeerMemoryFeatureFlags * pPeerMemoryFeatures)2043 tu_GetDeviceGroupPeerMemoryFeatures(
2044    VkDevice device,
2045    uint32_t heapIndex,
2046    uint32_t localDeviceIndex,
2047    uint32_t remoteDeviceIndex,
2048    VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
2049 {
2050    assert(localDeviceIndex == remoteDeviceIndex);
2051 
2052    *pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT |
2053                           VK_PEER_MEMORY_FEATURE_COPY_DST_BIT |
2054                           VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
2055                           VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
2056 }
2057 
tu_GetPhysicalDeviceMultisamplePropertiesEXT(VkPhysicalDevice physicalDevice,VkSampleCountFlagBits samples,VkMultisamplePropertiesEXT * pMultisampleProperties)2058 void tu_GetPhysicalDeviceMultisamplePropertiesEXT(
2059    VkPhysicalDevice                            physicalDevice,
2060    VkSampleCountFlagBits                       samples,
2061    VkMultisamplePropertiesEXT*                 pMultisampleProperties)
2062 {
2063    TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
2064 
2065    if (samples <= VK_SAMPLE_COUNT_4_BIT && pdevice->supported_extensions.EXT_sample_locations)
2066       pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 1, 1 };
2067    else
2068       pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 0, 0 };
2069 }
2070 
2071 
2072 VkResult
tu_CreatePrivateDataSlotEXT(VkDevice _device,const VkPrivateDataSlotCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPrivateDataSlotEXT * pPrivateDataSlot)2073 tu_CreatePrivateDataSlotEXT(VkDevice _device,
2074                             const VkPrivateDataSlotCreateInfoEXT* pCreateInfo,
2075                             const VkAllocationCallbacks* pAllocator,
2076                             VkPrivateDataSlotEXT* pPrivateDataSlot)
2077 {
2078    TU_FROM_HANDLE(tu_device, device, _device);
2079    return vk_private_data_slot_create(&device->vk,
2080                                       pCreateInfo,
2081                                       pAllocator,
2082                                       pPrivateDataSlot);
2083 }
2084 
2085 void
tu_DestroyPrivateDataSlotEXT(VkDevice _device,VkPrivateDataSlotEXT privateDataSlot,const VkAllocationCallbacks * pAllocator)2086 tu_DestroyPrivateDataSlotEXT(VkDevice _device,
2087                              VkPrivateDataSlotEXT privateDataSlot,
2088                              const VkAllocationCallbacks* pAllocator)
2089 {
2090    TU_FROM_HANDLE(tu_device, device, _device);
2091    vk_private_data_slot_destroy(&device->vk, privateDataSlot, pAllocator);
2092 }
2093 
2094 VkResult
tu_SetPrivateDataEXT(VkDevice _device,VkObjectType objectType,uint64_t objectHandle,VkPrivateDataSlotEXT privateDataSlot,uint64_t data)2095 tu_SetPrivateDataEXT(VkDevice _device,
2096                      VkObjectType objectType,
2097                      uint64_t objectHandle,
2098                      VkPrivateDataSlotEXT privateDataSlot,
2099                      uint64_t data)
2100 {
2101    TU_FROM_HANDLE(tu_device, device, _device);
2102    return vk_object_base_set_private_data(&device->vk,
2103                                           objectType,
2104                                           objectHandle,
2105                                           privateDataSlot,
2106                                           data);
2107 }
2108 
2109 void
tu_GetPrivateDataEXT(VkDevice _device,VkObjectType objectType,uint64_t objectHandle,VkPrivateDataSlotEXT privateDataSlot,uint64_t * pData)2110 tu_GetPrivateDataEXT(VkDevice _device,
2111                      VkObjectType objectType,
2112                      uint64_t objectHandle,
2113                      VkPrivateDataSlotEXT privateDataSlot,
2114                      uint64_t* pData)
2115 {
2116    TU_FROM_HANDLE(tu_device, device, _device);
2117    vk_object_base_get_private_data(&device->vk,
2118                                    objectType,
2119                                    objectHandle,
2120                                    privateDataSlot,
2121                                    pData);
2122 }
2123