[Mesa-dev] [PATCH v2 16/32] intel/isl: Pull the uncompressed surface view code from anv

Jason Ekstrand jason at jlekstrand.net
Fri Oct 12 18:46:46 UTC 2018


This adds a helper isl_surf_get_uncompressed_surf for creating a surface
which provides an uncompressed view into a compressed surface.  The code
is basically a direct port of the uncompressed surface code from the
Vulkan driver which, in turn, was a port from BLORP.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/intel/isl/isl.c          | 75 ++++++++++++++++++++++++++++++++++++
 src/intel/isl/isl.h          | 29 ++++++++++++++
 src/intel/vulkan/anv_image.c | 34 ++--------------
 3 files changed, 107 insertions(+), 31 deletions(-)

diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
index a118da56c17..b8af8ad1176 100644
--- a/src/intel/isl/isl.c
+++ b/src/intel/isl/isl.c
@@ -2414,6 +2414,81 @@ isl_surf_get_image_surf(const struct isl_device *dev,
    assert(ok);
 }
 
+void
+isl_surf_get_uncompressed_surf(const struct isl_device *dev,
+                               const struct isl_surf *surf,
+                               const struct isl_view *view,
+                               struct isl_surf *ucompr_surf,
+                               struct isl_view *ucompr_view,
+                               uint32_t *offset_B,
+                               uint32_t *x_offset_el,
+                               uint32_t *y_offset_el)
+{
+   const struct isl_format_layout *fmtl =
+      isl_format_get_layout(surf->format);
+
+   assert(fmtl->bw > 1 || fmtl->bh > 1 || fmtl->bd > 1);
+   assert(isl_format_is_compressed(surf->format));
+   assert(!isl_format_is_compressed(view->format));
+   assert(isl_format_get_layout(view->format)->bpb == fmtl->bpb);
+   assert(view->levels == 1);
+
+   const uint32_t view_width =
+      isl_minify(surf->logical_level0_px.width, view->base_level);
+   const uint32_t view_height =
+      isl_minify(surf->logical_level0_px.height, view->base_level);
+
+   const uint32_t ucompr_width = isl_align_div_npot(view_width, fmtl->bw);
+   const uint32_t ucompr_height = isl_align_div_npot(view_height, fmtl->bh);
+
+   {
+      /* For legacy tilings, we just make a new 2D surface which represents
+       * the single slice of the main surface.  Due to hardware restrictions
+       * with intratile offsets, we can only handle a single slice.
+       */
+      assert(view->array_len == 1);
+
+      uint32_t x_offset_sa, y_offset_sa;
+      isl_surf_get_image_surf(dev, surf,
+                              view->base_level,
+                              surf->dim == ISL_SURF_DIM_3D ?
+                                 0 : view->base_array_layer,
+                              surf->dim == ISL_SURF_DIM_3D ?
+                                 view->base_array_layer : 0,
+                              ucompr_surf,
+                              offset_B, &x_offset_sa, &y_offset_sa);
+
+      ucompr_surf->format = view->format;
+
+      /* We're making an uncompressed view here.  The image dimensions
+       * need to be scaled down by the block size.
+       */
+      assert(ucompr_surf->logical_level0_px.width == view_width);
+      assert(ucompr_surf->logical_level0_px.height == view_height);
+      assert(ucompr_surf->logical_level0_px.depth == 1);
+      assert(ucompr_surf->logical_level0_px.array_len = 1);
+      ucompr_surf->logical_level0_px.width = ucompr_width;
+      ucompr_surf->logical_level0_px.height = ucompr_height;
+
+      assert(ucompr_surf->phys_level0_sa.width % fmtl->bw == 0);
+      assert(ucompr_surf->phys_level0_sa.height % fmtl->bh == 0);
+      assert(ucompr_surf->phys_level0_sa.depth == 1);
+      assert(ucompr_surf->phys_level0_sa.array_len == 1);
+      ucompr_surf->phys_level0_sa.width /= fmtl->bw;
+      ucompr_surf->phys_level0_sa.height /= fmtl->bh;
+
+      *x_offset_el = isl_assert_div(x_offset_sa, fmtl->bw);
+      *y_offset_el = isl_assert_div(y_offset_sa, fmtl->bh);
+
+      /* The newly created image represents the one subimage we're referencing
+       * with this view so it only has one array slice and miplevel.
+       */
+      *ucompr_view = *view;
+      ucompr_view->base_array_layer = 0;
+      ucompr_view->base_level = 0;
+   }
+}
+
 void
 isl_tiling_get_intratile_offset_el(enum isl_tiling tiling,
                                    enum isl_surf_dim dim,
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index 200bfbfa85b..213f5b408e2 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -2045,6 +2045,35 @@ isl_surf_get_image_surf(const struct isl_device *dev,
                         uint32_t *x_offset_sa,
                         uint32_t *y_offset_sa);
 
+/**
+ * Create an isl_surf that is an uncompressed view of a compressed isl_surf
+ *
+ * The incoming surface must have a compressed format.  The incoming view must
+ * be a valid view for the given surface with the exception that it's format
+ * is an umcompressed format with the same bpb as the surface format.  The
+ * incoming view must have isl_view::levels == 1.
+ *
+ * When the function returns, the resulting combination of uncompressed_surf
+ * and uncompressed_view will be a valid view giving an uncompressed view of
+ * the incoming surface.  Depending on tiling, uncompressed_surf may have a
+ * different isl_surf::dim from surf and uncompressed_view may or may not have
+ * a zero base_array_layer.  For legacy tiling (not Yf or Ys), an intratile
+ * offset is returned in x_offset_sa and y_offset_sa.  For standard Y tilings
+ * (Yf and Ys), x_offset_sa and y_offset_sa will be set to zero.
+ *
+ * It is safe to call this function with surf == uncompressed_surf and
+ * view == uncompressed_view.
+ */
+void
+isl_surf_get_uncompressed_surf(const struct isl_device *dev,
+                               const struct isl_surf *surf,
+                               const struct isl_view *view,
+                               struct isl_surf *uncompressed_surf,
+                               struct isl_view *uncompressed_view,
+                               uint32_t *offset_B,
+                               uint32_t *x_offset_el,
+                               uint32_t *y_offset_el);
+
 /**
  * @brief Calculate the intratile offsets to a surface.
  *
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index e89ce012be7..388f9410564 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -1129,37 +1129,9 @@ anv_image_fill_surface_state(struct anv_device *device,
          assert(view.levels == 1);
          assert(view.array_len == 1);
 
-         isl_surf_get_image_surf(&device->isl_dev, isl_surf,
-                                 view.base_level,
-                                 surface->isl.dim == ISL_SURF_DIM_3D ?
-                                    0 : view.base_array_layer,
-                                 surface->isl.dim == ISL_SURF_DIM_3D ?
-                                    view.base_array_layer : 0,
-                                 &tmp_surf,
-                                 &offset_B, &tile_x_sa, &tile_y_sa);
-
-         /* The newly created image represents the one subimage we're
-          * referencing with this view so it only has one array slice and
-          * miplevel.
-          */
-         view.base_array_layer = 0;
-         view.base_level = 0;
-
-         /* We're making an uncompressed view here.  The image dimensions need
-          * to be scaled down by the block size.
-          */
-         const struct isl_format_layout *fmtl =
-            isl_format_get_layout(surface->isl.format);
-         tmp_surf.format = view.format;
-         tmp_surf.logical_level0_px.width =
-            DIV_ROUND_UP(tmp_surf.logical_level0_px.width, fmtl->bw);
-         tmp_surf.logical_level0_px.height =
-            DIV_ROUND_UP(tmp_surf.logical_level0_px.height, fmtl->bh);
-         tmp_surf.phys_level0_sa.width /= fmtl->bw;
-         tmp_surf.phys_level0_sa.height /= fmtl->bh;
-         tile_x_sa /= fmtl->bw;
-         tile_y_sa /= fmtl->bh;
-
+         isl_surf_get_uncompressed_surf(&device->isl_dev, isl_surf, &view,
+                                        &tmp_surf, &view,
+                                        &offset_B, &tile_x_sa, &tile_y_sa);
          isl_surf = &tmp_surf;
 
          if (device->info.gen <= 8) {
-- 
2.19.1



More information about the mesa-dev mailing list