radeonsi: implement replacement of sample_mask_in with helper_invocation
This just implements it in the PS prolog and LLVM IR (ACO already implements it), and enables it for monolithic shaders where it's already implemented in ac_nir_lower_ps_early. Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32910>
This commit is contained in:
@@ -1576,6 +1576,8 @@ static void si_dump_shader_key(const struct si_shader *shader, FILE *f)
|
||||
key->ps.part.prolog.samplemask_log_ps_iter);
|
||||
fprintf(f, " prolog.get_frag_coord_from_pixel_coord = %u\n",
|
||||
key->ps.part.prolog.get_frag_coord_from_pixel_coord);
|
||||
fprintf(f, " prolog.force_samplemask_to_helper_invocation = %u\n",
|
||||
key->ps.part.prolog.force_samplemask_to_helper_invocation);
|
||||
fprintf(f, " epilog.spi_shader_col_format = 0x%x\n",
|
||||
key->ps.part.epilog.spi_shader_col_format);
|
||||
fprintf(f, " epilog.color_is_int8 = 0x%X\n", key->ps.part.epilog.color_is_int8);
|
||||
@@ -2302,6 +2304,7 @@ static bool run_pre_link_optimization_passes(struct si_nir_shader_ctx *ctx)
|
||||
ac_nir_lower_ps_early_options early_options = {
|
||||
.force_center_interp_no_msaa = key->ps.part.prolog.force_persp_center_interp ||
|
||||
key->ps.part.prolog.force_linear_center_interp ||
|
||||
key->ps.part.prolog.force_samplemask_to_helper_invocation ||
|
||||
key->ps.mono.interpolate_at_sample_force_center,
|
||||
.load_sample_positions_always_loads_current_ones = true,
|
||||
.force_front_face = key->ps.opt.force_front_face_input,
|
||||
@@ -2331,7 +2334,11 @@ static bool run_pre_link_optimization_passes(struct si_nir_shader_ctx *ctx)
|
||||
|
||||
NIR_PASS(progress, nir, ac_nir_lower_ps_early, &early_options);
|
||||
|
||||
/* This adds gl_SampleMaskIn. */
|
||||
/* This adds gl_SampleMaskIn. It must be after ac_nir_lower_ps_early that lowers
|
||||
* sample_mask_in to load_helper_invocation because we only want to do that for user
|
||||
* shaders while keeping the real sample mask for smoothing, which is produced using
|
||||
* MSAA overrasterization over a single-sample color buffer.
|
||||
*/
|
||||
if (key->ps.mono.poly_line_smoothing)
|
||||
NIR_PASS(progress, nir, nir_lower_poly_line_smooth, SI_NUM_SMOOTH_AA_SAMPLES);
|
||||
|
||||
@@ -2704,6 +2711,12 @@ static void si_set_spi_ps_input_config_for_separate_prolog(struct si_shader *sha
|
||||
if (key->ps.part.prolog.samplemask_log_ps_iter)
|
||||
shader->config.spi_ps_input_ena |= S_0286CC_ANCILLARY_ENA(1);
|
||||
|
||||
if (key->ps.part.prolog.force_samplemask_to_helper_invocation) {
|
||||
assert(key->ps.part.prolog.samplemask_log_ps_iter == 0);
|
||||
assert(!key->ps.mono.poly_line_smoothing);
|
||||
shader->config.spi_ps_input_ena &= C_0286CC_SAMPLE_COVERAGE_ENA;
|
||||
}
|
||||
|
||||
/* The sample mask fixup has an optimization that replaces the sample mask with the sample ID. */
|
||||
if (key->ps.part.prolog.samplemask_log_ps_iter == 3)
|
||||
shader->config.spi_ps_input_ena &= C_0286CC_SAMPLE_COVERAGE_ENA;
|
||||
@@ -3342,7 +3355,8 @@ static void si_get_ps_prolog_key(struct si_shader *shader, union si_shader_part_
|
||||
key->ps_prolog.states.force_linear_center_interp ||
|
||||
key->ps_prolog.states.bc_optimize_for_persp || key->ps_prolog.states.bc_optimize_for_linear ||
|
||||
key->ps_prolog.states.samplemask_log_ps_iter ||
|
||||
key->ps_prolog.states.get_frag_coord_from_pixel_coord);
|
||||
key->ps_prolog.states.get_frag_coord_from_pixel_coord ||
|
||||
key->ps_prolog.states.force_samplemask_to_helper_invocation);
|
||||
key->ps_prolog.fragcoord_usage_mask =
|
||||
G_0286CC_POS_X_FLOAT_ENA(shader->config.spi_ps_input_ena) |
|
||||
(G_0286CC_POS_Y_FLOAT_ENA(shader->config.spi_ps_input_ena) << 1) |
|
||||
@@ -3451,7 +3465,8 @@ static bool si_need_ps_prolog(const union si_shader_part_key *key)
|
||||
key->ps_prolog.states.bc_optimize_for_persp ||
|
||||
key->ps_prolog.states.bc_optimize_for_linear || key->ps_prolog.states.poly_stipple ||
|
||||
key->ps_prolog.states.samplemask_log_ps_iter ||
|
||||
key->ps_prolog.states.get_frag_coord_from_pixel_coord;
|
||||
key->ps_prolog.states.get_frag_coord_from_pixel_coord ||
|
||||
key->ps_prolog.states.force_samplemask_to_helper_invocation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -677,6 +677,7 @@ struct si_ps_prolog_bits {
|
||||
unsigned bc_optimize_for_linear : 1;
|
||||
unsigned samplemask_log_ps_iter : 2;
|
||||
unsigned get_frag_coord_from_pixel_coord : 1;
|
||||
unsigned force_samplemask_to_helper_invocation : 1;
|
||||
};
|
||||
|
||||
/* Common PS bits between the shader key and the epilog key. */
|
||||
|
||||
@@ -270,6 +270,7 @@ si_aco_build_ps_prolog(struct aco_compiler_options *options,
|
||||
.samplemask_log_ps_iter = key->ps_prolog.states.samplemask_log_ps_iter,
|
||||
.get_frag_coord_from_pixel_coord = key->ps_prolog.states.get_frag_coord_from_pixel_coord,
|
||||
.pixel_center_integer = key->ps_prolog.pixel_center_integer,
|
||||
.force_samplemask_to_helper_invocation = key->ps_prolog.states.force_samplemask_to_helper_invocation,
|
||||
.num_interp_inputs = key->ps_prolog.num_interp_inputs,
|
||||
.colors_read = key->ps_prolog.colors_read,
|
||||
.color_interp_vgpr_index[0] = key->ps_prolog.color_interp_vgpr_index[0],
|
||||
|
||||
@@ -655,6 +655,13 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part
|
||||
|
||||
sample_mask_in = ac_to_float(&ctx->ac, sample_mask_in);
|
||||
ret = insert_ret_of_arg(ctx, ret, sample_mask_in, args->ac.sample_coverage.arg_index);
|
||||
} else if (key->ps_prolog.states.force_samplemask_to_helper_invocation) {
|
||||
LLVMValueRef sample_mask_in =
|
||||
LLVMBuildZExt(ctx->ac.builder,
|
||||
LLVMBuildNot(ctx->ac.builder, ac_build_load_helper_invocation(&ctx->ac), ""),
|
||||
ctx->ac.i32, "");
|
||||
ret = insert_ret_of_arg(ctx, ret, ac_to_float(&ctx->ac, sample_mask_in),
|
||||
args->ac.sample_coverage.arg_index);
|
||||
}
|
||||
|
||||
if (key->ps_prolog.states.get_frag_coord_from_pixel_coord) {
|
||||
|
||||
@@ -2864,6 +2864,7 @@ void si_ps_key_update_framebuffer_rasterizer_sample_shading(struct si_context *s
|
||||
key->ps.part.prolog.force_linear_center_interp = 0;
|
||||
key->ps.part.prolog.bc_optimize_for_persp = 0;
|
||||
key->ps.part.prolog.bc_optimize_for_linear = 0;
|
||||
key->ps.part.prolog.force_samplemask_to_helper_invocation = 0;
|
||||
key->ps.mono.interpolate_at_sample_force_center = 0;
|
||||
} else if (rs->multisample_enable && sctx->framebuffer.nr_samples > 1) {
|
||||
key->ps.part.prolog.force_persp_sample_interp = 0;
|
||||
@@ -2876,6 +2877,7 @@ void si_ps_key_update_framebuffer_rasterizer_sample_shading(struct si_context *s
|
||||
sel->info.uses_linear_center && sel->info.uses_linear_centroid;
|
||||
key->ps.part.prolog.get_frag_coord_from_pixel_coord =
|
||||
!sel->info.base.fs.uses_sample_shading && sel->info.reads_frag_coord_mask & 0x3;
|
||||
key->ps.part.prolog.force_samplemask_to_helper_invocation = 0;
|
||||
key->ps.mono.interpolate_at_sample_force_center = 0;
|
||||
} else {
|
||||
key->ps.part.prolog.force_persp_sample_interp = 0;
|
||||
@@ -2894,6 +2896,7 @@ void si_ps_key_update_framebuffer_rasterizer_sample_shading(struct si_context *s
|
||||
key->ps.part.prolog.bc_optimize_for_linear = 0;
|
||||
key->ps.part.prolog.get_frag_coord_from_pixel_coord =
|
||||
!!(sel->info.reads_frag_coord_mask & 0x3);
|
||||
key->ps.part.prolog.force_samplemask_to_helper_invocation = sel->info.reads_samplemask;
|
||||
key->ps.mono.interpolate_at_sample_force_center = sel->info.uses_interp_at_sample;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user