radeonsi: fix interpolateAt* with non-GL4 ARB_sample_shading
There is no test for this, but it's been broken. ARB_sample_shading doesn't set fs.uses_sample_shading in shader_info, which causes us to enter this path to force per-sample interpolation, but doing so breaks the shader if the PS prolog is used. Reviewed-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:
@@ -538,6 +538,7 @@ struct si_shader_info {
|
||||
bool uses_linear_center;
|
||||
bool uses_linear_centroid;
|
||||
bool uses_linear_sample;
|
||||
bool uses_interp_at_offset;
|
||||
bool uses_interp_at_sample;
|
||||
bool uses_instanceid;
|
||||
bool uses_base_vertex;
|
||||
@@ -824,6 +825,7 @@ struct si_shader_key_ps {
|
||||
|
||||
/* Flags for monolithic compilation only. */
|
||||
struct {
|
||||
unsigned force_mono : 1;
|
||||
unsigned poly_line_smoothing : 1;
|
||||
unsigned point_smoothing : 1;
|
||||
unsigned interpolate_at_sample_force_center : 1;
|
||||
|
||||
@@ -442,6 +442,8 @@ static void scan_instruction(const struct nir_shader *nir, struct si_shader_info
|
||||
} else {
|
||||
info->uses_persp_center = true;
|
||||
}
|
||||
if (intr->intrinsic == nir_intrinsic_load_barycentric_at_offset)
|
||||
info->uses_interp_at_offset = true;
|
||||
if (intr->intrinsic == nir_intrinsic_load_barycentric_at_sample)
|
||||
info->uses_interp_at_sample = true;
|
||||
break;
|
||||
|
||||
@@ -2865,6 +2865,11 @@ void si_ps_key_update_framebuffer_rasterizer_sample_shading(struct si_context *s
|
||||
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;
|
||||
/* Note that interpolateAt* requires center barycentrics while the PS prolog forces
|
||||
* per-sample barycentrics in center VGPRs, so it breaks it. The workaround is to
|
||||
* force monolithic compilation, which does the right thing.
|
||||
*/
|
||||
key->ps.mono.force_mono = sel->info.uses_interp_at_offset || sel->info.uses_interp_at_sample;
|
||||
key->ps.mono.interpolate_at_sample_force_center = 0;
|
||||
} else if (rs->multisample_enable && sctx->framebuffer.nr_samples > 1) {
|
||||
/* Note that sample shading is possible here. If it's enabled, all barycentrics are
|
||||
@@ -2881,6 +2886,7 @@ void si_ps_key_update_framebuffer_rasterizer_sample_shading(struct si_context *s
|
||||
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.force_mono = 0;
|
||||
key->ps.mono.interpolate_at_sample_force_center = 0;
|
||||
} else {
|
||||
key->ps.part.prolog.force_persp_sample_interp = 0;
|
||||
@@ -2900,6 +2906,7 @@ void si_ps_key_update_framebuffer_rasterizer_sample_shading(struct si_context *s
|
||||
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.force_mono = 0;
|
||||
key->ps.mono.interpolate_at_sample_force_center = sel->info.uses_interp_at_sample;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user