[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, ¶m->offset[0], ¶m->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