iris: Don't guess the aux_usage
authorNanley Chery <nanley.g.chery@intel.com>
Thu, 1 Aug 2019 23:49:57 +0000 (16:49 -0700)
committerNanley Chery <nanley.g.chery@intel.com>
Mon, 28 Oct 2019 17:47:06 +0000 (10:47 -0700)
Instead of guessing an aux_usage, then confirming it if the
isl_surf_get_*_surf functions are successful, just call the ISL
functions up-front. This will help us to more easily determine if a
depth buffer supports HIZ_CCS.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/gallium/drivers/iris/iris_resource.c

index 9bd9835e71b1af74bc933f9068b4d21f7578fe1a..b25f43ac2ad7f0561e1add3389a5b3ac8a3d39ac 100644 (file)
@@ -399,6 +399,28 @@ map_aux_addresses(struct iris_screen *screen, struct iris_resource *res)
    }
 }
 
+static bool
+want_ccs_e_for_format(const struct gen_device_info *devinfo,
+                      enum isl_format format)
+{
+   if (!isl_format_supports_ccs_e(devinfo, format))
+      return false;
+
+   const struct isl_format_layout *fmtl = isl_format_get_layout(format);
+
+   /* CCS_E seems to significantly hurt performance with 32-bit floating
+    * point formats.  For example, Paraview's "Wavelet Volume" case uses
+    * both R32_FLOAT and R32G32B32A32_FLOAT, and enabling CCS_E for those
+    * formats causes a 62% FPS drop.
+    *
+    * However, many benchmarks seem to use 16-bit float with no issues.
+    */
+   if (fmtl->channels.r.bits == 32 && fmtl->channels.r.type == ISL_SFLOAT)
+      return false;
+
+   return true;
+}
+
 /**
  * Configure aux for the resource, but don't allocate it. For images which
  * might be shared with modifiers, we must allocate the image and aux data in
@@ -410,22 +432,65 @@ iris_resource_configure_aux(struct iris_screen *screen,
                             uint64_t *aux_size_B,
                             uint32_t *alloc_flags)
 {
-   struct isl_device *isl_dev = &screen->isl_dev;
-   enum isl_aux_state initial_state;
-   UNUSED bool ok = false;
+   const struct gen_device_info *devinfo = &screen->devinfo;
+
+   /* Try to create the auxiliary surfaces allowed by the modifier or by
+    * the user if no modifier is specified.
+    */
+   assert(!res->mod_info || res->mod_info->aux_usage == ISL_AUX_USAGE_NONE ||
+                            res->mod_info->aux_usage == ISL_AUX_USAGE_CCS_E);
+
+   const bool has_mcs = !res->mod_info &&
+      isl_surf_get_mcs_surf(&screen->isl_dev, &res->surf, &res->aux.surf);
+
+   const bool has_hiz = !res->mod_info && !(INTEL_DEBUG & DEBUG_NO_HIZ) &&
+      isl_surf_get_hiz_surf(&screen->isl_dev, &res->surf, &res->aux.surf);
 
