Mesa (main): iris: Use isl_surf_get_image_surf instead of hand-rolling it

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 9 23:44:04 UTC 2021


Module: Mesa
Branch: main
Commit: 2ccdd639c2459cb3738d5ffa0ebcca8cfa0e1532
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2ccdd639c2459cb3738d5ffa0ebcca8cfa0e1532

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Thu Jun  3 17:49:02 2021 -0500

iris: Use isl_surf_get_image_surf instead of hand-rolling it

For the 3D RT read case on BDW, we can use the ISL helper.  For the 1D
array case, we don't actually need to flatten; we can just smash it to a
2D array surface because the layout for 1D and 2D is the same on BDW.

Reviewed-by: Nanley Chery <nanley.g.chery at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11235>

---

 src/gallium/drivers/iris/iris_resource.c |  88 -------------------------
 src/gallium/drivers/iris/iris_resource.h |   3 -
 src/gallium/drivers/iris/iris_state.c    | 108 +++++++++++--------------------
 3 files changed, 37 insertions(+), 162 deletions(-)

diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 0d1f493909e..2dfab91cd60 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -390,35 +390,6 @@ iris_get_depth_stencil_resources(struct pipe_resource *res,
    }
 }
 
-enum isl_dim_layout
-iris_get_isl_dim_layout(const struct intel_device_info *devinfo,
-                        enum isl_tiling tiling,
-                        enum pipe_texture_target target)
-{
-   switch (target) {
-   case PIPE_TEXTURE_1D:
-   case PIPE_TEXTURE_1D_ARRAY:
-      return (devinfo->ver >= 9 && tiling == ISL_TILING_LINEAR ?
-              ISL_DIM_LAYOUT_GFX9_1D : ISL_DIM_LAYOUT_GFX4_2D);
-
-   case PIPE_TEXTURE_2D:
-   case PIPE_TEXTURE_2D_ARRAY:
-   case PIPE_TEXTURE_RECT:
-   case PIPE_TEXTURE_CUBE:
-   case PIPE_TEXTURE_CUBE_ARRAY:
-      return ISL_DIM_LAYOUT_GFX4_2D;
-
-   case PIPE_TEXTURE_3D:
-      return (devinfo->ver >= 9 ?
-              ISL_DIM_LAYOUT_GFX4_2D : ISL_DIM_LAYOUT_GFX4_3D);
-
-   case PIPE_MAX_TEXTURE_TYPES:
-   case PIPE_BUFFER:
-      break;
-   }
-   unreachable("invalid texture type");
-}
-
 void
 iris_resource_disable_aux(struct iris_resource *res)
 {
@@ -1668,65 +1639,6 @@ get_image_offset_el(const struct isl_surf *surf, unsigned level, unsigned z,
    }
 }
 
