[Mesa-dev] [PATCH 08/16] radeonsi: emit dirty consecutive pointers in one SET_SH_REG packet

Marek Olšák maraeo at gmail.com
Fri Oct 13 12:04:04 UTC 2017


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

IB size: -1.6%
---
 src/gallium/drivers/radeonsi/si_descriptors.c | 66 ++++++++++++++++-----------
 1 file changed, 39 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index a0f3dcf..a2b7c11 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -1978,20 +1978,42 @@ static void si_emit_shader_pointer_body(struct radeon_winsys_cs *cs,
 static void si_emit_shader_pointer(struct si_context *sctx,
 				   struct si_descriptors *desc,
 				   unsigned sh_base)
 {
 	struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
 
 	si_emit_shader_pointer_head(cs, desc, sh_base, 1);
 	si_emit_shader_pointer_body(cs, desc);
 }
 
+static void si_emit_consecutive_shader_pointers(struct si_context *sctx,
+						unsigned pointer_mask,
+						unsigned sh_base)
+{
+	if (!sh_base)
+		return;
+
+	struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
+	unsigned mask = sctx->shader_pointers_dirty & pointer_mask;
+
+	while (mask) {
+		int start, count;
+		u_bit_scan_consecutive_range(&mask, &start, &count);
+
+		struct si_descriptors *descs = &sctx->descriptors[start];
+
+		si_emit_shader_pointer_head(cs, descs, sh_base, count);
+		for (int i = 0; i < count; i++)
+			si_emit_shader_pointer_body(cs, descs + i);
+	}
+}
+
 static void si_emit_global_shader_pointers(struct si_context *sctx,
 					   struct si_descriptors *descs)
 {
 	if (sctx->b.chip_class == GFX9) {
 		/* Broadcast it to all shader stages. */
 		si_emit_shader_pointer(sctx, descs,
 				       R_00B530_SPI_SHADER_USER_DATA_COMMON_0);
 		return;
 	}
 
@@ -2005,71 +2027,61 @@ static void si_emit_global_shader_pointers(struct si_context *sctx,
 			       R_00B230_SPI_SHADER_USER_DATA_GS_0);
 	si_emit_shader_pointer(sctx, descs,
 			       R_00B430_SPI_SHADER_USER_DATA_HS_0);
 	si_emit_shader_pointer(sctx, descs,
 			       R_00B530_SPI_SHADER_USER_DATA_LS_0);
 }
 
 void si_emit_graphics_shader_pointers(struct si_context *sctx,
                                       struct r600_atom *atom)
 {
-	unsigned mask;
 	uint32_t *sh_base = sctx->shader_pointers.sh_base;
-	struct si_descriptors *descs;
 
-	descs = &sctx->descriptors[SI_DESCS_RW_BUFFERS];
-
-	if (sctx->shader_pointers_dirty & (1 << SI_DESCS_RW_BUFFERS))
-		si_emit_global_shader_pointers(sctx, descs);
-
-	mask = sctx->shader_pointers_dirty &
-	       u_bit_consecutive(SI_DESCS_FIRST_SHADER,
-				 SI_DESCS_FIRST_COMPUTE - SI_DESCS_FIRST_SHADER);
+	if (sctx->shader_pointers_dirty & (1 << SI_DESCS_RW_BUFFERS)) {
+		si_emit_global_shader_pointers(sctx,
+					       &sctx->descriptors[SI_DESCS_RW_BUFFERS]);
+	}
 
-	while (mask) {
-		unsigned i = u_bit_scan(&mask);
-		unsigned shader = (i - SI_DESCS_FIRST_SHADER) / SI_NUM_SHADER_DESCS;
-		unsigned base = sh_base[shader];
+	si_emit_consecutive_shader_pointers(sctx, SI_DESCS_SHADER_MASK(VERTEX),
+					    sh_base[PIPE_SHADER_VERTEX]);
+	si_emit_consecutive_shader_pointers(sctx, SI_DESCS_SHADER_MASK(TESS_CTRL),
+					    sh_base[PIPE_SHADER_TESS_CTRL]);
+	si_emit_consecutive_shader_pointers(sctx, SI_DESCS_SHADER_MASK(TESS_EVAL),
+					    sh_base[PIPE_SHADER_TESS_EVAL]);
+	si_emit_consecutive_shader_pointers(sctx, SI_DESCS_SHADER_MASK(GEOMETRY),
+					    sh_base[PIPE_SHADER_GEOMETRY]);
+	si_emit_consecutive_shader_pointers(sctx, SI_DESCS_SHADER_MASK(FRAGMENT),
+					    sh_base[PIPE_SHADER_FRAGMENT]);
 
-		if (base)
-			si_emit_shader_pointer(sctx, descs + i, base);
-	}
 	sctx->shader_pointers_dirty &=
 		~u_bit_consecutive(SI_DESCS_RW_BUFFERS, SI_DESCS_FIRST_COMPUTE);
 
 	if (sctx->vertex_buffer_pointer_dirty) {
 		si_emit_shader_pointer(sctx, &sctx->vertex_buffers,
 				       sh_base[PIPE_SHADER_VERTEX]);
 		sctx->vertex_buffer_pointer_dirty = false;
 	}
 
 	if (sctx->graphics_bindless_pointer_dirty) {
 		si_emit_global_shader_pointers(sctx,
 					       &sctx->bindless_descriptors);
 		sctx->graphics_bindless_pointer_dirty = false;
 	}
 }
 
 void si_emit_compute_shader_pointers(struct si_context *sctx)
 {
 	unsigned base = R_00B900_COMPUTE_USER_DATA_0;
-	struct si_descriptors *descs = sctx->descriptors;
-	unsigned compute_mask =
-		u_bit_consecutive(SI_DESCS_FIRST_COMPUTE, SI_NUM_SHADER_DESCS);
-	unsigned mask = sctx->shader_pointers_dirty & compute_mask;
 
-	while (mask) {
-		unsigned i = u_bit_scan(&mask);
-
-		si_emit_shader_pointer(sctx, descs + i, base);
-	}
-	sctx->shader_pointers_dirty &= ~compute_mask;
+	si_emit_consecutive_shader_pointers(sctx, SI_DESCS_SHADER_MASK(COMPUTE),
+					    R_00B900_COMPUTE_USER_DATA_0);
+	sctx->shader_pointers_dirty &= ~SI_DESCS_SHADER_MASK(COMPUTE);
 
 	if (sctx->compute_bindless_pointer_dirty) {
 		si_emit_shader_pointer(sctx, &sctx->bindless_descriptors, base);
 		sctx->compute_bindless_pointer_dirty = false;
 	}
 }
 
 /* BINDLESS */
 
 static void si_init_bindless_descriptors(struct si_context *sctx,
-- 
2.7.4



More information about the mesa-dev mailing list