[Mesa-dev] [PATCH 2/6] intel/isl: Introduce tiled image offset

Topi Pohjolainen topi.pohjolainen at gmail.com
Wed Jul 26 19:28:34 UTC 2017


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/intel/blorp/blorp_blit.c           | 19 ++++++++------
 src/intel/isl/isl.c                    | 44 +++++++++++++++----------------
 src/intel/isl/isl.h                    | 29 +++++++++++----------
 src/mesa/drivers/dri/i965/intel_blit.c | 47 +++++++++++++++++++---------------
 4 files changed, 73 insertions(+), 66 deletions(-)

diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
index ed00516373..db675dc1e4 100644
--- a/src/intel/blorp/blorp_blit.c
+++ b/src/intel/blorp/blorp_blit.c
@@ -1405,12 +1405,14 @@ blorp_surf_convert_to_single_slice(const struct isl_device *isl_dev,
    else
       layer = info->view.base_array_layer;
 
-   uint32_t byte_offset;
+   struct isl_image_offset image_offset;
    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;
+                           &image_offset);
+   info->addr.offset += image_offset.tile_aligned_byte_offset;
+   info->tile_x_sa = image_offset.intra_tile_x;
+   info->tile_y_sa = image_offset.intra_tile_y;
 
    uint32_t tile_x_px, tile_y_px;
    surf_get_intratile_offset_px(info, &tile_x_px, &tile_y_px);
@@ -1905,7 +1907,8 @@ shrink_surface_params(const struct isl_device *dev,
                       struct brw_blorp_surface_info *info,
                       double *x0, double *x1, double *y0, double *y1)
 {
-   uint32_t byte_offset, x_offset_sa, y_offset_sa, size;
+   uint32_t x_offset_sa, y_offset_sa, size;
+   struct isl_image_offset image_offset;
    struct isl_extent2d px_size_sa;
    int adjust;
 
@@ -1922,10 +1925,10 @@ shrink_surface_params(const struct isl_device *dev,
    isl_tiling_get_intratile_offset_sa(info->surf.tiling,
                                       info->surf.format, info->surf.row_pitch,
                                       x_offset_sa, y_offset_sa,
-                                      &byte_offset,
-                                      &info->tile_x_sa, &info->tile_y_sa);
-
-   info->addr.offset += byte_offset;
+                                      &image_offset);
+   info->addr.offset += image_offset.tile_aligned_byte_offset;
+   info->tile_x_sa = image_offset.intra_tile_x;
+   info->tile_y_sa = image_offset.intra_tile_y;
 
    adjust = (int)info->tile_x_sa / px_size_sa.w - (int)*x0;
    *x0 += adjust;
diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
index 5e3d279b0b..8431d18639 100644
--- a/src/intel/isl/isl.c
+++ b/src/intel/isl/isl.c
@@ -2295,25 +2295,25 @@ isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf,
                                 &total_x_offset_el,
                                 &total_y_offset_el);
 
-   uint32_t x_offset_el, y_offset_el;
+   struct isl_image_offset image_offset;
    isl_tiling_get_intratile_offset_el(surf->tiling, fmtl->bpb,
                                       surf->row_pitch,
                                       total_x_offset_el,
                                       total_y_offset_el,
-                                      offset_B,
-                                      &x_offset_el,
-                                      &y_offset_el);
+                                      &image_offset);
+
+   *offset_B = image_offset.tile_aligned_byte_offset;
 
    if (x_offset_sa) {
-      *x_offset_sa = x_offset_el * fmtl->bw;
+      *x_offset_sa = image_offset.intra_tile_x * fmtl->bw;
    } else {
-      assert(x_offset_el == 0);
+      assert(image_offset.intra_tile_x == 0);
    }
 
    if (y_offset_sa) {
-      *y_offset_sa = y_offset_el * fmtl->bh;
+      *y_offset_sa = image_offset.intra_tile_y * fmtl->bh;
    } else {
-      assert(y_offset_el == 0);
+      assert(image_offset.intra_tile_y == 0);
    }
 }
 
@@ -2324,17 +2324,15 @@ isl_surf_get_image_surf(const struct isl_device *dev,
                         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)
+                        struct isl_image_offset *offset)
 {
    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);
