diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 480af85add9..c426712cebe 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_shader_info.c b/src/gallium/drivers/radeonsi/si_shader_info.c index 3ac7f798be9..b539f1fa3eb 100644 --- a/src/gallium/drivers/radeonsi/si_shader_info.c +++ b/src/gallium/drivers/radeonsi/si_shader_info.c @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp b/src/gallium/drivers/radeonsi/si_state_shaders.cpp index c309d5e398c..f2c886a4be3 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp +++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp @@ -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; }