}
if (zstex && zsbuf->u.tex.first_layer == 0 &&
- zsbuf->u.tex.last_layer == util_max_layer(&zstex->buffer.b.b, 0) &&
- /* TODO: enable fast clear for other mipmap levels */
- zsbuf->u.tex.level == 0) {
+ zsbuf->u.tex.last_layer == util_max_layer(&zstex->buffer.b.b, 0)) {
+ unsigned level = zsbuf->u.tex.level;
+
/* See whether we should enable TC-compatible HTILE. */
if (zstex->enable_tc_compatible_htile_next_clear &&
!zstex->tc_compatible_htile &&
- si_htile_enabled(zstex, zsbuf->u.tex.level, PIPE_MASK_ZS) &&
+ si_htile_enabled(zstex, level, PIPE_MASK_ZS) &&
/* If both depth and stencil are present, they must be cleared together. */
((buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL ||
(buffers & PIPE_CLEAR_DEPTH && (!zstex->surface.has_stencil ||
}
/* 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) &&
+ if (buffers & PIPE_CLEAR_DEPTH && si_htile_enabled(zstex, level, PIPE_MASK_Z) &&
(!zstex->tc_compatible_htile || depth == 0 || depth == 1)) {
/* Need to disable EXPCLEAR temporarily if clearing
* to a new value. */
- if (!zstex->depth_cleared || zstex->depth_clear_value != depth) {
+ if (!(zstex->depth_cleared_level_mask & BITFIELD_BIT(level)) ||
+ zstex->depth_clear_value[level] != depth) {
sctx->db_depth_disable_expclear = true;
}
- if (zstex->depth_clear_value != (float)depth) {
- if ((zstex->depth_clear_value != 0) != (depth != 0)) {
+ if (zstex->depth_clear_value[level] != (float)depth) {
+ if ((zstex->depth_clear_value[level] != 0) != (depth != 0)) {
/* ZRANGE_PRECISION register of a bound surface will change so we
* must flush the DB caches. */
needs_db_flush = true;
}
/* Update DB_DEPTH_CLEAR. */
- zstex->depth_clear_value = depth;
+ zstex->depth_clear_value[level] = depth;
sctx->framebuffer.dirty_zsbuf = true;
si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer);
}
/* 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) &&
+ si_htile_enabled(zstex, level, PIPE_MASK_S) &&
(!zstex->tc_compatible_htile || stencil == 0)) {
stencil &= 0xff;
/* Need to disable EXPCLEAR temporarily if clearing
* to a new value. */
- if (!zstex->stencil_cleared || zstex->stencil_clear_value != stencil) {
+ if (!(zstex->stencil_cleared_level_mask & BITFIELD_BIT(level)) ||
+ zstex->stencil_clear_value[level] != stencil) {
sctx->db_stencil_disable_expclear = true;
}
- if (zstex->stencil_clear_value != (uint8_t)stencil) {
+ if (zstex->stencil_clear_value[level] != (uint8_t)stencil) {
/* Update DB_STENCIL_CLEAR. */
- zstex->stencil_clear_value = stencil;
+ zstex->stencil_clear_value[level] = stencil;
sctx->framebuffer.dirty_zsbuf = true;
si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer);
}
if (sctx->db_depth_clear) {
sctx->db_depth_clear = false;
sctx->db_depth_disable_expclear = false;
- zstex->depth_cleared = true;
+ zstex->depth_cleared_level_mask |= BITFIELD_BIT(zsbuf->u.tex.level);
si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);
}
if (sctx->db_stencil_clear) {
sctx->db_stencil_clear = false;
sctx->db_stencil_disable_expclear = false;
- zstex->stencil_cleared = true;
+ zstex->stencil_cleared_level_mask |= BITFIELD_BIT(zsbuf->u.tex.level);
si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);
}
}
unsigned num_planes;
/* Depth buffer compression and fast clear. */
- float depth_clear_value;
+ float depth_clear_value[RADEON_SURF_MAX_LEVELS];
+ uint8_t stencil_clear_value[RADEON_SURF_MAX_LEVELS];
+ uint16_t depth_cleared_level_mask; /* if it was cleared at least once */
+ uint16_t stencil_cleared_level_mask; /* if it was cleared at least once */
uint16_t dirty_level_mask; /* each bit says if that mipmap is compressed */
uint16_t stencil_dirty_level_mask; /* each bit says if that mipmap is compressed */
enum pipe_format db_render_format : 16;
- uint8_t stencil_clear_value;
bool fmask_is_identity : 1;
bool tc_compatible_htile : 1;
bool enable_tc_compatible_htile_next_clear : 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 */
bool is_depth : 1;
bool db_compatible : 1;
}
}
+ unsigned level = zb->base.u.tex.level;
+
if (sctx->chip_class >= GFX10) {
radeon_set_context_reg(cs, R_028014_DB_HTILE_DATA_BASE, zb->db_htile_data_base);
radeon_set_context_reg(cs, R_02801C_DB_DEPTH_SIZE_XY, zb->db_depth_size);
radeon_set_context_reg_seq(cs, R_02803C_DB_DEPTH_INFO, 7);
radeon_emit(cs, S_02803C_RESOURCE_LEVEL(1)); /* DB_DEPTH_INFO */
radeon_emit(cs, db_z_info | /* DB_Z_INFO */
- S_028038_ZRANGE_PRECISION(tex->depth_clear_value != 0));
+ S_028038_ZRANGE_PRECISION(tex->depth_clear_value[level] != 0));
radeon_emit(cs, db_stencil_info); /* DB_STENCIL_INFO */
radeon_emit(cs, zb->db_depth_base); /* DB_Z_READ_BASE */
radeon_emit(cs, zb->db_stencil_base); /* DB_STENCIL_READ_BASE */
radeon_set_context_reg_seq(cs, R_028038_DB_Z_INFO, 10);
radeon_emit(cs, db_z_info | /* DB_Z_INFO */
- S_028038_ZRANGE_PRECISION(tex->depth_clear_value != 0));
+ S_028038_ZRANGE_PRECISION(tex->depth_clear_value[level] != 0));
radeon_emit(cs, db_stencil_info); /* DB_STENCIL_INFO */
radeon_emit(cs, zb->db_depth_base); /* DB_Z_READ_BASE */
radeon_emit(cs, S_028044_BASE_HI(zb->db_depth_base >> 32)); /* DB_Z_READ_BASE_HI */
radeon_emit(cs, zb->db_depth_info | /* DB_DEPTH_INFO */
S_02803C_ADDR5_SWIZZLE_MASK(!tex->tc_compatible_htile));
radeon_emit(cs, db_z_info | /* DB_Z_INFO */
- S_028040_ZRANGE_PRECISION(tex->depth_clear_value != 0));
+ S_028040_ZRANGE_PRECISION(tex->depth_clear_value[level] != 0));
radeon_emit(cs, db_stencil_info); /* DB_STENCIL_INFO */
radeon_emit(cs, zb->db_depth_base); /* DB_Z_READ_BASE */
radeon_emit(cs, zb->db_stencil_base); /* DB_STENCIL_READ_BASE */
}
radeon_set_context_reg_seq(cs, R_028028_DB_STENCIL_CLEAR, 2);
- radeon_emit(cs, tex->stencil_clear_value); /* R_028028_DB_STENCIL_CLEAR */
- radeon_emit(cs, fui(tex->depth_clear_value)); /* R_02802C_DB_DEPTH_CLEAR */
+ radeon_emit(cs, tex->stencil_clear_value[level]); /* R_028028_DB_STENCIL_CLEAR */
+ radeon_emit(cs, fui(tex->depth_clear_value[level])); /* R_02802C_DB_DEPTH_CLEAR */
radeon_set_context_reg(cs, R_028008_DB_DEPTH_VIEW, zb->db_depth_view);
radeon_set_context_reg(cs, R_028ABC_DB_HTILE_SURFACE, db_htile_surface);
memcpy(tex->color_clear_value, new_tex->color_clear_value, sizeof(tex->color_clear_value));
tex->last_msaa_resolve_target_micro_mode = new_tex->last_msaa_resolve_target_micro_mode;
- tex->depth_clear_value = new_tex->depth_clear_value;
+ memcpy(tex->depth_clear_value, new_tex->depth_clear_value, sizeof(tex->depth_clear_value));
tex->dirty_level_mask = new_tex->dirty_level_mask;
tex->stencil_dirty_level_mask = new_tex->stencil_dirty_level_mask;
tex->db_render_format = new_tex->db_render_format;
- tex->stencil_clear_value = new_tex->stencil_clear_value;
+ memcpy(tex->stencil_clear_value, new_tex->stencil_clear_value, sizeof(tex->stencil_clear_value));
tex->tc_compatible_htile = new_tex->tc_compatible_htile;
- tex->depth_cleared = new_tex->depth_cleared;
- tex->stencil_cleared = new_tex->stencil_cleared;
+ tex->depth_cleared_level_mask = new_tex->depth_cleared_level_mask;
+ tex->stencil_cleared_level_mask = new_tex->stencil_cleared_level_mask;
tex->upgraded_depth = new_tex->upgraded_depth;
tex->db_compatible = new_tex->db_compatible;
tex->can_sample_z = new_tex->can_sample_z;
/* Use 1.0 as the default clear value to get optimal ZRANGE_PRECISION if we don't
* get a fast clear.
*/
- tex->depth_clear_value = 1.0;
+ for (unsigned i = 0; i < ARRAY_SIZE(tex->depth_clear_value); i++)
+ tex->depth_clear_value[i] = 1.0;
/* On GFX8, HTILE uses different tiling depending on the TC_COMPATIBLE_HTILE
* setting, so we have to enable it if we enabled it at allocation.