[Mesa-dev] [PATCH 05/10] radeonsi: implement global resetting of texture descriptors

Marek Olšák maraeo at gmail.com
Thu May 19 10:59:13 UTC 2016


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

it will be used by texture reallocation
---
 src/gallium/drivers/radeon/r600_pipe_common.h |  7 ++++
 src/gallium/drivers/radeonsi/si_descriptors.c | 53 ++++++++++++++++++++++++---
 src/gallium/drivers/radeonsi/si_state.h       |  1 +
 src/gallium/drivers/radeonsi/si_state_draw.c  |  9 ++++-
 4 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 3e54534..e1a2efb 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -363,6 +363,12 @@ struct r600_common_screen {
 	 */
 	unsigned			compressed_colortex_counter;
 
+	/* Atomically increment this counter when an existing texture's
+	 * backing buffer or tile mode parameters have changed that requires
+	 * recomputation of shader descriptors.
+	 */
+	unsigned			dirty_tex_descriptor_counter;
+
 	void (*query_opaque_metadata)(struct r600_common_screen *rscreen,
 				      struct r600_texture *rtex,
 				      struct radeon_bo_metadata *md);
@@ -455,6 +461,7 @@ struct r600_common_context {
 	unsigned			gpu_reset_counter;
 	unsigned			last_dirty_fb_counter;
 	unsigned			last_compressed_colortex_counter;
+	unsigned			last_dirty_tex_descriptor_counter;
 
 	struct u_upload_mgr		*uploader;
 	struct u_suballocator		*allocator_so_filled_size;
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index d264ae7..e07252c 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -324,11 +324,12 @@ void si_set_mutable_tex_desc_fields(struct r600_texture *tex,
 
 static void si_set_sampler_view(struct si_context *sctx,
 				struct si_sampler_views *views,
-				unsigned slot, struct pipe_sampler_view *view)
+				unsigned slot, struct pipe_sampler_view *view,
+				bool disallow_early_out)
 {
 	struct si_sampler_view *rview = (struct si_sampler_view*)view;
 
-	if (views->views[slot] == view)
+	if (views->views[slot] == view && !disallow_early_out)
 		return;
 
 	if (view) {
@@ -398,11 +399,11 @@ static void si_set_sampler_views(struct pipe_context *ctx,
 		if (!views || !views[i]) {
 			samplers->depth_texture_mask &= ~(1u << slot);
 			samplers->compressed_colortex_mask &= ~(1u << slot);
-			si_set_sampler_view(sctx, &samplers->views, slot, NULL);
+			si_set_sampler_view(sctx, &samplers->views, slot, NULL, false);
 			continue;
 		}
 
-		si_set_sampler_view(sctx, &samplers->views, slot, views[i]);
+		si_set_sampler_view(sctx, &samplers->views, slot, views[i], false);
 
 		if (views[i]->texture && views[i]->texture->target != PIPE_BUFFER) {
 			struct r600_texture *rtex =
@@ -514,7 +515,9 @@ static void si_set_shader_image(struct si_context *ctx,
 	}
 
 	res = (struct r600_resource *)view->resource;
-	util_copy_image_view(&images->views[slot], view);
+
+	if (&images->views[slot] != view)
+		util_copy_image_view(&images->views[slot], view);
 
 	si_sampler_view_add_buffer(ctx, &res->b.b,
 				   RADEON_USAGE_READWRITE);
@@ -1353,6 +1356,46 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
 	}
 }
 
+/* Update mutable image descriptor fields of all bound textures. */
+void si_update_all_texture_descriptors(struct si_context *sctx)
+{
+	unsigned shader;
+
+	for (shader = 0; shader < SI_NUM_SHADERS; shader++) {
+		struct si_sampler_views *samplers = &sctx->samplers[shader].views;
+		struct si_images_info *images = &sctx->images[shader];
+		unsigned mask;
+
+		/* Images. */
+		mask = images->desc.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, images, i, view);
+		}
+
+		/* Sampler views. */
+		mask = samplers->desc.enabled_mask;
+		while (mask) {
+			unsigned i = u_bit_scan(&mask);
+			struct pipe_sampler_view *view = samplers->views[i];
+
+			if (!view ||
+			    !view->texture ||
+			    view->texture->target == PIPE_BUFFER)
+				continue;
+
+			si_set_sampler_view(sctx, samplers, i,
+					    samplers->views[i], true);
+		}
+	}
+}
+
 /* SHADER USER DATA */
 
 static void si_mark_shader_pointers_dirty(struct si_context *sctx,
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index c74214a..b13125b 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -264,6 +264,7 @@ void si_release_all_descriptors(struct si_context *sctx);
 void si_all_descriptors_begin_new_cs(struct si_context *sctx);
 void si_upload_const_buffer(struct si_context *sctx, struct r600_resource **rbuffer,
 			    const uint8_t *ptr, unsigned size, uint32_t *const_offset);
+void si_update_all_texture_descriptors(struct si_context *sctx);
 void si_shader_change_notify(struct si_context *sctx);
 void si_update_compressed_colortex_masks(struct si_context *sctx);
 void si_emit_graphics_shader_userdata(struct si_context *sctx,
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index dab0dcc..1800179 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -777,7 +777,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 	struct si_context *sctx = (struct si_context *)ctx;
 	struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
 	struct pipe_index_buffer ib = {};
-	unsigned mask, dirty_fb_counter;
+	unsigned mask, dirty_fb_counter, dirty_tex_counter;
 
 	if (!info->count && !info->indirect &&
 	    (info->indexed || !info->count_from_stream_output))
@@ -806,6 +806,13 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 		si_mark_atom_dirty(sctx, &sctx->framebuffer.atom);
 	}
 
+	/* Invalidate & recompute texture descriptors if needed. */
+	dirty_tex_counter = p_atomic_read(&sctx->b.screen->dirty_tex_descriptor_counter);
+	if (dirty_tex_counter != sctx->b.last_dirty_tex_descriptor_counter) {
+		sctx->b.last_dirty_tex_descriptor_counter = dirty_tex_counter;
+		si_update_all_texture_descriptors(sctx);
+	}
+
 	si_decompress_graphics_textures(sctx);
 
 	/* Set the rasterization primitive type.
-- 
2.7.4



More information about the mesa-dev mailing list