On 10.09.2014 22:59, Tom Stellard wrote:

+               /* Always use the default config when all backends are enabled. 
*/
+               if (rb_mask && util_bitcount(rb_mask) < max_backends) {
+                       /* XXX: I can't figure out what the *_XSEL and *_YSEL
+                        * fields are for, so I'm leaving them as their default
+                        * values. */
+                       unsigned pkr_mask = (sh_per_se | 0x1);
+                       unsigned se0_pkr0 = rb_mask & pkr_mask;
+                       unsigned se0_pkr1 = (rb_mask >>= sh_per_se) & pkr_mask;
+                       unsigned se1_pkr0 = (rb_mask >>= sh_per_se) & pkr_mask;
+                       unsigned se1_pkr1 = (rb_mask >>= sh_per_se) & pkr_mask;
+                       unsigned se_map = 0;
+                       unsigned se0_pkr_map = 0;
+                       unsigned se1_pkr_map = 0;
+                       unsigned se0_pkr0_rb_map = 0;
+                       unsigned se0_pkr1_rb_map = 0;
+                       unsigned se1_pkr0_rb_map = 0;
+                       unsigned se1_pkr1_rb_map = 0;
+                       if (!se0_pkr0 && !se0_pkr1) {
+                               /* se0 disabled */
+                               se_map |= 0x1;
+                       }
+                       if (se1_pkr0 || se1_pkr1) {
+                               /* se1 enabled */
+                               se_map |= 0x2;
+                       }
+                       if (!se0_pkr0) {
+                               /* se0 pkr0 disabled */
+                               se0_pkr_map |= 0x1;
+                       }
+                       if (se0_pkr1) {
+                               /* se0 pkr1 enabled */
+                               se0_pkr_map |= 0x2;
+                       }
+                       if (!se1_pkr0) {
+                               /* se1 pkr0 disabled */
+                               se1_pkr_map |= 0x1;
+                       }
+                       if (se1_pkr1) {
+                               /* se1 pkr1 enabled */
+                               se1_pkr_map |= 0x2;
+                       }
+
+                       se0_pkr0_rb_map = pkr_mask_to_map(se0_pkr0);
+                       se0_pkr1_rb_map = pkr_mask_to_map(se0_pkr1);
+                       se1_pkr0_rb_map = pkr_mask_to_map(se1_pkr0);
+                       se1_pkr1_rb_map = pkr_mask_to_map(se1_pkr1);
+
+                       assert(!se0_pkr0 || !se1_pkr0 || (se0_pkr0_rb_map == 
se1_pkr0_rb_map));
+                       assert(!se0_pkr1 || !se1_pkr1 || (se0_pkr1_rb_map == 
se1_pkr1_rb_map));
+                       raster_config &= C_028350_RB_MAP_PKR0;
+                       raster_config |= S_028350_RB_MAP_PKR0(se0_pkr0_rb_map);
+                       raster_config &= C_028350_RB_MAP_PKR1;
+                       raster_config |= S_028350_RB_MAP_PKR1(se0_pkr1_rb_map);
+                       raster_config &= C_028350_PKR_MAP;
+                       raster_config |= S_028350_PKR_MAP(se0_pkr_map);
+                       raster_config &= C_028350_SE_MAP;
+                       raster_config |= S_028350_SE_MAP(se_map);
+               }

Taking a closer look again at the kernel code and register spec, I'm afraid this logic is too static. I came up with the attached incremental patch. It tries to only modify raster_config as necessary, i.e. only if there are two SEs / packers per SE / RBs per packer but one of them is disabled. The result may be different between SEs.


--
Earthling Michel Dänzer            |                  http://www.amd.com
Libre software enthusiast          |                Mesa and X developer
commit 7103b9ccbc5b7ab9acc6eda2046b3db58bb6645d
Author: Michel Dänzer <michel.daen...@amd.com>
Date:   Thu Sep 11 17:12:54 2014 +0900

    radeonsi: Improve RASTER_CONFIG calculation for harvested cards

diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 21b9c34..91ada67 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2989,15 +2989,114 @@ void si_init_state_functions(struct si_context *sctx)
 	sctx->b.b.draw_vbo = si_draw_vbo;
 }
 
