From c9dbdc08b9de016ab3b076feac3df4c81009996e Mon Sep 17 00:00:00 2001 From: Anuj Phogat Date: Tue, 14 Apr 2015 22:06:49 -0700 Subject: [PATCH] i965/gen9: Plugin the code for selecting YF/YS tiling on skl+ Buffers with Yf/Ys tiling end up using meta upload / download paths or the blitter for cases where they used tiled_memcpy paths in case of Y tiling. This has exposed some bugs in meta path. To avoid any piglit regressions on SKL this patch keeps the Yf/Ys tiling disabled at the moment. V3: Make brw_miptree_choose_tr_mode() actually choose TRMODE. (Ben) Few cosmetic changes. V4: Get rid of brw_miptree_choose_tr_mode(). Take care of all tile resource modes {Yf, Ys, none} for all generations at one place. Signed-off-by: Anuj Phogat Reviewed-by: Ben Widawsky --- src/mesa/drivers/dri/i965/brw_tex_layout.c | 96 ++++++++++++++++++---- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index e35cb645c24..45bbf7e7d0f 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -810,27 +810,89 @@ brw_miptree_layout(struct brw_context *brw, enum intel_miptree_tiling_mode requested, uint32_t layout_flags) { - mt->tr_mode = INTEL_MIPTREE_TRMODE_NONE; + const unsigned bpp = mt->cpp * 8; + /* Enable YF/YS tiling only for color surfaces because depth and + * stencil surfaces are not supported in blitter using fast copy + * blit and meta PBO upload, download paths. No other paths + * currently support Yf/Ys tiled surfaces. + * FINISHME: Remove this restriction once we have a tiled_memcpy() + * path to do depth/stencil data upload/download to Yf/Ys tiled + * surfaces. + */ + const bool is_tr_mode_yf_ys_allowed = + brw->gen >= 9 && + !(layout_flags & MIPTREE_LAYOUT_FOR_BO) && + !mt->compressed && + _mesa_is_format_color_format(mt->format) && + (requested == INTEL_MIPTREE_TILING_Y || + requested == INTEL_MIPTREE_TILING_ANY) && + (bpp && is_power_of_two(bpp)) && + /* FIXME: To avoid piglit regressions keep the Yf/Ys tiling + * disabled at the moment. + */ + false; - intel_miptree_set_alignment(brw, mt, layout_flags); - intel_miptree_set_total_width_height(brw, mt); + /* Lower index (Yf) is the higher priority mode */ + const uint32_t tr_mode[3] = {INTEL_MIPTREE_TRMODE_YF, + INTEL_MIPTREE_TRMODE_YS, + INTEL_MIPTREE_TRMODE_NONE}; + int i = is_tr_mode_yf_ys_allowed ? 0 : ARRAY_SIZE(tr_mode) - 1; - if (!mt->total_width || !mt->total_height) { - intel_miptree_release(&mt); - return; - } + while (i < ARRAY_SIZE(tr_mode)) { + if (brw->gen < 9) + assert(tr_mode[i] == INTEL_MIPTREE_TRMODE_NONE); + else + assert(tr_mode[i] == INTEL_MIPTREE_TRMODE_YF || + tr_mode[i] == INTEL_MIPTREE_TRMODE_YS || + tr_mode[i] == INTEL_MIPTREE_TRMODE_NONE); - /* On Gen9+ the alignment values are expressed in multiples of the block - * size - */ - if (brw->gen >= 9) { - unsigned int i, j; - _mesa_get_format_block_size(mt->format, &i, &j); - mt->align_w /= i; - mt->align_h /= j; - } + mt->tr_mode = tr_mode[i]; + intel_miptree_set_alignment(brw, mt, layout_flags); + intel_miptree_set_total_width_height(brw, mt); + + if (!mt->total_width || !mt->total_height) { + intel_miptree_release(&mt); + break; + } + + /* On Gen9+ the alignment values are expressed in multiples of the + * block size. + */ + if (brw->gen >= 9) { + unsigned int i, j; + _mesa_get_format_block_size(mt->format, &i, &j); + mt->align_w /= i; + mt->align_h /= j; + } + + /* If there is already a BO, we cannot effect tiling modes */ + if (layout_flags & MIPTREE_LAYOUT_FOR_BO) + break; - if ((layout_flags & MIPTREE_LAYOUT_FOR_BO) == 0) mt->tiling = brw_miptree_choose_tiling(brw, requested, mt); + if (is_tr_mode_yf_ys_allowed) { + unsigned int level = 0; + + if (mt->tiling == I915_TILING_Y || + mt->tiling == (I915_TILING_Y | I915_TILING_X) || + mt->tr_mode == INTEL_MIPTREE_TRMODE_NONE) { + /* FIXME: Don't allow YS tiling at the moment. Using 64KB tiling + * for small textures might result in to memory wastage. Revisit + * this condition when we have more information about the specific + * cases where using YS over YF will be useful. + */ + if (mt->tr_mode != INTEL_MIPTREE_TRMODE_YS) + break; + } + /* Failed to use selected tr_mode. Free up the memory allocated + * for miptree levels in intel_miptree_total_width_height(). + */ + for (level = mt->first_level; level <= mt->last_level; level++) { + free(mt->level[level].slice); + mt->level[level].slice = NULL; + } + } + i++; + } } -- 2.30.2