anv: Enable compression on CCS modifiers (xe2)

Don't report compressed memory type in the case of Xe2 modifiers
as the Vulkan spec requires identical memory types behind the
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.

Instead, we require dedicated allocation to get the right
compressed memory in allocation stage. The BMG modifier also
requires scanout flag to set. Refer to comments.

Thanks for the help from:
Nanley Chery <nanley.g.chery@intel.com>
Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Kenneth Graunke <kenneth@whitecape.org>
and other people not listed.

Signed-off-by: Jianxun Zhang <jianxun.zhang@intel.com>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34567>
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 144093e..bb64264 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1559,15 +1559,31 @@
    if (wsi_info)
       alloc_flags |= ANV_BO_ALLOC_SCANOUT;
 
+   struct anv_image *image = dedicated_info ?
+                             anv_image_from_handle(dedicated_info->image) :
+                             NULL;
+
+   if (device->info->ver >= 20 && image &&
+       image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
+       isl_drm_modifier_has_aux(image->vk.drm_format_mod)) {
+      /* ISL should skip compression modifiers when no_ccs is set. */
+      assert(!INTEL_DEBUG(DEBUG_NO_CCS));
+      /* Images created with the Xe2 modifiers should be allocated into
+       * compressed memory, but we won't get such info from the memory type,
+       * refer to anv_image_is_pat_compressible(). We have to check the
+       * modifiers and enable compression if we can here.
+       */
+      alloc_flags |= ANV_BO_ALLOC_COMPRESSED;
+   } else if (mem_type->compressed && !INTEL_DEBUG(DEBUG_NO_CCS)) {
+      alloc_flags |= ANV_BO_ALLOC_COMPRESSED;
+   }
+
    /* Anything imported or exported is EXTERNAL */
    if (mem->vk.export_handle_types || mem->vk.import_handle_type) {
       alloc_flags |= ANV_BO_ALLOC_EXTERNAL;
 
       /* wsi has its own way of synchronizing with the compositor */
-      if (!wsi_info && dedicated_info &&
-          dedicated_info->image != VK_NULL_HANDLE) {
-         ANV_FROM_HANDLE(anv_image, image, dedicated_info->image);
-
+      if (!wsi_info && image) {
          /* Apply implicit sync to be compatible with clients relying on
           * implicit fencing. This matches the behavior in iris i915_batch
           * submit. An example client is VA-API (iHD), so only dedicated
@@ -1585,14 +1601,6 @@
       }
    }
 
-   /* TODO: Disabling compression on external bos will cause problems once we
-    * have a modifier that supports compression (Xe2+).
-    */
-   if (!(alloc_flags & ANV_BO_ALLOC_EXTERNAL) &&
-       mem_type->compressed &&
-       !INTEL_DEBUG(DEBUG_NO_CCS))
-      alloc_flags |= ANV_BO_ALLOC_COMPRESSED;
-
    if (mem_type->dynamic_visible)
       alloc_flags |= ANV_BO_ALLOC_DYNAMIC_VISIBLE_POOL;
 
@@ -1711,21 +1719,17 @@
    if (result != VK_SUCCESS)
       goto fail;
 
-   if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
-      ANV_FROM_HANDLE(anv_image, image, dedicated_info->image);
-
+   if (image && image->vk.wsi_legacy_scanout) {
       /* Some legacy (non-modifiers) consumers need the tiling to be set on
        * the BO.  In this case, we have a dedicated allocation.
        */
-      if (image->vk.wsi_legacy_scanout) {
-         const struct isl_surf *surf = &image->planes[0].primary_surface.isl;
-         result = anv_device_set_bo_tiling(device, mem->bo,
-                                           surf->row_pitch_B,
-                                           surf->tiling);
-         if (result != VK_SUCCESS) {
-            anv_device_release_bo(device, mem->bo);
-            goto fail;
-         }
+      const struct isl_surf *surf = &image->planes[0].primary_surface.isl;
+      result = anv_device_set_bo_tiling(device, mem->bo,
+                                        surf->row_pitch_B,
+                                        surf->tiling);
+      if (result != VK_SUCCESS) {
+         anv_device_release_bo(device, mem->bo);
+         goto fail;
       }
    }
 
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 81807b8..909b75d 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -2216,15 +2216,18 @@
     *    VkImageCreateInfo structure passed to vkCreateImage.
     */
 
-   /* There are no compression-enabled modifiers on Xe2, and all legacy
-    * modifiers are not defined with compression. We simply disable
-    * compression on all modifiers.
-    *
-    * We disable this in anv_AllocateMemory() as well.
+   /* Because we cannot report different memory types for uncompressed and
+    * compressed modifiers on the VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
+    * We don't set the right compressed memory type set for Xe2 modifiers, in
+    * order to keep the memory types same as the uncompressed modifiers. The
+    * image will get compressed memory through a dedicated allocation later.
     */
    if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
       return false;
 
+   if (image->vk.external_handle_types)
+      return false;
+
    /* Host accessed images cannot be compressed. */
    if (image->vk.usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT)
       return false;
@@ -2275,11 +2278,16 @@
          if (image->vk.wsi_legacy_scanout ||
              image->from_ahb ||
              (isl_drm_modifier_has_aux(image->vk.drm_format_mod) &&
-              anv_image_uses_aux_map(device, image))) {
-            /* If we need to set the tiling for external consumers or the
-             * modifier involves AUX tables, we need a dedicated allocation.
+              (anv_image_uses_aux_map(device, image) ||
+               device->info->ver >= 20))) {
+            /* On pre-Xe2 platforms, if we need to set the tiling for external
+             * consumers or the modifier involves AUX tables, we need a
+             * dedicated allocation. On Xe2+ platforms, a dedicated allocation
+             * is still needed because we need to pass modifier information
+             * down to the allocation path. Refer to
+             * anv_image_is_pat_compressible().
              *
-             * See also anv_AllocateMemory.
+             * See also anv_AllocateMemory().
              */
             requirements->prefersDedicatedAllocation = true;
             requirements->requiresDedicatedAllocation = true;