[Mesa-dev] [PATCH 05/11] intel/isl: Add a helper to get a subimage surface

Jason Ekstrand jason at jlekstrand.net
Wed Jul 12 00:04:34 UTC 2017


---
 src/intel/blorp/blorp_blit.c | 38 +++++++++++++-------------------------
 src/intel/isl/isl.c          | 35 +++++++++++++++++++++++++++++++++++
 src/intel/isl/isl.h          | 23 +++++++++++++++++++++++
 3 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
index 0850473..6407808 100644
--- a/src/intel/blorp/blorp_blit.c
+++ b/src/intel/blorp/blorp_blit.c
@@ -1406,36 +1406,24 @@ blorp_surf_convert_to_single_slice(const struct isl_device *isl_dev,
       layer = info->view.base_array_layer;
 
    uint32_t byte_offset;
-   isl_surf_get_image_offset_B_tile_sa(&info->surf,
-                                       info->view.base_level, layer, z,
-                                       &byte_offset,
-                                       &info->tile_x_sa, &info->tile_y_sa);
+   isl_surf_get_image_surf(isl_dev, &info->surf,
+                           info->view.base_level, layer, z,
+                           &info->surf,
+                           &byte_offset, &info->tile_x_sa, &info->tile_y_sa);
    info->addr.offset += byte_offset;
 
-   const uint32_t slice_width_px =
-      minify(info->surf.logical_level0_px.width, info->view.base_level);
-   const uint32_t slice_height_px =
-      minify(info->surf.logical_level0_px.height, info->view.base_level);
-
    uint32_t tile_x_px, tile_y_px;
    surf_get_intratile_offset_px(info, &tile_x_px, &tile_y_px);
 
-   struct isl_surf_init_info init_info = {
-      .dim = ISL_SURF_DIM_2D,
-      .format = info->surf.format,
-      .width = slice_width_px + tile_x_px,
-      .height = slice_height_px + tile_y_px,
-      .depth = 1,
-      .levels = 1,
-      .array_len = 1,
-      .samples = info->surf.samples,
-      .row_pitch = info->surf.row_pitch,
-      .usage = info->surf.usage,
-      .tiling_flags = 1 << info->surf.tiling,
-   };
-
-   ok = isl_surf_init_s(isl_dev, &info->surf, &init_info);
-   assert(ok);
+   /* Instead of using the X/Y Offset fields in RENDER_SURFACE_STATE, we place
+    * the image at the tile boundary and offset our sampling or rendering.
+    * For this reason, we need to grow the image by the offset to ensure that
+    * the hardware doesn't think we've gone past the edge.
+    */
+   info->surf.logical_level0_px.w += tile_x_px;
+   info->surf.logical_level0_px.h += tile_y_px;
+   info->surf.phys_level0_sa.w += info->tile_x_sa;
+   info->surf.phys_level0_sa.h += info->tile_y_sa;
 
    /* The view is also different now. */
    info->view.base_level = 0;
diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
index ba56d86..ce25c63 100644
--- a/src/intel/isl/isl.c
+++ b/src/intel/isl/isl.c
@@ -2221,6 +2221,41 @@ isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf,
 }
 
 void
+isl_surf_get_image_surf(const struct isl_device *dev,
+                        const struct isl_surf *surf,
+                        uint32_t level,
+                        uint32_t logical_array_layer,
+                        uint32_t logical_z_offset_px,
+                        struct isl_surf *image_surf,
+                        uint32_t *offset_B,
+                        uint32_t *x_offset_sa,
+                        uint32_t *y_offset_sa)
+{
+   isl_surf_get_image_offset_B_tile_sa(surf,
+                                       level,
+                                       logical_array_layer,
+                                       logical_z_offset_px,
+                                       offset_B,
+                                       x_offset_sa,
+                                       y_offset_sa);
+
+   bool ok UNUSED;
+   ok = isl_surf_init(dev, image_surf,
+                      .dim = ISL_SURF_DIM_2D,
+                      .format = surf->format,
+                      .width = isl_minify(surf->logical_level0_px.w, level),
+                      .height = isl_minify(surf->logical_level0_px.h, level),
+                      .depth = 1,
+                      .levels = 1,
+                      .array_len = 1,
+                      .samples = surf->samples,
+                      .row_pitch = surf->row_pitch,
+                      .usage = surf->usage,
+                      .tiling_flags = (1 << surf->tiling));
+   assert(ok);
+}
+
+void
 isl_tiling_get_intratile_offset_el(enum isl_tiling tiling,
                                    uint32_t bpb,
                                    uint32_t row_pitch,
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index 07ff01a..94784e2 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -1780,6 +1780,29 @@ isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf,
                                     uint32_t *y_offset_sa);
 
 /**
+ * Create an isl_surf that represents a particular subimage in the surface.
+ *
+ * The newly created surface will have a single miplevel and array slice.  The
+ * surface lives at the returned byte and intratile offsets, in samples.
+ *
+ * It is safe to call this function with surf == image_surf.
+ *
+ * @invariant level < surface levels
+ * @invariant logical_array_layer < logical array length of surface
+ * @invariant logical_z_offset_px < logical depth of surface at level
+ */
+void
+isl_surf_get_image_surf(const struct isl_device *dev,
+                        const struct isl_surf *surf,
+                        uint32_t level,
+                        uint32_t logical_array_layer,
+                        uint32_t logical_z_offset_px,
+                        struct isl_surf *image_surf,
+                        uint32_t *offset_B,
+                        uint32_t *x_offset_sa,
+                        uint32_t *y_offset_sa);
+
+/**
  * @brief Calculate the intratile offsets to a surface.
  *
  * In @a base_address_offset return the offset from the base of the surface to
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list