+                                       &offset->tile_aligned_byte_offset,
+                                       &offset->intra_tile_x,
+                                       &offset->intra_tile_y);
 
    /* Even for cube maps there will be only single face, therefore drop the
     * corresponding flag if present.
@@ -2364,16 +2362,14 @@ isl_tiling_get_intratile_offset_el(enum isl_tiling tiling,
                                    uint32_t row_pitch,
                                    uint32_t total_x_offset_el,
                                    uint32_t total_y_offset_el,
-                                   uint32_t *base_address_offset,
-                                   uint32_t *x_offset_el,
-                                   uint32_t *y_offset_el)
+                                   struct isl_image_offset *offset)
 {
    if (tiling == ISL_TILING_LINEAR) {
       assert(bpb % 8 == 0);
-      *base_address_offset = total_y_offset_el * row_pitch +
-                             total_x_offset_el * (bpb / 8);
-      *x_offset_el = 0;
-      *y_offset_el = 0;
+      offset->tile_aligned_byte_offset = total_y_offset_el * row_pitch +
+                                         total_x_offset_el * (bpb / 8);
+      offset->intra_tile_x = 0;
+      offset->intra_tile_y = 0;
       return;
    }
 
@@ -2395,14 +2391,14 @@ isl_tiling_get_intratile_offset_el(enum isl_tiling tiling,
    tile_info.phys_extent_B.width *= tile_el_scale;
 
    /* Compute the offset into the tile */
-   *x_offset_el = total_x_offset_el % tile_info.logical_extent_el.w;
-   *y_offset_el = total_y_offset_el % tile_info.logical_extent_el.h;
+   offset->intra_tile_x = total_x_offset_el % tile_info.logical_extent_el.w;
+   offset->intra_tile_y = total_y_offset_el % tile_info.logical_extent_el.h;
 
    /* Compute the offset of the tile in units of whole tiles */
    uint32_t x_offset_tl = total_x_offset_el / tile_info.logical_extent_el.w;
    uint32_t y_offset_tl = total_y_offset_el / tile_info.logical_extent_el.h;
 
-   *base_address_offset =
+   offset->tile_aligned_byte_offset =
       y_offset_tl * tile_info.phys_extent_B.h * row_pitch +
       x_offset_tl * tile_info.phys_extent_B.h * tile_info.phys_extent_B.w;
 }
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index dafe952298..6e5e6c79be 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -1367,6 +1367,16 @@ struct isl_depth_stencil_hiz_emit_info {
    float depth_clear_value;
 };
 
+/**
+ * Offset to an individual images in a surface in terms of tiles. Byte offset
+ * gives the tile and intra_tile_x/y the position within the tile.
+ */
+struct isl_image_offset {
+   uint32_t tile_aligned_byte_offset;
+   uint32_t intra_tile_x;
+   uint32_t intra_tile_y;
+};
+
 extern const struct isl_format_layout isl_format_layouts[];
 
 void
@@ -1860,9 +1870,7 @@ isl_surf_get_image_surf(const struct isl_device *dev,
                         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);
+                        struct isl_image_offset *offset);
 
 /**
  * @brief Calculate the intratile offsets to a surface.
@@ -1880,9 +1888,7 @@ isl_tiling_get_intratile_offset_el(enum isl_tiling tiling,
                                    uint32_t row_pitch,
                                    uint32_t total_x_offset_el,
                                    uint32_t total_y_offset_el,
-                                   uint32_t *base_address_offset,
-                                   uint32_t *x_offset_el,
-                                   uint32_t *y_offset_el);
+                                   struct isl_image_offset *offset);
 
 static inline void
 isl_tiling_get_intratile_offset_sa(enum isl_tiling tiling,
@@ -1890,9 +1896,7 @@ isl_tiling_get_intratile_offset_sa(enum isl_tiling tiling,
                                    uint32_t row_pitch,
                                    uint32_t total_x_offset_sa,
                                    uint32_t total_y_offset_sa,
-                                   uint32_t *base_address_offset,
-                                   uint32_t *x_offset_sa,
-                                   uint32_t *y_offset_sa)
+                                   struct isl_image_offset *offset)
 {
    const struct isl_format_layout *fmtl = isl_format_get_layout(format);
 
@@ -1907,10 +1911,9 @@ isl_tiling_get_intratile_offset_sa(enum isl_tiling tiling,
 
    isl_tiling_get_intratile_offset_el(tiling, fmtl->bpb, row_pitch,
                                       total_x_offset, total_y_offset,
-                                      base_address_offset,
-                                      x_offset_sa, y_offset_sa);
-   *x_offset_sa *= fmtl->bw;
-   *y_offset_sa *= fmtl->bh;
+                                      offset);
+   offset->intra_tile_x *= fmtl->bw;
+   offset->intra_tile_y *= fmtl->bh;
 }
 
 /**
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c
index eca8736804..e7338bdf46 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.c
+++ b/src/mesa/drivers/dri/i965/intel_blit.c
@@ -167,15 +167,12 @@ get_blit_intratile_offset_el(const struct brw_context *brw,
                              struct intel_mipmap_tree *mt,
                              uint32_t total_x_offset_el,
                              uint32_t total_y_offset_el,
-                             uint32_t *base_address_offset,
-                             uint32_t *x_offset_el,
-                             uint32_t *y_offset_el)
+                             struct isl_image_offset *image_offset)
 {
    isl_tiling_get_intratile_offset_el(mt->surf.tiling,
                                       mt->cpp * 8, mt->surf.row_pitch,
                                       total_x_offset_el, total_y_offset_el,
-                                      base_address_offset,
-                                      x_offset_el, y_offset_el);
+                                      image_offset);
    if (mt->surf.tiling == ISL_TILING_LINEAR) {
       /* From the Broadwell PRM docs for XY_SRC_COPY_BLT::SourceBaseAddress:
        *
@@ -188,12 +185,12 @@ get_blit_intratile_offset_el(const struct brw_context *brw,
        * In the linear case, we need to do some of our own aligning.
        */
       assert(mt->surf.row_pitch % 64 == 0);
