diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 3cbdf3c938a..cc0e58b74a0 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -719,6 +719,29 @@ free_aux_state_map(enum isl_aux_state **state) free(state); } +static bool +need_to_retile_as_linear(struct brw_context *brw, unsigned row_pitch, + enum isl_tiling tiling, unsigned samples) +{ + if (samples > 1) + return false; + + if (tiling == ISL_TILING_LINEAR) + return false; + + /* If the width is much smaller than a tile, don't bother tiling. */ + if (row_pitch < 64) + return true; + + if (ALIGN(row_pitch, 512) >= 32768) { + perf_debug("row pitch %u too large to blit, falling back to untiled", + row_pitch); + return true; + } + + return false; +} + static struct intel_mipmap_tree * make_surface(struct brw_context *brw, GLenum target, mesa_format format, unsigned first_level, unsigned last_level, @@ -767,6 +790,19 @@ make_surface(struct brw_context *brw, GLenum target, mesa_format format, if (!isl_surf_init_s(&brw->isl_dev, &mt->surf, &init_info)) goto fail; + /* In case caller doesn't specifically request Y-tiling (needed + * unconditionally for depth), check for corner cases needing special + * treatment. + */ + if (tiling_flags & ~ISL_TILING_Y0_BIT) { + if (need_to_retile_as_linear(brw, mt->surf.row_pitch, + mt->surf.tiling, mt->surf.samples)) { + init_info.tiling_flags = 1u << ISL_TILING_LINEAR; + if (!isl_surf_init_s(&brw->isl_dev, &mt->surf, &init_info)) + goto fail; + } + } + assert(mt->surf.size % mt->surf.row_pitch == 0); if (!bo) { |