radeonsi: don't invoke si_decompress_depth if textures are not dirty at binding

This eliminates the overhead of invoking si_decompress_depth.

The complication here is that we need to update needs_depth_decompress_mask
every time we update dirty_level_mask.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13492>
This commit is contained in:
Marek Olšák 2021-10-22 13:49:00 -04:00 committed by Marge Bot
parent 0e54ac7a3c
commit c494cfb1dd
5 changed files with 47 additions and 11 deletions

View file

@ -741,6 +741,7 @@ static void si_fast_clear(struct si_context *sctx, unsigned *buffers,
if ((eliminate_needed || fmask_decompress_needed) &&
!(tex->dirty_level_mask & (1 << level))) {
tex->dirty_level_mask |= 1 << level;
si_set_sampler_depth_decompress_mask(sctx, tex);
p_atomic_inc(&sctx->screen->compressed_colortex_counter);
}

View file

@ -490,14 +490,14 @@ static bool color_needs_decompression(struct si_texture *tex)
(tex->dirty_level_mask && (tex->cmask_buffer || tex->surface.meta_offset));
}
static bool depth_needs_decompression(struct si_texture *tex)
static bool depth_needs_decompression(struct si_texture *tex, bool is_stencil)
{
/* If the depth/stencil texture is TC-compatible, no decompression
* will be done. The decompression function will only flush DB caches
* to make it coherent with shaders. That's necessary because the driver
* doesn't flush DB caches in any other case.
*/
return tex->db_compatible;
return tex->db_compatible && (tex->dirty_level_mask || (is_stencil && tex->stencil_dirty_level_mask));
}
static void si_reset_sampler_view_slot(struct si_samplers *samplers, unsigned slot,
@ -548,15 +548,24 @@ static void si_set_sampler_views(struct si_context *sctx, unsigned shader,
samplers->needs_depth_decompress_mask &= ~(1u << slot);
samplers->needs_color_decompress_mask &= ~(1u << slot);
} else {
if (depth_needs_decompression(tex)) {
samplers->needs_depth_decompress_mask |= 1u << slot;
} else {
samplers->needs_depth_decompress_mask &= ~(1u << slot);
}
if (color_needs_decompression(tex)) {
samplers->needs_color_decompress_mask |= 1u << slot;
} else {
if (tex->is_depth) {
samplers->has_depth_tex_mask |= 1u << slot;
samplers->needs_color_decompress_mask &= ~(1u << slot);
if (depth_needs_decompression(tex, sview->is_stencil_sampler)) {
samplers->needs_depth_decompress_mask |= 1u << slot;
} else {
samplers->needs_depth_decompress_mask &= ~(1u << slot);
}
} else {
samplers->has_depth_tex_mask &= ~(1u << slot);
samplers->needs_depth_decompress_mask &= ~(1u << slot);
if (color_needs_decompression(tex)) {
samplers->needs_color_decompress_mask |= 1u << slot;
} else {
samplers->needs_color_decompress_mask &= ~(1u << slot);
}
}
if (vi_dcc_enabled(tex, sview->base.u.tex.first_level) &&
@ -597,6 +606,7 @@ static void si_set_sampler_views(struct si_context *sctx, unsigned shader,
unbound_mask |= BITFIELD_RANGE(start_slot + count, unbind_num_trailing_slots);
samplers->enabled_mask &= ~unbound_mask;
samplers->has_depth_tex_mask &= ~unbound_mask;
samplers->needs_depth_decompress_mask &= ~unbound_mask;
samplers->needs_color_decompress_mask &= ~unbound_mask;
@ -613,6 +623,11 @@ static void si_update_shader_needs_decompress_mask(struct si_context *sctx, unsi
sctx->shader_needs_decompress_mask |= shader_bit;
else
sctx->shader_needs_decompress_mask &= ~shader_bit;
if (samplers->has_depth_tex_mask)
sctx->shader_has_depth_tex |= shader_bit;
else
sctx->shader_has_depth_tex &= ~shader_bit;
}
static void si_pipe_set_sampler_views(struct pipe_context *ctx, enum pipe_shader_type shader,
@ -2434,7 +2449,7 @@ static void si_make_texture_handle_resident(struct pipe_context *ctx, uint64_t h
if (sview->base.texture->target != PIPE_BUFFER) {
struct si_texture *tex = (struct si_texture *)sview->base.texture;
if (depth_needs_decompression(tex)) {
if (depth_needs_decompression(tex, sview->is_stencil_sampler)) {
util_dynarray_append(&sctx->resident_tex_needs_depth_decompress,
struct si_texture_handle *, tex_handle);
}

View file

@ -732,6 +732,7 @@ struct si_samplers {
/* The i-th bit is set if that element is enabled (non-NULL resource). */
unsigned enabled_mask;
uint32_t has_depth_tex_mask;
uint32_t needs_depth_decompress_mask;
uint32_t needs_color_decompress_mask;
};
@ -1072,6 +1073,7 @@ struct si_context {
unsigned descriptors_dirty;
unsigned shader_pointers_dirty;
unsigned shader_needs_decompress_mask;
unsigned shader_has_depth_tex;
struct si_buffer_resources internal_bindings;
struct si_buffer_resources const_and_shader_buffers[SI_NUM_SHADERS];
struct si_samplers samplers[SI_NUM_SHADERS];

View file

@ -2671,6 +2671,21 @@ static void si_init_depth_surface(struct si_context *sctx, struct si_surface *su
surf->depth_initialized = true;
}
void si_set_sampler_depth_decompress_mask(struct si_context *sctx, struct si_texture *tex)
{
/* Check all sampler bindings in all shaders where depth textures are bound, and update
* which samplers should be decompressed.
*/
u_foreach_bit(sh, sctx->shader_has_depth_tex) {
u_foreach_bit(i, sctx->samplers[sh].has_depth_tex_mask) {
if (sctx->samplers[sh].views[i]->texture == &tex->buffer.b.b) {
sctx->samplers[sh].needs_depth_decompress_mask |= 1 << i;
sctx->shader_needs_decompress_mask |= 1 << sh;
}
}
}
}
void si_update_fb_dirtiness_after_rendering(struct si_context *sctx)
{
if (sctx->decompression_enabled)
@ -2684,6 +2699,8 @@ void si_update_fb_dirtiness_after_rendering(struct si_context *sctx)
if (tex->surface.has_stencil)
tex->stencil_dirty_level_mask |= 1 << surf->u.tex.level;
si_set_sampler_depth_decompress_mask(sctx, tex);
}
unsigned compressed_cb_mask = sctx->framebuffer.compressed_cb_mask;

View file

@ -539,6 +539,7 @@ struct pipe_sampler_view *si_create_sampler_view_custom(struct pipe_context *ctx
const struct pipe_sampler_view *state,
unsigned width0, unsigned height0,
unsigned force_level);
void si_set_sampler_depth_decompress_mask(struct si_context *sctx, struct si_texture *tex);
void si_update_fb_dirtiness_after_rendering(struct si_context *sctx);
void si_mark_display_dcc_dirty(struct si_context *sctx, struct si_texture *tex);
void si_update_ps_iter_samples(struct si_context *sctx);