X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fradeonsi%2Fsi_state.c;h=da3c7debd5780519675aa70cc2279eb89c7be5e2;hb=8d8f1ef573932679145b5aa8e2bafbf4c82701ef;hp=c151a980e01cc7b29286ddf67d45eac09b812441;hpb=b9fc9d3f241758ed8a274be7abf68bf448653508;p=mesa.git diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index c151a980e01..da3c7debd57 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -115,7 +115,7 @@ static void si_emit_cb_render_state(struct si_context *sctx, struct r600_atom *a /* GFX9: Flush DFSM when CB_TARGET_MASK changes. * I think we don't have to do anything between IBs. */ - if (sctx->b.chip_class >= GFX9 && + if (sctx->screen->dfsm_allowed && sctx->last_cb_target_mask != cb_target_mask) { sctx->last_cb_target_mask = cb_target_mask; @@ -441,6 +441,8 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx, blend->need_src_alpha_4bit |= 0xf; blend->cb_target_mask = 0; + blend->cb_target_enabled_4bit = 0; + for (int i = 0; i < 8; i++) { /* state->rt entries > 0 only written if independent blending */ const int j = state->independent_blend_enable ? i : 0; @@ -482,6 +484,8 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx, /* cb_render_state will disable unused ones */ blend->cb_target_mask |= (unsigned)state->rt[j].colormask << (4 * i); + if (state->rt[j].colormask) + blend->cb_target_enabled_4bit |= 0xf << (4 * i); if (!state->rt[j].colormask || !state->rt[j].blend_enable) { si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl); @@ -619,6 +623,13 @@ static void si_bind_blend_state(struct pipe_context *ctx, void *state) old_blend->blend_enable_4bit != blend->blend_enable_4bit || old_blend->need_src_alpha_4bit != blend->need_src_alpha_4bit) sctx->do_update_shaders = true; + + if (sctx->screen->dpbb_allowed && + (!old_blend || + old_blend->alpha_to_coverage != blend->alpha_to_coverage || + old_blend->blend_enable_4bit != blend->blend_enable_4bit || + old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit)) + si_mark_atom_dirty(sctx, &sctx->dpbb_state); } static void si_delete_blend_state(struct pipe_context *ctx, void *state) @@ -719,12 +730,6 @@ static void si_emit_clip_regs(struct si_context *sctx, struct r600_atom *atom) rs->pa_cl_clip_cntl | ucp_mask | S_028810_CLIP_DISABLE(window_space)); - - if (sctx->b.chip_class <= VI) { - /* reuse needs to be set off if we write oViewport */ - radeon_set_context_reg(cs, R_028AB4_VGT_REUSE_OFF, - S_028AB4_REUSE_OFF(info->writes_viewport_index)); - } } /* @@ -1046,6 +1051,14 @@ static uint32_t si_translate_stencil_op(int s_op) return 0; } +static bool si_dsa_writes_stencil(const struct pipe_stencil_state *s) +{ + return s->enabled && s->writemask && + (s->fail_op != PIPE_STENCIL_OP_KEEP || + s->zfail_op != PIPE_STENCIL_OP_KEEP || + s->zpass_op != PIPE_STENCIL_OP_KEEP); +} + static void *si_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { @@ -1103,6 +1116,15 @@ static void *si_create_dsa_state(struct pipe_context *ctx, si_pm4_set_reg(pm4, R_028024_DB_DEPTH_BOUNDS_MAX, fui(state->depth.bounds_max)); } + dsa->depth_enabled = state->depth.enabled; + dsa->depth_write_enabled = state->depth.enabled && + state->depth.writemask; + dsa->stencil_enabled = state->stencil[0].enabled; + dsa->stencil_write_enabled = state->stencil[0].enabled && + (si_dsa_writes_stencil(&state->stencil[0]) || + si_dsa_writes_stencil(&state->stencil[1])); + dsa->db_can_write = dsa->depth_write_enabled || + dsa->stencil_write_enabled; return dsa; } @@ -1125,6 +1147,13 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state) if (!old_dsa || old_dsa->alpha_func != dsa->alpha_func) sctx->do_update_shaders = true; + + if (sctx->screen->dpbb_allowed && + (!old_dsa || + (old_dsa->depth_enabled != dsa->depth_enabled || + old_dsa->stencil_enabled != dsa->stencil_enabled || + old_dsa->db_can_write != dsa->db_can_write))) + si_mark_atom_dirty(sctx, &sctx->dpbb_state); } static void si_delete_dsa_state(struct pipe_context *ctx, void *state) @@ -2146,36 +2175,36 @@ static void si_initialize_color_surface(struct si_context *sctx, unsigned color_info, color_attrib, color_view; unsigned format, swap, ntype, endian; const struct util_format_description *desc; - int i; + int firstchan; unsigned blend_clamp = 0, blend_bypass = 0; color_view = S_028C6C_SLICE_START(surf->base.u.tex.first_layer) | S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer); desc = util_format_description(surf->base.format); - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { + for (firstchan = 0; firstchan < 4; firstchan++) { + if (desc->channel[firstchan].type != UTIL_FORMAT_TYPE_VOID) { break; } } - if (i == 4 || desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) { + if (firstchan == 4 || desc->channel[firstchan].type == UTIL_FORMAT_TYPE_FLOAT) { ntype = V_028C70_NUMBER_FLOAT; } else { ntype = V_028C70_NUMBER_UNORM; if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) ntype = V_028C70_NUMBER_SRGB; - else if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - if (desc->channel[i].pure_integer) { + else if (desc->channel[firstchan].type == UTIL_FORMAT_TYPE_SIGNED) { + if (desc->channel[firstchan].pure_integer) { ntype = V_028C70_NUMBER_SINT; } else { - assert(desc->channel[i].normalized); + assert(desc->channel[firstchan].normalized); ntype = V_028C70_NUMBER_SNORM; } - } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) { - if (desc->channel[i].pure_integer) { + } else if (desc->channel[firstchan].type == UTIL_FORMAT_TYPE_UNSIGNED) { + if (desc->channel[firstchan].pure_integer) { ntype = V_028C70_NUMBER_UINT; } else { - assert(desc->channel[i].normalized); + assert(desc->channel[firstchan].normalized); ntype = V_028C70_NUMBER_UNORM; } } @@ -2298,7 +2327,7 @@ static void si_init_depth_surface(struct si_context *sctx, uint32_t z_info, s_info; format = si_translate_dbformat(rtex->db_render_format); - stencil_format = rtex->surface.flags & RADEON_SURF_SBUFFER ? + stencil_format = rtex->surface.has_stencil ? V_028044_STENCIL_8 : V_028044_STENCIL_INVALID; assert(format != V_028040_Z_INVALID); @@ -2327,8 +2356,7 @@ static void si_init_depth_surface(struct si_context *sctx, surf->db_depth_size = S_02801C_X_MAX(rtex->resource.b.b.width0 - 1) | S_02801C_Y_MAX(rtex->resource.b.b.height0 - 1); - /* Only use HTILE for the first level. */ - if (rtex->htile_offset && !level) { + if (r600_htile_enabled(rtex, level)) { z_info |= S_028038_TILE_SURFACE_ENABLE(1) | S_028038_ALLOW_EXPCLEAR(1); @@ -2344,7 +2372,7 @@ static void si_init_depth_surface(struct si_context *sctx, s_info |= S_02803C_ITERATE_FLUSH(1); } - if (rtex->surface.flags & RADEON_SURF_SBUFFER) { + if (rtex->surface.has_stencil) { /* Stencil buffer workaround ported from the SI-CI-VI code. * See that for explanation. */ @@ -2406,12 +2434,11 @@ static void si_init_depth_surface(struct si_context *sctx, surf->db_depth_slice = S_02805C_SLICE_TILE_MAX((levelinfo->nblk_x * levelinfo->nblk_y) / 64 - 1); - /* Only use HTILE for the first level. */ - if (rtex->htile_offset && !level) { + if (r600_htile_enabled(rtex, level)) { z_info |= S_028040_TILE_SURFACE_ENABLE(1) | S_028040_ALLOW_EXPCLEAR(1); - if (rtex->surface.flags & RADEON_SURF_SBUFFER) { + if (rtex->surface.has_stencil) { /* Workaround: For a not yet understood reason, the * combination of MSAA, fast stencil clear and stencil * decompress messes with subsequent stencil buffer @@ -2467,7 +2494,7 @@ void si_update_fb_dirtiness_after_rendering(struct si_context *sctx) rtex->dirty_level_mask |= 1 << surf->u.tex.level; - if (rtex->surface.flags & RADEON_SURF_SBUFFER) + if (rtex->surface.has_stencil) rtex->stencil_dirty_level_mask |= 1 << surf->u.tex.level; } if (sctx->framebuffer.compressed_cb_mask) { @@ -2572,11 +2599,10 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, * Only flush and wait for CB if there is actually a bound color buffer. */ if (sctx->framebuffer.nr_samples <= 1 && - sctx->framebuffer.state.nr_cbufs) { - sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 | - SI_CONTEXT_INV_GLOBAL_L2 | - SI_CONTEXT_FLUSH_AND_INV_CB; - } + sctx->framebuffer.state.nr_cbufs) + si_make_CB_shader_coherent(sctx, sctx->framebuffer.nr_samples, + sctx->framebuffer.CB_has_shader_readable_metadata); + sctx->b.flags |= SI_CONTEXT_CS_PARTIAL_FLUSH; /* u_blitter doesn't invoke depth decompression when it does multiple @@ -2586,9 +2612,16 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, * Note that lower mipmap levels aren't compressed. */ if (sctx->generate_mipmap_for_depth) { - sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 | - SI_CONTEXT_INV_GLOBAL_L2 | - SI_CONTEXT_FLUSH_AND_INV_DB; + si_make_DB_shader_coherent(sctx, 1, false, + sctx->framebuffer.DB_has_shader_readable_metadata); + } else if (sctx->b.chip_class == GFX9) { + /* It appears that DB metadata "leaks" in a sequence of: + * - depth clear + * - DCC decompress for shader image writes (with DB disabled) + * - render with DEPTH_BEFORE_SHADER=1 + * Flushing DB metadata works around the problem. + */ + sctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_DB_META; } /* Take the maximum of the old and new count. If the new count is lower, @@ -2613,6 +2646,8 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, sctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state); sctx->framebuffer.log_samples = util_logbase2(sctx->framebuffer.nr_samples); sctx->framebuffer.any_dst_linear = false; + sctx->framebuffer.CB_has_shader_readable_metadata = false; + sctx->framebuffer.DB_has_shader_readable_metadata = false; for (i = 0; i < state->nr_cbufs; i++) { if (!state->cbufs[i]) @@ -2647,6 +2682,9 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, if (rtex->surface.is_linear) sctx->framebuffer.any_dst_linear = true; + if (vi_dcc_enabled(rtex, surf->base.u.tex.level)) + sctx->framebuffer.CB_has_shader_readable_metadata = true; + r600_context_add_resource_size(ctx, surf->base.texture); p_atomic_inc(&rtex->framebuffers_bound); @@ -2665,6 +2703,10 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, if (!surf->depth_initialized) { si_init_depth_surface(sctx, surf); } + + if (vi_tc_compat_htile_enabled(rtex, surf->base.u.tex.level)) + sctx->framebuffer.DB_has_shader_readable_metadata = true; + r600_context_add_resource_size(ctx, surf->base.texture); } @@ -2672,6 +2714,9 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, si_mark_atom_dirty(sctx, &sctx->cb_render_state); si_mark_atom_dirty(sctx, &sctx->framebuffer.atom); + if (sctx->screen->dpbb_allowed) + si_mark_atom_dirty(sctx, &sctx->dpbb_state); + if (sctx->framebuffer.any_dst_linear != old_any_dst_linear) si_mark_atom_dirty(sctx, &sctx->msaa_config); @@ -2762,13 +2807,15 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom /* Compute mutable surface parameters. */ cb_color_base = tex->resource.gpu_address >> 8; - cb_color_fmask = cb_color_base; + cb_color_fmask = 0; cb_dcc_base = 0; cb_color_info = cb->cb_color_info | tex->cb_color_info; cb_color_attrib = cb->cb_color_attrib; - if (tex->fmask.size) + if (tex->fmask.size) { cb_color_fmask = (tex->resource.gpu_address + tex->fmask.offset) >> 8; + cb_color_fmask |= tex->fmask.tile_swizzle; + } /* Set up DCC. */ if (vi_dcc_enabled(tex, cb->base.u.tex.level)) { @@ -2782,6 +2829,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom cb_dcc_base = ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) + tex->dcc_offset) >> 8; + cb_dcc_base |= tex->surface.tile_swizzle; } if (sctx->b.chip_class >= GFX9) { @@ -2794,6 +2842,9 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom /* Set mutable surface parameters. */ cb_color_base += tex->surface.u.gfx9.surf_offset >> 8; + cb_color_base |= tex->surface.tile_swizzle; + if (!tex->fmask.size) + cb_color_fmask = cb_color_base; cb_color_attrib |= S_028C74_COLOR_SW_MODE(tex->surface.u.gfx9.surf.swizzle_mode) | S_028C74_FMASK_SW_MODE(tex->surface.u.gfx9.fmask.swizzle_mode) | S_028C74_RB_ALIGNED(meta.rb_aligned) | @@ -2826,6 +2877,12 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom unsigned cb_color_pitch, cb_color_slice, cb_color_fmask_slice; cb_color_base += level_info->offset >> 8; + /* Only macrotiled modes can set tile swizzle. */ + if (level_info->mode == RADEON_SURF_MODE_2D) + cb_color_base |= tex->surface.tile_swizzle; + + if (!tex->fmask.size) + cb_color_fmask = cb_color_base; if (cb_dcc_base) cb_dcc_base += level_info->dcc_offset >> 8; @@ -2945,7 +3002,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom radeon_set_context_reg(cs, R_028208_PA_SC_WINDOW_SCISSOR_BR, S_028208_BR_X(state->width) | S_028208_BR_Y(state->height)); - if (sctx->b.chip_class >= GFX9) { + if (sctx->screen->dfsm_allowed) { radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cs, EVENT_TYPE(V_028A90_BREAK_BATCH) | EVENT_INDEX(0)); } @@ -2973,8 +3030,7 @@ static void si_emit_msaa_sample_locs(struct si_context *sctx, if (has_msaa_sample_loc_bug) nr_samples = MAX2(nr_samples, 1); - if (nr_samples >= 1 && - (nr_samples != sctx->msaa_sample_locs.nr_samples)) { + if (nr_samples != sctx->msaa_sample_locs.nr_samples) { sctx->msaa_sample_locs.nr_samples = nr_samples; cayman_emit_msaa_sample_locs(cs, nr_samples); } @@ -3024,7 +3080,7 @@ static void si_emit_msaa_config(struct si_context *sctx, struct r600_atom *atom) sc_mode_cntl_1); /* GFX9: Flush DFSM when the AA mode changes. */ - if (sctx->b.chip_class >= GFX9) { + if (sctx->screen->dfsm_allowed) { radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); radeon_emit(cs, EVENT_TYPE(V_028A90_FLUSH_DFSM) | EVENT_INDEX(0)); } @@ -3042,6 +3098,8 @@ static void si_set_min_samples(struct pipe_context *ctx, unsigned min_samples) if (sctx->framebuffer.nr_samples > 1) si_mark_atom_dirty(sctx, &sctx->msaa_config); + if (sctx->screen->dpbb_allowed) + si_mark_atom_dirty(sctx, &sctx->dpbb_state); } /* @@ -3166,14 +3224,13 @@ si_make_texture_descriptor(struct si_screen *screen, uint32_t *fmask_state) { struct pipe_resource *res = &tex->resource.b.b; - const struct util_format_description *base_desc, *desc; + const struct util_format_description *desc; unsigned char swizzle[4]; int first_non_void; unsigned num_format, data_format, type; uint64_t va; desc = util_format_description(pipe_format); - base_desc = util_format_description(res->format); if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0}; @@ -3274,15 +3331,6 @@ si_make_texture_descriptor(struct si_screen *screen, data_format = 0; } - /* Enable clamping for UNORM depth formats promoted to Z32F. */ - if (screen->b.chip_class >= GFX9 && - util_format_has_depth(desc) && - num_format == V_008F14_IMG_NUM_FORMAT_FLOAT && - util_get_depth_format_type(base_desc) != UTIL_FORMAT_TYPE_FLOAT) { - /* NUM_FORMAT=FLOAT and DATA_FORMAT=24_8 means "clamp to [0,1]". */ - data_format = V_008F14_IMG_DATA_FORMAT_24_8; - } - /* S8 with Z32 HTILE needs a special format. */ if (screen->b.chip_class >= GFX9 && pipe_format == PIPE_FORMAT_S8_UINT && @@ -3412,7 +3460,7 @@ si_make_texture_descriptor(struct si_screen *screen, num_format = V_008F14_IMG_NUM_FORMAT_UINT; } - fmask_state[0] = va >> 8; + fmask_state[0] = (va >> 8) | tex->fmask.tile_swizzle; fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | S_008F14_DATA_FORMAT_GFX6(data_format) | S_008F14_NUM_FORMAT_GFX6(num_format); @@ -4025,11 +4073,9 @@ static void si_texture_barrier(struct pipe_context *ctx, unsigned flags) /* Multisample surfaces are flushed in si_decompress_textures. */ if (sctx->framebuffer.nr_samples <= 1 && - sctx->framebuffer.state.nr_cbufs) { - sctx->b.flags |= SI_CONTEXT_INV_VMEM_L1 | - SI_CONTEXT_INV_GLOBAL_L2 | - SI_CONTEXT_FLUSH_AND_INV_CB; - } + sctx->framebuffer.state.nr_cbufs) + si_make_CB_shader_coherent(sctx, sctx->framebuffer.nr_samples, + sctx->framebuffer.CB_has_shader_readable_metadata); } /* This only ensures coherency for shader image/buffer stores. */ @@ -4072,8 +4118,10 @@ static void si_memory_barrier(struct pipe_context *ctx, unsigned flags) if (flags & PIPE_BARRIER_FRAMEBUFFER && sctx->framebuffer.nr_samples <= 1 && sctx->framebuffer.state.nr_cbufs) { - sctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_CB | - SI_CONTEXT_WRITEBACK_GLOBAL_L2; + sctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_CB; + + if (sctx->b.chip_class <= VI) + sctx->b.flags |= SI_CONTEXT_WRITEBACK_GLOBAL_L2; } /* Indirect buffers use TC L2 on GFX9, but not older hw. */ @@ -4111,6 +4159,7 @@ void si_init_state_functions(struct si_context *sctx) si_init_atom(sctx, &sctx->framebuffer.atom, &sctx->atoms.s.framebuffer, si_emit_framebuffer_state); si_init_atom(sctx, &sctx->msaa_sample_locs.atom, &sctx->atoms.s.msaa_sample_locs, si_emit_msaa_sample_locs); si_init_atom(sctx, &sctx->db_render_state, &sctx->atoms.s.db_render_state, si_emit_db_render_state); + si_init_atom(sctx, &sctx->dpbb_state, &sctx->atoms.s.dpbb_state, si_emit_dpbb_state); si_init_atom(sctx, &sctx->msaa_config, &sctx->atoms.s.msaa_config, si_emit_msaa_config); si_init_atom(sctx, &sctx->sample_mask.atom, &sctx->atoms.s.sample_mask, si_emit_sample_mask); si_init_atom(sctx, &sctx->cb_render_state, &sctx->atoms.s.cb_render_state, si_emit_cb_render_state); @@ -4275,6 +4324,25 @@ void si_init_screen_state_functions(struct si_screen *sscreen) sscreen->b.apply_opaque_metadata = si_apply_opaque_metadata; } +static void si_set_grbm_gfx_index(struct si_context *sctx, + struct si_pm4_state *pm4, unsigned value) +{ + unsigned reg = sctx->b.chip_class >= CIK ? R_030800_GRBM_GFX_INDEX : + GRBM_GFX_INDEX; + si_pm4_set_reg(pm4, reg, value); +} + +static void si_set_grbm_gfx_index_se(struct si_context *sctx, + struct si_pm4_state *pm4, unsigned se) +{ + assert(se == ~0 || se < sctx->screen->b.info.max_se); + si_set_grbm_gfx_index(sctx, pm4, + (se == ~0 ? S_030800_SE_BROADCAST_WRITES(1) : + S_030800_SE_INDEX(se)) | + S_030800_SH_BROADCAST_WRITES(1) | + S_030800_INSTANCE_BROADCAST_WRITES(1)); +} + static void si_write_harvested_raster_configs(struct si_context *sctx, struct si_pm4_state *pm4, @@ -4377,28 +4445,12 @@ si_write_harvested_raster_configs(struct si_context *sctx, } } - /* GRBM_GFX_INDEX has a different offset on SI and CI+ */ - if (sctx->b.chip_class < CIK) - si_pm4_set_reg(pm4, GRBM_GFX_INDEX, - SE_INDEX(se) | SH_BROADCAST_WRITES | - INSTANCE_BROADCAST_WRITES); - else - si_pm4_set_reg(pm4, R_030800_GRBM_GFX_INDEX, - S_030800_SE_INDEX(se) | S_030800_SH_BROADCAST_WRITES(1) | - S_030800_INSTANCE_BROADCAST_WRITES(1)); + si_set_grbm_gfx_index_se(sctx, pm4, se); si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, raster_config_se); } + si_set_grbm_gfx_index(sctx, pm4, ~0); - /* GRBM_GFX_INDEX has a different offset on SI and CI+ */ - if (sctx->b.chip_class < CIK) - si_pm4_set_reg(pm4, GRBM_GFX_INDEX, - SE_BROADCAST_WRITES | SH_BROADCAST_WRITES | - INSTANCE_BROADCAST_WRITES); - else { - si_pm4_set_reg(pm4, R_030800_GRBM_GFX_INDEX, - S_030800_SE_BROADCAST_WRITES(1) | S_030800_SH_BROADCAST_WRITES(1) | - S_030800_INSTANCE_BROADCAST_WRITES(1)); - + if (sctx->b.chip_class >= CIK) { if ((num_se > 2) && ((!se_mask[0] && !se_mask[1]) || (!se_mask[2] && !se_mask[3]))) { raster_config_1 &= C_028354_SE_PAIR_MAP; @@ -4416,44 +4468,14 @@ si_write_harvested_raster_configs(struct si_context *sctx, } } -static void si_init_config(struct si_context *sctx) +static void si_set_raster_config(struct si_context *sctx, struct si_pm4_state *pm4) { struct si_screen *sscreen = sctx->screen; unsigned num_rb = MIN2(sctx->screen->b.info.num_render_backends, 16); unsigned rb_mask = sctx->screen->b.info.enabled_rb_mask; unsigned raster_config, raster_config_1; - uint64_t border_color_va = sctx->border_color_buffer->gpu_address; - struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); - - if (!pm4) - return; - - si_pm4_cmd_begin(pm4, PKT3_CONTEXT_CONTROL); - si_pm4_cmd_add(pm4, CONTEXT_CONTROL_LOAD_ENABLE(1)); - si_pm4_cmd_add(pm4, CONTEXT_CONTROL_SHADOW_ENABLE(1)); - si_pm4_cmd_end(pm4, false); - - si_pm4_cmd_begin(pm4, PKT3_CLEAR_STATE); - si_pm4_cmd_add(pm4, 0); - si_pm4_cmd_end(pm4, false); - - si_pm4_set_reg(pm4, R_028A18_VGT_HOS_MAX_TESS_LEVEL, fui(64)); - - /* FIXME calculate these values somehow ??? */ - if (sctx->b.chip_class <= VI) { - si_pm4_set_reg(pm4, R_028A54_VGT_GS_PER_ES, SI_GS_PER_ES); - si_pm4_set_reg(pm4, R_028A58_VGT_ES_PER_GS, 0x40); - } - - si_pm4_set_reg(pm4, R_028AA0_VGT_INSTANCE_STEP_RATE_0, 1); - if (sctx->b.chip_class < CIK) - si_pm4_set_reg(pm4, R_008A14_PA_CL_ENHANCE, S_008A14_NUM_CLIP_SEQ(3) | - S_008A14_CLIP_VTX_REORDER_ENA(1)); - - si_pm4_set_reg(pm4, R_028BD4_PA_SC_CENTROID_PRIORITY_0, 0x76543210); - si_pm4_set_reg(pm4, R_028BD8_PA_SC_CENTROID_PRIORITY_1, 0xfedcba98); - switch (sctx->screen->b.family) { + switch (sctx->b.family) { case CHIP_TAHITI: case CHIP_PITCAIRN: raster_config = 0x2a00126a; @@ -4525,30 +4547,82 @@ static void si_init_config(struct si_context *sctx) raster_config_1 = 0x00000000; break; default: - if (sctx->b.chip_class <= VI) { - fprintf(stderr, - "radeonsi: Unknown GPU, using 0 for raster_config\n"); - raster_config = 0x00000000; - raster_config_1 = 0x00000000; - } - break; + fprintf(stderr, + "radeonsi: Unknown GPU, using 0 for raster_config\n"); + raster_config = 0x00000000; + raster_config_1 = 0x00000000; } + if (!rb_mask || util_bitcount(rb_mask) >= num_rb) { + /* Always use the default config when all backends are enabled + * (or when we failed to determine the enabled backends). + */ + si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, + raster_config); + if (sctx->b.chip_class >= CIK) + si_pm4_set_reg(pm4, R_028354_PA_SC_RASTER_CONFIG_1, + raster_config_1); + } else { + si_write_harvested_raster_configs(sctx, pm4, raster_config, raster_config_1); + } +} + +static void si_init_config(struct si_context *sctx) +{ + struct si_screen *sscreen = sctx->screen; + uint64_t border_color_va = sctx->border_color_buffer->gpu_address; + bool has_clear_state = sscreen->has_clear_state; + struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); + + /* Only SI can disable CLEAR_STATE for now. */ + assert(has_clear_state || sscreen->b.chip_class == SI); + + if (!pm4) + return; + + si_pm4_cmd_begin(pm4, PKT3_CONTEXT_CONTROL); + si_pm4_cmd_add(pm4, CONTEXT_CONTROL_LOAD_ENABLE(1)); + si_pm4_cmd_add(pm4, CONTEXT_CONTROL_SHADOW_ENABLE(1)); + si_pm4_cmd_end(pm4, false); + + if (has_clear_state) { + si_pm4_cmd_begin(pm4, PKT3_CLEAR_STATE); + si_pm4_cmd_add(pm4, 0); + si_pm4_cmd_end(pm4, false); + } + + if (sctx->b.chip_class <= VI) + si_set_raster_config(sctx, pm4); + + si_pm4_set_reg(pm4, R_028A18_VGT_HOS_MAX_TESS_LEVEL, fui(64)); + if (!has_clear_state) + si_pm4_set_reg(pm4, R_028A1C_VGT_HOS_MIN_TESS_LEVEL, fui(0)); + + /* FIXME calculate these values somehow ??? */ if (sctx->b.chip_class <= VI) { - if (!rb_mask || util_bitcount(rb_mask) >= num_rb) { - /* Always use the default config when all backends are enabled - * (or when we failed to determine the enabled backends). - */ - si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, - raster_config); - if (sctx->b.chip_class >= CIK) - si_pm4_set_reg(pm4, R_028354_PA_SC_RASTER_CONFIG_1, - raster_config_1); - } else { - si_write_harvested_raster_configs(sctx, pm4, raster_config, raster_config_1); - } + si_pm4_set_reg(pm4, R_028A54_VGT_GS_PER_ES, SI_GS_PER_ES); + si_pm4_set_reg(pm4, R_028A58_VGT_ES_PER_GS, 0x40); } + if (!has_clear_state) { + si_pm4_set_reg(pm4, R_028A5C_VGT_GS_PER_VS, 0x2); + si_pm4_set_reg(pm4, R_028A8C_VGT_PRIMITIVEID_RESET, 0x0); + si_pm4_set_reg(pm4, R_028B98_VGT_STRMOUT_BUFFER_CONFIG, 0x0); + } + + si_pm4_set_reg(pm4, R_028AA0_VGT_INSTANCE_STEP_RATE_0, 1); + if (!has_clear_state) + si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0x0); + if (sctx->b.chip_class < CIK) + si_pm4_set_reg(pm4, R_008A14_PA_CL_ENHANCE, S_008A14_NUM_CLIP_SEQ(3) | + S_008A14_CLIP_VTX_REORDER_ENA(1)); + + si_pm4_set_reg(pm4, R_028BD4_PA_SC_CENTROID_PRIORITY_0, 0x76543210); + si_pm4_set_reg(pm4, R_028BD8_PA_SC_CENTROID_PRIORITY_1, 0xfedcba98); + + if (!has_clear_state) + si_pm4_set_reg(pm4, R_02882C_PA_SU_PRIM_FILTER_CNTL, 0); + /* CLEAR_STATE doesn't clear these correctly on certain generations. * I don't know why. Deduced by trial and error. */ @@ -4563,6 +4637,26 @@ static void si_init_config(struct si_context *sctx) S_028034_BR_X(16384) | S_028034_BR_Y(16384)); } + if (!has_clear_state) { + si_pm4_set_reg(pm4, R_02820C_PA_SC_CLIPRECT_RULE, 0xFFFF); + si_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, + S_028230_ER_TRI(0xA) | + S_028230_ER_POINT(0xA) | + S_028230_ER_RECT(0xA) | + /* Required by DX10_DIAMOND_TEST_ENA: */ + S_028230_ER_LINE_LR(0x1A) | + S_028230_ER_LINE_RL(0x26) | + S_028230_ER_LINE_TB(0xA) | + S_028230_ER_LINE_BT(0xA)); + /* PA_SU_HARDWARE_SCREEN_OFFSET must be 0 due to hw bug on SI */ + si_pm4_set_reg(pm4, R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0); + si_pm4_set_reg(pm4, R_028820_PA_CL_NANINF_CNTL, 0); + si_pm4_set_reg(pm4, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0); + si_pm4_set_reg(pm4, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0); + si_pm4_set_reg(pm4, R_028AC8_DB_PRELOAD_CONTROL, 0x0); + si_pm4_set_reg(pm4, R_02800C_DB_RENDER_OVERRIDE, 0); + } + if (sctx->b.chip_class >= GFX9) { si_pm4_set_reg(pm4, R_030920_VGT_MAX_VTX_INDX, ~0); si_pm4_set_reg(pm4, R_030924_VGT_MIN_VTX_INDX, 0); @@ -4595,26 +4689,39 @@ static void si_init_config(struct si_context *sctx) } si_pm4_set_reg(pm4, R_00B21C_SPI_SHADER_PGM_RSRC3_GS, S_00B21C_CU_EN(0xffff)); - if (sscreen->b.info.num_good_compute_units / - (sscreen->b.info.max_se * sscreen->b.info.max_sh_per_se) <= 4) { + /* Compute LATE_ALLOC_VS.LIMIT. */ + unsigned num_cu_per_sh = sscreen->b.info.num_good_compute_units / + (sscreen->b.info.max_se * + sscreen->b.info.max_sh_per_se); + unsigned late_alloc_limit; /* The limit is per SH. */ + + if (sctx->b.family == CHIP_KABINI) { + late_alloc_limit = 0; /* Potential hang on Kabini. */ + } else if (num_cu_per_sh <= 4) { /* Too few available compute units per SH. Disallowing - * VS to run on CU0 could hurt us more than late VS + * VS to run on one CU could hurt us more than late VS * allocation would help. * - * LATE_ALLOC_VS = 2 is the highest safe number. + * 2 is the highest safe number that allows us to keep + * all CUs enabled. */ - si_pm4_set_reg(pm4, R_00B118_SPI_SHADER_PGM_RSRC3_VS, S_00B118_CU_EN(0xffff)); - si_pm4_set_reg(pm4, R_00B11C_SPI_SHADER_LATE_ALLOC_VS, S_00B11C_LIMIT(2)); + late_alloc_limit = 2; } else { - /* Set LATE_ALLOC_VS == 31. It should be less than - * the number of scratch waves. Limitations: - * - VS can't execute on CU0. - * - If HS writes outputs to LDS, LS can't execute on CU0. + /* This is a good initial value, allowing 1 late_alloc + * wave per SIMD on num_cu - 2. */ - si_pm4_set_reg(pm4, R_00B118_SPI_SHADER_PGM_RSRC3_VS, S_00B118_CU_EN(0xfffe)); - si_pm4_set_reg(pm4, R_00B11C_SPI_SHADER_LATE_ALLOC_VS, S_00B11C_LIMIT(31)); + late_alloc_limit = (num_cu_per_sh - 2) * 4; + + /* The limit is 0-based, so 0 means 1. */ + assert(late_alloc_limit > 0 && late_alloc_limit <= 64); + late_alloc_limit -= 1; } + /* VS can't execute on one CU if the limit is > 2. */ + si_pm4_set_reg(pm4, R_00B118_SPI_SHADER_PGM_RSRC3_VS, + S_00B118_CU_EN(late_alloc_limit > 2 ? 0xfffe : 0xffff)); + si_pm4_set_reg(pm4, R_00B11C_SPI_SHADER_LATE_ALLOC_VS, + S_00B11C_LIMIT(late_alloc_limit)); si_pm4_set_reg(pm4, R_00B01C_SPI_SHADER_PGM_RSRC3_PS, S_00B01C_CU_EN(0xffff)); } @@ -4639,6 +4746,9 @@ static void si_init_config(struct si_context *sctx) vgt_tess_distribution |= S_028B50_TRAP_SPLIT(3); si_pm4_set_reg(pm4, R_028B50_VGT_TESS_DISTRIBUTION, vgt_tess_distribution); + } else if (!has_clear_state) { + si_pm4_set_reg(pm4, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL, 14); + si_pm4_set_reg(pm4, R_028C5C_VGT_OUT_DEALLOC_CNTL, 16); } si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, border_color_va >> 8); @@ -4662,12 +4772,6 @@ static void si_init_config(struct si_context *sctx) assert(0); } - si_pm4_set_reg(pm4, R_028060_DB_DFSM_CONTROL, - S_028060_PUNCHOUT_MODE(V_028060_FORCE_OFF)); - /* TODO: Enable the binner: */ - si_pm4_set_reg(pm4, R_028C44_PA_SC_BINNER_CNTL_0, - S_028C44_BINNING_MODE(V_028C44_DISABLE_BINNING_USE_LEGACY_SC) | - S_028C44_DISABLE_START_OF_PRIM(1)); si_pm4_set_reg(pm4, R_028C48_PA_SC_BINNER_CNTL_1, S_028C48_MAX_ALLOC_COUNT(MIN2(128, pc_lines / (4 * num_se))) | S_028C48_MAX_PRIM_PER_BATCH(1023));