[Mesa-dev] [PATCH 1/3] radeonsi: don't invoke DCC decompression in update_all_texture_descriptors

Marek Olšák maraeo at gmail.com
Mon Jan 30 00:33:55 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

This fixes a bug uncovered by the 17-part patch series, specifically:
  "gallium/radeon: merge dirty_fb_counter and dirty_tex_descriptor_counter"

If dirty_tex_counter has been updated and set_shader_image invokes DCC
decompression, the DCC decompression itself checks the counter and updates
descriptors, which in turn invokes the same DCC decompression. The blitter
can't handle the recursion and the driver eventually crashes.

Cc: 17.0 <mesa-stable at lists.freedesktop.org>
---
 src/gallium/drivers/radeonsi/si_descriptors.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 4a5407a..f0c0fc4 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -653,21 +653,22 @@ si_mark_image_range_valid(const struct pipe_image_view *view)
 
 	assert(res && res->b.b.target == PIPE_BUFFER);
 
 	util_range_add(&res->valid_buffer_range,
 		       view->u.buf.offset,
 		       view->u.buf.offset + view->u.buf.size);
 }
 
 static void si_set_shader_image(struct si_context *ctx,
 				unsigned shader,
-				unsigned slot, const struct pipe_image_view *view)
+				unsigned slot, const struct pipe_image_view *view,
+				bool skip_decompress)
 {
 	struct si_screen *screen = ctx->screen;
 	struct si_images_info *images = &ctx->images[shader];
 	struct si_descriptors *descs = si_image_descriptors(ctx, shader);
 	struct r600_resource *res;
 	uint32_t *desc = descs->list + slot * 8;
 
 	if (!view || !view->resource) {
 		si_disable_shader_image(ctx, shader, slot);
 		return;
@@ -695,21 +696,21 @@ static void si_set_shader_image(struct si_context *ctx,
 		static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
 		struct r600_texture *tex = (struct r600_texture *)res;
 		unsigned level = view->u.tex.level;
 		unsigned width, height, depth;
 		bool uses_dcc = tex->dcc_offset &&
 				level < tex->surface.num_dcc_levels;
 
 		assert(!tex->is_depth);
 		assert(tex->fmask.size == 0);
 
-		if (uses_dcc &&
+		if (uses_dcc && !skip_decompress &&
 		    (view->access & PIPE_IMAGE_ACCESS_WRITE ||
 		     !vi_dcc_formats_compatible(res->b.b.format, view->format))) {
 			/* If DCC can't be disabled, at least decompress it.
 			 * The decompression is relatively cheap if the surface
 			 * has been decompressed already.
 			 */
 			if (r600_texture_disable_dcc(&ctx->b, tex))
 				uses_dcc = false;
 			else
 				ctx->b.decompress_dcc(&ctx->b.b, tex);
@@ -769,24 +770,24 @@ si_set_shader_images(struct pipe_context *pipe,
 
 	assert(shader < SI_NUM_SHADERS);
 
 	if (!count)
 		return;
 
 	assert(start_slot + count <= SI_NUM_IMAGES);
 
 	if (views) {
 		for (i = 0, slot = start_slot; i < count; ++i, ++slot)
-			si_set_shader_image(ctx, shader, slot, &views[i]);
+			si_set_shader_image(ctx, shader, slot, &views[i], false);
 	} else {
 		for (i = 0, slot = start_slot; i < count; ++i, ++slot)
-			si_set_shader_image(ctx, shader, slot, NULL);
+			si_set_shader_image(ctx, shader, slot, NULL, false);
 	}
 
 	si_update_compressed_tex_shader_mask(ctx, shader);
 }
 
 static void
 si_images_update_compressed_colortex_mask(struct si_images_info *images)
 {
 	unsigned mask = images->enabled_mask;
 
@@ -1706,21 +1707,21 @@ void si_update_all_texture_descriptors(struct si_context *sctx)
 		/* Images. */
 		mask = images->enabled_mask;
 		while (mask) {
 			unsigned i = u_bit_scan(&mask);
 			struct pipe_image_view *view = &images->views[i];
 
 			if (!view->resource ||
 			    view->resource->target == PIPE_BUFFER)
 				continue;
 
-			si_set_shader_image(sctx, shader, i, view);
+			si_set_shader_image(sctx, shader, i, view, true);
 		}
 
 		/* Sampler views. */
 		mask = samplers->enabled_mask;
 		while (mask) {
 			unsigned i = u_bit_scan(&mask);
 			struct pipe_sampler_view *view = samplers->views[i];
 
 			if (!view ||
 			    !view->texture ||
-- 
2.7.4



More information about the mesa-dev mailing list