anv: Refactor creation of aux surfaces (v2)
[mesa.git] / src / intel / vulkan / anv_image.c
index 57f80510a1e66911961b6201d43fd92863ec2586..8db77b1fdcc03548c6dfa7918a28cfd0d355761e 100644 (file)
@@ -341,95 +341,26 @@ add_aux_state_tracking_buffer(struct anv_image *image,
 }
 
 /**
- * Initialize the anv_image::*_surface selected by \a aspect. Then update the
- * image's memory requirements (that is, the image's size and alignment).
+ * The return code indicates whether creation of the VkImage should continue
+ * or fail, not whether the creation of the aux surface succeeded.  If the aux
+ * surface is not required (for example, by neither hardware nor DRM format
+ * modifier), then this may return VK_SUCCESS when creation of the aux surface
+ * fails.
  */
 static VkResult
-make_surface(struct anv_device *device,
-             struct anv_image *image,
-             const VkImageFormatListCreateInfoKHR *fmt_list,
-             uint32_t stride,
-             isl_tiling_flags_t tiling_flags,
-             isl_surf_usage_flags_t isl_extra_usage_flags,
-             VkImageAspectFlagBits aspect)
+add_aux_surface_if_supported(struct anv_device *device,
+                             struct anv_image *image,
+                             uint32_t plane,
+                             struct anv_format_plane plane_format,
+                             const VkImageFormatListCreateInfoKHR *fmt_list,
+                             isl_surf_usage_flags_t isl_extra_usage_flags)
 {
+   VkImageAspectFlags aspect = plane_format.aspect;
    bool ok;
 
-   static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
-      [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
-      [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
-      [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
-   };
-
-   image->extent = anv_sanitize_image_extent(image->type, image->extent);
-
-   const unsigned plane = anv_image_aspect_to_plane(image->aspects, aspect);
-   const  struct anv_format_plane plane_format =
-      anv_get_format_plane(&device->info, image->vk_format, aspect, image->tiling);
-   struct anv_surface *anv_surf = &image->planes[plane].surface;
-
-   const isl_surf_usage_flags_t usage =
-      choose_isl_surf_usage(image->create_flags, image->usage,
-                            isl_extra_usage_flags, aspect);
-
-   VkImageUsageFlags plane_vk_usage =
-      aspect == VK_IMAGE_ASPECT_STENCIL_BIT ?
-      image->stencil_usage : image->usage;
-
-   bool needs_shadow =
-      anv_image_plane_needs_shadow_surface(&device->info,
-                                   plane_format,
-                                   image->tiling,
-                                   plane_vk_usage,
-                                   image->create_flags,
-                                   &tiling_flags);
-
-   ok = isl_surf_init(&device->isl_dev, &anv_surf->isl,
-      .dim = vk_to_isl_surf_dim[image->type],
-      .format = plane_format.isl_format,
-      .width = image->extent.width / plane_format.denominator_scales[0],
-      .height = image->extent.height / plane_format.denominator_scales[1],
-      .depth = image->extent.depth,
-      .levels = image->levels,
-      .array_len = image->array_size,
-      .samples = image->samples,
-      .min_alignment_B = 0,
-      .row_pitch_B = stride,
-      .usage = usage,
-      .tiling_flags = tiling_flags);
-
-   if (!ok)
-      return VK_ERROR_OUT_OF_DEVICE_MEMORY;
-
-   image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE;
-
-   add_surface(image, anv_surf, plane);
-
-   if (needs_shadow) {
-      ok = isl_surf_init(&device->isl_dev, &image->planes[plane].shadow_surface.isl,
-         .dim = vk_to_isl_surf_dim[image->type],
-         .format = plane_format.isl_format,
-         .width = image->extent.width,
-         .height = image->extent.height,
-         .depth = image->extent.depth,
-         .levels = image->levels,
-         .array_len = image->array_size,
-         .samples = image->samples,
-         .min_alignment_B = 0,
-         .row_pitch_B = stride,
-         .usage = ISL_SURF_USAGE_TEXTURE_BIT |
-                  (usage & ISL_SURF_USAGE_CUBE_BIT),
-         .tiling_flags = ISL_TILING_ANY_MASK);
-
-      /* isl_surf_init() will fail only if provided invalid input. Invalid input
-       * is illegal in Vulkan.
-       */
-      assert(ok);
-
-      add_surface(image, &image->planes[plane].shadow_surface, plane);
-   }
+   /* The aux surface must not be already added. */
+   assert(image->planes[plane].aux_surface.isl.size_B == 0);
 
-   /* Add aux surface. */
    if ((isl_extra_usage_flags & ISL_SURF_USAGE_DISABLE_AUX_BIT)) {
       /* Nevermind. No aux surface. */
    } else if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
@@ -453,7 +384,6 @@ make_surface(struct anv_device *device,
       } else if (device->info.gen == 8 && image->samples > 1) {
          anv_perf_warn(device, image, "Enable gen8 multisampled HiZ");
       } else if (!unlikely(INTEL_DEBUG & DEBUG_NO_HIZ)) {
-         assert(image->planes[plane].aux_surface.isl.size_B == 0);
          ok = isl_surf_get_hiz_surf(&device->isl_dev,
                                     &image->planes[plane].surface.isl,
                                     &image->planes[plane].aux_surface.isl);
@@ -479,7 +409,6 @@ make_surface(struct anv_device *device,
          likely((INTEL_DEBUG & DEBUG_NO_RBC) == 0);
 
       if (allow_compression) {
-         assert(image->planes[plane].aux_surface.isl.size_B == 0);
          ok = isl_surf_get_ccs_surf(&device->isl_dev,
                                     &image->planes[plane].surface.isl,
                                     &image->planes[plane].aux_surface.isl,
@@ -535,7 +464,6 @@ make_surface(struct anv_device *device,
       }
    } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples > 1) {
       assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
-      assert(image->planes[plane].aux_surface.isl.size_B == 0);
       ok = isl_surf_get_mcs_surf(&device->isl_dev,
                                  &image->planes[plane].surface.isl,
                                  &image->planes[plane].aux_surface.isl);
@@ -546,6 +474,104 @@ make_surface(struct anv_device *device,
       }
    }
 
+   return VK_SUCCESS;
+}
+
+/**
+ * Initialize the anv_image::*_surface selected by \a aspect. Then update the
+ * image's memory requirements (that is, the image's size and alignment).
+ */
+static VkResult
+make_surface(struct anv_device *device,
+             struct anv_image *image,
+             const VkImageFormatListCreateInfoKHR *fmt_list,
+             uint32_t stride,
+             isl_tiling_flags_t tiling_flags,
+             isl_surf_usage_flags_t isl_extra_usage_flags,
+             VkImageAspectFlagBits aspect)
+{
+   VkResult result;
+   bool ok;
+
+   static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
+      [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
+      [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
+      [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
+   };
+
+   image->extent = anv_sanitize_image_extent(image->type, image->extent);
+
+   const unsigned plane = anv_image_aspect_to_plane(image->aspects, aspect);
+   const  struct anv_format_plane plane_format =
+      anv_get_format_plane(&device->info, image->vk_format, aspect, image->tiling);
+   struct anv_surface *anv_surf = &image->planes[plane].surface;
+
+   const isl_surf_usage_flags_t usage =
+      choose_isl_surf_usage(image->create_flags, image->usage,
+                            isl_extra_usage_flags, aspect);
+
+   VkImageUsageFlags plane_vk_usage =
+      aspect == VK_IMAGE_ASPECT_STENCIL_BIT ?
+      image->stencil_usage : image->usage;
+
+   bool needs_shadow =
+      anv_image_plane_needs_shadow_surface(&device->info,
+                                   plane_format,
+                                   image->tiling,
+                                   plane_vk_usage,
+                                   image->create_flags,
+                                   &tiling_flags);
+
+   ok = isl_surf_init(&device->isl_dev, &anv_surf->isl,
+      .dim = vk_to_isl_surf_dim[image->type],
+      .format = plane_format.isl_format,
+      .width = image->extent.width / plane_format.denominator_scales[0],
+      .height = image->extent.height / plane_format.denominator_scales[1],
+      .depth = image->extent.depth,
+      .levels = image->levels,
+      .array_len = image->array_size,
+      .samples = image->samples,
+      .min_alignment_B = 0,
+      .row_pitch_B = stride,
+      .usage = usage,
+      .tiling_flags = tiling_flags);
+
+   if (!ok)
+      return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+
+   image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE;
+
+   add_surface(image, anv_surf, plane);
+
+   if (needs_shadow) {
+      ok = isl_surf_init(&device->isl_dev, &image->planes[plane].shadow_surface.isl,
+         .dim = vk_to_isl_surf_dim[image->type],
+         .format = plane_format.isl_format,
+         .width = image->extent.width,
+         .height = image->extent.height,
+         .depth = image->extent.depth,
+         .levels = image->levels,
+         .array_len = image->array_size,
+         .samples = image->samples,
+         .min_alignment_B = 0,
+         .row_pitch_B = stride,
+         .usage = ISL_SURF_USAGE_TEXTURE_BIT |
+                  (usage & ISL_SURF_USAGE_CUBE_BIT),
+         .tiling_flags = ISL_TILING_ANY_MASK);
+
+      /* isl_surf_init() will fail only if provided invalid input. Invalid input
+       * is illegal in Vulkan.
+       */
+      assert(ok);
+
+      add_surface(image, &image->planes[plane].shadow_surface, plane);
+   }
+
+   result = add_aux_surface_if_supported(device, image, plane, plane_format,
+                                         fmt_list, isl_extra_usage_flags);
+   if (result != VK_SUCCESS)
+      return result;
+
    assert((image->planes[plane].offset + image->planes[plane].size) == image->size);
 
    /* Upper bound of the last surface should be smaller than the plane's