diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index d7cdc7936ca..9ad4a39db0e 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -2360,8 +2360,32 @@ tu_pipeline_shader_key_init(struct ir3_shader_key *key, key->msaa = true; } - /* note: not actually used by ir3, just checked in tu6_emit_fs_inputs */ - if (msaa_info->sampleShadingEnable) + /* The 1.3.215 spec says: + * + * Sample shading can be used to specify a minimum number of unique + * samples to process for each fragment. If sample shading is enabled, + * an implementation must provide a minimum of + * + * max(ceil(minSampleShadingFactor * totalSamples), 1) + * + * unique associated data for each fragment, where + * minSampleShadingFactor is the minimum fraction of sample shading. + * + * The definition is pretty much the same as OpenGL's GL_SAMPLE_SHADING. + * They both require unique associated data. + * + * There are discussions to change the definition, such that + * sampleShadingEnable does not imply unique associated data. Before the + * discussions are settled and before apps (i.e., ANGLE) are fixed to + * follow the new and incompatible definition, we should stick to the + * current definition. + * + * Note that ir3_shader_key::sample_shading is not actually used by ir3, + * just checked in tu6_emit_fs_inputs. We will also copy the value to + * tu_shader_key::force_sample_interp in a bit. + */ + if (msaa_info->sampleShadingEnable && + (msaa_info->minSampleShading * msaa_info->rasterizationSamples) > 1.0f) key->sample_shading = true; /* We set this after we compile to NIR because we need the prim mode */ @@ -2739,6 +2763,7 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder, keys[MESA_SHADER_VERTEX].multiview_mask = builder->multiview_mask; keys[MESA_SHADER_FRAGMENT].multiview_mask = builder->multiview_mask; + keys[MESA_SHADER_FRAGMENT].force_sample_interp = ir3_key.sample_shading; unsigned char pipeline_sha1[20]; tu_hash_shaders(pipeline_sha1, stage_infos, builder->layout, keys, &ir3_key, compiler); diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index c38eb756a17..8bf74d365d0 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -1360,6 +1360,7 @@ struct tu_shader struct tu_shader_key { unsigned multiview_mask; + bool force_sample_interp; enum ir3_wavesize_option api_wavesize, real_wavesize; }; diff --git a/src/freedreno/vulkan/tu_shader.c b/src/freedreno/vulkan/tu_shader.c index bf298ef5103..41c8a4f8dd5 100644 --- a/src/freedreno/vulkan/tu_shader.c +++ b/src/freedreno/vulkan/tu_shader.c @@ -747,6 +747,13 @@ tu_shader_create(struct tu_device *dev, &shader->multi_pos_output, dev); } + if (nir->info.stage == MESA_SHADER_FRAGMENT && key->force_sample_interp) { + nir_foreach_shader_in_variable(var, nir) { + if (!var->data.centroid) + var->data.sample = true; + } + } + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const, nir_address_format_32bit_offset);