On Wed, May 3, 2017 at 2:22 AM, Topi Pohjolainen <topi.pohjolai...@gmail.com > wrote:
> Signed-off-by: Topi Pohjolainen <topi.pohjolai...@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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev