[Mesa-dev] [PATCH 9/9] radeonsi: keep track of dirty descriptor sets

Nicolai Hähnle nhaehnle at gmail.com
Fri Jun 3 17:01:31 UTC 2016


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Reduces CPU load for draw calls that change none or few of the descriptors.
---
 src/gallium/drivers/radeonsi/si_descriptors.c | 39 ++++++++++++++++++++++++---
 src/gallium/drivers/radeonsi/si_pipe.h        |  1 +
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 6c87d42..c3f4b66 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -398,6 +398,7 @@ static void si_set_sampler_view(struct si_context *sctx,
 	}
 
 	descs->dirty_mask |= 1u << slot;
+	sctx->descriptors_dirty |= 1u << si_sampler_descriptors_idx(shader);
 }
 
 static bool is_compressed_colortex(struct r600_texture *rtex)
@@ -534,6 +535,7 @@ si_disable_shader_image(struct si_context *ctx, unsigned shader, unsigned slot)
 		memcpy(descs->list + slot*8, null_image_descriptor, 8*4);
 		images->enabled_mask &= ~(1u << slot);
 		descs->dirty_mask |= 1u << slot;
+		ctx->descriptors_dirty |= 1u << si_image_descriptors_idx(shader);
 	}
 }
 
@@ -636,6 +638,7 @@ static void si_set_shader_image(struct si_context *ctx,
 
 	images->enabled_mask |= 1u << slot;
 	descs->dirty_mask |= 1u << slot;
+	ctx->descriptors_dirty |= 1u << si_image_descriptors_idx(shader);
 }
 
 static void
@@ -717,6 +720,7 @@ static void si_bind_sampler_states(struct pipe_context *ctx, unsigned shader,
 
 		memcpy(desc->list + slot * 16 + 12, sstates[i]->val, 4*4);
 		desc->dirty_mask |= 1u << slot;
+		sctx->descriptors_dirty |= 1u << si_sampler_descriptors_idx(shader);
 	}
 }
 
@@ -965,6 +969,7 @@ static void si_set_constant_buffer(struct si_context *sctx,
 	}
 
 	descs->dirty_mask |= 1u << slot;
+	sctx->descriptors_dirty |= 1u << descriptors_idx;
 }
 
 void si_set_rw_buffer(struct si_context *sctx,
@@ -1026,6 +1031,8 @@ static void si_set_shader_buffers(struct pipe_context *ctx, unsigned shader,
 			memset(desc, 0, sizeof(uint32_t) * 4);
 			buffers->enabled_mask &= ~(1u << slot);
 			descs->dirty_mask |= 1u << slot;
+			sctx->descriptors_dirty |=
+				1u << si_shader_buffer_descriptors_idx(shader);
 			continue;
 		}
 
@@ -1048,6 +1055,8 @@ static void si_set_shader_buffers(struct pipe_context *ctx, unsigned shader,
 				      buffers->shader_usage, buffers->priority);
 		buffers->enabled_mask |= 1u << slot;
 		descs->dirty_mask |= 1u << slot;
+		sctx->descriptors_dirty |=
+			1u << si_shader_buffer_descriptors_idx(shader);
 	}
 }
 
@@ -1142,6 +1151,7 @@ void si_set_ring_buffer(struct pipe_context *ctx, uint slot,
 	}
 
 	descs->dirty_mask |= 1u << slot;
+	sctx->descriptors_dirty |= 1u << SI_DESCS_RW_BUFFERS;
 }
 
 /* STREAMOUT BUFFERS */
@@ -1251,6 +1261,8 @@ static void si_set_streamout_targets(struct pipe_context *ctx,
 		buffers->enabled_mask &= ~(1u << bufidx);
 		descs->dirty_mask |= 1u << bufidx;
 	}