-static unsigned pkr_mask_to_map(unsigned mask)
-{
-	switch(mask & 0x3) {
-	case 0x0:
-	case 0x1: return 0x0;
-	case 0x2: return 0x3;
-	case 0x3: return 0x2;
+static void
+si_write_harvested_raster_configs(struct si_context *sctx,
+				  struct si_pm4_state *pm4,
+				  unsigned raster_config)
+{
+	unsigned sh_per_se = MAX2(sctx->screen->b.info.max_sh_per_se, 1);
+	unsigned num_se = MAX2(sctx->screen->b.info.max_se, 1);
+	unsigned rb_mask = sctx->screen->b.info.si_backend_enabled_mask;
+	unsigned num_rb = sctx->screen->b.info.r600_num_backends;
+	unsigned rb_per_pkr = num_rb / num_se / sh_per_se;
+	unsigned rb_per_se = num_rb / num_se;
+	unsigned se0_mask = (1 << rb_per_se) - 1;
+	unsigned se1_mask = se0_mask << rb_per_se;
+	unsigned se;
+
+	assert(num_se == 1 || num_se == 2);
+	assert(sh_per_se == 1 || sh_per_se == 2);
+	assert(rb_per_pkr == 1 || rb_per_pkr == 2);
+
+	fprintf(stderr, "Original raster_config = 0x%x, rb_mask = 0x%x\n",
+		raster_config, rb_mask);
+
+	/* XXX: I can't figure out what the *_XSEL and *_YSEL
+	 * fields are for, so I'm leaving them as their default
+	 * values. */
+
+	se0_mask &= rb_mask;
+	se1_mask &= rb_mask;
+	if (num_se == 2 && (!se0_mask || !se1_mask)) {
+		raster_config &= C_028350_SE_MAP;
+
+		if (!se0_mask) {
+			raster_config |=
+				S_028350_SE_MAP(V_028350_RASTER_CONFIG_SE_MAP_3);
+		} else {
+			raster_config |=
+				S_028350_SE_MAP(V_028350_RASTER_CONFIG_SE_MAP_0);
+		}
 	}
-	return 0;
+
+	for (se = 0; se < num_se; se++) {
+		unsigned raster_config_se = raster_config;
+		unsigned pkr0_mask = ((1 << rb_per_pkr) - 1) << (se * rb_per_se);
+		unsigned pkr1_mask = pkr0_mask << rb_per_pkr;
+
+		pkr0_mask &= rb_mask;
+		pkr1_mask &= rb_mask;
+		if (sh_per_se == 2 && (!pkr0_mask || !pkr1_mask)) {
+			raster_config_se &= C_028350_PKR_MAP;
+
+			if (!pkr0_mask) {
+				raster_config_se |=
+					S_028350_PKR_MAP(V_028350_RASTER_CONFIG_PKR_MAP_3);
+			} else {
+				raster_config_se |=
+					S_028350_PKR_MAP(V_028350_RASTER_CONFIG_PKR_MAP_0);
+			}
+		}
+
+		if (rb_per_pkr == 2) {
+			unsigned rb0_mask = 1 << (se * rb_per_se);
+			unsigned rb1_mask = rb0_mask << 1;
+
+			rb0_mask &= rb_mask;
+			rb1_mask &= rb_mask;
+			if (!rb0_mask || !rb1_mask) {
+				raster_config_se &= C_028350_RB_MAP_PKR0;
+
+				if (!rb0_mask) {
+					raster_config_se |=
+						S_028350_RB_MAP_PKR0(V_028350_RASTER_CONFIG_RB_MAP_3);
+				} else {
+					raster_config_se |=
+						S_028350_RB_MAP_PKR0(V_028350_RASTER_CONFIG_RB_MAP_0);
+				}
+			}
+
+			if (sh_per_se == 2) {
+				rb0_mask = 1 << (se * rb_per_se + rb_per_pkr);
+				rb1_mask = rb0_mask << 1;
+				rb0_mask &= rb_mask;
+				rb1_mask &= rb_mask;
+				if (!rb0_mask || !rb1_mask) {
+					raster_config_se &= C_028350_RB_MAP_PKR1;
+
+					if (!rb0_mask) {
+						raster_config_se |=
+							S_028350_RB_MAP_PKR1(V_028350_RASTER_CONFIG_RB_MAP_3);
+					} else {
+						raster_config_se |=
+							S_028350_RB_MAP_PKR1(V_028350_RASTER_CONFIG_RB_MAP_0);
+					}
+				}
+			}
+		}
+
+		fprintf(stderr, "SE%d: raster_config = 0x%x\n",
+			se, raster_config_se);
+
+		si_pm4_set_reg(pm4, GRBM_GFX_INDEX,
+			       SE_INDEX(se) | SH_BROADCAST_WRITES |
+			       INSTANCE_BROADCAST_WRITES);
+		si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, raster_config_se);
+	}
+
+	si_pm4_set_reg(pm4, GRBM_GFX_INDEX,
+		       SE_BROADCAST_WRITES | SH_BROADCAST_WRITES |
+		       INSTANCE_BROADCAST_WRITES);
 }
 
 void si_init_config(struct si_context *sctx)
@@ -3071,11 +3170,10 @@ void si_init_config(struct si_context *sctx)
 			break;
 		}
 	} else {
-		unsigned raster_config = 0;
-		unsigned sh_per_se = MAX2(sctx->screen->b.info.max_sh_per_se, 1);
-		unsigned num_se = MAX2(sctx->screen->b.info.max_se, 1);
 		unsigned rb_mask = sctx->screen->b.info.si_backend_enabled_mask;
-		unsigned max_backends = 2 * sh_per_se * num_se;
+		unsigned num_rb = sctx->screen->b.info.r600_num_backends;
+		unsigned raster_config;
+
 		switch (sctx->screen->b.family) {
 		case CHIP_TAHITI:
 		case CHIP_PITCAIRN:
@@ -3091,69 +3189,19 @@ void si_init_config(struct si_context *sctx)
 			raster_config = 0x00000000;
 			break;
 		default:
+			fprintf(stderr,
+				"radeonsi: Unknown GPU, using 0 for raster_config\n");
 			raster_config = 0x00000000;
 			break;
 		}
 
 		/* Always use the default config when all backends are enabled. */
-		if (rb_mask && util_bitcount(rb_mask) < max_backends) {
-			/* XXX: I can't figure out what the *_XSEL and *_YSEL
-			 * fields are for, so I'm leaving them as their default
-			 * values. */
-			unsigned pkr_mask = (sh_per_se | 0x1);
-			unsigned se0_pkr0 = rb_mask & pkr_mask;
-			unsigned se0_pkr1 = (rb_mask >>= sh_per_se) & pkr_mask;
-			unsigned se1_pkr0 = (rb_mask >>= sh_per_se) & pkr_mask;
-			unsigned se1_pkr1 = (rb_mask >>= sh_per_se) & pkr_mask;
-			unsigned se_map = 0;
-			unsigned se0_pkr_map = 0;
-			unsigned se1_pkr_map = 0;
-			unsigned se0_pkr0_rb_map = 0;
-			unsigned se0_pkr1_rb_map = 0;
-			unsigned se1_pkr0_rb_map = 0;
-			unsigned se1_pkr1_rb_map = 0;
-			if (!se0_pkr0 && !se0_pkr1) {
-				/* se0 disabled */
-				se_map |= 0x1;
-			}
-			if (se1_pkr0 || se1_pkr1) {
-				/* se1 enabled */
-				se_map |= 0x2;
-			}
-			if (!se0_pkr0) {
-				/* se0 pkr0 disabled */
-				se0_pkr_map |= 0x1;
-			}
-			if (se0_pkr1) {
-				/* se0 pkr1 enabled */
-				se0_pkr_map |= 0x2;
-			}
-			if (!se1_pkr0) {
-				/* se1 pkr0 disabled */
-				se1_pkr_map |= 0x1;
-			}
-			if (se1_pkr1) {
-				/* se1 pkr1 enabled */
-				se1_pkr_map |= 0x2;
-			}
-
-			se0_pkr0_rb_map = pkr_mask_to_map(se0_pkr0);
-			se0_pkr1_rb_map = pkr_mask_to_map(se0_pkr1);
-			se1_pkr0_rb_map = pkr_mask_to_map(se1_pkr0);
-			se1_pkr1_rb_map = pkr_mask_to_map(se1_pkr1);
-
-			assert(!se0_pkr0 || !se1_pkr0 || (se0_pkr0_rb_map == se1_pkr0_rb_map));
-			assert(!se0_pkr1 || !se1_pkr1 || (se0_pkr1_rb_map == se1_pkr1_rb_map));
-			raster_config &= C_028350_RB_MAP_PKR0;
-			raster_config |= S_028350_RB_MAP_PKR0(se0_pkr0_rb_map);
-			raster_config &= C_028350_RB_MAP_PKR1;
-			raster_config |= S_028350_RB_MAP_PKR1(se0_pkr1_rb_map);
-			raster_config &= C_028350_PKR_MAP;
-			raster_config |= S_028350_PKR_MAP(se0_pkr_map);
-			raster_config &= C_028350_SE_MAP;
-			raster_config |= S_028350_SE_MAP(se_map);
+		if (rb_mask && util_bitcount(rb_mask) >= num_rb) {
+			si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG,
+				       raster_config);
+		} else {
+			si_write_harvested_raster_configs(sctx, pm4, raster_config);
 		}
-		si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, raster_config);
 	}
 
 	si_pm4_set_reg(pm4, R_028204_PA_SC_WINDOW_SCISSOR_TL, S_028204_WINDOW_OFFSET_DISABLE(1));
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to