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