diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 80e03678366..9984045ba05 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1137,6 +1137,9 @@ struct si_context { bool ps_uses_fbfetch; bool smoothing_enabled; + /* point smoothing state.*/ + bool point_smoothing_enabled; + /* DB render state. */ unsigned ps_db_shader_control; unsigned dbcb_copy_sample; diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 9874c964ac9..531fc60ca95 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -43,6 +43,18 @@ static const char scratch_rsrc_dword1_symbol[] = "SCRATCH_RSRC_DWORD1"; static void si_dump_shader_key(const struct si_shader *shader, FILE *f); +/* Get the number of all interpolated inputs */ +unsigned si_get_ps_num_interp(struct si_shader *ps) +{ + struct si_shader_info *info = &ps->selector->info; + unsigned num_colors = !!(info->colors_read & 0x0f) + !!(info->colors_read & 0xf0); + unsigned num_interp = + ps->selector->info.num_inputs + (ps->key.ps.part.prolog.color_two_side ? num_colors : 0); + + assert(num_interp <= 32); + return MIN2(num_interp, 32); +} + /** Whether the shader runs as a combination of multiple API shaders */ bool si_is_multi_part_shader(struct si_shader *shader) { @@ -1293,6 +1305,7 @@ static void si_dump_shader_key(const struct si_shader *shader, FILE *f) fprintf(f, " epilog.clamp_color = %u\n", key->ps.part.epilog.clamp_color); fprintf(f, " epilog.dual_src_blend_swizzle = %u\n", key->ps.part.epilog.dual_src_blend_swizzle); fprintf(f, " mono.poly_line_smoothing = %u\n", key->ps.mono.poly_line_smoothing); + fprintf(f, " mono.point_smoothing = %u\n", key->ps.mono.point_smoothing); fprintf(f, " mono.interpolate_at_sample_force_center = %u\n", key->ps.mono.interpolate_at_sample_force_center); fprintf(f, " mono.fbfetch_msaa = %u\n", key->ps.mono.fbfetch_msaa); @@ -1650,6 +1663,9 @@ struct nir_shader *si_get_nir_shader(struct si_shader *shader, bool *free_nir, if (sel->stage == MESA_SHADER_FRAGMENT && key->ps.mono.poly_line_smoothing) NIR_PASS(progress, nir, nir_lower_poly_line_smooth, SI_NUM_SMOOTH_AA_SAMPLES); + if (sel->stage == MESA_SHADER_FRAGMENT && key->ps.mono.point_smoothing) + NIR_PASS(progress, nir, nir_lower_point_smooth); + if (progress) si_nir_opts(sel->screen, nir, true); diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 8bed98dbd82..dff39ae11f6 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -733,6 +733,7 @@ struct si_shader_key_ps { /* Flags for monolithic compilation only. */ struct { unsigned poly_line_smoothing : 1; + unsigned point_smoothing : 1; unsigned interpolate_at_sample_force_center : 1; unsigned fbfetch_msaa : 1; unsigned fbfetch_is_1D : 1; @@ -979,6 +980,7 @@ void si_multiwave_lds_size_workaround(struct si_screen *sscreen, unsigned *lds_s const char *si_get_shader_name(const struct si_shader *shader); void si_shader_binary_clean(struct si_shader_binary *binary); struct nir_shader *si_deserialize_shader(struct si_shader_selector *sel); +unsigned si_get_ps_num_interp(struct si_shader *ps); /* si_shader_info.c */ void si_nir_scan_shader(struct si_screen *sscreen, const struct nir_shader *nir, @@ -1059,6 +1061,7 @@ static inline bool si_shader_uses_discard(struct si_shader *shader) /* Changes to this should also update ps_modifies_zs. */ return shader->selector->info.base.fs.uses_discard || shader->key.ps.part.prolog.poly_stipple || + shader->key.ps.mono.point_smoothing || shader->key.ps.part.epilog.alpha_func != PIPE_FUNC_ALWAYS; } diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c index b6023f47241..fc3f932bdd1 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c @@ -899,6 +899,7 @@ bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shader *shad ctx->abi.color1 = ac_to_integer(&ctx->ac, ac_build_gather_values(&ctx->ac, values, 4)); } + ctx->abi.num_interp = si_get_ps_num_interp(shader); ctx->abi.interp_at_sample_force_center = ctx->shader->key.ps.mono.interpolate_at_sample_force_center; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 94c9241ef06..be87e2478de 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -949,6 +949,7 @@ static void *si_create_rs_state(struct pipe_context *ctx, const struct pipe_rast rs->line_smooth = state->line_smooth; rs->line_width = state->line_width; rs->poly_smooth = state->poly_smooth; + rs->point_smooth = state->point_smooth; rs->uses_poly_offset = state->offset_point || state->offset_line || state->offset_tri; rs->clamp_fragment_color = state->clamp_fragment_color; rs->clamp_vertex_color = state->clamp_vertex_color; @@ -1195,6 +1196,7 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state) old_rs->multisample_enable != rs->multisample_enable || old_rs->poly_stipple_enable != rs->poly_stipple_enable || old_rs->poly_smooth != rs->poly_smooth || old_rs->line_smooth != rs->line_smooth || + old_rs->point_smooth != rs->point_smooth || old_rs->clamp_fragment_color != rs->clamp_fragment_color || old_rs->force_persample_interp != rs->force_persample_interp || old_rs->polygon_mode_is_points != rs->polygon_mode_is_points) { @@ -1207,6 +1209,7 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state) if (old_rs->line_smooth != rs->line_smooth || old_rs->poly_smooth != rs->poly_smooth || + old_rs->point_smooth != rs->point_smooth || old_rs->poly_stipple_enable != rs->poly_stipple_enable || old_rs->flatshade != rs->flatshade) si_update_vrs_flat_shading(sctx); diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index e48e1665054..4ca3595d452 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -91,6 +91,7 @@ struct si_state_rasterizer { unsigned poly_stipple_enable : 1; unsigned line_smooth : 1; unsigned poly_smooth : 1; + unsigned point_smooth : 1; unsigned uses_poly_offset : 1; unsigned clamp_fragment_color : 1; unsigned clamp_vertex_color : 1; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp b/src/gallium/drivers/radeonsi/si_state_shaders.cpp index fa349a20ce1..722e5d43967 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp +++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp @@ -1770,17 +1770,6 @@ static void si_shader_vs(struct si_screen *sscreen, struct si_shader *shader, polaris_set_vgt_vertex_reuse(sscreen, shader->selector, shader); } -static unsigned si_get_ps_num_interp(struct si_shader *ps) -{ - struct si_shader_info *info = &ps->selector->info; - unsigned num_colors = !!(info->colors_read & 0x0f) + !!(info->colors_read & 0xf0); - unsigned num_interp = - ps->selector->info.num_inputs + (ps->key.ps.part.prolog.color_two_side ? num_colors : 0); - - assert(num_interp <= 32); - return MIN2(num_interp, 32); -} - static unsigned si_get_spi_shader_col_format(struct si_shader *shader) { unsigned spi_shader_col_format = shader->key.ps.part.epilog.spi_shader_col_format; @@ -1994,8 +1983,11 @@ static void si_shader_ps(struct si_screen *sscreen, struct si_shader *shader) spi_ps_in_control = S_0286D8_NUM_INTERP(num_interp) | S_0286D8_PS_W32_EN(shader->wave_size == 32); - /* Workaround when there are no PS inputs but LDS is used. */ - if (sscreen->info.gfx_level == GFX11 && !num_interp && shader->config.lds_size) + /* Enable PARAM_GEN for point smoothing. + * Gfx11 workaround when there are no PS inputs but LDS is used. + */ + if ((sscreen->info.gfx_level == GFX11 && !num_interp && shader->config.lds_size) || + shader->key.ps.mono.point_smoothing) spi_ps_in_control |= S_0286D8_PARAM_GEN(1); shader->ctx_reg.ps.num_interp = num_interp; @@ -2187,7 +2179,8 @@ void si_update_ps_inputs_read_or_disabled(struct si_context *sctx) ps->info.writes_samplemask || sctx->queued.named.blend->alpha_to_coverage || sctx->queued.named.dsa->alpha_func != PIPE_FUNC_ALWAYS || - sctx->queued.named.rasterizer->poly_stipple_enable; + sctx->queued.named.rasterizer->poly_stipple_enable || + sctx->queued.named.rasterizer->point_smooth; unsigned ps_colormask = si_get_total_colormask(sctx); ps_disabled = sctx->queued.named.rasterizer->rasterizer_discard || @@ -2388,6 +2381,9 @@ static void si_ps_key_update_primtype_shader_rasterizer_framebuffer(struct si_co key->ps.mono.poly_line_smoothing = ((is_poly && rs->poly_smooth) || (is_line && rs->line_smooth)) && sctx->framebuffer.nr_samples <= 1; + + key->ps.mono.point_smoothing = rs->point_smooth && + sctx->current_rast_prim == PIPE_PRIM_POINTS; } void si_ps_key_update_sample_shading(struct si_context *sctx) @@ -3552,7 +3548,7 @@ void si_update_vrs_flat_shading(struct si_context *sctx) if (allow_flat_shading && (rs->line_smooth || rs->poly_smooth || rs->poly_stipple_enable || - (!rs->flatshade && info->uses_interp_color))) + rs->point_smooth || (!rs->flatshade && info->uses_interp_color))) allow_flat_shading = false; if (sctx->allow_flat_shading != allow_flat_shading) {