diff --git a/src/amd/compiler/aco_shader_info.h b/src/amd/compiler/aco_shader_info.h index ed1325fad26..e2819a508d9 100644 --- a/src/amd/compiler/aco_shader_info.h +++ b/src/amd/compiler/aco_shader_info.h @@ -91,6 +91,8 @@ struct aco_ps_prolog_info { bool force_linear_sample_interp; bool force_persp_center_interp; bool force_linear_center_interp; + bool uses_persp_centroid; + bool uses_linear_centroid; unsigned samplemask_log_ps_iter; bool force_samplemask_to_helper_invocation; diff --git a/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp b/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp index 0118fa5b3a6..fa26a0bd624 100644 --- a/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp +++ b/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp @@ -64,6 +64,8 @@ overwrite_interp_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo) cond = bool_to_vector_condition(ctx, cond); if (finfo->bc_optimize_for_persp) { + assert(finfo->uses_persp_centroid); + Temp center = get_arg(ctx, ctx->args->persp_center); Temp centroid = get_arg(ctx, ctx->args->persp_centroid); @@ -73,6 +75,8 @@ overwrite_interp_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo) } if (finfo->bc_optimize_for_linear) { + assert(finfo->uses_linear_centroid); + Temp center = get_arg(ctx, ctx->args->linear_center); Temp centroid = get_arg(ctx, ctx->args->linear_centroid); @@ -85,25 +89,29 @@ overwrite_interp_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo) if (finfo->force_persp_sample_interp) { Temp persp_sample = get_arg(ctx, ctx->args->persp_sample); ctx->arg_temps[ctx->args->persp_center.arg_index] = persp_sample; - ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_sample; + if (finfo->uses_persp_centroid) + ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_sample; } if (finfo->force_linear_sample_interp) { Temp linear_sample = get_arg(ctx, ctx->args->linear_sample); ctx->arg_temps[ctx->args->linear_center.arg_index] = linear_sample; - ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_sample; + if (finfo->uses_linear_centroid) + ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_sample; } if (finfo->force_persp_center_interp) { Temp persp_center = get_arg(ctx, ctx->args->persp_center); ctx->arg_temps[ctx->args->persp_sample.arg_index] = persp_center; - ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_center; + if (finfo->uses_persp_centroid) + ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_center; } if (finfo->force_linear_center_interp) { Temp linear_center = get_arg(ctx, ctx->args->linear_center); ctx->arg_temps[ctx->args->linear_sample.arg_index] = linear_center; - ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_center; + if (finfo->uses_linear_centroid) + ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_center; } } diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 8b2106ecdc5..93be4b593e1 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1744,6 +1744,10 @@ static void si_get_ps_prolog_key(struct si_shader *shader, union si_shader_part_ 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.force_samplemask_to_helper_invocation); + key->ps_prolog.uses_persp_centroid = + G_0286CC_PERSP_CENTROID_ENA(shader->config.spi_ps_input_addr); /* addr because the PS prolog may use it */ + key->ps_prolog.uses_linear_centroid = + G_0286CC_LINEAR_CENTROID_ENA(shader->config.spi_ps_input_addr); /* addr because the PS prolog may use it */ 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) | diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 47df36fdb86..fc3f914d66d 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -564,6 +564,8 @@ union si_shader_part_key { /* Color interpolation and two-side color selection. */ unsigned colors_read : 8; /* color input components read */ unsigned num_interp_inputs : 5; /* BCOLOR is at this location */ + unsigned uses_persp_centroid : 1; + unsigned uses_linear_centroid : 1; unsigned fragcoord_usage_mask : 4; unsigned wqm : 1; uint8_t color_attr_index[2]; diff --git a/src/gallium/drivers/radeonsi/si_shader_aco.c b/src/gallium/drivers/radeonsi/si_shader_aco.c index ff11d4773ea..bae3a4fea5d 100644 --- a/src/gallium/drivers/radeonsi/si_shader_aco.c +++ b/src/gallium/drivers/radeonsi/si_shader_aco.c @@ -253,6 +253,8 @@ si_aco_build_ps_prolog(struct aco_compiler_options *options, .force_linear_sample_interp = key->ps_prolog.states.force_linear_sample_interp, .force_persp_center_interp = key->ps_prolog.states.force_persp_center_interp, .force_linear_center_interp = key->ps_prolog.states.force_linear_center_interp, + .uses_persp_centroid = key->ps_prolog.uses_persp_centroid, + .uses_linear_centroid = key->ps_prolog.uses_linear_centroid, .samplemask_log_ps_iter = key->ps_prolog.states.samplemask_log_ps_iter, .force_samplemask_to_helper_invocation = key->ps_prolog.states.force_samplemask_to_helper_invocation, diff --git a/src/gallium/drivers/radeonsi/si_shader_args.c b/src/gallium/drivers/radeonsi/si_shader_args.c index d452425a29a..3ae18e1b329 100644 --- a/src/gallium/drivers/radeonsi/si_shader_args.c +++ b/src/gallium/drivers/radeonsi/si_shader_args.c @@ -673,11 +673,17 @@ void si_get_ps_prolog_args(struct si_shader_args *args, ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_sample); ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_center); - ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_centroid); + + if (key->ps_prolog.uses_persp_centroid) + ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_centroid); + /* skip PERSP_PULL_MODEL */ ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_sample); ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_center); - ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_centroid); + + if (key->ps_prolog.uses_linear_centroid) + ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_centroid); + ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_VALUE, &args->ac.line_stipple_tex_ena); /* POS_X|Y|Z|W_FLOAT */ diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c b/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c index 121e453d7a4..00ddffd1626 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c @@ -550,15 +550,22 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part bc_optimize = LLVMBuildTrunc(ctx->ac.builder, bc_optimize, ctx->ac.i1, ""); if (key->ps_prolog.states.bc_optimize_for_persp) { + assert(key->ps_prolog.uses_persp_centroid); + center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_center)); centroid = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_centroid)); + /* Select PERSP_CENTROID. */ tmp = LLVMBuildSelect(ctx->ac.builder, bc_optimize, center, centroid, ""); ret = insert_ret_of_arg(ctx, ret, tmp, args->ac.persp_centroid.arg_index); } + if (key->ps_prolog.states.bc_optimize_for_linear) { + assert(key->ps_prolog.uses_linear_centroid); + center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_center)); centroid = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_centroid)); + /* Select PERSP_CENTROID. */ tmp = LLVMBuildSelect(ctx->ac.builder, bc_optimize, center, centroid, ""); ret = insert_ret_of_arg(ctx, ret, tmp, args->ac.linear_centroid.arg_index); @@ -570,15 +577,21 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part LLVMValueRef persp_sample = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_sample)); /* Overwrite PERSP_CENTER. */ ret = insert_ret_of_arg(ctx, ret, persp_sample, args->ac.persp_center.arg_index); - /* Overwrite PERSP_CENTROID. */ - ret = insert_ret_of_arg(ctx, ret, persp_sample, args->ac.persp_centroid.arg_index); + + if (key->ps_prolog.uses_persp_centroid) { + /* Overwrite PERSP_CENTROID. */ + ret = insert_ret_of_arg(ctx, ret, persp_sample, args->ac.persp_centroid.arg_index); + } } if (key->ps_prolog.states.force_linear_sample_interp) { LLVMValueRef linear_sample = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_sample)); /* Overwrite LINEAR_CENTER. */ ret = insert_ret_of_arg(ctx, ret, linear_sample, args->ac.linear_center.arg_index); - /* Overwrite LINEAR_CENTROID. */ - ret = insert_ret_of_arg(ctx, ret, linear_sample, args->ac.linear_centroid.arg_index); + + if (key->ps_prolog.uses_linear_centroid) { + /* Overwrite LINEAR_CENTROID. */ + ret = insert_ret_of_arg(ctx, ret, linear_sample, args->ac.linear_centroid.arg_index); + } } /* Force center interpolation. */ @@ -586,15 +599,21 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part LLVMValueRef persp_center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_center)); /* Overwrite PERSP_SAMPLE. */ ret = insert_ret_of_arg(ctx, ret, persp_center, args->ac.persp_sample.arg_index); - /* Overwrite PERSP_CENTROID. */ - ret = insert_ret_of_arg(ctx, ret, persp_center, args->ac.persp_centroid.arg_index); + + if (key->ps_prolog.uses_persp_centroid) { + /* Overwrite PERSP_CENTROID. */ + ret = insert_ret_of_arg(ctx, ret, persp_center, args->ac.persp_centroid.arg_index); + } } if (key->ps_prolog.states.force_linear_center_interp) { LLVMValueRef linear_center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_center)); /* Overwrite LINEAR_SAMPLE. */ ret = insert_ret_of_arg(ctx, ret, linear_center, args->ac.linear_sample.arg_index); - /* Overwrite LINEAR_CENTROID. */ - ret = insert_ret_of_arg(ctx, ret, linear_center, args->ac.linear_centroid.arg_index); + + if (key->ps_prolog.uses_linear_centroid) { + /* Overwrite LINEAR_CENTROID. */ + ret = insert_ret_of_arg(ctx, ret, linear_center, args->ac.linear_centroid.arg_index); + } } /* Interpolate colors. */ diff --git a/src/gallium/drivers/radeonsi/si_shader_variant_info.c b/src/gallium/drivers/radeonsi/si_shader_variant_info.c index cf0bc4ef10d..94c542b5541 100644 --- a/src/gallium/drivers/radeonsi/si_shader_variant_info.c +++ b/src/gallium/drivers/radeonsi/si_shader_variant_info.c @@ -612,15 +612,22 @@ unsigned si_get_spi_ps_input_addr_for_prolog(struct si_shader_selector *sel) { unsigned spi_ps_input_addr = S_0286D0_PERSP_SAMPLE_ENA(1) | S_0286D0_PERSP_CENTER_ENA(1) | - S_0286D0_PERSP_CENTROID_ENA(1) | S_0286D0_LINEAR_SAMPLE_ENA(1) | S_0286D0_LINEAR_CENTER_ENA(1) | - S_0286D0_LINEAR_CENTROID_ENA(1) | S_0286D0_LINE_STIPPLE_TEX_ENA(1) | S_0286D0_FRONT_FACE_ENA(1) | S_0286D0_ANCILLARY_ENA(1) | S_0286D0_SAMPLE_COVERAGE_ENA(1) | S_0286D0_POS_FIXED_PT_ENA(1); + /* This includes color interpolation at centroid even if the main shader part doesn't + * use the barycentrics. The PS prolog can still use them. + */ + if (sel->info.uses_sysval_persp_centroid) + spi_ps_input_addr |= S_0286D0_PERSP_CENTROID_ENA(1); + + if (sel->info.uses_sysval_linear_centroid) + spi_ps_input_addr |= S_0286D0_LINEAR_CENTROID_ENA(1); + return spi_ps_input_addr; }