-/**
- * Compute the offset (in bytes) from the start of the BO to the given x
- * and y coordinate.  For tiled BOs, caller must ensure that x and y are
- * multiples of the tile size.
- */
-static uint32_t
-iris_resource_get_aligned_offset(const struct iris_resource *res,
-                                 uint32_t x, uint32_t y)
-{
-   const struct isl_format_layout *fmtl = isl_format_get_layout(res->surf.format);
-   unsigned cpp = fmtl->bpb / 8;
-   uint32_t pitch = res->surf.row_pitch_B;
-
-   switch (res->surf.tiling) {
-   default:
-      unreachable("not reached");
-   case ISL_TILING_LINEAR:
-      return y * pitch + x * cpp;
-   case ISL_TILING_X:
-      assert((x % (512 / cpp)) == 0);
-      assert((y % 8) == 0);
-      return y * pitch + x / (512 / cpp) * 4096;
-   case ISL_TILING_Y0:
-      assert((x % (128 / cpp)) == 0);
-      assert((y % 32) == 0);
-      return y * pitch + x / (128 / cpp) * 4096;
-   }
-}
-
-/**
- * Rendering with tiled buffers requires that the base address of the buffer
- * be aligned to a page boundary.  For renderbuffers, and sometimes with
- * textures, we may want the surface to point at a texture image level that
- * isn't at a page boundary.
- *
- * This function returns an appropriately-aligned base offset
- * according to the tiling restrictions, plus any required x/y offset
- * from there.
- */
-uint32_t
-iris_resource_get_tile_offsets(const struct iris_resource *res,
-                               uint32_t level, uint32_t z,
-                               uint32_t *tile_x, uint32_t *tile_y)
-{
-   uint32_t x, y;
-   uint32_t mask_x, mask_y;
-
-   const struct isl_format_layout *fmtl = isl_format_get_layout(res->surf.format);
-   const unsigned cpp = fmtl->bpb / 8;
-
-   isl_get_tile_masks(res->surf.tiling, cpp, &mask_x, &mask_y);
-   get_image_offset_el(&res->surf, level, z, &x, &y);
-
-   *tile_x = x & mask_x;
-   *tile_y = y & mask_y;
-
-   return iris_resource_get_aligned_offset(res, x & ~mask_x, y & ~mask_y);
-}
-
 /**
  * Get pointer offset into stencil buffer.
  *
diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h
index 967ec036fd5..7d5720e5cc5 100644
--- a/src/gallium/drivers/iris/iris_resource.h
+++ b/src/gallium/drivers/iris/iris_resource.h
@@ -491,9 +491,6 @@ target_to_isl_surf_dim(enum pipe_texture_target target)
    unreachable("invalid texture type");
 }
 
-uint32_t iris_resource_get_tile_offsets(const struct iris_resource *res,
-                                        uint32_t level, uint32_t z,
-                                        uint32_t *tile_x, uint32_t *tile_y);
 enum isl_aux_usage iris_resource_texture_aux_usage(struct iris_context *ice,
                                                    const struct iris_resource *res,
                                                    enum isl_format view_fmt);
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 67929dd71bd..abb315ebdb4 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -2307,66 +2307,6 @@ update_surface_state_addrs(struct u_upload_mgr *mgr,
    return true;
 }
 
-#if GFX_VER == 8
-/**
- * Return an ISL surface for use with non-coherent render target reads.
- *
- * In a few complex cases, we can't use the SURFACE_STATE for normal render
- * target writes.  We need to make a separate one for sampling which refers
- * to the single slice of the texture being read.
- */
-static void
-get_rt_read_isl_surf(const struct intel_device_info *devinfo,
-                     struct iris_resource *res,
-                     enum pipe_texture_target target,
-                     struct isl_view *view,
-                     uint32_t *offset_to_tile,
-                     uint32_t *tile_x_sa,
-                     uint32_t *tile_y_sa,
-                     struct isl_surf *surf)
-{
-   *surf = res->surf;
-
-   const enum isl_dim_layout dim_layout =
-      iris_get_isl_dim_layout(devinfo, res->surf.tiling, target);
-
-   surf->dim = target_to_isl_surf_dim(target);
-
-   if (surf->dim_layout == dim_layout)
-      return;
-
-   /* The layout of the specified texture target is not compatible with the
-    * actual layout of the miptree structure in memory -- You're entering
-    * dangerous territory, this can only possibly work if you only intended
-    * to access a single level and slice of the texture, and the hardware
-    * supports the tile offset feature in order to allow non-tile-aligned
-    * base offsets, since we'll have to point the hardware to the first
-    * texel of the level instead of relying on the usual base level/layer
-    * controls.
-    */
-   assert(view->levels == 1 && view->array_len == 1);
-   assert(*tile_x_sa == 0 && *tile_y_sa == 0);
-
-   *offset_to_tile = iris_resource_get_tile_offsets(res, view->base_level,
-                                                    view->base_array_layer,
-                                                    tile_x_sa, tile_y_sa);
-   const unsigned l = view->base_level;
-
-   surf->logical_level0_px.width = minify(surf->logical_level0_px.width, l);
-   surf->logical_level0_px.height = surf->dim <= ISL_SURF_DIM_1D ? 1 :
-      minify(surf->logical_level0_px.height, l);
-   surf->logical_level0_px.depth = surf->dim <= ISL_SURF_DIM_2D ? 1 :
-      minify(surf->logical_level0_px.depth, l);
-
-   surf->logical_level0_px.array_len = 1;
-   surf->levels = 1;
-   surf->dim_layout = dim_layout;
-
-   view->base_level = 0;
-   view->base_array_layer = 0;
-}
-#endif
-
 static void
 fill_surface_state(struct isl_device *isl_dev,
                    void *map,
@@ -2577,11 +2517,6 @@ iris_create_surface(struct pipe_context *ctx,
    };
 
 #if GFX_VER == 8
-   enum pipe_texture_target target = (tex->target == PIPE_TEXTURE_3D &&
-                                      array_len == 1) ? PIPE_TEXTURE_2D :
-                                     tex->target == PIPE_TEXTURE_1D_ARRAY ?
-                                     PIPE_TEXTURE_2D_ARRAY : tex->target;
-
    struct isl_view *read_view = &surf->read_view;
    *read_view = (struct isl_view) {
       .format = fmt.fmt,
@@ -2592,6 +2527,39 @@ iris_create_surface(struct pipe_context *ctx,
       .swizzle = ISL_SWIZZLE_IDENTITY,
       .usage = ISL_SURF_USAGE_TEXTURE_BIT,
    };
+
+   struct isl_surf read_surf = res->surf;
+   uint32_t read_surf_offset_B = 0;
+   uint32_t read_surf_tile_x_sa = 0, read_surf_tile_y_sa = 0;
+   if (tex->target == PIPE_TEXTURE_3D && array_len == 1) {
+      /* The minimum array element field of the surface state structure is
+       * ignored by the sampler unit for 3D textures on some hardware.  If the
+       * render buffer is a single slice of a 3D texture, create a 2D texture
+       * covering that slice.
+       *
+       * TODO: This only handles the case where we're rendering to a single
+       * slice of an array texture.  If we have layered rendering combined
+       * with non-coherent FB fetch and a non-zero base_array_layer, then
+       * we're going to run into problems.
+       *
+       * See https://gitlab.freedesktop.org/mesa/mesa/-/issues/4904
+       */
+      isl_surf_get_image_surf(&screen->isl_dev, &res->surf,
+                              read_view->base_level,
+                              0, read_view->base_array_layer,
+                              &read_surf, &read_surf_offset_B,
+                              &read_surf_tile_x_sa, &read_surf_tile_y_sa);
+      read_view->base_level = 0;
+      read_view->base_array_layer = 0;
+      assert(read_view->array_len == 1);
+   } else if (tex->target == PIPE_TEXTURE_1D_ARRAY) {
+      /* Convert 1D array textures to 2D arrays because shaders always provide
+       * the array index coordinate at the Z component to avoid recompiles
+       * when changing the texture target of the framebuffer.
+       */
+      assert(read_surf.dim_layout == ISL_DIM_LAYOUT_GFX4_2D);
+      read_surf.dim = ISL_SURF_DIM_2D;
+   }
 #endif
 
    surf->clear_color = res->aux.clear_color;
@@ -2628,12 +2596,10 @@ iris_create_surface(struct pipe_context *ctx,
          map += SURFACE_STATE_ALIGNMENT;
 
 #if GFX_VER == 8
-         struct isl_surf surf;
-         uint32_t offset_to_tile = 0, tile_x_sa = 0, tile_y_sa = 0;
-         get_rt_read_isl_surf(devinfo, res, target, read_view,
-                              &offset_to_tile, &tile_x_sa, &tile_y_sa, &surf);
-         fill_surface_state(&screen->isl_dev, map_read, res, &surf, read_view,
-                            aux_usage, offset_to_tile, tile_x_sa, tile_y_sa);
+         fill_surface_state(&screen->isl_dev, map_read, res,
+                            &read_surf, read_view, aux_usage,
+                            read_surf_offset_B,
+                            read_surf_tile_x_sa, read_surf_tile_y_sa);
          map_read += SURFACE_STATE_ALIGNMENT;
 #endif
       }



More information about the mesa-commit mailing list