vulkan/wsi: Use the interface from the real modifiers extension
[mesa.git] / src / intel / vulkan / anv_image.c
index 66116a8a67d15d23fb4f853e005940a54d24d05d..37e1cae32ae39628559792da1d206bce2bb43839 100644 (file)
@@ -34,6 +34,8 @@
 #include "vk_util.h"
 #include "util/u_math.h"
 
+#include "common/gen_aux_map.h"
+
 #include "vk_format_info.h"
 
 static isl_surf_usage_flags_t
@@ -109,6 +111,8 @@ choose_isl_tiling_flags(const struct anv_image_create_info *anv_info,
    case VK_IMAGE_TILING_LINEAR:
       flags = ISL_TILING_LINEAR_BIT;
       break;
+   case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
+      flags = 1 << isl_mod_info->tiling;
    }
 
    if (anv_info->isl_tiling_flags)
@@ -117,9 +121,6 @@ choose_isl_tiling_flags(const struct anv_image_create_info *anv_info,
    if (legacy_scanout)
       flags &= ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT;
 
-   if (isl_mod_info)
-      flags &= 1 << isl_mod_info->tiling;
-
    assert(flags);
 
    return flags;
@@ -157,19 +158,21 @@ add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane)
 }
 
 
-static bool
-all_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
-                             const VkImageFormatListCreateInfoKHR *fmt_list,
-                             struct anv_image *image)
+bool
+anv_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
+                             VkImageCreateFlags create_flags,
+                             VkFormat vk_format,
+                             VkImageTiling vk_tiling,
+                             const VkImageFormatListCreateInfoKHR *fmt_list)
 {
    enum isl_format format =
-      anv_get_isl_format(devinfo, image->vk_format,
-                         VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);
+      anv_get_isl_format(devinfo, vk_format,
+                         VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling);
 
    if (!isl_format_supports_ccs_e(devinfo, format))
       return false;
 
-   if (!(image->create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
+   if (!(create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
       return true;
 
    if (!fmt_list || fmt_list->viewFormatCount == 0)
@@ -178,7 +181,7 @@ all_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
    for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) {
       enum isl_format view_format =
          anv_get_isl_format(devinfo, fmt_list->pViewFormats[i],
-                            VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);
+                            VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling);
 
       if (!isl_formats_are_ccs_e_compatible(devinfo, format, view_format))
          return false;
@@ -283,6 +286,15 @@ add_aux_state_tracking_buffer(struct anv_image *image,
       }
    }
 
+   /* Add some padding to make sure the fast clear color state buffer starts at
+    * a 4K alignment. We believe that 256B might be enough, but due to lack of
+    * testing we will leave this as 4K for now.
+    */
+   image->planes[plane].size = ALIGN(image->planes[plane].size, 4096);
+   image->size = ALIGN(image->size, 4096);
+
+   assert(image->planes[plane].offset % 4096 == 0);
+
    image->planes[plane].fast_clear_state_offset =
       image->planes[plane].offset + image->planes[plane].size;
 
@@ -449,7 +461,8 @@ make_surface(const struct anv_device *dev,
          assert(image->planes[plane].aux_surface.isl.size_B == 0);
          ok = isl_surf_get_ccs_surf(&dev->isl_dev,
                                     &image->planes[plane].surface.isl,
-                                    &image->planes[plane].aux_surface.isl, 0);
+                                    &image->planes[plane].aux_surface.isl,
+                                    NULL, 0);
          if (ok) {
 
             /* Disable CCS when it is not useful (i.e., when you can't render
@@ -468,9 +481,6 @@ make_surface(const struct anv_device *dev,
                return VK_SUCCESS;
             }
 
-            add_surface(image, &image->planes[plane].aux_surface, plane);
-            add_aux_state_tracking_buffer(image, plane, dev);
-
             /* For images created without MUTABLE_FORMAT_BIT set, we know that
              * they will always be used with the original format.  In
              * particular, they will always be used with a format that
@@ -482,7 +492,16 @@ make_surface(const struct anv_device *dev,
             if (!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
                 image->ccs_e_compatible) {
                image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E;
+            } else if (dev->info.gen >= 12) {
+               anv_perf_warn(dev->instance, image,
+                             "The CCS_D aux mode is not yet handled on "
+                             "Gen12+. Not allocating a CCS buffer.");
+               image->planes[plane].aux_surface.isl.size_B = 0;
+               return VK_SUCCESS;
             }
+
+            add_surface(image, &image->planes[plane].aux_surface, plane);
+            add_aux_state_tracking_buffer(image, plane, dev);
          }
       }
    } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples > 1) {
@@ -569,10 +588,14 @@ anv_image_create(VkDevice _device,
 
    const struct wsi_image_create_info *wsi_info =
       vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
-   if (wsi_info && wsi_info->modifier_count > 0) {
+
+   if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
+      const VkImageDrmFormatModifierListCreateInfoEXT *mod_info =
+         vk_find_struct_const(pCreateInfo->pNext,
+                              IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
       isl_mod_info = choose_drm_format_mod(&device->instance->physicalDevice,
-                                           wsi_info->modifier_count,
-                                           wsi_info->modifiers);
+                                           mod_info->drmFormatModifierCount,
+                                           mod_info->pDrmFormatModifiers);
       assert(isl_mod_info);
    }
 
@@ -636,7 +659,8 @@ anv_image_create(VkDevice _device,
                            IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
 
    image->ccs_e_compatible =
-      all_formats_ccs_e_compatible(&device->info, fmt_list, image);
+      anv_formats_ccs_e_compatible(&device->info, image->create_flags,
+                                   image->vk_format, image->tiling, fmt_list);
 
    uint32_t b;
    for_each_bit(b, image->aspects) {
@@ -704,13 +728,13 @@ anv_image_from_swapchain(VkDevice device,
    local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
 
    /* If the image has a particular modifier, specify that modifier. */
-   struct wsi_image_create_info local_wsi_info = {
-      .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
-      .modifier_count = 1,
-      .modifiers = &swapchain_image->drm_format_mod,
+   VkImageDrmFormatModifierListCreateInfoEXT local_modifier_info = {
+      .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
+      .drmFormatModifierCount = 1,
+      .pDrmFormatModifiers = &swapchain_image->drm_format_mod,
    };
    if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID)
-      __vk_append_struct(&local_create_info, &local_wsi_info);
+      __vk_append_struct(&local_create_info, &local_modifier_info);
 
    return anv_image_create(device,
       &(struct anv_image_create_info) {
@@ -727,7 +751,7 @@ anv_CreateImage(VkDevice device,
                 const VkAllocationCallbacks *pAllocator,
                 VkImage *pImage)
 {
-   const struct VkExternalMemoryImageCreateInfo *create_info =
+   const VkExternalMemoryImageCreateInfo *create_info =
       vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
 
    if (create_info && (create_info->handleTypes &
@@ -736,7 +760,7 @@ anv_CreateImage(VkDevice device,
                                      pAllocator, pImage);
 
    bool use_external_format = false;
-   const struct VkExternalFormatANDROID *ext_format =
+   const VkExternalFormatANDROID *ext_format =
       vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
 
    /* "If externalFormat is zero, the effect is as if the
@@ -778,10 +802,15 @@ anv_DestroyImage(VkDevice _device, VkImage _image,
       return;
 
    for (uint32_t p = 0; p < image->n_planes; ++p) {
+      if (anv_image_plane_uses_aux_map(device, image, p) &&
+          image->planes[p].address.bo) {
+         gen_aux_map_unmap_range(device->aux_map_ctx,
+                                 image->planes[p].aux_map_surface_address,
+                                 image->planes[p].surface.isl.size_B);
+      }
       if (image->planes[p].bo_is_owned) {
          assert(image->planes[p].address.bo != NULL);
-         anv_bo_cache_release(device, &device->bo_cache,
-                              image->planes[p].address.bo);
+         anv_device_release_bo(device, image->planes[p].address.bo);
       }
    }
 
@@ -797,6 +826,12 @@ static void anv_image_bind_memory_plane(struct anv_device *device,
    assert(!image->planes[plane].bo_is_owned);
 
    if (!memory) {
+      if (anv_image_plane_uses_aux_map(device, image, plane) &&
+          image->planes[plane].address.bo) {
+         gen_aux_map_unmap_range(device->aux_map_ctx,
+                                 image->planes[plane].aux_map_surface_address,
+                                 image->planes[plane].surface.isl.size_B);
+      }
       image->planes[plane].address = ANV_NULL_ADDRESS;
       return;
    }
@@ -805,6 +840,20 @@ static void anv_image_bind_memory_plane(struct anv_device *device,
       .bo = memory->bo,
       .offset = memory_offset,
    };
+
+   if (anv_image_plane_uses_aux_map(device, image, plane)) {
+      image->planes[plane].aux_map_surface_address =
+         anv_address_physical(
+            anv_address_add(image->planes[plane].address,
+                            image->planes[plane].surface.offset));
+
+      gen_aux_map_add_image(device->aux_map_ctx,
+                            &image->planes[plane].surface.isl,
+                            image->planes[plane].aux_map_surface_address,
+                            anv_address_physical(
+                               anv_address_add(image->planes[plane].address,
+                                               image->planes[plane].aux_surface.offset)));
+   }
 }
 
 /* We are binding AHardwareBuffer. Get a description, resolve the
@@ -1020,6 +1069,21 @@ void anv_GetImageSubresourceLayout(
    }
 }
 
+VkResult anv_GetImageDrmFormatModifierPropertiesEXT(
+    VkDevice                                    device,
+    VkImage                                     _image,
+    VkImageDrmFormatModifierPropertiesEXT*      pProperties)
+{
+   ANV_FROM_HANDLE(anv_image, image, _image);
+
+   assert(pProperties->sType =
+          VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT);
+
+   pProperties->drmFormatModifier = image->drm_format_mod;
+
+   return VK_SUCCESS;
+}
+
 /**
  * This function determines the optimal buffer to use for a given
  * VkImageLayout and other pieces of information needed to make that
@@ -1061,7 +1125,7 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
       return ISL_AUX_USAGE_NONE;
 
    /* All images that use an auxiliary surface are required to be tiled. */
-   assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
+   assert(image->planes[plane].surface.isl.tiling != ISL_TILING_LINEAR);
 
    /* Stencil has no aux */
    assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
@@ -1088,7 +1152,6 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
     */
    case VK_IMAGE_LAYOUT_GENERAL:
    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
-   case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
       if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
          /* This buffer could be a depth buffer used in a transfer operation.
           * BLORP currently doesn't use HiZ for transfer operations so we must
@@ -1103,10 +1166,12 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
 
 
    /* Sampling Layouts */
+   case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR:
    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
    case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
       assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
       /* Fall-through */
+   case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
       if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
          if (anv_can_sample_with_hiz(devinfo, image))
@@ -1117,6 +1182,9 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
          return image->planes[plane].aux_usage;
       }
 
+   case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR:
+      return ISL_AUX_USAGE_NONE;
+
 
    case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
       assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
@@ -1137,6 +1205,8 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
    /* Rendering Layouts */
    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
       assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
+      /* fall-through */
+   case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR:
       if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) {
          assert(image->samples == 1);
          return ISL_AUX_USAGE_CCS_D;
@@ -1145,6 +1215,7 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
          return image->planes[plane].aux_usage;
       }
 
+   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR:
    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
    case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
       assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);
@@ -1181,6 +1252,9 @@ anv_layout_to_fast_clear_type(const struct gen_device_info * const devinfo,
                               const VkImageAspectFlagBits aspect,
                               const VkImageLayout layout)
 {
+   if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)
+      return ANV_FAST_CLEAR_NONE;
+
    /* The aspect must be exactly one of the image aspects. */
    assert(util_bitcount(aspect) == 1 && (aspect & image->aspects));
 
@@ -1191,7 +1265,7 @@ anv_layout_to_fast_clear_type(const struct gen_device_info * const devinfo,
       return ANV_FAST_CLEAR_NONE;
 
    /* All images that use an auxiliary surface are required to be tiled. */
-   assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
+   assert(image->planes[plane].surface.isl.tiling != ISL_TILING_LINEAR);
 
    /* Stencil has no aux */
    assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
@@ -1429,7 +1503,7 @@ anv_image_fill_surface_state(struct anv_device *device,
       if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE) {
          if (aux_usage == ISL_AUX_USAGE_HIZ) {
             clear_address = (struct anv_address) {
-               .bo = &device->hiz_clear_bo,
+               .bo = device->hiz_clear_bo,
                .offset = 0,
             };
          } else {
@@ -1537,7 +1611,7 @@ anv_CreateImageView(VkDevice _device,
 
    /* Check if a conversion info was passed. */
    const struct anv_format *conv_format = NULL;
-   const struct VkSamplerYcbcrConversionInfo *conv_info =
+   const VkSamplerYcbcrConversionInfo *conv_info =
       vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO);
 
    /* If image has an external format, the pNext chain must contain an instance of