radv: Expose VK_EXT_ycbcr_image_arrays.
[mesa.git] / src / amd / vulkan / radv_device.c
index c2de61c935d1bd26b7a3ea5c8d31db4248385b9d..b7f991fce72c8a9f4ef28f53125f5e59af14105a 100644 (file)
@@ -48,6 +48,8 @@
 #include "util/build_id.h"
 #include "util/debug.h"
 #include "util/mesa-sha1.h"
+#include "compiler/glsl_types.h"
+#include "util/xmlpool.h"
 
 static int
 radv_device_get_cache_uuid(enum radeon_family family, void *uuid)
@@ -87,7 +89,6 @@ static void
 radv_get_device_name(enum radeon_family family, char *name, size_t name_len)
 {
        const char *chip_string;
-       char llvm_string[32] = {};
 
        switch (family) {
        case CHIP_TAHITI: chip_string = "AMD RADV TAHITI"; break;
@@ -116,10 +117,7 @@ radv_get_device_name(enum radeon_family family, char *name, size_t name_len)
        default: chip_string = "AMD RADV unknown"; break;
        }
 
-       snprintf(llvm_string, sizeof(llvm_string),
-                " (LLVM %i.%i.%i)", (HAVE_LLVM >> 8) & 0xff,
-                HAVE_LLVM & 0xff, MESA_LLVM_VERSION_PATCH);
-       snprintf(name, name_len, "%s%s", chip_string, llvm_string);
+       snprintf(name, name_len, "%s (LLVM " MESA_LLVM_VERSION_STRING ")", chip_string);
 }
 
 static uint64_t
@@ -337,7 +335,7 @@ radv_physical_device_init(struct radv_physical_device *device,
            device->rad_info.chip_class > GFX9)
                fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");
 
