summaryrefslogtreecommitdiff
path: root/src/freedreno/vulkan/tu_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/freedreno/vulkan/tu_device.c')
-rw-r--r--src/freedreno/vulkan/tu_device.c2590
1 files changed, 0 insertions, 2590 deletions
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
deleted file mode 100644
index 3be2e54df10..00000000000
--- a/src/freedreno/vulkan/tu_device.c
+++ /dev/null
@@ -1,2590 +0,0 @@
-/*
- * Copyright © 2016 Red Hat.
- * Copyright © 2016 Bas Nieuwenhuizen
- *
- * based in part on anv driver which is:
- * Copyright © 2015 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include "tu_private.h"
-#include "tu_cs.h"
-
-#include <fcntl.h>
-#include <poll.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/sysinfo.h>
-#include <unistd.h>
-
-#include "util/debug.h"
-#include "util/disk_cache.h"
-#include "util/u_atomic.h"
-#include "vk_format.h"
-#include "vk_util.h"
-
-/* for fd_get_driver/device_uuid() */
-#include "freedreno/common/freedreno_uuid.h"
-
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
- defined(VK_USE_PLATFORM_XCB_KHR) || \
- defined(VK_USE_PLATFORM_XLIB_KHR) || \
- defined(VK_USE_PLATFORM_DISPLAY_KHR)
-#define TU_HAS_SURFACE 1
-#else
-#define TU_HAS_SURFACE 0
-#endif
-
-
-static int
-tu_device_get_cache_uuid(uint16_t family, void *uuid)
-{
- uint32_t mesa_timestamp;
- uint16_t f = family;
- memset(uuid, 0, VK_UUID_SIZE);
- if (!disk_cache_get_function_timestamp(tu_device_get_cache_uuid,
- &mesa_timestamp))
- return -1;
-
- memcpy(uuid, &mesa_timestamp, 4);
- memcpy((char *) uuid + 4, &f, 2);
- snprintf((char *) uuid + 6, VK_UUID_SIZE - 10, "tu");
- return 0;
-}
-
-#define TU_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_EnumerateInstanceVersion(uint32_t *pApiVersion)
-{
- *pApiVersion = TU_API_VERSION;
- return VK_SUCCESS;
-}
-
-static const struct vk_instance_extension_table tu_instance_extensions_supported = {
- .KHR_device_group_creation = true,
- .KHR_external_fence_capabilities = true,
- .KHR_external_memory_capabilities = true,
- .KHR_external_semaphore_capabilities = true,
- .KHR_get_physical_device_properties2 = true,
- .KHR_surface = TU_HAS_SURFACE,
- .KHR_get_surface_capabilities2 = TU_HAS_SURFACE,
- .EXT_debug_report = true,
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
- .KHR_wayland_surface = true,
-#endif
-#ifdef VK_USE_PLATFORM_XCB_KHR
- .KHR_xcb_surface = true,
-#endif
-#ifdef VK_USE_PLATFORM_XLIB_KHR
- .KHR_xlib_surface = true,
-#endif
-#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
- .EXT_acquire_xlib_display = true,
-#endif
-#ifdef VK_USE_PLATFORM_DISPLAY_KHR
- .KHR_display = true,
- .KHR_get_display_properties2 = true,
- .EXT_direct_mode_display = true,
- .EXT_display_surface_counter = true,
-#endif
-};
-
-static void
-get_device_extensions(const struct tu_physical_device *device,
- struct vk_device_extension_table *ext)
-{
- *ext = (struct vk_device_extension_table) {
- .KHR_16bit_storage = device->info->a6xx.storage_16bit,
- .KHR_bind_memory2 = true,
- .KHR_create_renderpass2 = true,
- .KHR_dedicated_allocation = true,
- .KHR_depth_stencil_resolve = true,
- .KHR_descriptor_update_template = true,
- .KHR_device_group = true,
- .KHR_draw_indirect_count = true,
- .KHR_external_fence = true,
- .KHR_external_fence_fd = true,
- .KHR_external_memory = true,
- .KHR_external_memory_fd = true,
- .KHR_external_semaphore = true,
- .KHR_external_semaphore_fd = true,
- .KHR_get_memory_requirements2 = true,
- .KHR_incremental_present = TU_HAS_SURFACE,
- .KHR_image_format_list = true,
- .KHR_maintenance1 = true,
- .KHR_maintenance2 = true,
- .KHR_maintenance3 = true,
- .KHR_multiview = true,
- .KHR_performance_query = device->instance->debug_flags & TU_DEBUG_PERFC,
- .KHR_pipeline_executable_properties = true,
- .KHR_push_descriptor = true,
- .KHR_relaxed_block_layout = true,
- .KHR_sampler_mirror_clamp_to_edge = true,
- .KHR_sampler_ycbcr_conversion = true,
- .KHR_shader_draw_parameters = true,
- .KHR_shader_float_controls = true,
- .KHR_shader_float16_int8 = true,
- .KHR_shader_terminate_invocation = true,
- .KHR_spirv_1_4 = true,
- .KHR_storage_buffer_storage_class = true,
- .KHR_swapchain = TU_HAS_SURFACE,
- .KHR_uniform_buffer_standard_layout = true,
- .KHR_variable_pointers = true,
- .KHR_vulkan_memory_model = true,
-#ifndef TU_USE_KGSL
- .KHR_timeline_semaphore = true,
-#endif
-#ifdef VK_USE_PLATFORM_DISPLAY_KHR
- .EXT_display_control = true,
-#endif
- .EXT_external_memory_dma_buf = true,
- .EXT_image_drm_format_modifier = true,
- .EXT_sample_locations = device->info->a6xx.has_sample_locations,
- .EXT_sampler_filter_minmax = true,
- .EXT_transform_feedback = true,
- .EXT_4444_formats = true,
- .EXT_conditional_rendering = true,
- .EXT_custom_border_color = true,
- .EXT_depth_clip_enable = true,
- .EXT_descriptor_indexing = true,
- .EXT_extended_dynamic_state = true,
- .EXT_extended_dynamic_state2 = true,
- .EXT_filter_cubic = device->info->a6xx.has_tex_filter_cubic,
- .EXT_host_query_reset = true,
- .EXT_index_type_uint8 = true,
- .EXT_memory_budget = true,
- .EXT_private_data = true,
- .EXT_robustness2 = true,
- .EXT_scalar_block_layout = true,
- .EXT_separate_stencil_usage = true,
- .EXT_shader_demote_to_helper_invocation = true,
- .EXT_shader_stencil_export = true,
- .EXT_shader_viewport_index_layer = true,
- .EXT_vertex_attribute_divisor = true,
- .EXT_provoking_vertex = true,
-#ifdef ANDROID
- .ANDROID_native_buffer = true,
-#endif
- .IMG_filter_cubic = device->info->a6xx.has_tex_filter_cubic,
- .VALVE_mutable_descriptor_type = true,
- };
-}
-
-VkResult
-tu_physical_device_init(struct tu_physical_device *device,
- struct tu_instance *instance)
-{
- VkResult result = VK_SUCCESS;
-
- device->name = fd_dev_name(&device->dev_id);
-
- const struct fd_dev_info *info = fd_dev_info(&device->dev_id);
- if (!info) {
- result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
- "device %s is unsupported", device->name);
- return result;
- }
- switch (fd_dev_gen(&device->dev_id)) {
- case 6:
- device->info = info;
- device->ccu_offset_bypass = device->info->num_ccu * A6XX_CCU_DEPTH_SIZE;
- device->ccu_offset_gmem = (device->gmem_size -
- device->info->num_ccu * A6XX_CCU_GMEM_COLOR_SIZE);
- break;
- default:
- result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
- "device %s is unsupported", device->name);
- return result;
- }
- if (tu_device_get_cache_uuid(fd_dev_gpu_id(&device->dev_id), device->cache_uuid)) {
- result = vk_startup_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
- "cannot generate UUID");
- return result;
- }
-
- /* The gpu id is already embedded in the uuid so we just pass "tu"
- * when creating the cache.
- */
- char buf[VK_UUID_SIZE * 2 + 1];
- disk_cache_format_hex_id(buf, device->cache_uuid, VK_UUID_SIZE * 2);
- device->disk_cache = disk_cache_create(device->name, buf, 0);
-
- vk_warn_non_conformant_implementation("tu");
-
- fd_get_driver_uuid(device->driver_uuid);
- fd_get_device_uuid(device->device_uuid, &device->dev_id);
-
- struct vk_device_extension_table supported_extensions;
- get_device_extensions(device, &supported_extensions);
-
- struct vk_physical_device_dispatch_table dispatch_table;
- vk_physical_device_dispatch_table_from_entrypoints(
- &dispatch_table, &tu_physical_device_entrypoints, true);
-
- result = vk_physical_device_init(&device->vk, &instance->vk,
- &supported_extensions,
- &dispatch_table);
- if (result != VK_SUCCESS)
- return result;
-
-#if TU_HAS_SURFACE
- result = tu_wsi_init(device);
- if (result != VK_SUCCESS) {
- vk_startup_errorf(instance, result, "WSI init failure");
- vk_physical_device_finish(&device->vk);
- return result;
- }
-#endif
-
- return VK_SUCCESS;
-}
-
-static void
-tu_physical_device_finish(struct tu_physical_device *device)
-{
-#if TU_HAS_SURFACE
- tu_wsi_finish(device);
-#endif
-
- disk_cache_destroy(device->disk_cache);
- close(device->local_fd);
- if (device->master_fd != -1)
- close(device->master_fd);
-
- vk_physical_device_finish(&device->vk);
-}
-
-static const struct debug_control tu_debug_options[] = {
- { "startup", TU_DEBUG_STARTUP },
- { "nir", TU_DEBUG_NIR },
- { "nobin", TU_DEBUG_NOBIN },
- { "sysmem", TU_DEBUG_SYSMEM },
- { "forcebin", TU_DEBUG_FORCEBIN },
- { "noubwc", TU_DEBUG_NOUBWC },
- { "nomultipos", TU_DEBUG_NOMULTIPOS },
- { "nolrz", TU_DEBUG_NOLRZ },
- { "perfc", TU_DEBUG_PERFC },
- { "flushall", TU_DEBUG_FLUSHALL },
- { "syncdraw", TU_DEBUG_SYNCDRAW },
- { NULL, 0 }
-};
-
-const char *
-tu_get_debug_option_name(int id)
-{
- assert(id < ARRAY_SIZE(tu_debug_options) - 1);
- return tu_debug_options[id].string;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkInstance *pInstance)
-{
- struct tu_instance *instance;
- VkResult result;
-
- assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
-
- if (pAllocator == NULL)
- pAllocator = vk_default_allocator();
-
- instance = vk_zalloc(pAllocator, sizeof(*instance), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-
- if (!instance)
- return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
-
- struct vk_instance_dispatch_table dispatch_table;
- vk_instance_dispatch_table_from_entrypoints(
- &dispatch_table, &tu_instance_entrypoints, true);
-
- result = vk_instance_init(&instance->vk,
- &tu_instance_extensions_supported,
- &dispatch_table,
- pCreateInfo, pAllocator);
- if (result != VK_SUCCESS) {
- vk_free(pAllocator, instance);
- return vk_error(NULL, result);
- }
-
- instance->physical_device_count = -1;
-
- instance->debug_flags =
- parse_debug_string(getenv("TU_DEBUG"), tu_debug_options);
-
-#ifdef DEBUG
- /* Enable startup debugging by default on debug drivers. You almost always
- * want to see your startup failures in that case, and it's hard to set
- * this env var on android.
- */
- instance->debug_flags |= TU_DEBUG_STARTUP;
-#endif
-
- if (instance->debug_flags & TU_DEBUG_STARTUP)
- mesa_logi("Created an instance");
-
- VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
-
- *pInstance = tu_instance_to_handle(instance);
-
-#ifdef HAVE_PERFETTO
- tu_perfetto_init();
-#endif
-
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_DestroyInstance(VkInstance _instance,
- const VkAllocationCallbacks *pAllocator)
-{
- TU_FROM_HANDLE(tu_instance, instance, _instance);
-
- if (!instance)
- return;
-
- for (int i = 0; i < instance->physical_device_count; ++i) {
- tu_physical_device_finish(instance->physical_devices + i);
- }
-
- VG(VALGRIND_DESTROY_MEMPOOL(instance));
-
- vk_instance_finish(&instance->vk);
- vk_free(&instance->vk.alloc, instance);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_EnumeratePhysicalDevices(VkInstance _instance,
- uint32_t *pPhysicalDeviceCount,
- VkPhysicalDevice *pPhysicalDevices)
-{
- TU_FROM_HANDLE(tu_instance, instance, _instance);
- VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
-
- VkResult result;
-
- if (instance->physical_device_count < 0) {
- result = tu_enumerate_devices(instance);
- if (result != VK_SUCCESS && result != VK_ERROR_INCOMPATIBLE_DRIVER)
- return result;
- }
-
- for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
- vk_outarray_append(&out, p)
- {
- *p = tu_physical_device_to_handle(instance->physical_devices + i);
- }
- }
-
- return vk_outarray_status(&out);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_EnumeratePhysicalDeviceGroups(
- VkInstance _instance,
- uint32_t *pPhysicalDeviceGroupCount,
- VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
-{
- TU_FROM_HANDLE(tu_instance, instance, _instance);
- VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,
- pPhysicalDeviceGroupCount);
- VkResult result;
-
- if (instance->physical_device_count < 0) {
- result = tu_enumerate_devices(instance);
- if (result != VK_SUCCESS && result != VK_ERROR_INCOMPATIBLE_DRIVER)
- return result;
- }
-
- for (uint32_t i = 0; i < instance->physical_device_count; ++i) {
- vk_outarray_append(&out, p)
- {
- p->physicalDeviceCount = 1;
- p->physicalDevices[0] =
- tu_physical_device_to_handle(instance->physical_devices + i);
- p->subsetAllocation = false;
- }
- }
-
- return vk_outarray_status(&out);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
- VkPhysicalDeviceFeatures2 *pFeatures)
-{
- TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
-
- pFeatures->features = (VkPhysicalDeviceFeatures) {
- .robustBufferAccess = true,
- .fullDrawIndexUint32 = true,
- .imageCubeArray = true,
- .independentBlend = true,
- .geometryShader = true,
- .tessellationShader = true,
- .sampleRateShading = true,
- .dualSrcBlend = true,
- .logicOp = true,
- .multiDrawIndirect = true,
- .drawIndirectFirstInstance = true,
- .depthClamp = true,
- .depthBiasClamp = true,
- .fillModeNonSolid = true,
- .depthBounds = true,
- .wideLines = false,
- .largePoints = true,
- .alphaToOne = true,
- .multiViewport = true,
- .samplerAnisotropy = true,
- .textureCompressionETC2 = true,
- .textureCompressionASTC_LDR = true,
- .textureCompressionBC = true,
- .occlusionQueryPrecise = true,
- .pipelineStatisticsQuery = true,
- .vertexPipelineStoresAndAtomics = true,
- .fragmentStoresAndAtomics = true,
- .shaderTessellationAndGeometryPointSize = false,
- .shaderImageGatherExtended = true,
- .shaderStorageImageExtendedFormats = true,
- .shaderStorageImageMultisample = false,
- .shaderUniformBufferArrayDynamicIndexing = true,
- .shaderSampledImageArrayDynamicIndexing = true,
- .shaderStorageBufferArrayDynamicIndexing = true,
- .shaderStorageImageArrayDynamicIndexing = true,
- .shaderStorageImageReadWithoutFormat = true,
- .shaderStorageImageWriteWithoutFormat = true,
- .shaderClipDistance = true,
- .shaderCullDistance = true,
- .shaderFloat64 = false,
- .shaderInt64 = false,
- .shaderInt16 = true,
- .sparseBinding = false,
- .variableMultisampleRate = true,
- .inheritedQueries = true,
- };
-
- vk_foreach_struct(ext, pFeatures->pNext)
- {
- switch (ext->sType) {
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
- VkPhysicalDeviceVulkan11Features *features = (void *) ext;
- features->storageBuffer16BitAccess = pdevice->info->a6xx.storage_16bit;
- features->uniformAndStorageBuffer16BitAccess = false;
- features->storagePushConstant16 = false;
- features->storageInputOutput16 = false;
- features->multiview = true;
- features->multiviewGeometryShader = false;
- features->multiviewTessellationShader = false;
- features->variablePointersStorageBuffer = true;
- features->variablePointers = true;
- features->protectedMemory = false;
- features->samplerYcbcrConversion = true;
- features->shaderDrawParameters = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: {
- VkPhysicalDeviceVulkan12Features *features = (void *) ext;
- features->samplerMirrorClampToEdge = true;
- features->drawIndirectCount = true;
- features->storageBuffer8BitAccess = false;
- features->uniformAndStorageBuffer8BitAccess = false;
- features->storagePushConstant8 = false;
- features->shaderBufferInt64Atomics = false;
- features->shaderSharedInt64Atomics = false;
- features->shaderFloat16 = true;
- features->shaderInt8 = false;
-
- features->descriptorIndexing = true;
- features->shaderInputAttachmentArrayDynamicIndexing = false;
- features->shaderUniformTexelBufferArrayDynamicIndexing = true;
- features->shaderStorageTexelBufferArrayDynamicIndexing = true;
- features->shaderUniformBufferArrayNonUniformIndexing = true;
- features->shaderSampledImageArrayNonUniformIndexing = true;
- features->shaderStorageBufferArrayNonUniformIndexing = true;
- features->shaderStorageImageArrayNonUniformIndexing = true;
- features->shaderInputAttachmentArrayNonUniformIndexing = false;
- features->shaderUniformTexelBufferArrayNonUniformIndexing = true;
- features->shaderStorageTexelBufferArrayNonUniformIndexing = true;
- features->descriptorBindingUniformBufferUpdateAfterBind = false;
- features->descriptorBindingSampledImageUpdateAfterBind = true;
- features->descriptorBindingStorageImageUpdateAfterBind = true;
- features->descriptorBindingStorageBufferUpdateAfterBind = true;
- features->descriptorBindingUniformTexelBufferUpdateAfterBind = true;
- features->descriptorBindingStorageTexelBufferUpdateAfterBind = true;
- features->descriptorBindingUpdateUnusedWhilePending = true;
- features->descriptorBindingPartiallyBound = true;
- features->descriptorBindingVariableDescriptorCount = true;
- features->runtimeDescriptorArray = true;
-
- features->samplerFilterMinmax = true;
- features->scalarBlockLayout = true;
- features->imagelessFramebuffer = false;
- features->uniformBufferStandardLayout = false;
- features->shaderSubgroupExtendedTypes = false;
- features->separateDepthStencilLayouts = false;
- features->hostQueryReset = true;
- features->timelineSemaphore = true;
- features->bufferDeviceAddress = false;
- features->bufferDeviceAddressCaptureReplay = false;
- features->bufferDeviceAddressMultiDevice = false;
- features->vulkanMemoryModel = true;
- features->vulkanMemoryModelDeviceScope = true;
- features->vulkanMemoryModelAvailabilityVisibilityChains = true;
- features->shaderOutputViewportIndex = true;
- features->shaderOutputLayer = true;
- features->subgroupBroadcastDynamicId = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: {
- VkPhysicalDeviceVariablePointersFeatures *features = (void *) ext;
- features->variablePointersStorageBuffer = true;
- features->variablePointers = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
- VkPhysicalDeviceMultiviewFeatures *features =
- (VkPhysicalDeviceMultiviewFeatures *) ext;
- features->multiview = true;
- features->multiviewGeometryShader = false;
- features->multiviewTessellationShader = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
- VkPhysicalDeviceShaderDrawParametersFeatures *features =
- (VkPhysicalDeviceShaderDrawParametersFeatures *) ext;
- features->shaderDrawParameters = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
- VkPhysicalDeviceProtectedMemoryFeatures *features =
- (VkPhysicalDeviceProtectedMemoryFeatures *) ext;
- features->protectedMemory = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
- VkPhysicalDevice16BitStorageFeatures *features =
- (VkPhysicalDevice16BitStorageFeatures *) ext;
- features->storageBuffer16BitAccess = pdevice->info->a6xx.storage_16bit;
- features->uniformAndStorageBuffer16BitAccess = false;
- features->storagePushConstant16 = false;
- features->storageInputOutput16 = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
- VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =
- (VkPhysicalDeviceSamplerYcbcrConversionFeatures *) ext;
- features->samplerYcbcrConversion = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
- VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features =
- (VkPhysicalDeviceDescriptorIndexingFeaturesEXT *) ext;
- features->shaderInputAttachmentArrayDynamicIndexing = false;
- features->shaderUniformTexelBufferArrayDynamicIndexing = true;
- features->shaderStorageTexelBufferArrayDynamicIndexing = true;
- features->shaderUniformBufferArrayNonUniformIndexing = true;
- features->shaderSampledImageArrayNonUniformIndexing = true;
- features->shaderStorageBufferArrayNonUniformIndexing = true;
- features->shaderStorageImageArrayNonUniformIndexing = true;
- features->shaderInputAttachmentArrayNonUniformIndexing = false;
- features->shaderUniformTexelBufferArrayNonUniformIndexing = true;
- features->shaderStorageTexelBufferArrayNonUniformIndexing = true;
- features->descriptorBindingUniformBufferUpdateAfterBind = false;
- features->descriptorBindingSampledImageUpdateAfterBind = true;
- features->descriptorBindingStorageImageUpdateAfterBind = true;
- features->descriptorBindingStorageBufferUpdateAfterBind = true;
- features->descriptorBindingUniformTexelBufferUpdateAfterBind = true;
- features->descriptorBindingStorageTexelBufferUpdateAfterBind = true;
- features->descriptorBindingUpdateUnusedWhilePending = true;
- features->descriptorBindingPartiallyBound = true;
- features->descriptorBindingVariableDescriptorCount = true;
- features->runtimeDescriptorArray = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
- VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
- (VkPhysicalDeviceConditionalRenderingFeaturesEXT *) ext;
- features->conditionalRendering = true;
- features->inheritedConditionalRendering = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
- VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
- (VkPhysicalDeviceTransformFeedbackFeaturesEXT *) ext;
- features->transformFeedback = true;
- features->geometryStreams = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {
- VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =
- (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;
- features->indexTypeUint8 = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
- VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
- (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
- features->vertexAttributeInstanceRateDivisor = true;
- features->vertexAttributeInstanceRateZeroDivisor = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
- VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =
- (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;
- features->uniformBufferStandardLayout = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {
- VkPhysicalDevicePrivateDataFeaturesEXT *features =
- (VkPhysicalDevicePrivateDataFeaturesEXT *)ext;
- features->privateData = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
- VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =
- (VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;
- features->depthClipEnable = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: {
- VkPhysicalDevice4444FormatsFeaturesEXT *features = (void *)ext;
- features->formatA4R4G4B4 = true;
- features->formatA4B4G4R4 = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
- VkPhysicalDeviceCustomBorderColorFeaturesEXT *features = (void *) ext;
- features->customBorderColors = true;
- features->customBorderColorWithoutFormat = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
- VkPhysicalDeviceHostQueryResetFeaturesEXT *features =
- (VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;
- features->hostQueryReset = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {
- VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features = (void *)ext;
- features->extendedDynamicState = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: {
- VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features =
- (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;
- features->extendedDynamicState2 = true;
- features->extendedDynamicState2LogicOp = false;
- features->extendedDynamicState2PatchControlPoints = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {
- VkPhysicalDevicePerformanceQueryFeaturesKHR *feature =
- (VkPhysicalDevicePerformanceQueryFeaturesKHR *)ext;
- feature->performanceCounterQueryPools = true;
- feature->performanceCounterMultipleQueryPools = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR: {
- VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *features =
- (VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *)ext;
- features->pipelineExecutableInfo = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES: {
- VkPhysicalDeviceShaderFloat16Int8Features *features =
- (VkPhysicalDeviceShaderFloat16Int8Features *) ext;
- features->shaderFloat16 = true;
- features->shaderInt8 = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
- VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features = (void *)ext;
- features->scalarBlockLayout = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
- VkPhysicalDeviceRobustness2FeaturesEXT *features = (void *)ext;
- features->robustBufferAccess2 = true;
- features->robustImageAccess2 = true;
- features->nullDescriptor = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT: {
- VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *features =
- (VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *)ext;
- features->shaderDemoteToHelperInvocation = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR: {
- VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *features =
- (VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *)ext;
- features->shaderTerminateInvocation = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR: {
- VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *feature =
- (VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *)ext;
- feature->vulkanMemoryModel = true;
- feature->vulkanMemoryModelDeviceScope = true;
- feature->vulkanMemoryModelAvailabilityVisibilityChains = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES: {
- VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *features =
- (VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *) ext;
- features->timelineSemaphore = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {
- VkPhysicalDeviceProvokingVertexFeaturesEXT *features =
- (VkPhysicalDeviceProvokingVertexFeaturesEXT *)ext;
- features->provokingVertexLast = true;
- features->transformFeedbackPreservesProvokingVertex = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE: {
- VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *features =
- (VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *)ext;
- features->mutableDescriptorType = true;
- break;
- }
-
- default:
- break;
- }
- }
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
- VkPhysicalDeviceProperties2 *pProperties)
-{
- TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
- VkSampleCountFlags sample_counts =
- VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT;
-
- /* I have no idea what the maximum size is, but the hardware supports very
- * large numbers of descriptors (at least 2^16). This limit is based on
- * CP_LOAD_STATE6, which has a 28-bit field for the DWORD offset, so that
- * we don't have to think about what to do if that overflows, but really
- * nothing is likely to get close to this.
- */
- const size_t max_descriptor_set_size = (1 << 28) / A6XX_TEX_CONST_DWORDS;
-
- VkPhysicalDeviceLimits limits = {
- .maxImageDimension1D = (1 << 14),
- .maxImageDimension2D = (1 << 14),
- .maxImageDimension3D = (1 << 11),
- .maxImageDimensionCube = (1 << 14),
- .maxImageArrayLayers = (1 << 11),
- .maxTexelBufferElements = 128 * 1024 * 1024,
- .maxUniformBufferRange = MAX_UNIFORM_BUFFER_RANGE,
- .maxStorageBufferRange = MAX_STORAGE_BUFFER_RANGE,
- .maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
- .maxMemoryAllocationCount = UINT32_MAX,
- .maxSamplerAllocationCount = 64 * 1024,
- .bufferImageGranularity = 64, /* A cache line */
- .sparseAddressSpaceSize = 0,
- .maxBoundDescriptorSets = MAX_SETS,
- .maxPerStageDescriptorSamplers = max_descriptor_set_size,
- .maxPerStageDescriptorUniformBuffers = max_descriptor_set_size,
- .maxPerStageDescriptorStorageBuffers = max_descriptor_set_size,
- .maxPerStageDescriptorSampledImages = max_descriptor_set_size,
- .maxPerStageDescriptorStorageImages = max_descriptor_set_size,
- .maxPerStageDescriptorInputAttachments = MAX_RTS,
- .maxPerStageResources = max_descriptor_set_size,
- .maxDescriptorSetSamplers = max_descriptor_set_size,
- .maxDescriptorSetUniformBuffers = max_descriptor_set_size,
- .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS,
- .maxDescriptorSetStorageBuffers = max_descriptor_set_size,
- .maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS,
- .maxDescriptorSetSampledImages = max_descriptor_set_size,
- .maxDescriptorSetStorageImages = max_descriptor_set_size,
- .maxDescriptorSetInputAttachments = MAX_RTS,
- .maxVertexInputAttributes = 32,
- .maxVertexInputBindings = 32,
- .maxVertexInputAttributeOffset = 4095,
- .maxVertexInputBindingStride = 2048,
- .maxVertexOutputComponents = 128,
- .maxTessellationGenerationLevel = 64,
- .maxTessellationPatchSize = 32,
- .maxTessellationControlPerVertexInputComponents = 128,
- .maxTessellationControlPerVertexOutputComponents = 128,
- .maxTessellationControlPerPatchOutputComponents = 120,
- .maxTessellationControlTotalOutputComponents = 4096,
- .maxTessellationEvaluationInputComponents = 128,
- .maxTessellationEvaluationOutputComponents = 128,
- .maxGeometryShaderInvocations = 32,
- .maxGeometryInputComponents = 64,
- .maxGeometryOutputComponents = 128,
- .maxGeometryOutputVertices = 256,
- .maxGeometryTotalOutputComponents = 1024,
- .maxFragmentInputComponents = 124,
- .maxFragmentOutputAttachments = 8,
- .maxFragmentDualSrcAttachments = 1,
- .maxFragmentCombinedOutputResources = 8,
- .maxComputeSharedMemorySize = 32768,
- .maxComputeWorkGroupCount = { 65535, 65535, 65535 },
- .maxComputeWorkGroupInvocations = 2048,
- .maxComputeWorkGroupSize = { 1024, 1024, 1024 },
- .subPixelPrecisionBits = 8,
- .subTexelPrecisionBits = 8,
- .mipmapPrecisionBits = 8,
- .maxDrawIndexedIndexValue = UINT32_MAX,
- .maxDrawIndirectCount = UINT32_MAX,
- .maxSamplerLodBias = 4095.0 / 256.0, /* [-16, 15.99609375] */
- .maxSamplerAnisotropy = 16,
- .maxViewports = MAX_VIEWPORTS,
- .maxViewportDimensions = { (1 << 14), (1 << 14) },
- .viewportBoundsRange = { INT16_MIN, INT16_MAX },
- .viewportSubPixelBits = 8,
- .minMemoryMapAlignment = 4096, /* A page */
- .minTexelBufferOffsetAlignment = 64,
- .minUniformBufferOffsetAlignment = 64,
- .minStorageBufferOffsetAlignment = 64,
- .minTexelOffset = -16,
- .maxTexelOffset = 15,
- .minTexelGatherOffset = -32,
- .maxTexelGatherOffset = 31,
- .minInterpolationOffset = -0.5,
- .maxInterpolationOffset = 0.4375,
- .subPixelInterpolationOffsetBits = 4,
- .maxFramebufferWidth = (1 << 14),
- .maxFramebufferHeight = (1 << 14),
- .maxFramebufferLayers = (1 << 10),
- .framebufferColorSampleCounts = sample_counts,
- .framebufferDepthSampleCounts = sample_counts,
- .framebufferStencilSampleCounts = sample_counts,
- .framebufferNoAttachmentsSampleCounts = sample_counts,
- .maxColorAttachments = MAX_RTS,
- .sampledImageColorSampleCounts = sample_counts,
- .sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT,
- .sampledImageDepthSampleCounts = sample_counts,
- .sampledImageStencilSampleCounts = sample_counts,
- .storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
- .maxSampleMaskWords = 1,
- .timestampComputeAndGraphics = true,
- .timestampPeriod = 1000000000.0 / 19200000.0, /* CP_ALWAYS_ON_COUNTER is fixed 19.2MHz */
- .maxClipDistances = 8,
- .maxCullDistances = 8,
- .maxCombinedClipAndCullDistances = 8,
- .discreteQueuePriorities = 2,
- .pointSizeRange = { 1, 4092 },
- .lineWidthRange = { 1.0, 1.0 },
- .pointSizeGranularity = 0.0625,
- .lineWidthGranularity = 0.0,
- .strictLines = false, /* FINISHME */
- .standardSampleLocations = true,
- .optimalBufferCopyOffsetAlignment = 128,
- .optimalBufferCopyRowPitchAlignment = 128,
- .nonCoherentAtomSize = 64,
- };
-
- pProperties->properties = (VkPhysicalDeviceProperties) {
- .apiVersion = TU_API_VERSION,
- .driverVersion = vk_get_driver_version(),
- .vendorID = 0, /* TODO */
- .deviceID = 0,
- .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
- .limits = limits,
- .sparseProperties = { 0 },
- };
-
- strcpy(pProperties->properties.deviceName, pdevice->name);
- memcpy(pProperties->properties.pipelineCacheUUID, pdevice->cache_uuid, VK_UUID_SIZE);
-
- vk_foreach_struct(ext, pProperties->pNext)
- {
- switch (ext->sType) {
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
- VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
- (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
- properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
- VkPhysicalDeviceIDProperties *properties =
- (VkPhysicalDeviceIDProperties *) ext;
- memcpy(properties->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
- memcpy(properties->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
- properties->deviceLUIDValid = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {
- VkPhysicalDeviceMultiviewProperties *properties =
- (VkPhysicalDeviceMultiviewProperties *) ext;
- properties->maxMultiviewViewCount = MAX_VIEWS;
- properties->maxMultiviewInstanceIndex = INT_MAX;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
- VkPhysicalDevicePointClippingProperties *properties =
- (VkPhysicalDevicePointClippingProperties *) ext;
- properties->pointClippingBehavior =
- VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
- VkPhysicalDeviceMaintenance3Properties *properties =
- (VkPhysicalDeviceMaintenance3Properties *) ext;
- /* Make sure everything is addressable by a signed 32-bit int, and
- * our largest descriptors are 96 bytes. */
- properties->maxPerSetDescriptors = (1ull << 31) / 96;
- /* Our buffer size fields allow only this much */
- properties->maxMemoryAllocationSize = 0xFFFFFFFFull;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
- VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =
- (VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext;
-
- properties->maxTransformFeedbackStreams = IR3_MAX_SO_STREAMS;
- properties->maxTransformFeedbackBuffers = IR3_MAX_SO_BUFFERS;
- properties->maxTransformFeedbackBufferSize = UINT32_MAX;
- properties->maxTransformFeedbackStreamDataSize = 512;
- properties->maxTransformFeedbackBufferDataSize = 512;
- properties->maxTransformFeedbackBufferDataStride = 512;
- properties->transformFeedbackQueries = true;
- properties->transformFeedbackStreamsLinesTriangles = true;
- properties->transformFeedbackRasterizationStreamSelect = true;
- properties->transformFeedbackDraw = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT: {
- VkPhysicalDeviceSampleLocationsPropertiesEXT *properties =
- (VkPhysicalDeviceSampleLocationsPropertiesEXT *)ext;
- properties->sampleLocationSampleCounts = 0;
- if (pdevice->vk.supported_extensions.EXT_sample_locations) {
- properties->sampleLocationSampleCounts =
- VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT;
- }
- properties->maxSampleLocationGridSize = (VkExtent2D) { 1 , 1 };
- properties->sampleLocationCoordinateRange[0] = 0.0f;
- properties->sampleLocationCoordinateRange[1] = 0.9375f;
- properties->sampleLocationSubPixelBits = 4;
- properties->variableSampleLocations = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES: {
- VkPhysicalDeviceSamplerFilterMinmaxProperties *properties =
- (VkPhysicalDeviceSamplerFilterMinmaxProperties *)ext;
- properties->filterMinmaxImageComponentMapping = true;
- properties->filterMinmaxSingleComponentFormats = true;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {
- VkPhysicalDeviceSubgroupProperties *properties =
- (VkPhysicalDeviceSubgroupProperties *)ext;
- properties->subgroupSize = 128;
- properties->supportedStages = VK_SHADER_STAGE_COMPUTE_BIT;
- properties->supportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT |
- VK_SUBGROUP_FEATURE_VOTE_BIT |
- VK_SUBGROUP_FEATURE_BALLOT_BIT;
- properties->quadOperationsInAllStages = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
- VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
- (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
- props->maxVertexAttribDivisor = UINT32_MAX;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
- VkPhysicalDeviceCustomBorderColorPropertiesEXT *props = (void *)ext;
- props->maxCustomBorderColorSamplers = TU_BORDER_COLOR_COUNT;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES: {
- VkPhysicalDeviceDepthStencilResolveProperties *props =
- (VkPhysicalDeviceDepthStencilResolveProperties *)ext;
- props->independentResolve = false;
- props->independentResolveNone = false;
- props->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
- props->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR: {
- VkPhysicalDevicePerformanceQueryPropertiesKHR *properties =
- (VkPhysicalDevicePerformanceQueryPropertiesKHR *)ext;
- properties->allowCommandBufferQueryCopies = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT: {
- VkPhysicalDeviceDescriptorIndexingPropertiesEXT *props =
- (VkPhysicalDeviceDescriptorIndexingPropertiesEXT *)ext;
- props->shaderUniformBufferArrayNonUniformIndexingNative = true;
- props->shaderSampledImageArrayNonUniformIndexingNative = true;
- props->shaderStorageBufferArrayNonUniformIndexingNative = true;
- props->shaderStorageImageArrayNonUniformIndexingNative = true;
- props->shaderInputAttachmentArrayNonUniformIndexingNative = false;
- props->robustBufferAccessUpdateAfterBind = false;
- props->quadDivergentImplicitLod = false;
-
- props->maxUpdateAfterBindDescriptorsInAllPools = max_descriptor_set_size;
- props->maxPerStageDescriptorUpdateAfterBindSamplers = max_descriptor_set_size;
- props->maxPerStageDescriptorUpdateAfterBindUniformBuffers = max_descriptor_set_size;
- props->maxPerStageDescriptorUpdateAfterBindStorageBuffers = max_descriptor_set_size;
- props->maxPerStageDescriptorUpdateAfterBindSampledImages = max_descriptor_set_size;
- props->maxPerStageDescriptorUpdateAfterBindStorageImages = max_descriptor_set_size;
- props->maxPerStageDescriptorUpdateAfterBindInputAttachments = max_descriptor_set_size;
- props->maxPerStageUpdateAfterBindResources = max_descriptor_set_size;
- props->maxDescriptorSetUpdateAfterBindSamplers = max_descriptor_set_size;
- props->maxDescriptorSetUpdateAfterBindUniformBuffers = max_descriptor_set_size;
- props->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS;
- props->maxDescriptorSetUpdateAfterBindStorageBuffers = max_descriptor_set_size;
- props->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS;
- props->maxDescriptorSetUpdateAfterBindSampledImages = max_descriptor_set_size;
- props->maxDescriptorSetUpdateAfterBindStorageImages = max_descriptor_set_size;
- props->maxDescriptorSetUpdateAfterBindInputAttachments = max_descriptor_set_size;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES: {
- VkPhysicalDeviceFloatControlsProperties *properties =
- (VkPhysicalDeviceFloatControlsProperties *) ext;
- properties->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
- properties->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
- properties->shaderSignedZeroInfNanPreserveFloat16 = true;
- properties->shaderSignedZeroInfNanPreserveFloat32 = true;
- properties->shaderSignedZeroInfNanPreserveFloat64 = false;
- properties->shaderDenormPreserveFloat16 = false;
- properties->shaderDenormPreserveFloat32 = false;
- properties->shaderDenormPreserveFloat64 = false;
- properties->shaderDenormFlushToZeroFloat16 = true;
- properties->shaderDenormFlushToZeroFloat32 = true;
- properties->shaderDenormFlushToZeroFloat64 = false;
- properties->shaderRoundingModeRTEFloat16 = true;
- properties->shaderRoundingModeRTEFloat32 = true;
- properties->shaderRoundingModeRTEFloat64 = false;
- properties->shaderRoundingModeRTZFloat16 = false;
- properties->shaderRoundingModeRTZFloat32 = false;
- properties->shaderRoundingModeRTZFloat64 = false;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: {
- VkPhysicalDeviceRobustness2PropertiesEXT *props = (void *)ext;
- /* see write_buffer_descriptor() */
- props->robustStorageBufferAccessSizeAlignment = 4;
- /* see write_ubo_descriptor() */
- props->robustUniformBufferAccessSizeAlignment = 16;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES: {
- VkPhysicalDeviceTimelineSemaphorePropertiesKHR *props =
- (VkPhysicalDeviceTimelineSemaphorePropertiesKHR *) ext;
- props->maxTimelineSemaphoreValueDifference = UINT64_MAX;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {
- VkPhysicalDeviceProvokingVertexPropertiesEXT *properties =
- (VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext;
- properties->provokingVertexModePerPipeline = true;
- properties->transformFeedbackPreservesTriangleFanProvokingVertex = false;
- break;
- }
- default:
- break;
- }
- }
-}
-
-static const VkQueueFamilyProperties tu_queue_family_properties = {
- .queueFlags =
- VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT,
- .queueCount = 1,
- .timestampValidBits = 48,
- .minImageTransferGranularity = { 1, 1, 1 },
-};
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetPhysicalDeviceQueueFamilyProperties2(
- VkPhysicalDevice physicalDevice,
- uint32_t *pQueueFamilyPropertyCount,
- VkQueueFamilyProperties2 *pQueueFamilyProperties)
-{
- VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
-
- vk_outarray_append(&out, p)
- {
- p->queueFamilyProperties = tu_queue_family_properties;
- }
-}
-
-uint64_t
-tu_get_system_heap_size()
-{
- struct sysinfo info;
- sysinfo(&info);
-
- uint64_t total_ram = (uint64_t) info.totalram * (uint64_t) info.mem_unit;
-
- /* We don't want to burn too much ram with the GPU. If the user has 4GiB
- * or less, we use at most half. If they have more than 4GiB, we use 3/4.
- */
- uint64_t available_ram;
- if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
- available_ram = total_ram / 2;
- else
- available_ram = total_ram * 3 / 4;
-
- return available_ram;
-}
-
-static VkDeviceSize
-tu_get_budget_memory(struct tu_physical_device *physical_device)
-{
- uint64_t heap_size = physical_device->heap.size;
- uint64_t heap_used = physical_device->heap.used;
- uint64_t sys_available;
- ASSERTED bool has_available_memory =
- os_get_available_system_memory(&sys_available);
- assert(has_available_memory);
-
- /*
- * Let's not incite the app to starve the system: report at most 90% of
- * available system memory.
- */
- uint64_t heap_available = sys_available * 9 / 10;
- return MIN2(heap_size, heap_used + heap_available);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice pdev,
- VkPhysicalDeviceMemoryProperties2 *props2)
-{
- TU_FROM_HANDLE(tu_physical_device, physical_device, pdev);
-
- VkPhysicalDeviceMemoryProperties *props = &props2->memoryProperties;
- props->memoryHeapCount = 1;
- props->memoryHeaps[0].size = physical_device->heap.size;
- props->memoryHeaps[0].flags = physical_device->heap.flags;
-
- props->memoryTypeCount = 1;
- props->memoryTypes[0].propertyFlags =
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
- props->memoryTypes[0].heapIndex = 0;
-
- vk_foreach_struct(ext, props2->pNext)
- {
- switch (ext->sType) {
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: {
- VkPhysicalDeviceMemoryBudgetPropertiesEXT *memory_budget_props =
- (VkPhysicalDeviceMemoryBudgetPropertiesEXT *) ext;
- memory_budget_props->heapUsage[0] = physical_device->heap.used;
- memory_budget_props->heapBudget[0] = tu_get_budget_memory(physical_device);
-
- /* The heapBudget and heapUsage values must be zero for array elements
- * greater than or equal to VkPhysicalDeviceMemoryProperties::memoryHeapCount
- */
- for (unsigned i = 1; i < VK_MAX_MEMORY_HEAPS; i++) {
- memory_budget_props->heapBudget[i] = 0u;
- memory_budget_props->heapUsage[i] = 0u;
- }
- break;
- }
- default:
- break;
- }
- }
-}
-
-static VkResult
-tu_queue_init(struct tu_device *device,
- struct tu_queue *queue,
- uint32_t queue_family_index,
- int idx,
- VkDeviceQueueCreateFlags flags)
-{
- vk_object_base_init(&device->vk, &queue->base, VK_OBJECT_TYPE_QUEUE);
-
- queue->device = device;
- queue->queue_family_index = queue_family_index;
- queue->queue_idx = idx;
- queue->flags = flags;
-
- list_inithead(&queue->queued_submits);
-
- int ret = tu_drm_submitqueue_new(device, 0, &queue->msm_queue_id);
- if (ret)
- return vk_startup_errorf(device->instance, VK_ERROR_INITIALIZATION_FAILED,
- "submitqueue create failed");
-
- queue->fence = -1;
-
- return VK_SUCCESS;
-}
-
-static void
-tu_queue_finish(struct tu_queue *queue)
-{
- vk_object_base_finish(&queue->base);
- if (queue->fence >= 0)
- close(queue->fence);
- tu_drm_submitqueue_close(queue->device, queue->msm_queue_id);
-}
-
-uint64_t
-tu_device_ticks_to_ns(struct tu_device *dev, uint64_t ts)
-{
- /* This is based on the 19.2MHz always-on rbbm timer.
- *
- * TODO we should probably query this value from kernel..
- */
- return ts * (1000000000 / 19200000);
-}
-
-static void*
-tu_trace_create_ts_buffer(struct u_trace_context *utctx, uint32_t size)
-{
- struct tu_device *device =
- container_of(utctx, struct tu_device, trace_context);
-
- struct tu_bo *bo = ralloc(NULL, struct tu_bo);
- tu_bo_init_new(device, bo, size, false);
-
- return bo;
-}
-
-static void
-tu_trace_destroy_ts_buffer(struct u_trace_context *utctx, void *timestamps)
-{
- struct tu_device *device =
- container_of(utctx, struct tu_device, trace_context);
- struct tu_bo *bo = timestamps;
-
- tu_bo_finish(device, bo);
- ralloc_free(bo);
-}
-
-static void
-tu_trace_record_ts(struct u_trace *ut, void *cs, void *timestamps,
- unsigned idx)
-{
- struct tu_bo *bo = timestamps;
- struct tu_cs *ts_cs = cs;
-
- unsigned ts_offset = idx * sizeof(uint64_t);
- tu_cs_emit_pkt7(ts_cs, CP_EVENT_WRITE, 4);
- tu_cs_emit(ts_cs, CP_EVENT_WRITE_0_EVENT(RB_DONE_TS) | CP_EVENT_WRITE_0_TIMESTAMP);
- tu_cs_emit_qw(ts_cs, bo->iova + ts_offset);
- tu_cs_emit(ts_cs, 0x00000000);
-}
-
-static uint64_t
-tu_trace_read_ts(struct u_trace_context *utctx,
- void *timestamps, unsigned idx, void *flush_data)
-{
- struct tu_device *device =
- container_of(utctx, struct tu_device, trace_context);
- struct tu_bo *bo = timestamps;
- struct tu_u_trace_flush_data *trace_flush_data = flush_data;
-
- /* Only need to stall on results for the first entry: */
- if (idx == 0) {
- tu_device_wait_u_trace(device, trace_flush_data->syncobj);
- }
-
- if (tu_bo_map(device, bo) != VK_SUCCESS) {
- return U_TRACE_NO_TIMESTAMP;
- }
-
- uint64_t *ts = bo->map;
-
- /* Don't translate the no-timestamp marker: */
- if (ts[idx] == U_TRACE_NO_TIMESTAMP)
- return U_TRACE_NO_TIMESTAMP;
-
- return tu_device_ticks_to_ns(device, ts[idx]);
-}
-
-static void
-tu_trace_delete_flush_data(struct u_trace_context *utctx, void *flush_data)
-{
- struct tu_device *device =
- container_of(utctx, struct tu_device, trace_context);
- struct tu_u_trace_flush_data *trace_flush_data = flush_data;
-
- tu_u_trace_cmd_data_finish(device, trace_flush_data->cmd_trace_data,
- trace_flush_data->trace_count);
- vk_free(&device->vk.alloc, trace_flush_data->syncobj);
- vk_free(&device->vk.alloc, trace_flush_data);
-}
-
-void
-tu_copy_timestamp_buffer(struct u_trace_context *utctx, void *cmdstream,
- void *ts_from, uint32_t from_offset,
- void *ts_to, uint32_t to_offset,
- uint32_t count)
-{
- struct tu_cs *cs = cmdstream;
- struct tu_bo *bo_from = ts_from;
- struct tu_bo *bo_to = ts_to;
-
- tu_cs_emit_pkt7(cs, CP_MEMCPY, 5);
- tu_cs_emit(cs, count * sizeof(uint64_t) / sizeof(uint32_t));
- tu_cs_emit_qw(cs, bo_from->iova + from_offset * sizeof(uint64_t));
- tu_cs_emit_qw(cs, bo_to->iova + to_offset * sizeof(uint64_t));
-}
-
-VkResult
-tu_create_copy_timestamp_cs(struct tu_cmd_buffer *cmdbuf, struct tu_cs** cs,
- struct u_trace **trace_copy)
-{
- *cs = vk_zalloc(&cmdbuf->device->vk.alloc, sizeof(struct tu_cs), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
-
- if (*cs == NULL) {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
-
- tu_cs_init(*cs, cmdbuf->device, TU_CS_MODE_GROW,
- list_length(&cmdbuf->trace.trace_chunks) * 6 + 3);
-
- tu_cs_begin(*cs);
-
- tu_cs_emit_wfi(*cs);
- tu_cs_emit_pkt7(*cs, CP_WAIT_FOR_ME, 0);
-
- *trace_copy = vk_zalloc(&cmdbuf->device->vk.alloc, sizeof(struct u_trace), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
-
- if (*trace_copy == NULL) {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
-
- u_trace_init(*trace_copy, cmdbuf->trace.utctx);
- u_trace_clone_append(u_trace_begin_iterator(&cmdbuf->trace),
- u_trace_end_iterator(&cmdbuf->trace),
- *trace_copy, *cs,
- tu_copy_timestamp_buffer);
-
- tu_cs_emit_wfi(*cs);
-
- tu_cs_end(*cs);
-
- return VK_SUCCESS;
-}
-
-void
-tu_u_trace_cmd_data_finish(struct tu_device *device,
- struct tu_u_trace_cmd_data *trace_data,
- uint32_t entry_count)
-{
- for (uint32_t i = 0; i < entry_count; ++i) {
- /* Only if we had to create a copy of trace we should free it */
- if (trace_data[i].timestamp_copy_cs != NULL) {
- tu_cs_finish(trace_data[i].timestamp_copy_cs);
- vk_free(&device->vk.alloc, trace_data[i].timestamp_copy_cs);
-
- u_trace_fini(trace_data[i].trace);
- vk_free(&device->vk.alloc, trace_data[i].trace);
- }
- }
-
- vk_free(&device->vk.alloc, trace_data);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_CreateDevice(VkPhysicalDevice physicalDevice,
- const VkDeviceCreateInfo *pCreateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkDevice *pDevice)
-{
- TU_FROM_HANDLE(tu_physical_device, physical_device, physicalDevice);
- VkResult result;
- struct tu_device *device;
- bool custom_border_colors = false;
- bool perf_query_pools = false;
- bool robust_buffer_access2 = false;
-
- /* Check enabled features */
- if (pCreateInfo->pEnabledFeatures) {
- VkPhysicalDeviceFeatures2 supported_features = {
- .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
- };
- tu_GetPhysicalDeviceFeatures2(physicalDevice, &supported_features);
- VkBool32 *supported_feature = (VkBool32 *) &supported_features.features;
- VkBool32 *enabled_feature = (VkBool32 *) pCreateInfo->pEnabledFeatures;
- unsigned num_features =
- sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
- for (uint32_t i = 0; i < num_features; i++) {
- if (enabled_feature[i] && !supported_feature[i])
- return vk_startup_errorf(physical_device->instance,
- VK_ERROR_FEATURE_NOT_PRESENT,
- "Missing feature bit %d\n", i);
- }
- }
-
- vk_foreach_struct_const(ext, pCreateInfo->pNext) {
- switch (ext->sType) {
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
- const VkPhysicalDeviceCustomBorderColorFeaturesEXT *border_color_features = (const void *)ext;
- custom_border_colors = border_color_features->customBorderColors;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {
- const VkPhysicalDevicePerformanceQueryFeaturesKHR *feature =
- (VkPhysicalDevicePerformanceQueryFeaturesKHR *)ext;
- perf_query_pools = feature->performanceCounterQueryPools;
- break;
- }
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
- VkPhysicalDeviceRobustness2FeaturesEXT *features = (void *)ext;
- robust_buffer_access2 = features->robustBufferAccess2;
- break;
- }
- default:
- break;
- }
- }
-
- device = vk_zalloc2(&physical_device->instance->vk.alloc, pAllocator,
- sizeof(*device), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
- if (!device)
- return vk_startup_errorf(physical_device->instance, VK_ERROR_OUT_OF_HOST_MEMORY, "OOM");
-
- struct vk_device_dispatch_table dispatch_table;
- vk_device_dispatch_table_from_entrypoints(
- &dispatch_table, &tu_device_entrypoints, true);
-
- result = vk_device_init(&device->vk, &physical_device->vk,
- &dispatch_table, pCreateInfo, pAllocator);
- if (result != VK_SUCCESS) {
- vk_free(&device->vk.alloc, device);
- return vk_startup_errorf(physical_device->instance, result,
- "vk_device_init failed");
- }
-
- device->instance = physical_device->instance;
- device->physical_device = physical_device;
- device->fd = physical_device->local_fd;
- device->_lost = false;
-
- mtx_init(&device->bo_mutex, mtx_plain);
- pthread_mutex_init(&device->submit_mutex, NULL);
-
- for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
- const VkDeviceQueueCreateInfo *queue_create =
- &pCreateInfo->pQueueCreateInfos[i];
- uint32_t qfi = queue_create->queueFamilyIndex;
- device->queues[qfi] = vk_alloc(
- &device->vk.alloc, queue_create->queueCount * sizeof(struct tu_queue),
- 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
- if (!device->queues[qfi]) {
- result = vk_startup_errorf(physical_device->instance,
- VK_ERROR_OUT_OF_HOST_MEMORY,
- "OOM");
- goto fail_queues;
- }
-
- memset(device->queues[qfi], 0,
- queue_create->queueCount * sizeof(struct tu_queue));
-
- device->queue_count[qfi] = queue_create->queueCount;
-
- for (unsigned q = 0; q < queue_create->queueCount; q++) {
- result = tu_queue_init(device, &device->queues[qfi][q], qfi, q,
- queue_create->flags);
- if (result != VK_SUCCESS)
- goto fail_queues;
- }
- }
-
- device->compiler = ir3_compiler_create(NULL, &physical_device->dev_id,
- robust_buffer_access2);
- if (!device->compiler) {
- result = vk_startup_errorf(physical_device->instance,
- VK_ERROR_INITIALIZATION_FAILED,
- "failed to initialize ir3 compiler");
- goto fail_queues;
- }
-
- /* initial sizes, these will increase if there is overflow */
- device->vsc_draw_strm_pitch = 0x1000 + VSC_PAD;
- device->vsc_prim_strm_pitch = 0x4000 + VSC_PAD;
-
- uint32_t global_size = sizeof(struct tu6_global);
- if (custom_border_colors)
- global_size += TU_BORDER_COLOR_COUNT * sizeof(struct bcolor_entry);
-
- result = tu_bo_init_new(device, &device->global_bo, global_size,
- TU_BO_ALLOC_ALLOW_DUMP);
- if (result != VK_SUCCESS) {
- vk_startup_errorf(device->instance, result, "BO init");
- goto fail_global_bo;
- }
-
- result = tu_bo_map(device, &device->global_bo);
- if (result != VK_SUCCESS) {
- vk_startup_errorf(device->instance, result, "BO map");
- goto fail_global_bo_map;
- }
-
- struct tu6_global *global = device->global_bo.map;
- tu_init_clear_blit_shaders(device);
- global->predicate = 0;
- tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK],
- &(VkClearColorValue) {}, false);
- tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_TRANSPARENT_BLACK],
- &(VkClearColorValue) {}, true);
- tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK],
- &(VkClearColorValue) { .float32[3] = 1.0f }, false);
- tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_OPAQUE_BLACK],
- &(VkClearColorValue) { .int32[3] = 1 }, true);
- tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE],
- &(VkClearColorValue) { .float32[0 ... 3] = 1.0f }, false);
- tu6_pack_border_color(&global->bcolor_builtin[VK_BORDER_COLOR_INT_OPAQUE_WHITE],
- &(VkClearColorValue) { .int32[0 ... 3] = 1 }, true);
-
- /* initialize to ones so ffs can be used to find unused slots */
- BITSET_ONES(device->custom_border_color);
-
- VkPipelineCacheCreateInfo ci;
- ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
- ci.pNext = NULL;
- ci.flags = 0;
- ci.pInitialData = NULL;
- ci.initialDataSize = 0;
- VkPipelineCache pc;
- result =
- tu_CreatePipelineCache(tu_device_to_handle(device), &ci, NULL, &pc);
- if (result != VK_SUCCESS) {
- vk_startup_errorf(device->instance, result, "create pipeline cache failed");
- goto fail_pipeline_cache;
- }
-
- if (perf_query_pools) {
- /* Prepare command streams setting pass index to the PERF_CNTRS_REG
- * from 0 to 31. One of these will be picked up at cmd submit time
- * when the perf query is executed.
- */
- struct tu_cs *cs;
-
- if (!(device->perfcntrs_pass_cs = calloc(1, sizeof(struct tu_cs)))) {
- result = vk_startup_errorf(device->instance,
- VK_ERROR_OUT_OF_HOST_MEMORY, "OOM");
- goto fail_perfcntrs_pass_alloc;
- }
-
- device->perfcntrs_pass_cs_entries = calloc(32, sizeof(struct tu_cs_entry));
- if (!device->perfcntrs_pass_cs_entries) {
- result = vk_startup_errorf(device->instance,
- VK_ERROR_OUT_OF_HOST_MEMORY, "OOM");
- goto fail_perfcntrs_pass_entries_alloc;
- }
-
- cs = device->perfcntrs_pass_cs;
- tu_cs_init(cs, device, TU_CS_MODE_SUB_STREAM, 96);
-
- for (unsigned i = 0; i < 32; i++) {
- struct tu_cs sub_cs;
-
- result = tu_cs_begin_sub_stream(cs, 3, &sub_cs);
- if (result != VK_SUCCESS) {
- vk_startup_errorf(device->instance, result,
- "failed to allocate commands streams");
- goto fail_prepare_perfcntrs_pass_cs;
- }
-
- tu_cs_emit_regs(&sub_cs, A6XX_CP_SCRATCH_REG(PERF_CNTRS_REG, 1 << i));
- tu_cs_emit_pkt7(&sub_cs, CP_WAIT_FOR_ME, 0);
-
- device->perfcntrs_pass_cs_entries[i] = tu_cs_end_sub_stream(cs, &sub_cs);
- }
- }
-
- /* Initialize a condition variable for timeline semaphore */
- pthread_condattr_t condattr;
- if (pthread_condattr_init(&condattr) != 0) {
- result = vk_startup_errorf(physical_device->instance,
- VK_ERROR_INITIALIZATION_FAILED,
- "pthread condattr init");
- goto fail_timeline_cond;
- }
- if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) != 0) {
- pthread_condattr_destroy(&condattr);
- result = vk_startup_errorf(physical_device->instance,
- VK_ERROR_INITIALIZATION_FAILED,
- "pthread condattr clock setup");
- goto fail_timeline_cond;
- }
- if (pthread_cond_init(&device->timeline_cond, &condattr) != 0) {
- pthread_condattr_destroy(&condattr);
- result = vk_startup_errorf(physical_device->instance,
- VK_ERROR_INITIALIZATION_FAILED,
- "pthread cond init");
- goto fail_timeline_cond;
- }
- pthread_condattr_destroy(&condattr);
-
- device->mem_cache = tu_pipeline_cache_from_handle(pc);
-
- for (unsigned i = 0; i < ARRAY_SIZE(device->scratch_bos); i++)
- mtx_init(&device->scratch_bos[i].construct_mtx, mtx_plain);
-
- mtx_init(&device->mutex, mtx_plain);
-
- device->submit_count = 0;
- u_trace_context_init(&device->trace_context, device,
- tu_trace_create_ts_buffer,
- tu_trace_destroy_ts_buffer,
- tu_trace_record_ts,
- tu_trace_read_ts,
- tu_trace_delete_flush_data);
-
- *pDevice = tu_device_to_handle(device);
- return VK_SUCCESS;
-
-fail_timeline_cond:
-fail_prepare_perfcntrs_pass_cs:
- free(device->perfcntrs_pass_cs_entries);
- tu_cs_finish(device->perfcntrs_pass_cs);
-fail_perfcntrs_pass_entries_alloc:
- free(device->perfcntrs_pass_cs);
-fail_perfcntrs_pass_alloc:
- tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL);
-fail_pipeline_cache:
- tu_destroy_clear_blit_shaders(device);
-fail_global_bo_map:
- tu_bo_finish(device, &device->global_bo);
- vk_free(&device->vk.alloc, device->bo_idx);
- vk_free(&device->vk.alloc, device->bo_list);
-fail_global_bo:
- ir3_compiler_destroy(device->compiler);
-
-fail_queues:
- for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
- for (unsigned q = 0; q < device->queue_count[i]; q++)
- tu_queue_finish(&device->queues[i][q]);
- if (device->queue_count[i])
- vk_free(&device->vk.alloc, device->queues[i]);
- }
-
- vk_device_finish(&device->vk);
- vk_free(&device->vk.alloc, device);
- return result;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
-
- if (!device)
- return;
-
- u_trace_context_fini(&device->trace_context);
-
- for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
- for (unsigned q = 0; q < device->queue_count[i]; q++)
- tu_queue_finish(&device->queues[i][q]);
- if (device->queue_count[i])
- vk_free(&device->vk.alloc, device->queues[i]);
- }
-
- for (unsigned i = 0; i < ARRAY_SIZE(device->scratch_bos); i++) {
- if (device->scratch_bos[i].initialized)
- tu_bo_finish(device, &device->scratch_bos[i].bo);
- }
-
- tu_destroy_clear_blit_shaders(device);
-
- ir3_compiler_destroy(device->compiler);
-
- VkPipelineCache pc = tu_pipeline_cache_to_handle(device->mem_cache);
- tu_DestroyPipelineCache(tu_device_to_handle(device), pc, NULL);
-
- if (device->perfcntrs_pass_cs) {
- free(device->perfcntrs_pass_cs_entries);
- tu_cs_finish(device->perfcntrs_pass_cs);
- free(device->perfcntrs_pass_cs);
- }
-
- pthread_cond_destroy(&device->timeline_cond);
- vk_free(&device->vk.alloc, device->bo_list);
- vk_free(&device->vk.alloc, device->bo_idx);
- vk_device_finish(&device->vk);
- vk_free(&device->vk.alloc, device);
-}
-
-VkResult
-_tu_device_set_lost(struct tu_device *device,
- const char *msg, ...)
-{
- /* Set the flag indicating that waits should return in finite time even
- * after device loss.
- */
- p_atomic_inc(&device->_lost);
-
- /* TODO: Report the log message through VkDebugReportCallbackEXT instead */
- va_list ap;
- va_start(ap, msg);
- mesa_loge_v(msg, ap);
- va_end(ap);
-
- if (env_var_as_boolean("TU_ABORT_ON_DEVICE_LOSS", false))
- abort();
-
- return VK_ERROR_DEVICE_LOST;
-}
-
-VkResult
-tu_get_scratch_bo(struct tu_device *dev, uint64_t size, struct tu_bo **bo)
-{
- unsigned size_log2 = MAX2(util_logbase2_ceil64(size), MIN_SCRATCH_BO_SIZE_LOG2);
- unsigned index = size_log2 - MIN_SCRATCH_BO_SIZE_LOG2;
- assert(index < ARRAY_SIZE(dev->scratch_bos));
-
- for (unsigned i = index; i < ARRAY_SIZE(dev->scratch_bos); i++) {
- if (p_atomic_read(&dev->scratch_bos[i].initialized)) {
- /* Fast path: just return the already-allocated BO. */
- *bo = &dev->scratch_bos[i].bo;
- return VK_SUCCESS;
- }
- }
-
- /* Slow path: actually allocate the BO. We take a lock because the process
- * of allocating it is slow, and we don't want to block the CPU while it
- * finishes.
- */
- mtx_lock(&dev->scratch_bos[index].construct_mtx);
-
- /* Another thread may have allocated it already while we were waiting on
- * the lock. We need to check this in order to avoid double-allocating.
- */
- if (dev->scratch_bos[index].initialized) {
- mtx_unlock(&dev->scratch_bos[index].construct_mtx);
- *bo = &dev->scratch_bos[index].bo;
- return VK_SUCCESS;
- }
-
- unsigned bo_size = 1ull << size_log2;
- VkResult result = tu_bo_init_new(dev, &dev->scratch_bos[index].bo, bo_size,
- TU_BO_ALLOC_NO_FLAGS);
- if (result != VK_SUCCESS) {
- mtx_unlock(&dev->scratch_bos[index].construct_mtx);
- return result;
- }
-
- p_atomic_set(&dev->scratch_bos[index].initialized, true);
-
- mtx_unlock(&dev->scratch_bos[index].construct_mtx);
-
- *bo = &dev->scratch_bos[index].bo;
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
- VkLayerProperties *pProperties)
-{
- *pPropertyCount = 0;
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetDeviceQueue2(VkDevice _device,
- const VkDeviceQueueInfo2 *pQueueInfo,
- VkQueue *pQueue)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- struct tu_queue *queue;
-
- queue =
- &device->queues[pQueueInfo->queueFamilyIndex][pQueueInfo->queueIndex];
- if (pQueueInfo->flags != queue->flags) {
- /* From the Vulkan 1.1.70 spec:
- *
- * "The queue returned by vkGetDeviceQueue2 must have the same
- * flags value from this structure as that used at device
- * creation time in a VkDeviceQueueCreateInfo instance. If no
- * matching flags were specified at device creation time then
- * pQueue will return VK_NULL_HANDLE."
- */
- *pQueue = VK_NULL_HANDLE;
- return;
- }
-
- *pQueue = tu_queue_to_handle(queue);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_QueueWaitIdle(VkQueue _queue)
-{
- TU_FROM_HANDLE(tu_queue, queue, _queue);
-
- if (tu_device_is_lost(queue->device))
- return VK_ERROR_DEVICE_LOST;
-
- if (queue->fence < 0)
- return VK_SUCCESS;
-
- pthread_mutex_lock(&queue->device->submit_mutex);
-
- do {
- tu_device_submit_deferred_locked(queue->device);
-
- if (list_is_empty(&queue->queued_submits))
- break;
-
- pthread_cond_wait(&queue->device->timeline_cond,
- &queue->device->submit_mutex);
- } while (!list_is_empty(&queue->queued_submits));
-
- pthread_mutex_unlock(&queue->device->submit_mutex);
-
- struct pollfd fds = { .fd = queue->fence, .events = POLLIN };
- int ret;
- do {
- ret = poll(&fds, 1, -1);
- } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
-
- /* TODO: otherwise set device lost ? */
- assert(ret == 1 && !(fds.revents & (POLLERR | POLLNVAL)));
-
- close(queue->fence);
- queue->fence = -1;
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_DeviceWaitIdle(VkDevice _device)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
-
- if (tu_device_is_lost(device))
- return VK_ERROR_DEVICE_LOST;
-
- for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
- for (unsigned q = 0; q < device->queue_count[i]; q++) {
- tu_QueueWaitIdle(tu_queue_to_handle(&device->queues[i][q]));
- }
- }
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_EnumerateInstanceExtensionProperties(const char *pLayerName,
- uint32_t *pPropertyCount,
- VkExtensionProperties *pProperties)
-{
- if (pLayerName)
- return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
-
- return vk_enumerate_instance_extension_properties(
- &tu_instance_extensions_supported, pPropertyCount, pProperties);
-}
-
-VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
-tu_GetInstanceProcAddr(VkInstance _instance, const char *pName)
-{
- TU_FROM_HANDLE(tu_instance, instance, _instance);
- return vk_instance_get_proc_addr(&instance->vk,
- &tu_instance_entrypoints,
- pName);
-}
-
-/* The loader wants us to expose a second GetInstanceProcAddr function
- * to work around certain LD_PRELOAD issues seen in apps.
- */
-PUBLIC
-VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
-vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName);
-
-PUBLIC
-VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
-vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
-{
- return tu_GetInstanceProcAddr(instance, pName);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_AllocateMemory(VkDevice _device,
- const VkMemoryAllocateInfo *pAllocateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkDeviceMemory *pMem)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- struct tu_device_memory *mem;
- VkResult result;
-
- assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
-
- if (pAllocateInfo->allocationSize == 0) {
- /* Apparently, this is allowed */
- *pMem = VK_NULL_HANDLE;
- return VK_SUCCESS;
- }
-
- struct tu_memory_heap *mem_heap = &device->physical_device->heap;
- uint64_t mem_heap_used = p_atomic_read(&mem_heap->used);
- if (mem_heap_used > mem_heap->size)
- return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
-
- mem = vk_object_alloc(&device->vk, pAllocator, sizeof(*mem),
- VK_OBJECT_TYPE_DEVICE_MEMORY);
- if (mem == NULL)
- return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-
- const VkImportMemoryFdInfoKHR *fd_info =
- vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
- if (fd_info && !fd_info->handleType)
- fd_info = NULL;
-
- if (fd_info) {
- assert(fd_info->handleType ==
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
- fd_info->handleType ==
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
-
- /*
- * TODO Importing the same fd twice gives us the same handle without
- * reference counting. We need to maintain a per-instance handle-to-bo
- * table and add reference count to tu_bo.
- */
- result = tu_bo_init_dmabuf(device, &mem->bo,
- pAllocateInfo->allocationSize, fd_info->fd);
- if (result == VK_SUCCESS) {
- /* take ownership and close the fd */
- close(fd_info->fd);
- }
- } else {
- result =
- tu_bo_init_new(device, &mem->bo, pAllocateInfo->allocationSize,
- TU_BO_ALLOC_NO_FLAGS);
- }
-
-
- if (result == VK_SUCCESS) {
- mem_heap_used = p_atomic_add_return(&mem_heap->used, mem->bo.size);
- if (mem_heap_used > mem_heap->size) {
- p_atomic_add(&mem_heap->used, -mem->bo.size);
- tu_bo_finish(device, &mem->bo);
- result = vk_errorf(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY,
- "Out of heap memory");
- }
- }
-
- if (result != VK_SUCCESS) {
- vk_object_free(&device->vk, pAllocator, mem);
- return result;
- }
-
- *pMem = tu_device_memory_to_handle(mem);
-
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_FreeMemory(VkDevice _device,
- VkDeviceMemory _mem,
- const VkAllocationCallbacks *pAllocator)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_device_memory, mem, _mem);
-
- if (mem == NULL)
- return;
-
- p_atomic_add(&device->physical_device->heap.used, -mem->bo.size);
- tu_bo_finish(device, &mem->bo);
- vk_object_free(&device->vk, pAllocator, mem);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_MapMemory(VkDevice _device,
- VkDeviceMemory _memory,
- VkDeviceSize offset,
- VkDeviceSize size,
- VkMemoryMapFlags flags,
- void **ppData)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_device_memory, mem, _memory);
- VkResult result;
-
- if (mem == NULL) {
- *ppData = NULL;
- return VK_SUCCESS;
- }
-
- if (!mem->bo.map) {
- result = tu_bo_map(device, &mem->bo);
- if (result != VK_SUCCESS)
- return result;
- }
-
- *ppData = mem->bo.map + offset;
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_UnmapMemory(VkDevice _device, VkDeviceMemory _memory)
-{
- /* TODO: unmap here instead of waiting for FreeMemory */
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_FlushMappedMemoryRanges(VkDevice _device,
- uint32_t memoryRangeCount,
- const VkMappedMemoryRange *pMemoryRanges)
-{
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_InvalidateMappedMemoryRanges(VkDevice _device,
- uint32_t memoryRangeCount,
- const VkMappedMemoryRange *pMemoryRanges)
-{
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetBufferMemoryRequirements2(
- VkDevice device,
- const VkBufferMemoryRequirementsInfo2 *pInfo,
- VkMemoryRequirements2 *pMemoryRequirements)
-{
- TU_FROM_HANDLE(tu_buffer, buffer, pInfo->buffer);
-
- pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
- .memoryTypeBits = 1,
- .alignment = 64,
- .size = MAX2(align64(buffer->size, 64), buffer->size),
- };
-
- vk_foreach_struct(ext, pMemoryRequirements->pNext) {
- switch (ext->sType) {
- case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
- VkMemoryDedicatedRequirements *req =
- (VkMemoryDedicatedRequirements *) ext;
- req->requiresDedicatedAllocation = false;
- req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
- break;
- }
- default:
- break;
- }
- }
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetImageMemoryRequirements2(VkDevice device,
- const VkImageMemoryRequirementsInfo2 *pInfo,
- VkMemoryRequirements2 *pMemoryRequirements)
-{
- TU_FROM_HANDLE(tu_image, image, pInfo->image);
-
- pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {
- .memoryTypeBits = 1,
- .alignment = image->layout[0].base_align,
- .size = image->total_size
- };
-
- vk_foreach_struct(ext, pMemoryRequirements->pNext) {
- switch (ext->sType) {
- case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
- VkMemoryDedicatedRequirements *req =
- (VkMemoryDedicatedRequirements *) ext;
- req->requiresDedicatedAllocation = image->shareable;
- req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
- break;
- }
- default:
- break;
- }
- }
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetImageSparseMemoryRequirements2(
- VkDevice device,
- const VkImageSparseMemoryRequirementsInfo2 *pInfo,
- uint32_t *pSparseMemoryRequirementCount,
- VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
-{
- tu_stub();
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetDeviceMemoryCommitment(VkDevice device,
- VkDeviceMemory memory,
- VkDeviceSize *pCommittedMemoryInBytes)
-{
- *pCommittedMemoryInBytes = 0;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_BindBufferMemory2(VkDevice device,
- uint32_t bindInfoCount,
- const VkBindBufferMemoryInfo *pBindInfos)
-{
- for (uint32_t i = 0; i < bindInfoCount; ++i) {
- TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory);
- TU_FROM_HANDLE(tu_buffer, buffer, pBindInfos[i].buffer);
-
- if (mem) {
- buffer->bo = &mem->bo;
- buffer->bo_offset = pBindInfos[i].memoryOffset;
- } else {
- buffer->bo = NULL;
- }
- }
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_BindImageMemory2(VkDevice device,
- uint32_t bindInfoCount,
- const VkBindImageMemoryInfo *pBindInfos)
-{
- for (uint32_t i = 0; i < bindInfoCount; ++i) {
- TU_FROM_HANDLE(tu_image, image, pBindInfos[i].image);
- TU_FROM_HANDLE(tu_device_memory, mem, pBindInfos[i].memory);
-
- if (mem) {
- image->bo = &mem->bo;
- image->bo_offset = pBindInfos[i].memoryOffset;
- } else {
- image->bo = NULL;
- image->bo_offset = 0;
- }
- }
-
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_QueueBindSparse(VkQueue _queue,
- uint32_t bindInfoCount,
- const VkBindSparseInfo *pBindInfo,
- VkFence _fence)
-{
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_CreateEvent(VkDevice _device,
- const VkEventCreateInfo *pCreateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkEvent *pEvent)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
-
- struct tu_event *event =
- vk_object_alloc(&device->vk, pAllocator, sizeof(*event),
- VK_OBJECT_TYPE_EVENT);
- if (!event)
- return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-
- VkResult result = tu_bo_init_new(device, &event->bo, 0x1000,
- TU_BO_ALLOC_NO_FLAGS);
- if (result != VK_SUCCESS)
- goto fail_alloc;
-
- result = tu_bo_map(device, &event->bo);
- if (result != VK_SUCCESS)
- goto fail_map;
-
- *pEvent = tu_event_to_handle(event);
-
- return VK_SUCCESS;
-
-fail_map:
- tu_bo_finish(device, &event->bo);
-fail_alloc:
- vk_object_free(&device->vk, pAllocator, event);
- return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_DestroyEvent(VkDevice _device,
- VkEvent _event,
- const VkAllocationCallbacks *pAllocator)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_event, event, _event);
-
- if (!event)
- return;
-
- tu_bo_finish(device, &event->bo);
- vk_object_free(&device->vk, pAllocator, event);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_GetEventStatus(VkDevice _device, VkEvent _event)
-{
- TU_FROM_HANDLE(tu_event, event, _event);
-
- if (*(uint64_t*) event->bo.map == 1)
- return VK_EVENT_SET;
- return VK_EVENT_RESET;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_SetEvent(VkDevice _device, VkEvent _event)
-{
- TU_FROM_HANDLE(tu_event, event, _event);
- *(uint64_t*) event->bo.map = 1;
-
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_ResetEvent(VkDevice _device, VkEvent _event)
-{
- TU_FROM_HANDLE(tu_event, event, _event);
- *(uint64_t*) event->bo.map = 0;
-
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_CreateBuffer(VkDevice _device,
- const VkBufferCreateInfo *pCreateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkBuffer *pBuffer)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- struct tu_buffer *buffer;
-
- assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
-
- buffer = vk_object_alloc(&device->vk, pAllocator, sizeof(*buffer),
- VK_OBJECT_TYPE_BUFFER);
- if (buffer == NULL)
- return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-
- buffer->size = pCreateInfo->size;
- buffer->usage = pCreateInfo->usage;
- buffer->flags = pCreateInfo->flags;
-
- *pBuffer = tu_buffer_to_handle(buffer);
-
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_DestroyBuffer(VkDevice _device,
- VkBuffer _buffer,
- const VkAllocationCallbacks *pAllocator)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_buffer, buffer, _buffer);
-
- if (!buffer)
- return;
-
- vk_object_free(&device->vk, pAllocator, buffer);
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_CreateFramebuffer(VkDevice _device,
- const VkFramebufferCreateInfo *pCreateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkFramebuffer *pFramebuffer)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_render_pass, pass, pCreateInfo->renderPass);
- struct tu_framebuffer *framebuffer;
-
- assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
-
- size_t size = sizeof(*framebuffer) + sizeof(struct tu_attachment_info) *
- pCreateInfo->attachmentCount;
- framebuffer = vk_object_alloc(&device->vk, pAllocator, size,
- VK_OBJECT_TYPE_FRAMEBUFFER);
- if (framebuffer == NULL)
- return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-
- framebuffer->attachment_count = pCreateInfo->attachmentCount;
- framebuffer->width = pCreateInfo->width;
- framebuffer->height = pCreateInfo->height;
- framebuffer->layers = pCreateInfo->layers;
- for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
- VkImageView _iview = pCreateInfo->pAttachments[i];
- struct tu_image_view *iview = tu_image_view_from_handle(_iview);
- framebuffer->attachments[i].attachment = iview;
- }
-
- tu_framebuffer_tiling_config(framebuffer, device, pass);
-
- *pFramebuffer = tu_framebuffer_to_handle(framebuffer);
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_DestroyFramebuffer(VkDevice _device,
- VkFramebuffer _fb,
- const VkAllocationCallbacks *pAllocator)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_framebuffer, fb, _fb);
-
- if (!fb)
- return;
-
- vk_object_free(&device->vk, pAllocator, fb);
-}
-
-static void
-tu_init_sampler(struct tu_device *device,
- struct tu_sampler *sampler,
- const VkSamplerCreateInfo *pCreateInfo)
-{
- const struct VkSamplerReductionModeCreateInfo *reduction =
- vk_find_struct_const(pCreateInfo->pNext, SAMPLER_REDUCTION_MODE_CREATE_INFO);
- const struct VkSamplerYcbcrConversionInfo *ycbcr_conversion =
- vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO);
- const VkSamplerCustomBorderColorCreateInfoEXT *custom_border_color =
- vk_find_struct_const(pCreateInfo->pNext, SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
- /* for non-custom border colors, the VK enum is translated directly to an offset in
- * the border color buffer. custom border colors are located immediately after the
- * builtin colors, and thus an offset of TU_BORDER_COLOR_BUILTIN is added.
- */
- uint32_t border_color = (unsigned) pCreateInfo->borderColor;
- if (pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT ||
- pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT) {
- mtx_lock(&device->mutex);
- border_color = BITSET_FFS(device->custom_border_color);
- BITSET_CLEAR(device->custom_border_color, border_color);
- mtx_unlock(&device->mutex);
- tu6_pack_border_color(device->global_bo.map + gb_offset(bcolor[border_color]),
- &custom_border_color->customBorderColor,
- pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
- border_color += TU_BORDER_COLOR_BUILTIN;
- }
-
- unsigned aniso = pCreateInfo->anisotropyEnable ?
- util_last_bit(MIN2((uint32_t)pCreateInfo->maxAnisotropy >> 1, 8)) : 0;
- bool miplinear = (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR);
- float min_lod = CLAMP(pCreateInfo->minLod, 0.0f, 4095.0f / 256.0f);
- float max_lod = CLAMP(pCreateInfo->maxLod, 0.0f, 4095.0f / 256.0f);
-
- sampler->descriptor[0] =
- COND(miplinear, A6XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) |
- A6XX_TEX_SAMP_0_XY_MAG(tu6_tex_filter(pCreateInfo->magFilter, aniso)) |
- A6XX_TEX_SAMP_0_XY_MIN(tu6_tex_filter(pCreateInfo->minFilter, aniso)) |
- A6XX_TEX_SAMP_0_ANISO(aniso) |
- A6XX_TEX_SAMP_0_WRAP_S(tu6_tex_wrap(pCreateInfo->addressModeU)) |
- A6XX_TEX_SAMP_0_WRAP_T(tu6_tex_wrap(pCreateInfo->addressModeV)) |
- A6XX_TEX_SAMP_0_WRAP_R(tu6_tex_wrap(pCreateInfo->addressModeW)) |
- A6XX_TEX_SAMP_0_LOD_BIAS(pCreateInfo->mipLodBias);
- sampler->descriptor[1] =
- /* COND(!cso->seamless_cube_map, A6XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF) | */
- COND(pCreateInfo->unnormalizedCoordinates, A6XX_TEX_SAMP_1_UNNORM_COORDS) |
- A6XX_TEX_SAMP_1_MIN_LOD(min_lod) |
- A6XX_TEX_SAMP_1_MAX_LOD(max_lod) |
- COND(pCreateInfo->compareEnable,
- A6XX_TEX_SAMP_1_COMPARE_FUNC(tu6_compare_func(pCreateInfo->compareOp)));
- sampler->descriptor[2] = A6XX_TEX_SAMP_2_BCOLOR(border_color);
- sampler->descriptor[3] = 0;
-
- if (reduction) {
- sampler->descriptor[2] |= A6XX_TEX_SAMP_2_REDUCTION_MODE(
- tu6_reduction_mode(reduction->reductionMode));
- }
-
- sampler->ycbcr_sampler = ycbcr_conversion ?
- tu_sampler_ycbcr_conversion_from_handle(ycbcr_conversion->conversion) : NULL;
-
- if (sampler->ycbcr_sampler &&
- sampler->ycbcr_sampler->chroma_filter == VK_FILTER_LINEAR) {
- sampler->descriptor[2] |= A6XX_TEX_SAMP_2_CHROMA_LINEAR;
- }
-
- /* TODO:
- * A6XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR disables mipmapping, but vk has no NONE mipfilter?
- */
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_CreateSampler(VkDevice _device,
- const VkSamplerCreateInfo *pCreateInfo,
- const VkAllocationCallbacks *pAllocator,
- VkSampler *pSampler)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- struct tu_sampler *sampler;
-
- assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
-
- sampler = vk_object_alloc(&device->vk, pAllocator, sizeof(*sampler),
- VK_OBJECT_TYPE_SAMPLER);
- if (!sampler)
- return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-
- tu_init_sampler(device, sampler, pCreateInfo);
- *pSampler = tu_sampler_to_handle(sampler);
-
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_DestroySampler(VkDevice _device,
- VkSampler _sampler,
- const VkAllocationCallbacks *pAllocator)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_sampler, sampler, _sampler);
- uint32_t border_color;
-
- if (!sampler)
- return;
-
- border_color = (sampler->descriptor[2] & A6XX_TEX_SAMP_2_BCOLOR__MASK) >> A6XX_TEX_SAMP_2_BCOLOR__SHIFT;
- if (border_color >= TU_BORDER_COLOR_BUILTIN) {
- border_color -= TU_BORDER_COLOR_BUILTIN;
- /* if the sampler had a custom border color, free it. TODO: no lock */
- mtx_lock(&device->mutex);
- assert(!BITSET_TEST(device->custom_border_color, border_color));
- BITSET_SET(device->custom_border_color, border_color);
- mtx_unlock(&device->mutex);
- }
-
- vk_object_free(&device->vk, pAllocator, sampler);
-}
-
-/* vk_icd.h does not declare this function, so we declare it here to
- * suppress Wmissing-prototypes.
- */
-PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
-vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion);
-
-PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
-vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion)
-{
- /* For the full details on loader interface versioning, see
- * <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
- * What follows is a condensed summary, to help you navigate the large and
- * confusing official doc.
- *
- * - Loader interface v0 is incompatible with later versions. We don't
- * support it.
- *
- * - In loader interface v1:
- * - The first ICD entrypoint called by the loader is
- * vk_icdGetInstanceProcAddr(). The ICD must statically expose this
- * entrypoint.
- * - The ICD must statically expose no other Vulkan symbol unless it
- * is linked with -Bsymbolic.
- * - Each dispatchable Vulkan handle created by the ICD must be
- * a pointer to a struct whose first member is VK_LOADER_DATA. The
- * ICD must initialize VK_LOADER_DATA.loadMagic to
- * ICD_LOADER_MAGIC.
- * - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
- * vkDestroySurfaceKHR(). The ICD must be capable of working with
- * such loader-managed surfaces.
- *
- * - Loader interface v2 differs from v1 in:
- * - The first ICD entrypoint called by the loader is
- * vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
- * statically expose this entrypoint.
- *
- * - Loader interface v3 differs from v2 in:
- * - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
- * vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
- * because the loader no longer does so.
- */
- *pSupportedVersion = MIN2(*pSupportedVersion, 3u);
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_GetMemoryFdKHR(VkDevice _device,
- const VkMemoryGetFdInfoKHR *pGetFdInfo,
- int *pFd)
-{
- TU_FROM_HANDLE(tu_device, device, _device);
- TU_FROM_HANDLE(tu_device_memory, memory, pGetFdInfo->memory);
-
- assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
-
- /* At the moment, we support only the below handle types. */
- assert(pGetFdInfo->handleType ==
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
- pGetFdInfo->handleType ==
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
-
- int prime_fd = tu_bo_export_dmabuf(device, &memory->bo);
- if (prime_fd < 0)
- return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
-
- *pFd = prime_fd;
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR VkResult VKAPI_CALL
-tu_GetMemoryFdPropertiesKHR(VkDevice _device,
- VkExternalMemoryHandleTypeFlagBits handleType,
- int fd,
- VkMemoryFdPropertiesKHR *pMemoryFdProperties)
-{
- assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
- pMemoryFdProperties->memoryTypeBits = 1;
- return VK_SUCCESS;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetPhysicalDeviceExternalFenceProperties(
- VkPhysicalDevice physicalDevice,
- const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
- VkExternalFenceProperties *pExternalFenceProperties)
-{
- pExternalFenceProperties->exportFromImportedHandleTypes = 0;
- pExternalFenceProperties->compatibleHandleTypes = 0;
- pExternalFenceProperties->externalFenceFeatures = 0;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetDeviceGroupPeerMemoryFeatures(
- VkDevice device,
- uint32_t heapIndex,
- uint32_t localDeviceIndex,
- uint32_t remoteDeviceIndex,
- VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
-{
- assert(localDeviceIndex == remoteDeviceIndex);
-
- *pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT |
- VK_PEER_MEMORY_FEATURE_COPY_DST_BIT |
- VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
- VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
-}
-
-VKAPI_ATTR void VKAPI_CALL
-tu_GetPhysicalDeviceMultisamplePropertiesEXT(
- VkPhysicalDevice physicalDevice,
- VkSampleCountFlagBits samples,
- VkMultisamplePropertiesEXT* pMultisampleProperties)
-{
- TU_FROM_HANDLE(tu_physical_device, pdevice, physicalDevice);
-
- if (samples <= VK_SAMPLE_COUNT_4_BIT && pdevice->vk.supported_extensions.EXT_sample_locations)
- pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 1, 1 };
- else
- pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 0, 0 };
-}