diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index b8cf49a6b47..7e19b89e030 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -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); } diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index bab6654df1b..6ea4610f774 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -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); } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 6782069deec..26f32d42c36 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -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]; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index c5724f4bdea..1b46fe0885e 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 29965f83b43..e9dcb1da65b 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -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);