[Mesa-dev] [PATCH] glsl: do not set the 'smooth' qualifier by default on ES shaders

Nicolai Hähnle nhaehnle at gmail.com
Tue Sep 26 15:11:46 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

It leads to surprising states with integer inputs and outputs on
vertex processing stages (e.g. geometry stages). Instead, rely on the
driver to choose smooth interpolation by default.

We still allow varyings to match when one stage declares it as smooth
and the other declares it without interpolation qualifiers.
--
This should cover all the relevant I/O checks, tested with dEQP.
---
 src/compiler/glsl/ast_to_hir.cpp    | 11 -----------
 src/compiler/glsl/link_varyings.cpp | 17 ++++++++++++++++-
 src/mesa/main/shader_query.cpp      |  8 +++++++-
 3 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index c46454956d7..1999e68158c 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -3119,31 +3119,20 @@ interpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
                                   struct _mesa_glsl_parse_state *state,
                                   YYLTYPE *loc)
 {
    glsl_interp_mode interpolation;
    if (qual->flags.q.flat)
       interpolation = INTERP_MODE_FLAT;
    else if (qual->flags.q.noperspective)
       interpolation = INTERP_MODE_NOPERSPECTIVE;
    else if (qual->flags.q.smooth)
       interpolation = INTERP_MODE_SMOOTH;
-   else if (state->es_shader &&
-            ((mode == ir_var_shader_in &&
-              state->stage != MESA_SHADER_VERTEX) ||
-             (mode == ir_var_shader_out &&
-              state->stage != MESA_SHADER_FRAGMENT)))
-      /* Section 4.3.9 (Interpolation) of the GLSL ES 3.00 spec says:
-       *
-       *    "When no interpolation qualifier is present, smooth interpolation
-       *    is used."
-       */
-      interpolation = INTERP_MODE_SMOOTH;
    else
       interpolation = INTERP_MODE_NONE;
 
    validate_interpolation_qualifier(state, loc,
                                     interpolation,
                                     qual, var_type, mode);
 
    return interpolation;
 }
 
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index 528506fd0eb..7c90de393ad 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -318,22 +318,37 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
    }
 
    /* GLSL >= 4.40 removes text requiring interpolation qualifiers
     * to match cross stage, they must only match within the same stage.
     *
     * From page 84 (page 90 of the PDF) of the GLSL 4.40 spec:
     *
     *     "It is a link-time error if, within the same stage, the interpolation
     *     qualifiers of variables of the same name do not match.
     *
+    * Section 4.3.9 (Interpolation) of the GLSL ES 3.00 spec says:
+    *
+    *    "When no interpolation qualifier is present, smooth interpolation
+    *    is used."
+    *
+    * So we match variables where one is smooth and the other has no explicit
+    * qualifier.
     */
-   if (input->data.interpolation != output->data.interpolation &&
+   unsigned input_interpolation = input->data.interpolation;
+   unsigned output_interpolation = output->data.interpolation;
+   if (prog->IsES) {
+      if (input_interpolation == INTERP_MODE_NONE)
+         input_interpolation = INTERP_MODE_SMOOTH;
+      if (output_interpolation == INTERP_MODE_NONE)
+         output_interpolation = INTERP_MODE_SMOOTH;
+   }
+   if (input_interpolation != output_interpolation &&
        prog->data->Version < 440) {
       linker_error(prog,
                    "%s shader output `%s' specifies %s "
                    "interpolation qualifier, "
                    "but %s shader input specifies %s "
                    "interpolation qualifier\n",
                    _mesa_shader_stage_to_string(producer_stage),
                    output->name,
                    interpolation_string(output->data.interpolation),
                    _mesa_shader_stage_to_string(consumer_stage),
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 64e68b4a26d..6712bb45fb2 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -1627,21 +1627,27 @@ validate_io(struct gl_program *producer, struct gl_program *consumer)
        *    Precision      |   mediump   |  Yes
        *                   |    highp    |
        *    ---------------+-------------+------
        *    Variance       |  invariant  |   No
        *    ---------------+-------------+------
        *    Memory         |     all     |  N/A
        *
        * Note that location mismatches are detected by the loops above that
        * find the producer variable that goes with the consumer variable.
        */
-      if (producer_var->interpolation != consumer_var->interpolation) {
+      unsigned producer_interpolation = producer_var->interpolation;
+      unsigned consumer_interpolation = consumer_var->interpolation;
+      if (producer_interpolation == INTERP_MODE_NONE)
+         producer_interpolation = INTERP_MODE_SMOOTH;
+      if (consumer_interpolation == INTERP_MODE_NONE)
+         consumer_interpolation = INTERP_MODE_SMOOTH;
+      if (producer_interpolation != consumer_interpolation) {
          valid = false;
          goto out;
       }
 
       if (producer_var->precision != consumer_var->precision) {
          valid = false;
          goto out;
       }
 
       if (producer_var->outermost_struct_type != consumer_var->outermost_struct_type) {
-- 
2.11.0



More information about the mesa-dev mailing list