+   const bool has_ccs =
+      ((!res->mod_info && !(INTEL_DEBUG & DEBUG_NO_RBC)) ||
+       (res->mod_info && res->mod_info->aux_usage != ISL_AUX_USAGE_NONE)) &&
+      isl_surf_get_ccs_surf(&screen->isl_dev, &res->surf, &res->aux.surf,
+                            NULL, 0);
+
+   /* We should have at most one aux surface. */
+   assert(has_mcs + has_hiz + has_ccs <= 1);
+
+   if (res->mod_info && has_ccs) {
+      /* Only allow a CCS modifier if the aux was created successfully. */
+      res->aux.possible_usages |= 1 << res->mod_info->aux_usage;
+   } else if (has_mcs) {
+      res->aux.possible_usages |= 1 << ISL_AUX_USAGE_MCS;
+   } else if (has_hiz) {
+      res->aux.possible_usages |= 1 << ISL_AUX_USAGE_HIZ;
+   } else if (has_ccs) {
+      if (want_ccs_e_for_format(devinfo, res->surf.format))
+         res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_E;
+
+      if (isl_format_supports_ccs_d(devinfo, res->surf.format))
+         res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_D;
+   }
+
+   res->aux.usage = util_last_bit(res->aux.possible_usages) - 1;
+
+   res->aux.sampler_usages = res->aux.possible_usages;
+
+   /* We don't always support sampling with hiz. But when we do, it must be
+    * single sampled.
+    */
+   if (!devinfo->has_sample_with_hiz || res->surf.samples > 1)
+      res->aux.sampler_usages &= ~(1 << ISL_AUX_USAGE_HIZ);
+
+   enum isl_aux_state initial_state;
    *aux_size_B = 0;
    *alloc_flags = 0;
    assert(!res->aux.bo);
 
    switch (res->aux.usage) {
    case ISL_AUX_USAGE_NONE:
-      res->aux.surf.size_B = 0;
-      ok = true;
-      break;
+      /* Having no aux buffer is only okay if there's no modifier with aux. */
+      return !res->mod_info || res->mod_info->aux_usage == ISL_AUX_USAGE_NONE;
    case ISL_AUX_USAGE_HIZ:
       initial_state = ISL_AUX_STATE_AUX_INVALID;
-      ok = isl_surf_get_hiz_surf(isl_dev, &res->surf, &res->aux.surf);
       break;
    case ISL_AUX_USAGE_MCS:
       /* The Ivybridge PRM, Vol 2 Part 1 p326 says:
@@ -438,7 +503,6 @@ iris_resource_configure_aux(struct iris_screen *screen,
        * 1's, so we simply memset it to 0xff.
        */
       initial_state = ISL_AUX_STATE_CLEAR;
-      ok = isl_surf_get_mcs_surf(isl_dev, &res->surf, &res->aux.surf);
       break;
    case ISL_AUX_USAGE_CCS_D:
    case ISL_AUX_USAGE_CCS_E:
@@ -461,18 +525,9 @@ iris_resource_configure_aux(struct iris_screen *screen,
       else
          initial_state = ISL_AUX_STATE_PASS_THROUGH;
       *alloc_flags |= BO_ALLOC_ZEROED;
-      ok = isl_surf_get_ccs_surf(isl_dev, &res->surf, &res->aux.surf, NULL, 0);
       break;
    }
 
-   /* We should have a valid aux_surf. */
-   if (!ok)
-      return false;
-
-   /* No work is needed for a zero-sized auxiliary buffer. */
-   if (res->aux.surf.size_B == 0)
-      return true;
-
    if (!res->aux.state) {
       /* Create the aux_state for the auxiliary buffer. */
       res->aux.state = create_aux_state_map(res, initial_state);
@@ -619,55 +674,6 @@ iris_resource_finish_aux_import(struct pipe_screen *pscreen,
    res->base.next = NULL;
 }
 
-static bool
-supports_mcs(const struct isl_surf *surf)
-{
-   /* MCS compression only applies to multisampled resources. */
-   if (surf->samples <= 1)
-      return false;
-
-   /* Depth and stencil buffers use the IMS (interleaved) layout. */
-   if (isl_surf_usage_is_depth_or_stencil(surf->usage))
-      return false;
-
-   return true;
-}
-
-static bool
-supports_ccs(const struct gen_device_info *devinfo,
-             const struct isl_surf *surf)
-{
-   /* CCS only supports singlesampled resources. */
-   if (surf->samples > 1)
-      return false;
-
-   /* Note: still need to check the format! */
-
-   return true;
-}
-
-static bool
-want_ccs_e_for_format(const struct gen_device_info *devinfo,
-                      enum isl_format format)
-{
-   if (!isl_format_supports_ccs_e(devinfo, format))
-      return false;
-
-   const struct isl_format_layout *fmtl = isl_format_get_layout(format);
-
-   /* CCS_E seems to significantly hurt performance with 32-bit floating
-    * point formats.  For example, Paraview's "Wavelet Volume" case uses
-    * both R32_FLOAT and R32G32B32A32_FLOAT, and enabling CCS_E for those
-    * formats causes a 62% FPS drop.
-    *
-    * However, many benchmarks seem to use 16-bit float with no issues.
-    */
-   if (fmtl->channels.r.bits == 32 && fmtl->channels.r.type == ISL_SFLOAT)
-      return false;
-
-   return true;
-}
-
 static struct pipe_resource *
 iris_resource_create_for_buffer(struct pipe_screen *pscreen,
                                 const struct pipe_resource *templ)
@@ -781,33 +787,6 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen,
                     .tiling_flags = tiling_flags);
    assert(isl_surf_created_successfully);
 
-   if (res->mod_info) {
-      res->aux.possible_usages |= 1 << res->mod_info->aux_usage;
-   } else if (supports_mcs(&res->surf)) {
-      res->aux.possible_usages |= 1 << ISL_AUX_USAGE_MCS;
-   } else if (has_depth) {
-      if (likely(!(INTEL_DEBUG & DEBUG_NO_HIZ)))
-         res->aux.possible_usages |= 1 << ISL_AUX_USAGE_HIZ;
-   } else if (likely(!(INTEL_DEBUG & DEBUG_NO_RBC)) &&
-              supports_ccs(devinfo, &res->surf)) {
-      if (want_ccs_e_for_format(devinfo, res->surf.format))
-         res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_E;
-
-      if (isl_format_supports_ccs_d(devinfo, res->surf.format))
-         res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_D;
-   }
-
-   res->aux.usage = util_last_bit(res->aux.possible_usages) - 1;
-
-   res->aux.sampler_usages = res->aux.possible_usages;
-
-   /* We don't always support sampling with hiz. But when we do, it must be
-    * single sampled.
-    */
-   if (!devinfo->has_sample_with_hiz || res->surf.samples > 1) {
-      res->aux.sampler_usages &= ~(1 << ISL_AUX_USAGE_HIZ);
-   }
-
    const char *name = "miptree";
    enum iris_memory_zone memzone = IRIS_MEMZONE_OTHER;
 
@@ -1003,9 +982,6 @@ iris_resource_from_handle(struct pipe_screen *pscreen,
             if (res->mod_info->aux_usage != ISL_AUX_USAGE_NONE) {
                uint32_t alloc_flags;
                uint64_t size;
-               res->aux.usage = res->mod_info->aux_usage;
-               res->aux.possible_usages = 1 << res->mod_info->aux_usage;
-               res->aux.sampler_usages = res->aux.possible_usages;
                bool ok = iris_resource_configure_aux(screen, res, true, &size,
                                                      &alloc_flags);
                assert(ok);