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); +} + 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