-      uint32_t delta = *base_address_offset & 63;
+      uint32_t delta = image_offset->tile_aligned_byte_offset & 63;
       assert(delta % mt->cpp == 0);
-      *base_address_offset -= delta;
-      *x_offset_el += delta / mt->cpp;
+      image_offset->tile_aligned_byte_offset -= delta;
+      image_offset->intra_tile_x += delta / mt->cpp;
    } else {
-      assert(*base_address_offset % 4096 == 0);
+      assert(image_offset->tile_aligned_byte_offset % 4096 == 0);
    }
 }
 
@@ -239,27 +236,33 @@ emit_miptree_blit(struct brw_context *brw,
          const uint32_t chunk_w = MIN2(max_chunk_size, width - chunk_x);
          const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y);
 
-         uint32_t src_offset, src_tile_x, src_tile_y;
+         struct isl_image_offset src_offset;
          get_blit_intratile_offset_el(brw, src_mt,
                                       src_x + chunk_x, src_y + chunk_y,
-                                      &src_offset, &src_tile_x, &src_tile_y);
+                                      &src_offset);
 
-         uint32_t dst_offset, dst_tile_x, dst_tile_y;
+         struct isl_image_offset dst_offset;
          get_blit_intratile_offset_el(brw, dst_mt,
                                       dst_x + chunk_x, dst_y + chunk_y,
-                                      &dst_offset, &dst_tile_x, &dst_tile_y);
+                                      &dst_offset);
 
          if (!intelEmitCopyBlit(brw,
                                 src_mt->cpp,
                                 reverse ? -src_mt->surf.row_pitch :
                                            src_mt->surf.row_pitch,
-                                src_mt->bo, src_mt->offset + src_offset,
+                                src_mt->bo,
+                                src_mt->offset +
+                                   src_offset.tile_aligned_byte_offset,
                                 src_mt->surf.tiling,
                                 dst_mt->surf.row_pitch,
-                                dst_mt->bo, dst_mt->offset + dst_offset,
+                                dst_mt->bo,
+                                dst_mt->offset +
+                                   dst_offset.tile_aligned_byte_offset,
                                 dst_mt->surf.tiling,
-                                src_tile_x, src_tile_y,
-                                dst_tile_x, dst_tile_y,
+                                src_offset.intra_tile_x,
+                                src_offset.intra_tile_y,
+                                dst_offset.intra_tile_x,
+                                dst_offset.intra_tile_y,
                                 chunk_w, chunk_h,
                                 logicop)) {
             /* If this is ever going to fail, it will fail on the first chunk */
@@ -816,10 +819,12 @@ intel_miptree_set_alpha_to_one(struct brw_context *brw,
          const uint32_t chunk_w = MIN2(max_chunk_size, width - chunk_x);
          const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y);
 
-         uint32_t offset, tile_x, tile_y;
+         struct isl_image_offset image_offset;
          get_blit_intratile_offset_el(brw, mt,
                                       x + chunk_x, y + chunk_y,
-                                      &offset, &tile_x, &tile_y);
+                                      &image_offset);
+
+         /* BUG: intra tile offsets are ignored. */
 
          BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, false);
          OUT_BATCH(CMD | (length - 2));
@@ -831,11 +836,11 @@ intel_miptree_set_alpha_to_one(struct brw_context *brw,
          if (brw->gen >= 8) {
             OUT_RELOC64(mt->bo,
                         I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-                        offset);
+                        image_offset.tile_aligned_byte_offset);
          } else {
             OUT_RELOC(mt->bo,
                       I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-                      offset);
+                      image_offset.tile_aligned_byte_offset);
          }
          OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
          ADVANCE_BATCH_TILED(dst_y_tiled, false);
-- 
2.11.0



More information about the mesa-dev mailing list