[Mesa-dev] [PATCH 2/2] radeonsi: Decompress DCC textures in a render feedback loop.

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Tue May 31 16:04:40 UTC 2016


By using a counter to quickly reject textures that are not
bound to a framebuffer, the performance impact when binding
sampler_views/images is not too large.

Signed-off-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
---
 src/gallium/drivers/radeonsi/si_blit.c        | 99 +++++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/si_descriptors.c |  8 +++
 src/gallium/drivers/radeonsi/si_pipe.h        |  3 +
 src/gallium/drivers/radeonsi/si_state.c       |  2 +
 4 files changed, 112 insertions(+)

diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 716a522..262c6a4 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -412,6 +412,103 @@ si_decompress_image_color_textures(struct si_context *sctx,
 	}
 }
 
+static void si_check_render_feedback_textures(struct si_context *sctx,
+                                              struct si_textures_info *textures)
+{
+	uint32_t mask = textures->views.desc.enabled_mask;
+
+	while (mask) {
+		const struct pipe_sampler_view *view;
+		struct r600_texture *tex;
+		bool render_feedback = false;
+
+		unsigned i = u_bit_scan(&mask);
+
+		view = textures->views.views[i];
+		if(view->texture->target == PIPE_BUFFER)
+			continue;
+
+		tex = (struct r600_texture *)view->texture;
+		if (!tex->dcc_offset)
+			continue;
+
+		for (unsigned j = 0; j < sctx->framebuffer.state.nr_cbufs; ++j) {
+			struct r600_surface * surf;
+
+			if (!sctx->framebuffer.state.cbufs[j])
+				continue;
+
+			surf = (struct r600_surface*)sctx->framebuffer.state.cbufs[j];
+
+			if (tex == (struct r600_texture*)surf->base.texture &&
+			    surf->base.u.tex.level >= view->u.tex.first_level &&
+			    surf->base.u.tex.level <= view->u.tex.last_level &&
+			    surf->base.u.tex.first_layer <= view->u.tex.last_layer &&
+			    surf->base.u.tex.last_layer >= view->u.tex.first_layer)
+				render_feedback = true;
+		}
+
+		if (render_feedback) {
+			struct si_screen *screen = sctx->screen;
+			r600_texture_disable_dcc(&screen->b, tex);
+		}
+	}
+}
+
+static void si_check_render_feedback_images(struct si_context *sctx,
+                                            struct si_images_info *images)
+{
+	uint32_t mask = images->desc.enabled_mask;
+
+	while (mask) {
+		const struct pipe_image_view *view;
+		struct r600_texture *tex;
+		bool render_feedback = false;
+
+		unsigned i = u_bit_scan(&mask);
+
+		view = &images->views[i];
+		if (view->resource->target == PIPE_BUFFER)
+			continue;
+
+		tex = (struct r600_texture *)view->resource;
+		if (!tex->dcc_offset)
+			continue;
+
+		for (unsigned j = 0; j < sctx->framebuffer.state.nr_cbufs; ++j) {
+			struct r600_surface * surf;
+
+			if (!sctx->framebuffer.state.cbufs[j])
+				continue;
+
+			surf = (struct r600_surface*)sctx->framebuffer.state.cbufs[j];
+
+			if (tex == (struct r600_texture*)surf->base.texture &&
+			    surf->base.u.tex.level == view->u.tex.level &&
+			    surf->base.u.tex.first_layer <= view->u.tex.last_layer &&
+			    surf->base.u.tex.last_layer >= view->u.tex.first_layer)
+				render_feedback = true;
+		}
+
+		if (render_feedback) {
+			struct si_screen *screen = sctx->screen;
+			r600_texture_disable_dcc(&screen->b, tex);
+		}
+	}
+}
+
+static void si_check_render_feedback(struct si_context *sctx) {
+
+	if (!sctx->need_check_render_feedback)
+		return;
+
+	for (int i = 0; i < SI_NUM_SHADERS; ++i) {
+		si_check_render_feedback_images(sctx, &sctx->images[i]);
+		si_check_render_feedback_textures(sctx, &sctx->samplers[i]);
+	}
+	sctx->need_check_render_feedback = false;
+}
+
 static void si_decompress_textures(struct si_context *sctx, int shader_start,
                                    int shader_end)
 {
@@ -439,6 +536,8 @@ static void si_decompress_textures(struct si_context *sctx, int shader_start,
 			si_decompress_image_color_textures(sctx, &sctx->images[i]);
 		}
 	}
+
+	si_check_render_feedback(sctx);
 }
 
 void si_decompress_graphics_textures(struct si_context *sctx)
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 855b79e..ec17474 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -387,6 +387,10 @@ static void si_set_sampler_views(struct pipe_context *ctx,
 			} else {
 				samplers->compressed_colortex_mask &= ~(1u << slot);
 			}
+
+			if (rtex->dcc_offset &&
+			    p_atomic_read(&rtex->framebuffers_bound))
+				sctx->need_check_render_feedback = true;
 		} else {
 			samplers->depth_texture_mask &= ~(1u << slot);
 			samplers->compressed_colortex_mask &= ~(1u << slot);
@@ -527,6 +531,10 @@ si_set_shader_images(struct pipe_context *pipe, unsigned shader,
 				images->compressed_colortex_mask &= ~(1 << slot);
 			}
 
+			if (tex->dcc_offset &&
+			    p_atomic_read(&tex->framebuffers_bound))
+				ctx->need_check_render_feedback = true;
+
 			/* Always force the base level to the selected level.
 			 *
 			 * This is required for 3D textures, where otherwise
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index e5b88c7..b48b1bb 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -323,6 +323,9 @@ struct si_context {
 	uint64_t		dmesg_timestamp;
 	unsigned		last_bo_count;
 	struct radeon_bo_list_item *last_bo_list;
+
+	/* Other state */
+	bool need_check_render_feedback;
 };
 
 /* cik_sdma.c */
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 436b868..d350fda 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2429,6 +2429,8 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 		     old_nr_samples != 1))
 			si_mark_atom_dirty(sctx, &sctx->msaa_sample_locs);
 	}
+
+	sctx->need_check_render_feedback = true;
 }
 
 static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom *atom)
-- 
2.8.3



More information about the mesa-dev mailing list