radeonsi: take color interpolation into account for shader variants

Fixes:
- Sample shading now uses per-sample interpolation for colors if colors
  are the only inputs. (this is the only case that was broken)

Optimizations:
- BC_OPTIMIZE (barycentric optimization) is now enabled with MSAA if colors
  are qualified with both center and centroid. (BC_OPTIMIZE means that
  the hardware skips initializing centroid (i,j) if they are equal to
  center (i,j))
- If MSAA is disabled and at least 2 out of (center, centroid, sample) are
  used by all inputs now including colors, center is forced for all inputs.
- If INTERP_MODE_COLOR is not used and the legacy GL shade model is flat,
  the shader variant for flat shading is not generated.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8225>
This commit is contained in:
Marek Olšák
2020-12-24 07:42:12 -05:00
committed by Marge Bot
parent 31240a875c
commit 76eb3478cf
3 changed files with 50 additions and 10 deletions

View File

@@ -363,6 +363,10 @@ struct si_shader_info {
bool writes_stencil; /**< does fragment shader write stencil value? */
bool writes_samplemask; /**< does fragment shader write sample mask? */
bool writes_edgeflag; /**< vertex shader outputs edgeflag */
bool uses_interp_color;
bool uses_persp_center_color;
bool uses_persp_centroid_color;
bool uses_persp_sample_color;
bool uses_persp_center;
bool uses_persp_centroid;
bool uses_persp_sample;

View File

@@ -266,6 +266,37 @@ static void scan_instruction(const struct nir_shader *nir, struct si_shader_info
unsigned index = intr->intrinsic == nir_intrinsic_load_color1;
uint8_t mask = nir_ssa_def_components_read(&intr->dest.ssa);
info->colors_read |= mask << (index * 4);
switch (info->color_interpolate[index]) {
case INTERP_MODE_SMOOTH:
if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_SAMPLE)
info->uses_persp_sample = true;
else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTROID)
info->uses_persp_centroid = true;
else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTER)
info->uses_persp_center = true;
break;
case INTERP_MODE_NOPERSPECTIVE:
if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_SAMPLE)
info->uses_linear_sample = true;
else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTROID)
info->uses_linear_centroid = true;
else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTER)
info->uses_linear_center = true;
break;
case INTERP_MODE_COLOR:
/* We don't know the final value. This will be FLAT if flatshading is enabled
* in the rasterizer state, otherwise it will be SMOOTH.
*/
info->uses_interp_color = true;
if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_SAMPLE)
info->uses_persp_sample_color = true;
else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTROID)
info->uses_persp_centroid_color = true;
else if (info->color_interpolate_loc[index] == TGSI_INTERPOLATE_LOC_CENTER)
info->uses_persp_center_color = true;
break;
}
break;
}
case nir_intrinsic_load_barycentric_at_offset: /* uses center */

View File

@@ -2009,7 +2009,7 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh
bool is_line = util_prim_is_lines(sctx->current_rast_prim);
key->part.ps.prolog.color_two_side = rs->two_side && sel->info.colors_read;
key->part.ps.prolog.flatshade_colors = rs->flatshade && sel->info.colors_read;
key->part.ps.prolog.flatshade_colors = rs->flatshade && sel->info.uses_interp_color;
key->part.ps.epilog.alpha_to_one = blend->alpha_to_one && rs->multisample_enable;
@@ -2023,30 +2023,35 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_sh
key->part.ps.prolog.samplemask_log_ps_iter = util_logbase2(sctx->ps_iter_samples);
}
bool uses_persp_center = sel->info.uses_persp_center ||
(!rs->flatshade && sel->info.uses_persp_center_color);
bool uses_persp_centroid = sel->info.uses_persp_centroid ||
(!rs->flatshade && sel->info.uses_persp_centroid_color);
bool uses_persp_sample = sel->info.uses_persp_sample ||
(!rs->flatshade && sel->info.uses_persp_sample_color);
if (rs->force_persample_interp && rs->multisample_enable &&
sctx->framebuffer.nr_samples > 1 && sctx->ps_iter_samples > 1) {
key->part.ps.prolog.force_persp_sample_interp =
sel->info.uses_persp_center || sel->info.uses_persp_centroid;
uses_persp_center || uses_persp_centroid;
key->part.ps.prolog.force_linear_sample_interp =
sel->info.uses_linear_center || sel->info.uses_linear_centroid;
} else if (rs->multisample_enable && sctx->framebuffer.nr_samples > 1) {
key->part.ps.prolog.bc_optimize_for_persp =
sel->info.uses_persp_center && sel->info.uses_persp_centroid;
uses_persp_center && uses_persp_centroid;
key->part.ps.prolog.bc_optimize_for_linear =
sel->info.uses_linear_center && sel->info.uses_linear_centroid;
} else {
/* Make sure SPI doesn't compute more than 1 pair
* of (i,j), which is the optimization here. */
key->part.ps.prolog.force_persp_center_interp = sel->info.uses_persp_center +
sel->info.uses_persp_centroid +
sel->info.uses_persp_sample >
1;
key->part.ps.prolog.force_persp_center_interp = uses_persp_center +
uses_persp_centroid +
uses_persp_sample > 1;
key->part.ps.prolog.force_linear_center_interp = sel->info.uses_linear_center +
sel->info.uses_linear_centroid +
sel->info.uses_linear_sample >
1;
sel->info.uses_linear_centroid +
sel->info.uses_linear_sample > 1;
if (sel->info.uses_interp_at_sample)
key->mono.u.ps.interpolate_at_sample_force_center = 1;