diff options
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 128 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/sid.h | 8 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 3 | ||||
-rw-r--r-- | src/gallium/winsys/radeon/drm/radeon_winsys.h | 1 |
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]; |