summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c128
-rw-r--r--src/gallium/drivers/radeonsi/sid.h8
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_winsys.c3
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h1
4 files changed, 134 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index ea8e61a0419..f24c28e9220 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3081,6 +3081,110 @@ void si_init_state_functions(struct si_context *sctx)
sctx->b.b.draw_vbo = si_draw_vbo;
}
+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);
+
+ /* 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);
+ }
+ }
+
+ 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);
+ }
+ }
+ }
+ }
+
+ 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)
{
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
@@ -3152,24 +3256,38 @@ void si_init_config(struct si_context *sctx)
break;
}
} else {
+ unsigned rb_mask = sctx->screen->b.info.si_backend_enabled_mask;
+ unsigned num_rb = sctx->screen->b.info.r600_num_backends;
+ unsigned raster_config;
+
switch (sctx->screen->b.family) {
case CHIP_TAHITI:
case CHIP_PITCAIRN:
- si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x2a00126a);
+ raster_config = 0x2a00126a;
break;
case CHIP_VERDE:
- si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x0000124a);
+ raster_config = 0x0000124a;
break;
case CHIP_OLAND:
- si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000082);
+ raster_config = 0x00000082;
break;
case CHIP_HAINAN:
- si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000000);
+ raster_config = 0x00000000;
break;
default:
- si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000000);
+ 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) >= 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_028204_PA_SC_WINDOW_SCISSOR_TL, S_028204_WINDOW_OFFSET_DISABLE(1));
diff --git a/src/gallium/drivers/radeonsi/sid.h b/src/gallium/drivers/radeonsi/sid.h
index c4d4afd6f02..c78ba7c2991 100644
--- a/src/gallium/drivers/radeonsi/sid.h
+++ b/src/gallium/drivers/radeonsi/sid.h
@@ -204,7 +204,13 @@
* 6. COMMAND [29:22] | BYTE_COUNT [20:0]
*/
-
+#define GRBM_GFX_INDEX 0x802C
+#define INSTANCE_INDEX(x) ((x) << 0)
+#define SH_INDEX(x) ((x) << 8)
+#define SE_INDEX(x) ((x) << 16)
+#define SH_BROADCAST_WRITES (1 << 29)
+#define INSTANCE_BROADCAST_WRITES (1 << 30)
+#define SE_BROADCAST_WRITES (1 << 31)
#define R_0084FC_CP_STRMOUT_CNTL 0x0084FC
#define S_0084FC_OFFSET_UPDATE_DONE(x) (((x) & 0x1) << 0)
#define R_0085F0_CP_COHER_CNTL 0x0085F0
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index c207a85c6f4..3974034c911 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -325,6 +325,9 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws)
&ws->info.max_sclk);
ws->info.max_sclk /= 1000;
+ radeon_get_drm_value(ws->fd, RADEON_INFO_SI_BACKEND_ENABLED_MASK, NULL,
+ &ws->info.si_backend_enabled_mask);
+
ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
/* Generation-specific queries. */
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index 18fefbeebcb..5dc9313ce05 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -231,6 +231,7 @@ struct radeon_info {
boolean si_tile_mode_array_valid;
uint32_t si_tile_mode_array[32];
+ uint32_t si_backend_enabled_mask;
boolean cik_macrotile_mode_array_valid;
uint32_t cik_macrotile_mode_array[16];