}
if (inplace_planes) {
- bool has_htile = si_htile_enabled(tex, first_level);
- bool tc_compat_htile = vi_tc_compat_htile_enabled(tex, first_level);
+ bool has_htile = si_htile_enabled(tex, first_level, inplace_planes);
+ bool tc_compat_htile = vi_tc_compat_htile_enabled(tex, first_level,
+ inplace_planes);
/* Don't decompress if there is no HTILE or when HTILE is
* TC-compatible. */
}
if (zstex &&
- si_htile_enabled(zstex, zsbuf->u.tex.level) &&
zsbuf->u.tex.first_layer == 0 &&
zsbuf->u.tex.last_layer == util_max_layer(&zstex->buffer.b.b, 0)) {
/* TC-compatible HTILE only supports depth clears to 0 or 1. */
if (buffers & PIPE_CLEAR_DEPTH &&
+ si_htile_enabled(zstex, zsbuf->u.tex.level, PIPE_MASK_Z) &&
(!zstex->tc_compatible_htile ||
depth == 0 || depth == 1)) {
/* Need to disable EXPCLEAR temporarily if clearing
/* TC-compatible HTILE only supports stencil clears to 0. */
if (buffers & PIPE_CLEAR_STENCIL &&
+ si_htile_enabled(zstex, zsbuf->u.tex.level, PIPE_MASK_S) &&
(!zstex->tc_compatible_htile || stencil == 0)) {
stencil &= 0xff;
unsigned dcc_tile_swizzle = tex->surface.tile_swizzle << 8;
dcc_tile_swizzle &= tex->surface.dcc_alignment - 1;
meta_va |= dcc_tile_swizzle;
- } else if (vi_tc_compat_htile_enabled(tex, first_level)) {
+ } else if (vi_tc_compat_htile_enabled(tex, first_level,
+ is_stencil ? PIPE_MASK_S : PIPE_MASK_Z)) {
meta_va = tex->buffer.gpu_address + tex->htile_offset;
}
enum pipe_format db_render_format:16;
uint8_t stencil_clear_value;
bool tc_compatible_htile:1;
+ bool htile_stencil_disabled:1;
bool depth_cleared:1; /* if it was cleared at least once */
bool stencil_cleared:1; /* if it was cleared at least once */
bool upgraded_depth:1; /* upgraded from unorm to Z32_FLOAT */
}
static inline bool
-si_htile_enabled(struct si_texture *tex, unsigned level)
+si_htile_enabled(struct si_texture *tex, unsigned level, unsigned zs_mask)
{
+ if (zs_mask == PIPE_MASK_S && tex->htile_stencil_disabled)
+ return false;
+
return tex->htile_offset && level == 0;
}
static inline bool
-vi_tc_compat_htile_enabled(struct si_texture *tex, unsigned level)
+vi_tc_compat_htile_enabled(struct si_texture *tex, unsigned level, unsigned zs_mask)
{
assert(!tex->tc_compatible_htile || tex->htile_offset);
- return tex->tc_compatible_htile && level == 0;
+ return tex->tc_compatible_htile && si_htile_enabled(tex, level, zs_mask);
}
static inline unsigned si_get_ps_iter_samples(struct si_context *sctx)
surf->db_depth_size = S_02801C_X_MAX(tex->buffer.b.b.width0 - 1) |
S_02801C_Y_MAX(tex->buffer.b.b.height0 - 1);
- if (si_htile_enabled(tex, level)) {
+ if (si_htile_enabled(tex, level, PIPE_MASK_ZS)) {
z_info |= S_028038_TILE_SURFACE_ENABLE(1) |
S_028038_ALLOW_EXPCLEAR(1);
if (sctx->chip_class >= GFX10) {
z_info |= S_028040_ITERATE_FLUSH(1);
- s_info |= S_028044_ITERATE_FLUSH(1);
+ s_info |= S_028044_ITERATE_FLUSH(!tex->htile_stencil_disabled);
} else {
z_info |= S_028038_ITERATE_FLUSH(1);
s_info |= S_02803C_ITERATE_FLUSH(1);
}
}
- if (tex->surface.has_stencil) {
+ if (tex->surface.has_stencil && !tex->htile_stencil_disabled) {
/* Stencil buffer workaround ported from the GFX6-GFX8 code.
* See that for explanation.
*/
surf->db_depth_slice = S_02805C_SLICE_TILE_MAX((levelinfo->nblk_x *
levelinfo->nblk_y) / 64 - 1);
- if (si_htile_enabled(tex, level)) {
+ if (si_htile_enabled(tex, level, PIPE_MASK_ZS)) {
z_info |= S_028040_TILE_SURFACE_ENABLE(1) |
S_028040_ALLOW_EXPCLEAR(1);
si_init_depth_surface(sctx, surf);
}
- if (vi_tc_compat_htile_enabled(zstex, surf->base.u.tex.level))
+ if (vi_tc_compat_htile_enabled(zstex, surf->base.u.tex.level,
+ PIPE_MASK_ZS))
sctx->framebuffer.DB_has_shader_readable_metadata = true;
si_context_add_resource_size(sctx, surf->base.texture);
if (sscreen->info.chip_class >= GFX9) {
tex->can_sample_z = true;
tex->can_sample_s = true;
+
+ /* Stencil texturing with HTILE doesn't work
+ * with mipmapping on Navi10-14. */
+ if ((sscreen->info.family == CHIP_NAVI10 ||
+ sscreen->info.family == CHIP_NAVI12 ||
+ sscreen->info.family == CHIP_NAVI14) &&
+ base->last_level > 0)
+ tex->htile_stencil_disabled = true;
} else {
tex->can_sample_z = !tex->surface.u.legacy.depth_adjusted;
tex->can_sample_s = !tex->surface.u.legacy.stencil_adjusted;