+
+	sctx->descriptors_dirty |= 1u << SI_DESCS_RW_BUFFERS;
 }
 
 static void si_desc_reset_buffer_offset(struct pipe_context *ctx,
@@ -1324,6 +1336,7 @@ static void si_reset_buffer_resources(struct si_context *sctx,
 						    descs->list + i*4,
 						    old_va, buf);
 			descs->dirty_mask |= 1u << i;
+			sctx->descriptors_dirty |= 1u << descriptors_idx;
 
 			radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
 						(struct r600_resource *)buf,
@@ -1387,6 +1400,7 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
 		si_desc_reset_buffer_offset(ctx, descs->list + i*4,
 					    old_va, buf);
 		descs->dirty_mask |= 1u << i;
+		sctx->descriptors_dirty |= 1u << SI_DESCS_RW_BUFFERS;
 
 		radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
 					  rbuffer, buffers->shader_usage,
@@ -1431,6 +1445,8 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
 							    i * 16 + 4,
 							    old_va, buf);
 				descs->dirty_mask |= 1u << i;
+				sctx->descriptors_dirty |=
+					1u << si_sampler_descriptors_idx(shader);
 
 				radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
 						      rbuffer, RADEON_USAGE_READ,
@@ -1457,6 +1473,8 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
 					ctx, descs->list + i * 8 + 4,
 					old_va, buf);
 				descs->dirty_mask |= 1u << i;
+				sctx->descriptors_dirty |=
+					1u << si_image_descriptors_idx(shader);
 
 				radeon_add_to_buffer_list(
 					&sctx->b, &sctx->b.gfx, rbuffer,
@@ -1686,6 +1704,8 @@ void si_init_all_descriptors(struct si_context *sctx)
 	si_init_descriptors(&sctx->vertex_buffers, SI_SGPR_VERTEX_BUFFERS,
 			    4, SI_NUM_VERTEX_BUFFERS, NULL, NULL);
 
+	sctx->descriptors_dirty = u_bit_consecutive(0, SI_NUM_DESCS);
+
 	assert(ce_offset <= 32768);
 
 	/* Set pipe_context functions. */
@@ -1711,14 +1731,19 @@ void si_init_all_descriptors(struct si_context *sctx)
 
 bool si_upload_graphics_shader_descriptors(struct si_context *sctx)
 {
-	int i;
+	const unsigned mask = u_bit_consecutive(0, SI_DESCS_FIRST_COMPUTE);
+	unsigned dirty = sctx->descriptors_dirty & mask;
+
+	while (dirty) {
+		unsigned i = u_bit_scan(&dirty);
 
-	for (i = 0; i < SI_DESCS_FIRST_COMPUTE; ++i) {
 		if (!si_upload_descriptors(sctx, &sctx->descriptors[i],
 					   &sctx->shader_userdata.atom))
 			return false;
 	}
 
+	sctx->descriptors_dirty &= ~mask;
+
 	return si_upload_vertex_buffer_descriptors(sctx);
 }
 
@@ -1727,13 +1752,19 @@ bool si_upload_compute_shader_descriptors(struct si_context *sctx)
 	/* Does not update rw_buffers as that is not needed for compute shaders
 	 * and the input buffer is using the same SGPR's anyway.
 	 */
-	unsigned i;
+	const unsigned mask = u_bit_consecutive(SI_DESCS_FIRST_COMPUTE,
+						SI_NUM_DESCS - SI_DESCS_FIRST_COMPUTE);
+	unsigned dirty = sctx->descriptors_dirty & mask;
+
+	while (dirty) {
+		unsigned i = u_bit_scan(&dirty);
 
-	for (i = SI_DESCS_FIRST_COMPUTE; i < SI_NUM_DESCS; ++i) {
 		if (!si_upload_descriptors(sctx, &sctx->descriptors[i], NULL))
 			return false;
 	}
 
+	sctx->descriptors_dirty &= ~mask;
+
 	return true;
 }
 
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 7a593d3..d4c5514 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -249,6 +249,7 @@ struct si_context {
 	/* shader descriptors */
 	struct si_descriptors		vertex_buffers;
 	struct si_descriptors		descriptors[SI_NUM_DESCS];
+	unsigned			descriptors_dirty;
 	struct si_buffer_resources	rw_buffers;
 	struct si_buffer_resources	const_buffers[SI_NUM_SHADERS];
 	struct si_buffer_resources	shader_buffers[SI_NUM_SHADERS];
-- 
2.7.4



More information about the mesa-dev mailing list