[Mesa-dev] [v2 18/39] intel/isl/gen6: Add offsetting support for back-to-back layouts

Jason Ekstrand jason at jlekstrand.net
Mon May 8 19:05:24 UTC 2017


On Wed, May 3, 2017 at 2:22 AM, Topi Pohjolainen <topi.pohjolainen at gmail.com
> wrote:

> Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
> ---
>  src/intel/blorp/blorp_blit.c      |  2 +-
>  src/intel/isl/isl.c               | 29 +++++++++++++++++++++---
>  src/intel/isl/isl.h               | 14 ++++++++++--
>  src/intel/isl/isl_gen6.c          | 46 ++++++++++++++++++++++++++++++
> +++++++++
>  src/intel/isl/isl_storage_image.c |  3 ++-
>  5 files changed, 87 insertions(+), 7 deletions(-)
>
> diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
> index 8e3fc31..ca42600 100644
> --- a/src/intel/blorp/blorp_blit.c
> +++ b/src/intel/blorp/blorp_blit.c
> @@ -1398,7 +1398,7 @@ surf_convert_to_single_slice(const struct
> isl_device *isl_dev,
>        layer = info->view.base_array_layer;
>
>     uint32_t x_offset_sa, y_offset_sa;
> -   isl_surf_get_image_offset_sa(&info->surf, info->view.base_level,
> +   isl_surf_get_image_offset_sa(isl_dev, &info->surf,
> info->view.base_level,
>                                  layer, z, &x_offset_sa, &y_offset_sa);
>
>     uint32_t byte_offset;
> diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
> index f89f351..e06bb94 100644
> --- a/src/intel/isl/isl.c
> +++ b/src/intel/isl/isl.c
> @@ -1295,6 +1295,20 @@ isl_apply_surface_padding(const struct isl_device
> *dev,
>     }
>  }
>
> +/* On Gen6 hardware doesn't support mipmapping for stencil (W-tiled) and
> + * for HIZ. As workaround one places all slices back-to-back. Slices for
> + * level zero are back-to-back, followed by slices to level one, etc. This
> + * allows layered rendering once driver offsets the image to the first
> + * slice of particular level.
> + */
> +static bool
> +isl_surf_needs_back_to_back_layout(const struct isl_device *dev,
> +                                   enum isl_tiling tiling)
> +{
> +   return ISL_DEV_GEN(dev) == 6 &&
> +          (tiling == ISL_TILING_W || tiling == ISL_TILING_HIZ);
>

If we're going to have a new back-to-back layout, let's just make a new
ISL_DIM_LAYOUT_GEN6_BACK_TO_ BACK layout.  One of the things ISL tries very
hard to do is to make sure that the isl_surf contains 100% of the
information required to understand the surface layout.


> +}
> +
>  bool
>  isl_surf_init_s(const struct isl_device *dev,
>                  struct isl_surf *surf,
> @@ -1906,7 +1920,8 @@ get_image_offset_sa_gen9_1d(const struct isl_surf
> *surf,
>   * @invariant logical_z_offset_px < logical depth of surface at level
>   */
>  void
> -isl_surf_get_image_offset_sa(const struct isl_surf *surf,
> +isl_surf_get_image_offset_sa(const struct isl_device *dev,
> +                             const struct isl_surf *surf,
>                               uint32_t level,
>                               uint32_t logical_array_layer,
>                               uint32_t logical_z_offset_px,
> @@ -1918,6 +1933,13 @@ isl_surf_get_image_offset_sa(const struct isl_surf
> *surf,
>     assert(logical_z_offset_px
>            < isl_minify(surf->logical_level0_px.depth, level));
>
> +   if (isl_surf_needs_back_to_back_layout(dev, surf->tiling)) {
> +      get_image_offset_sa_gen6_back_to_back(surf, level,
> logical_array_layer,
> +                                            logical_z_offset_px,
> +                                            x_offset_sa, y_offset_sa);
> +      return;
> +   }
> +
>     switch (surf->dim_layout) {
>     case ISL_DIM_LAYOUT_GEN9_1D:
>        get_image_offset_sa_gen9_1d(surf, level, logical_array_layer,
> @@ -1939,7 +1961,8 @@ isl_surf_get_image_offset_sa(const struct isl_surf
> *surf,
>  }
>
>  void
> -isl_surf_get_image_offset_el(const struct isl_surf *surf,
> +isl_surf_get_image_offset_el(const struct isl_device *dev,
> +                             const struct isl_surf *surf,
>                               uint32_t level,
>                               uint32_t logical_array_layer,
>                               uint32_t logical_z_offset_px,
> @@ -1954,7 +1977,7 @@ isl_surf_get_image_offset_el(const struct isl_surf
> *surf,
>            < isl_minify(surf->logical_level0_px.depth, level));
>
>     uint32_t x_offset_sa, y_offset_sa;
> -   isl_surf_get_image_offset_sa(surf, level,
> +   isl_surf_get_image_offset_sa(dev, surf, level,
>                                  logical_array_layer,
>                                  logical_z_offset_px,
>                                  &x_offset_sa,
> diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
> index 7778551..3685ddf 100644
> --- a/src/intel/isl/isl.h
> +++ b/src/intel/isl/isl.h
> @@ -1484,6 +1484,14 @@ isl_surf_get_array_pitch(const struct isl_surf
> *surf)
>     return isl_surf_get_array_pitch_sa_rows(surf) * surf->row_pitch;
>  }
>
> +void
> +get_image_offset_sa_gen6_back_to_back(const struct isl_surf *surf,
> +                                      uint32_t level,
> +                                      uint32_t logical_array_layer,
> +                                      uint32_t logical_z_offset_px,
> +                                      uint32_t *x_offset_sa,
> +                                      uint32_t *y_offset_sa);
> +
>  /**
>   * Calculate the offset, in units of surface samples, to a subimage in the
>   * surface.
> @@ -1493,7 +1501,8 @@ isl_surf_get_array_pitch(const struct isl_surf *surf)
>   * @invariant logical_z_offset_px < logical depth of surface at level
>   */
>  void
> -isl_surf_get_image_offset_sa(const struct isl_surf *surf,
> +isl_surf_get_image_offset_sa(const struct isl_device *dev,
> +                             const struct isl_surf *surf,
>                               uint32_t level,
>                               uint32_t logical_array_layer,
>                               uint32_t logical_z_offset_px,
> @@ -1509,7 +1518,8 @@ isl_surf_get_image_offset_sa(const struct isl_surf
> *surf,
>   * @invariant logical_z_offset_px < logical depth of surface at level
>   */
>  void
> -isl_surf_get_image_offset_el(const struct isl_surf *surf,
> +isl_surf_get_image_offset_el(const struct isl_device *dev,
> +                             const struct isl_surf *surf,
>                               uint32_t level,
>                               uint32_t logical_array_layer,
>                               uint32_t logical_z_offset_px,
> diff --git a/src/intel/isl/isl_gen6.c b/src/intel/isl/isl_gen6.c
> index b746903..8bd5dbc 100644
> --- a/src/intel/isl/isl_gen6.c
> +++ b/src/intel/isl/isl_gen6.c
> @@ -145,3 +145,49 @@ isl_gen6_choose_image_alignment_el(const struct
> isl_device *dev,
>
>     *image_align_el = isl_extent3d(4, 2, 1);
>  }
> +
> +void
> +get_image_offset_sa_gen6_back_to_back(const struct isl_surf *surf,
> +                                      uint32_t level,
> +                                      uint32_t logical_array_layer,
> +                                      uint32_t logical_z_offset_px,
> +                                      uint32_t *x_offset_sa,
> +                                      uint32_t *y_offset_sa)
> +{
> +   assert(level < surf->levels);
> +
> +   const struct isl_extent3d image_align_sa =
> +      isl_surf_get_image_alignment_sa(surf);
> +
> +   assert(surf->tiling == ISL_TILING_W ||
> +          surf->tiling == ISL_TILING_HIZ);
> +   const uint32_t tile_align_h = surf->tiling == ISL_TILING_W ? 64 : 32;
> +
> +   uint32_t y = 0;
> +   for (unsigned i = 0; i < level; ++i) {
> +      const unsigned d = surf->dim_layout == ISL_DIM_LAYOUT_GEN4_3D ?
> +                         isl_minify(surf->phys_level0_sa.depth, i) :
> +                         surf->phys_level0_sa.array_len;
> +      const unsigned h = isl_minify(surf->phys_level0_sa.height, i);
> +      y += d * isl_align_npot(h, image_align_sa.h);
> +
> +      /* Align on tile boundary so that driver can offset without
> intra-tile
> +       * offsets.
> +       */
> +      y = isl_align(y, tile_align_h);
> +   }
> +
> +   const unsigned level_h = isl_minify(surf->phys_level0_sa.height,
> level);
> +   const unsigned aligned_level_h = isl_align_npot(level_h,
> image_align_sa.h);
> +
> +   if (surf->dim_layout == ISL_DIM_LAYOUT_GEN4_3D) {
> +      assert(logical_z_offset_px < surf->logical_level0_px.depth);
> +      y += logical_z_offset_px * aligned_level_h;
> +   } else {
> +      assert(logical_array_layer < surf->logical_level0_px.array_len);
> +      y += logical_array_layer * aligned_level_h;
> +   }
> +
> +   *x_offset_sa = 0;
> +   *y_offset_sa = y;
> +}
> diff --git a/src/intel/isl/isl_storage_image.c
> b/src/intel/isl/isl_storage_image.c
> index 4c56e78..9aeeede 100644
> --- a/src/intel/isl/isl_storage_image.c
> +++ b/src/intel/isl/isl_storage_image.c
> @@ -226,7 +226,8 @@ isl_surf_fill_image_param(const struct isl_device
> *dev,
>                         view->base_array_layer;
>     }
>
> -   isl_surf_get_image_offset_el(surf, view->base_level,
> view->base_array_layer,
> +   isl_surf_get_image_offset_el(dev, surf,
> +                                view->base_level, view->base_array_layer,
>                                  0, &param->offset[0],  &param->offset[1]);
>
>     const int cpp = isl_format_get_layout(surf->format)->bpb / 8;
> --
> 2.9.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170508/2f29a0d2/attachment-0001.html>


More information about the mesa-dev mailing list