-       radv_get_driver_uuid(&device->device_uuid);
+       radv_get_driver_uuid(&device->driver_uuid);
        radv_get_device_uuid(&device->rad_info, &device->device_uuid);
 
        if (device->rad_info.family == CHIP_STONEY ||
@@ -369,6 +367,11 @@ radv_physical_device_init(struct radv_physical_device *device,
        device->dcc_msaa_allowed =
                (device->instance->perftest_flags & RADV_PERFTEST_DCC_MSAA);
 
+       /* TODO: Figure out how to use LOAD_CONTEXT_REG on SI/CIK. */
+       device->has_load_ctx_reg_pkt = device->rad_info.chip_class >= GFX9 ||
+                                      (device->rad_info.chip_class >= VI &&
+                                       device->rad_info.me_fw_feature >= 41);
+
        radv_physical_device_init_mem_types(device);
        radv_fill_device_extension_table(device, &device->supported_extensions);
 
@@ -475,6 +478,7 @@ static const struct debug_control radv_perftest_options[] = {
        {"sisched", RADV_PERFTEST_SISCHED},
        {"localbos", RADV_PERFTEST_LOCAL_BOS},
        {"dccmsaa", RADV_PERFTEST_DCC_MSAA},
+       {"bolist", RADV_PERFTEST_BO_LIST},
        {NULL, 0}
 };
 
@@ -517,6 +521,20 @@ static int radv_get_instance_extension_index(const char *name)
        return -1;
 }
 
+static const char radv_dri_options_xml[] =
+DRI_CONF_BEGIN
+       DRI_CONF_SECTION_QUALITY
+               DRI_CONF_ADAPTIVE_SYNC("true")
+       DRI_CONF_SECTION_END
+DRI_CONF_END;
+
+static void  radv_init_dri_options(struct radv_instance *instance)
+{
+       driParseOptionInfo(&instance->available_dri_options, radv_dri_options_xml);
+       driParseConfigFiles(&instance->dri_options,
+                           &instance->available_dri_options,
+                           0, "radv", NULL);
+}
 
 VkResult radv_CreateInstance(
        const VkInstanceCreateInfo*                 pCreateInfo,
@@ -533,7 +551,7 @@ VkResult radv_CreateInstance(
            pCreateInfo->pApplicationInfo->apiVersion != 0) {
                client_version = pCreateInfo->pApplicationInfo->apiVersion;
        } else {
-               radv_EnumerateInstanceVersion(&client_version);
+               client_version = VK_API_VERSION_1_0;
        }
 
        instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
@@ -580,9 +598,11 @@ VkResult radv_CreateInstance(
        }
 
        _mesa_locale_init();
+       glsl_type_singleton_init_or_ref();
 
        VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
 
+       radv_init_dri_options(instance);
        radv_handle_per_app_options(instance, pCreateInfo->pApplicationInfo);
 
        *pInstance = radv_instance_to_handle(instance);
@@ -605,8 +625,12 @@ void radv_DestroyInstance(
 
        VG(VALGRIND_DESTROY_MEMPOOL(instance));
 
+       glsl_type_singleton_decref();
        _mesa_locale_fini();
 
+       driDestroyOptionCache(&instance->dri_options);
+       driDestroyOptionInfo(&instance->available_dri_options);
+
        vk_debug_report_instance_destroy(&instance->debug_report_callbacks);
 
        vk_free(&instance->alloc, instance);
@@ -734,8 +758,7 @@ void radv_GetPhysicalDeviceFeatures(
                .alphaToOne                               = true,
                .multiViewport                            = true,
                .samplerAnisotropy                        = true,
-               .textureCompressionETC2                   = pdevice->rad_info.chip_class >= GFX9 ||
-                                                           pdevice->rad_info.family == CHIP_STONEY,
+               .textureCompressionETC2                   = radv_device_supports_etc(pdevice),
                .textureCompressionASTC_LDR               = false,
                .textureCompressionBC                     = true,
                .occlusionQueryPrecise                    = true,
@@ -802,13 +825,13 @@ void radv_GetPhysicalDeviceFeatures2(
                        features->storageBuffer16BitAccess = enabled;
                        features->uniformAndStorageBuffer16BitAccess = enabled;
                        features->storagePushConstant16 = enabled;
-                       features->storageInputOutput16 = enabled;
+                       features->storageInputOutput16 = enabled && HAVE_LLVM >= 0x900;
                        break;
                }
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
                        VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =
                            (VkPhysicalDeviceSamplerYcbcrConversionFeatures*)ext;
-                       features->samplerYcbcrConversion = false;
+                       features->samplerYcbcrConversion = true;
                        break;
                }
                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
@@ -817,13 +840,13 @@ void radv_GetPhysicalDeviceFeatures2(
                        features->shaderInputAttachmentArrayDynamicIndexing = true;
                        features->shaderUniformTexelBufferArrayDynamicIndexing = true;
                        features->shaderStorageTexelBufferArrayDynamicIndexing = true;
-                       features->shaderUniformBufferArrayNonUniformIndexing = false;
-                       features->shaderSampledImageArrayNonUniformIndexing = false;
-                       features->shaderStorageBufferArrayNonUniformIndexing = false;
-                       features->shaderStorageImageArrayNonUniformIndexing = false;
-                       features->shaderInputAttachmentArrayNonUniformIndexing = false;
-                       features->shaderUniformTexelBufferArrayNonUniformIndexing = false;
-                       features->shaderStorageTexelBufferArrayNonUniformIndexing = false;
+                       features->shaderUniformBufferArrayNonUniformIndexing = true;
+                       features->shaderSampledImageArrayNonUniformIndexing = true;
+                       features->shaderStorageBufferArrayNonUniformIndexing = true;
+                       features->shaderStorageImageArrayNonUniformIndexing = true;
+                       features->shaderInputAttachmentArrayNonUniformIndexing = true;
+                       features->shaderUniformTexelBufferArrayNonUniformIndexing = true;
+                       features->shaderStorageTexelBufferArrayNonUniformIndexing = true;
                        features->descriptorBindingUniformBufferUpdateAfterBind = true;
                        features->descriptorBindingSampledImageUpdateAfterBind = true;
                        features->descriptorBindingStorageImageUpdateAfterBind = true;
@@ -863,6 +886,79 @@ void radv_GetPhysicalDeviceFeatures2(
                        features->scalarBlockLayout = pdevice->rad_info.chip_class >= CIK;
                        break;
                }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT: {
+                       VkPhysicalDeviceMemoryPriorityFeaturesEXT *features =
+                               (VkPhysicalDeviceMemoryPriorityFeaturesEXT *)ext;
+                       features->memoryPriority = VK_TRUE;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT: {
+                       VkPhysicalDeviceBufferAddressFeaturesEXT *features =
+                               (VkPhysicalDeviceBufferAddressFeaturesEXT *)ext;
+                       features->bufferDeviceAddress = true;
+                       features->bufferDeviceAddressCaptureReplay = false;
+                       features->bufferDeviceAddressMultiDevice = false;
+                       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_HOST_QUERY_RESET_FEATURES_EXT: {
+                       VkPhysicalDeviceHostQueryResetFeaturesEXT *features =
+                               (VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;
+                       features->hostQueryReset = true;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
+                       VkPhysicalDevice8BitStorageFeaturesKHR *features =
+                           (VkPhysicalDevice8BitStorageFeaturesKHR*)ext;
+                       bool enabled = pdevice->rad_info.chip_class >= VI;
+                       features->storageBuffer8BitAccess = enabled;
+                       features->uniformAndStorageBuffer8BitAccess = enabled;
+                       features->storagePushConstant8 = enabled;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
+                       VkPhysicalDeviceFloat16Int8FeaturesKHR *features =
+                               (VkPhysicalDeviceFloat16Int8FeaturesKHR*)ext;
+                       features->shaderFloat16 = pdevice->rad_info.chip_class >= VI && HAVE_LLVM >= 0x0800;
+                       features->shaderInt8 = true;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {
+                       VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features =
+                               (VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *)ext;
+                       /* TODO: Enable this once the driver supports 64-bit
+                        * compare&swap atomic operations.
+                        */
+                       features->shaderBufferInt64Atomics = false;
+                       features->shaderSharedInt64Atomics = false;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
+                       VkPhysicalDeviceInlineUniformBlockFeaturesEXT *features =
+                               (VkPhysicalDeviceInlineUniformBlockFeaturesEXT *)ext;
+
+                       features->inlineUniformBlock = true;
+                       features->descriptorBindingInlineUniformBlockUpdateAfterBind = true;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV: {
+                       VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *features =
+                               (VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *)ext;
+                       features->computeDerivativeGroupQuads = false;
+                       features->computeDerivativeGroupLinear = true;
+                       break;
+               }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT: {
+                       VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *features =
+                               (VkPhysicalDeviceYcbcrImageArraysFeaturesEXT*)ext;
+                       features->ycbcrImageArrays = true;
+                       break;
+               }
                default:
                        break;
                }
@@ -920,8 +1016,8 @@ void radv_GetPhysicalDeviceProperties(
                .maxDescriptorSetSampledImages            = max_descriptor_set_size,
                .maxDescriptorSetStorageImages            = max_descriptor_set_size,
                .maxDescriptorSetInputAttachments         = max_descriptor_set_size,
-               .maxVertexInputAttributes                 = 32,
-               .maxVertexInputBindings                   = 32,
+               .maxVertexInputAttributes                 = MAX_VERTEX_ATTRIBS,
+               .maxVertexInputBindings                   = MAX_VBS,
                .maxVertexInputAttributeOffset            = 2047,
                .maxVertexInputBindingStride              = 2048,
                .maxVertexOutputComponents                = 128,
@@ -992,7 +1088,7 @@ void radv_GetPhysicalDeviceProperties(
                .maxCullDistances                         = 8,
                .maxCombinedClipAndCullDistances          = 8,
                .discreteQueuePriorities                  = 2,
-               .pointSizeRange                           = { 0.125, 255.875 },
+               .pointSizeRange                           = { 0.0, 8192.0 },
                .lineWidthRange                           = { 0.0, 7.9921875 },
                .pointSizeGranularity                     = (1.0 / 8.0),
                .lineWidthGranularity                     = (1.0 / 128.0),
@@ -1123,7 +1219,7 @@ void radv_GetPhysicalDeviceProperties2(
 
                        /* SGPR. */
                        properties->sgprsPerSimd =
-                               radv_get_num_physical_sgprs(pdevice);
+                               ac_get_num_physical_sgprs(pdevice->rad_info.chip_class);
                        properties->minSgprAllocation =
                                pdevice->rad_info.chip_class >= VI ? 16 : 8;
                        properties->maxSgprAllocation =
@@ -1157,7 +1253,8 @@ void radv_GetPhysicalDeviceProperties2(
                        properties->robustBufferAccessUpdateAfterBind = false;
                        properties->quadDivergentImplicitLod = false;
 
-                       size_t max_descriptor_set_size = ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS) /
+                       size_t max_descriptor_set_size = ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS -
+                               MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_INLINE_UNIFORM_BLOCK_COUNT) /
                                  (32 /* uniform buffer, 32 due to potential space wasted on alignment */ +
                                   32 /* storage buffer, 32 due to potential space wasted on alignment */ +
                                   32 /* sampler, largest when combined with image */ +
@@ -1220,9 +1317,7 @@ void radv_GetPhysicalDeviceProperties2(
                        memset(driver_props->driverInfo, 0, VK_MAX_DRIVER_INFO_SIZE_KHR);
                        snprintf(driver_props->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR,
                                "Mesa " PACKAGE_VERSION MESA_GIT_SHA1
-                               " (LLVM %d.%d.%d)",
-                                (HAVE_LLVM >> 8) & 0xff, HAVE_LLVM & 0xff,
-                                MESA_LLVM_VERSION_PATCH);
+                               " (LLVM " MESA_LLVM_VERSION_STRING ")");
 
                        driver_props->conformanceVersion = (VkConformanceVersionKHR) {
                                .major = 1,
@@ -1247,6 +1342,17 @@ void radv_GetPhysicalDeviceProperties2(
                        properties->transformFeedbackDraw = true;
                        break;
                }
+               case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: {
+                       VkPhysicalDeviceInlineUniformBlockPropertiesEXT *props =
+                               (VkPhysicalDeviceInlineUniformBlockPropertiesEXT *)ext;
+
+                       props->maxInlineUniformBlockSize = MAX_INLINE_UNIFORM_BLOCK_SIZE;
+                       props->maxPerStageDescriptorInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_SETS;
+                       props->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_SETS;
+                       props->maxDescriptorSetInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_COUNT;
+                       props->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_COUNT;
+                       break;
+               }
                default:
                        break;
                }
@@ -1545,6 +1651,9 @@ static VkResult radv_bo_list_add(struct radv_device *device,
 {
        struct radv_bo_list *bo_list = &device->bo_list;
 
+       if (bo->is_local)
+               return VK_SUCCESS;
+
        if (unlikely(!device->use_global_bo_list))
                return VK_SUCCESS;
 
@@ -1572,6 +1681,9 @@ static void radv_bo_list_remove(struct radv_device *device,
 {
        struct radv_bo_list *bo_list = &device->bo_list;
 
+       if (bo->is_local)
+               return;
+
        if (unlikely(!device->use_global_bo_list))
                return;
 
@@ -1682,7 +1794,9 @@ VkResult radv_CreateDevice(
         * from the descriptor set anymore, so we have to use a global BO list.
         */
        device->use_global_bo_list =
-               device->enabled_extensions.EXT_descriptor_indexing;
+               (device->instance->perftest_flags & RADV_PERFTEST_BO_LIST) ||
+               device->enabled_extensions.EXT_descriptor_indexing ||
+               device->enabled_extensions.EXT_buffer_device_address;
 
        mtx_init(&device->shader_slab_mutex, mtx_plain);
        list_inithead(&device->shader_slabs);
@@ -2373,7 +2487,8 @@ radv_get_preamble_cs(struct radv_queue *queue,
                                                              scratch_size,
                                                              4096,
                                                              RADEON_DOMAIN_VRAM,
-                                                             ring_bo_flags);
+                                                             ring_bo_flags,
+                                                             RADV_BO_PRIORITY_SCRATCH);
                if (!scratch_bo)
                        goto fail;
        } else
@@ -2384,7 +2499,8 @@ radv_get_preamble_cs(struct radv_queue *queue,
                                                                      compute_scratch_size,
                                                                      4096,
                                                                      RADEON_DOMAIN_VRAM,
-                                                                     ring_bo_flags);
+                                                                     ring_bo_flags,
+                                                                     RADV_BO_PRIORITY_SCRATCH);
                if (!compute_scratch_bo)
                        goto fail;
 
@@ -2396,7 +2512,8 @@ radv_get_preamble_cs(struct radv_queue *queue,
                                                                esgs_ring_size,
                                                                4096,
                                                                RADEON_DOMAIN_VRAM,
-                                                               ring_bo_flags);
+                                                               ring_bo_flags,
+                                                               RADV_BO_PRIORITY_SCRATCH);
                if (!esgs_ring_bo)
                        goto fail;
        } else {
@@ -2409,7 +2526,8 @@ radv_get_preamble_cs(struct radv_queue *queue,
                                                                gsvs_ring_size,
                                                                4096,
                                                                RADEON_DOMAIN_VRAM,
-                                                               ring_bo_flags);
+                                                               ring_bo_flags,
+                                                               RADV_BO_PRIORITY_SCRATCH);
                if (!gsvs_ring_bo)
                        goto fail;
        } else {
@@ -2422,7 +2540,8 @@ radv_get_preamble_cs(struct radv_queue *queue,
                                                                 tess_offchip_ring_offset + tess_offchip_ring_size,
                                                                 256,
                                                                 RADEON_DOMAIN_VRAM,
-                                                                ring_bo_flags);
+                                                                ring_bo_flags,
+                                                                RADV_BO_PRIORITY_SCRATCH);
                if (!tess_rings_bo)
                        goto fail;
        } else {
@@ -2450,7 +2569,8 @@ radv_get_preamble_cs(struct radv_queue *queue,
                                                                 RADEON_DOMAIN_VRAM,
                                                                 RADEON_FLAG_CPU_ACCESS |
                                                                 RADEON_FLAG_NO_INTERPROCESS_SHARING |
-                                                                RADEON_FLAG_READ_ONLY);
+                                                                RADEON_FLAG_READ_ONLY,
+                                                                RADV_BO_PRIORITY_DESCRIPTOR);
                if (!descriptor_bo)
                        goto fail;
        } else
@@ -2778,7 +2898,7 @@ VkResult radv_QueueSubmit(
        struct radeon_winsys_fence *base_fence = fence ? fence->fence : NULL;
        struct radeon_winsys_ctx *ctx = queue->hw_ctx;
        int ret;
-       uint32_t max_cs_submission = queue->device->trace_bo ? 1 : UINT32_MAX;
+       uint32_t max_cs_submission = queue->device->trace_bo ? 1 : RADV_MAX_IBS_PER_SUBMIT;
        uint32_t scratch_size = 0;
        uint32_t compute_scratch_size = 0;
        uint32_t esgs_ring_size = 0, gsvs_ring_size = 0;
@@ -3080,6 +3200,16 @@ static VkResult radv_alloc_memory(struct radv_device *device,
                mem->buffer = NULL;
        }
 
+       float priority_float = 0.5;
+       const struct VkMemoryPriorityAllocateInfoEXT *priority_ext =
+               vk_find_struct_const(pAllocateInfo->pNext,
+                                    MEMORY_PRIORITY_ALLOCATE_INFO_EXT);
+       if (priority_ext)
+               priority_float = priority_ext->priority;
+
+       unsigned priority = MIN2(RADV_BO_PRIORITY_APPLICATION_MAX - 1,
+                                (int)(priority_float * RADV_BO_PRIORITY_APPLICATION_MAX));
+
        mem->user_ptr = NULL;
 
        if (import_info) {
@@ -3088,7 +3218,7 @@ static VkResult radv_alloc_memory(struct radv_device *device,
                       import_info->handleType ==
                       VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
                mem->bo = device->ws->buffer_from_fd(device->ws, import_info->fd,
-                                                    NULL, NULL);
+                                                    priority, NULL, NULL);
                if (!mem->bo) {
                        result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
                        goto fail;
@@ -3099,7 +3229,8 @@ static VkResult radv_alloc_memory(struct radv_device *device,
                assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
                assert(mem_type_index == RADV_MEM_TYPE_GTT_CACHED);
                mem->bo = device->ws->buffer_from_ptr(device->ws, host_ptr_info->pHostPointer,
-                                                     pAllocateInfo->allocationSize);
+                                                     pAllocateInfo->allocationSize,
+                                                     priority);
                if (!mem->bo) {
                        result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
                        goto fail;
@@ -3122,11 +3253,15 @@ static VkResult radv_alloc_memory(struct radv_device *device,
                if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE)
                        flags |= RADEON_FLAG_GTT_WC;
 
-               if (!dedicate_info && !import_info && (!export_info || !export_info->handleTypes))
+               if (!dedicate_info && !import_info && (!export_info || !export_info->handleTypes)) {
                        flags |= RADEON_FLAG_NO_INTERPROCESS_SHARING;
+                       if (device->use_global_bo_list) {
+                               flags |= RADEON_FLAG_PREFER_LOCAL_BO;
+                       }
+               }
 
                mem->bo = device->ws->buffer_create(device->ws, alloc_size, device->physical_device->rad_info.max_alignment,
-                                                   domain, flags);
+                                                   domain, flags, priority);
 
                if (!mem->bo) {
                        result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
@@ -3593,7 +3728,7 @@ void radv_DestroyFence(
 }
 
 
-static uint64_t radv_get_current_time()
+uint64_t radv_get_current_time(void)
 {
        struct timespec tv;
        clock_gettime(CLOCK_MONOTONIC, &tv);
@@ -3886,7 +4021,8 @@ VkResult radv_CreateEvent(
 
        event->bo = device->ws->buffer_create(device->ws, 8, 8,
                                              RADEON_DOMAIN_GTT,
-                                             RADEON_FLAG_VA_UNCACHED | RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING);
+                                             RADEON_FLAG_VA_UNCACHED | RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING,
+                                             RADV_BO_PRIORITY_FENCE);
        if (!event->bo) {
                vk_free2(&device->alloc, pAllocator, event);
                return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
@@ -3972,7 +4108,8 @@ VkResult radv_CreateBuffer(
        if (pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
                buffer->bo = device->ws->buffer_create(device->ws,
                                                       align64(buffer->size, 4096),
-                                                      4096, 0, RADEON_FLAG_VIRTUAL);
+                                                      4096, 0, RADEON_FLAG_VIRTUAL,
+                                                      RADV_BO_PRIORITY_VIRTUAL);
                if (!buffer->bo) {
                        vk_free2(&device->alloc, pAllocator, buffer);
                        return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
@@ -4001,13 +4138,22 @@ void radv_DestroyBuffer(
        vk_free2(&device->alloc, pAllocator, buffer);
 }
 
+VkDeviceAddress radv_GetBufferDeviceAddressEXT(
+       VkDevice                                    device,
+       const VkBufferDeviceAddressInfoEXT*         pInfo)
+{
+       RADV_FROM_HANDLE(radv_buffer, buffer, pInfo->buffer);
+       return radv_buffer_get_va(buffer->bo) + buffer->offset;
+}
+
+
 static inline unsigned
-si_tile_mode_index(const struct radv_image *image, unsigned level, bool stencil)
+si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil)
 {
        if (stencil)
-               return image->surface.u.legacy.stencil_tiling_index[level];
+               return plane->surface.u.legacy.stencil_tiling_index[level];
        else
-               return image->surface.u.legacy.tiling_index[level];
+               return plane->surface.u.legacy.tiling_index[level];
 }
 
 static uint32_t radv_surface_max_layer_count(struct radv_image_view *iview)
@@ -4028,9 +4174,9 @@ radv_init_dcc_control_reg(struct radv_device *device,
                return 0;
 
        if (iview->image->info.samples > 1) {
-               if (iview->image->surface.bpe == 1)
+               if (iview->image->planes[0].surface.bpe == 1)
                        max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
-               else if (iview->image->surface.bpe == 2)
+               else if (iview->image->planes[0].surface.bpe == 2)
                        max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_128B;
        }
 
@@ -4075,7 +4221,8 @@ radv_initialise_color_surface(struct radv_device *device,
        unsigned ntype, format, swap, endian;
        unsigned blend_clamp = 0, blend_bypass = 0;
        uint64_t va;
-       const struct radeon_surf *surf = &iview->image->surface;
+       const struct radv_image_plane *plane = &iview->image->planes[iview->plane_id];
+       const struct radeon_surf *surf = &plane->surface;
 
        desc = vk_format_description(iview->vk_format);
 
@@ -4084,35 +4231,37 @@ radv_initialise_color_surface(struct radv_device *device,
        /* Intensity is implemented as Red, so treat it that way. */
        cb->cb_color_attrib = S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] == VK_SWIZZLE_1);
 
-       va = radv_buffer_get_va(iview->bo) + iview->image->offset;
+       va = radv_buffer_get_va(iview->bo) + iview->image->offset + plane->offset;
 
        cb->cb_color_base = va >> 8;
 
        if (device->physical_device->rad_info.chip_class >= GFX9) {
                struct gfx9_surf_meta_flags meta;
                if (iview->image->dcc_offset)
-                       meta = iview->image->surface.u.gfx9.dcc;
+                       meta = surf->u.gfx9.dcc;
                else
-                       meta = iview->image->surface.u.gfx9.cmask;
+                       meta = surf->u.gfx9.cmask;
 
-               cb->cb_color_attrib |= S_028C74_COLOR_SW_MODE(iview->image->surface.u.gfx9.surf.swizzle_mode) |
-                       S_028C74_FMASK_SW_MODE(iview->image->surface.u.gfx9.fmask.swizzle_mode) |
+               cb->cb_color_attrib |= S_028C74_COLOR_SW_MODE(surf->u.gfx9.surf.swizzle_mode) |
+                       S_028C74_FMASK_SW_MODE(surf->u.gfx9.fmask.swizzle_mode) |
                        S_028C74_RB_ALIGNED(meta.rb_aligned) |
                        S_028C74_PIPE_ALIGNED(meta.pipe_aligned);
 
-               cb->cb_color_base += iview->image->surface.u.gfx9.surf_offset >> 8;
-               cb->cb_color_base |= iview->image->surface.tile_swizzle;
+               cb->cb_color_base += surf->u.gfx9.surf_offset >> 8;
+               cb->cb_color_base |= surf->tile_swizzle;
+
+               cb->cb_mrt_epitch = S_0287A0_EPITCH(surf->u.gfx9.surf.epitch);
        } else {
                const struct legacy_surf_level *level_info = &surf->u.legacy.level[iview->base_mip];
                unsigned pitch_tile_max, slice_tile_max, tile_mode_index;
 
                cb->cb_color_base += level_info->offset >> 8;
                if (level_info->mode == RADEON_SURF_MODE_2D)
-                       cb->cb_color_base |= iview->image->surface.tile_swizzle;
+                       cb->cb_color_base |= surf->tile_swizzle;
 
                pitch_tile_max = level_info->nblk_x / 8 - 1;
                slice_tile_max = (level_info->nblk_x * level_info->nblk_y) / 64 - 1;
-               tile_mode_index = si_tile_mode_index(iview->image, iview->base_mip, false);
+               tile_mode_index = si_tile_mode_index(plane, iview->base_mip, false);
 
                cb->cb_color_pitch = S_028C64_TILE_MAX(pitch_tile_max);
                cb->cb_color_slice = S_028C68_TILE_MAX(slice_tile_max);
@@ -4142,7 +4291,7 @@ radv_initialise_color_surface(struct radv_device *device,
        va = radv_buffer_get_va(iview->bo) + iview->image->offset;
        va += iview->image->dcc_offset;
        cb->cb_dcc_base = va >> 8;
-       cb->cb_dcc_base |= iview->image->surface.tile_swizzle;
+       cb->cb_dcc_base |= surf->tile_swizzle;
 
        uint32_t max_slice = radv_surface_max_layer_count(iview) - 1;
        cb->cb_color_view = S_028C6C_SLICE_START(iview->base_layer) |
@@ -4225,7 +4374,7 @@ radv_initialise_color_surface(struct radv_device *device,
        /* This must be set for fast clear to work without FMASK. */
        if (!radv_image_has_fmask(iview->image) &&
            device->physical_device->rad_info.chip_class == SI) {
-               unsigned bankh = util_logbase2(iview->image->surface.u.legacy.bankh);
+               unsigned bankh = util_logbase2(surf->u.legacy.bankh);
                cb->cb_color_attrib |= S_028C74_FMASK_BANK_HEIGHT(bankh);
        }
 
@@ -4235,7 +4384,7 @@ radv_initialise_color_surface(struct radv_device *device,
 
                cb->cb_color_view |= S_028C6C_MIP_LEVEL(iview->base_mip);
                cb->cb_color_attrib |= S_028C74_MIP0_DEPTH(mip0_depth) |
-                       S_028C74_RESOURCE_TYPE(iview->image->surface.u.gfx9.resource_type);
+                       S_028C74_RESOURCE_TYPE(surf->u.gfx9.resource_type);
                cb->cb_color_attrib2 = S_028C68_MIP0_WIDTH(iview->extent.width - 1) |
                        S_028C68_MIP0_HEIGHT(iview->extent.height - 1) |
                        S_028C68_MAX_MIP(iview->image->info.levels - 1);
@@ -4290,6 +4439,11 @@ radv_initialise_ds_surface(struct radv_device *device,
        unsigned format, stencil_format;
        uint64_t va, s_offs, z_offs;
        bool stencil_only = false;
+       const struct radv_image_plane *plane = &iview->image->planes[0];
+       const struct radeon_surf *surf = &plane->surface;
+
+       assert(vk_format_get_plane_count(iview->image->vk_format) == 1);
+
        memset(ds, 0, sizeof(*ds));
        switch (iview->image->vk_format) {
        case VK_FORMAT_D24_UNORM_S8_UINT:
@@ -4316,7 +4470,7 @@ radv_initialise_ds_surface(struct radv_device *device,
        }
 
        format = radv_translate_dbformat(iview->image->vk_format);
-       stencil_format = iview->image->surface.has_stencil ?
+       stencil_format = surf->has_stencil ?
                V_028044_STENCIL_8 : V_028044_STENCIL_INVALID;
 
        uint32_t max_slice = radv_surface_max_layer_count(iview) - 1;
@@ -4330,19 +4484,19 @@ radv_initialise_ds_surface(struct radv_device *device,
        s_offs = z_offs = va;
 
        if (device->physical_device->rad_info.chip_class >= GFX9) {
-               assert(iview->image->surface.u.gfx9.surf_offset == 0);
-               s_offs += iview->image->surface.u.gfx9.stencil_offset;
+               assert(surf->u.gfx9.surf_offset == 0);
+               s_offs += surf->u.gfx9.stencil_offset;
 
                ds->db_z_info = S_028038_FORMAT(format) |
                        S_028038_NUM_SAMPLES(util_logbase2(iview->image->info.samples)) |
-                       S_028038_SW_MODE(iview->image->surface.u.gfx9.surf.swizzle_mode) |
+                       S_028038_SW_MODE(surf->u.gfx9.surf.swizzle_mode) |
                        S_028038_MAXMIP(iview->image->info.levels - 1) |
                        S_028038_ZRANGE_PRECISION(1);
                ds->db_stencil_info = S_02803C_FORMAT(stencil_format) |
-                       S_02803C_SW_MODE(iview->image->surface.u.gfx9.stencil.swizzle_mode);
+                       S_02803C_SW_MODE(surf->u.gfx9.stencil.swizzle_mode);
 
-               ds->db_z_info2 = S_028068_EPITCH(iview->image->surface.u.gfx9.surf.epitch);
-               ds->db_stencil_info2 = S_02806C_EPITCH(iview->image->surface.u.gfx9.stencil.epitch);
+               ds->db_z_info2 = S_028068_EPITCH(surf->u.gfx9.surf.epitch);
+               ds->db_stencil_info2 = S_02806C_EPITCH(surf->u.gfx9.stencil.epitch);
                ds->db_depth_view |= S_028008_MIPID(level);
 
                ds->db_depth_size = S_02801C_X_MAX(iview->image->info.width - 1) |
@@ -4360,24 +4514,24 @@ radv_initialise_ds_surface(struct radv_device *device,
                                ds->db_stencil_info |= S_02803C_ITERATE_FLUSH(1);
                        }
 
-                       if (!iview->image->surface.has_stencil)
+                       if (!surf->has_stencil)
                                /* Use all of the htile_buffer for depth if there's no stencil. */
                                ds->db_stencil_info |= S_02803C_TILE_STENCIL_DISABLE(1);
                        va = radv_buffer_get_va(iview->bo) + iview->image->offset +
                                iview->image->htile_offset;
                        ds->db_htile_data_base = va >> 8;
                        ds->db_htile_surface = S_028ABC_FULL_CACHE(1) |
-                               S_028ABC_PIPE_ALIGNED(iview->image->surface.u.gfx9.htile.pipe_aligned) |
-                               S_028ABC_RB_ALIGNED(iview->image->surface.u.gfx9.htile.rb_aligned);
+                               S_028ABC_PIPE_ALIGNED(surf->u.gfx9.htile.pipe_aligned) |
+                               S_028ABC_RB_ALIGNED(surf->u.gfx9.htile.rb_aligned);
                }
        } else {
-               const struct legacy_surf_level *level_info = &iview->image->surface.u.legacy.level[level];
+               const struct legacy_surf_level *level_info = &surf->u.legacy.level[level];
 
                if (stencil_only)
-                       level_info = &iview->image->surface.u.legacy.stencil_level[level];
+                       level_info = &surf->u.legacy.stencil_level[level];
 
-               z_offs += iview->image->surface.u.legacy.level[level].offset;
-               s_offs += iview->image->surface.u.legacy.stencil_level[level].offset;
+               z_offs += surf->u.legacy.level[level].offset;
+               s_offs += surf->u.legacy.stencil_level[level].offset;
 
                ds->db_depth_info = S_02803C_ADDR5_SWIZZLE_MASK(!radv_image_is_tc_compat_htile(iview->image));
                ds->db_z_info = S_028040_FORMAT(format) | S_028040_ZRANGE_PRECISION(1);
@@ -4388,9 +4542,9 @@ radv_initialise_ds_surface(struct radv_device *device,
 
                if (device->physical_device->rad_info.chip_class >= CIK) {
                        struct radeon_info *info = &device->physical_device->rad_info;
-                       unsigned tiling_index = iview->image->surface.u.legacy.tiling_index[level];
-                       unsigned stencil_index = iview->image->surface.u.legacy.stencil_tiling_index[level];
-                       unsigned macro_index = iview->image->surface.u.legacy.macro_tile_index;
+                       unsigned tiling_index = surf->u.legacy.tiling_index[level];
+                       unsigned stencil_index = surf->u.legacy.stencil_tiling_index[level];
+                       unsigned macro_index = surf->u.legacy.macro_tile_index;
                        unsigned tile_mode = info->si_tile_mode_array[tiling_index];
                        unsigned stencil_tile_mode = info->si_tile_mode_array[stencil_index];
                        unsigned macro_mode = info->cik_macrotile_mode_array[macro_index];
@@ -4408,9 +4562,9 @@ radv_initialise_ds_surface(struct radv_device *device,
                        ds->db_z_info |= S_028040_TILE_SPLIT(G_009910_TILE_SPLIT(tile_mode));
                        ds->db_stencil_info |= S_028044_TILE_SPLIT(G_009910_TILE_SPLIT(stencil_tile_mode));
                } else {
-                       unsigned tile_mode_index = si_tile_mode_index(iview->image, level, false);
+                       unsigned tile_mode_index = si_tile_mode_index(&iview->image->planes[0], level, false);
                        ds->db_z_info |= S_028040_TILE_MODE_INDEX(tile_mode_index);
-                       tile_mode_index = si_tile_mode_index(iview->image, level, true);
+                       tile_mode_index = si_tile_mode_index(&iview->image->planes[0], level, true);
                        ds->db_stencil_info |= S_028044_TILE_MODE_INDEX(tile_mode_index);
                        if (stencil_only)
                                ds->db_z_info |= S_028040_TILE_MODE_INDEX(tile_mode_index);
@@ -4423,7 +4577,7 @@ radv_initialise_ds_surface(struct radv_device *device,
                if (radv_htile_enabled(iview->image, level)) {
                        ds->db_z_info |= S_028040_TILE_SURFACE_ENABLE(1);
 
-                       if (!iview->image->surface.has_stencil &&
+                       if (!surf->has_stencil &&
                            !radv_image_is_tc_compat_htile(iview->image))
                                /* Use all of the htile_buffer for depth if there's no stencil. */
                                ds->db_stencil_info |= S_028044_TILE_STENCIL_DISABLE(1);
@@ -4473,10 +4627,10 @@ VkResult radv_CreateFramebuffer(
                VkImageView _iview = pCreateInfo->pAttachments[i];
                struct radv_image_view *iview = radv_image_view_from_handle(_iview);
                framebuffer->attachments[i].attachment = iview;
-               if (iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) {
-                       radv_initialise_color_surface(device, &framebuffer->attachments[i].cb, iview);
-               } else if (iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
+               if (iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
                        radv_initialise_ds_surface(device, &framebuffer->attachments[i].ds, iview);
+               } else {
+                       radv_initialise_color_surface(device, &framebuffer->attachments[i].cb, iview);
                }
                framebuffer->width = MIN2(framebuffer->width, iview->extent.width);
                framebuffer->height = MIN2(framebuffer->height, iview->extent.height);
@@ -4689,6 +4843,10 @@ VkResult radv_CreateSampler(
        RADV_FROM_HANDLE(radv_device, device, _device);
        struct radv_sampler *sampler;
 
+       const struct VkSamplerYcbcrConversionInfo *ycbcr_conversion =
+               vk_find_struct_const(pCreateInfo->pNext,
+                                    SAMPLER_YCBCR_CONVERSION_INFO);
+
        assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
 
        sampler = vk_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
@@ -4697,6 +4855,8 @@ VkResult radv_CreateSampler(
                return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
 
        radv_init_sampler(device, sampler, pCreateInfo);
+
+       sampler->ycbcr_sampler = ycbcr_conversion ? radv_sampler_ycbcr_conversion_from_handle(ycbcr_conversion->conversion): NULL;
        *pSampler = radv_sampler_to_handle(sampler);
 
        return VK_SUCCESS;