spirv/nir: Set uses_sample_shading from spirv_to_nir

We don't really want to base this on a late nir_gather_info for two
reasons:

 1) The Vulkan spec says that if a sample-qualified input, SampleID, or
    SamplePosition are in the entry-point's interface, you get
    per-sample dispatch.  This means we really should gather this
    information before dead-code has a chance to delete anything.

 2) We want to be able to add nir_intrinsic_load_sample_pos intrinsics
    as part of lowering passes without causing per-sample interpolation.
    This means nir_gather_info needs to stop gathering it.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14020>
This commit is contained in:
Jason Ekstrand 2021-12-01 15:59:48 -06:00 committed by Marge Bot
parent 830654b7b0
commit b6543470fe
1 changed files with 41 additions and 0 deletions

View File

@ -6651,6 +6651,47 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
b->shader->info.shared_size = size;
}
if (stage == MESA_SHADER_FRAGMENT) {
/* From the Vulkan 1.2.199 spec:
*
* "If a fragment shader entry points interface includes an input
* variable decorated with SamplePosition, Sample Shading is
* considered enabled with a minSampleShading value of 1.0."
*
* Similar text exists for SampleId. Regarding the Sample decoration,
* the Vulkan 1.2.199 spec says:
*
* "If a fragment shader input is decorated with Sample, a separate
* value must be assigned to that variable for each covered sample in
* the fragment, and that value must be sampled at the location of
* the individual sample. When rasterizationSamples is
* VK_SAMPLE_COUNT_1_BIT, the fragment center must be used for
* Centroid, Sample, and undecorated attribute interpolation."
*
* Unfortunately, this isn't quite as clear about static use and the
* interface but the static use check should be valid.
*
* For OpenGL, similar language exists but it's all more wishy-washy.
* We'll assume the same behavior across APIs.
*/
nir_foreach_variable_with_modes(var, b->shader,
nir_var_shader_in |
nir_var_system_value) {
struct nir_variable_data *members =
var->members ? var->members : &var->data;
uint16_t num_members = var->members ? var->num_members : 1;
for (uint16_t i = 0; i < num_members; i++) {
if (members[i].mode == nir_var_system_value &&
(members[i].location == SYSTEM_VALUE_SAMPLE_ID ||
members[i].location == SYSTEM_VALUE_SAMPLE_POS))
b->shader->info.fs.uses_sample_shading = true;
if (members[i].mode == nir_var_shader_in && members[i].sample)
b->shader->info.fs.uses_sample_shading = true;
}
}
}
/* Unparent the shader from the vtn_builder before we delete the builder */
ralloc_steal(NULL, b->shader);