Bug 96971

Summary: invariant qualifier is not valid for shader inputs
Product: Mesa Reporter: Qiankun Miao <qiankun.miao>
Component: Drivers/DRI/i965Assignee: Kenneth Graunke <kenneth>
Status: RESOLVED FIXED QA Contact: Intel 3D Bugs Mailing List <intel-3d-bugs>
Severity: normal    
Priority: medium    
Version: git   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Qiankun Miao 2016-07-18 08:46:59 UTC
Currently, only glsl es in mesa follows this rule. But glsl compiler should also follow this rule. The behavior is specified in GLSLangSpec.4.40, in Section 4.8.1 The Invariant Qualifier: "Only variables output from a shader can be candidates for invariance." and "As only outputs need be declared with invariant, an output from one shader stage will still match an input of a subsequent stage without the input being declared as invariant."

So, input without invariant declaration should be valid.
But following code snippet in mesa/src/compiler/glsl/link_varyings.cpp makes it an error:


   if (!prog->IsES && input->data.invariant != output->data.invariant) {
      linker_error(prog,                                                                                                                                                                   
                   "%s shader output `%s' %s invariant qualifier, "
                   "but %s shader input %s invariant qualifier\n",
                   _mesa_shader_stage_to_string(producer_stage),
                   output->name,
                   (output->data.invariant) ? "has" : "lacks",
                   _mesa_shader_stage_to_string(consumer_stage),
                   (input->data.invariant) ? "has" : "lacks");
      return;
   }
Comment 1 Kenneth Graunke 2016-08-11 20:48:59 UTC
Patch on the list:
https://lists.freedesktop.org/archives/mesa-dev/2016-August/125793.html

For the original WebGL test, you'll also need
https://lists.freedesktop.org/archives/mesa-dev/2016-August/125792.html
Comment 2 Kenneth Graunke 2016-08-12 06:59:49 UTC
Should be fixed by:

commit f9f462936ad903f93829404ce99a2580ea21b725
Author: Kenneth Graunke <kenneth@whitecape.org>
Date:   Thu Aug 11 06:12:53 2016 -0700

    glsl: Fix invariant matching in GLSL 4.30 and GLSL ES 1.00.
    
commit dffa371665fc45481f6b6686e586f9be2b36a915
Author: Kenneth Graunke <kenneth@whitecape.org>
Date:   Thu Aug 11 11:40:25 2016 -0700

    glsl: Fix inout qualifier handling in GLSL 4.40.

I've marked the first one for stable, so Emil should backport it to 12.0.x.  (The latter isn't necessary as enhanced layouts support is only on master.)
Comment 3 Qiankun Miao 2016-08-19 11:05:42 UTC
(In reply to Kenneth Graunke from comment #2)
> Should be fixed by:
> 
> commit f9f462936ad903f93829404ce99a2580ea21b725
> Author: Kenneth Graunke <kenneth@whitecape.org>
> Date:   Thu Aug 11 06:12:53 2016 -0700
> 
>     glsl: Fix invariant matching in GLSL 4.30 and GLSL ES 1.00.
>     
> commit dffa371665fc45481f6b6686e586f9be2b36a915
> Author: Kenneth Graunke <kenneth@whitecape.org>
> Date:   Thu Aug 11 11:40:25 2016 -0700
> 
>     glsl: Fix inout qualifier handling in GLSL 4.40.
> 
> I've marked the first one for stable, so Emil should backport it to 12.0.x. 
> (The latter isn't necessary as enhanced layouts support is only on master.)

Thanks Kenneth for these fixes. 
Sorry, there may be some misunderstandings before.
In Section 4.8.1 The Invariant Qualifier of GLSLangSpec.4.50.diff.pdf, the following sentences describe invariant qualifier:
"
Only variables output from a shader (including those that are then input to a subsequent shader) can be candidates for invariance.  This includes user-defined output variables and the built-in output variables.
As only outputs need be declared with invariant, an output from one shader stage will still match an input of a subsequent stage without the input being declared as invariant.
"

The sentence "As only outputs need be declared with invariant, an output from one shader stage will still match an input of a subsequent stage without the input being declared as invariant" seems to say invariant doesn't need to match between output and input and input can also be declared as invariant. What do you think?
Comment 4 Kenneth Graunke 2016-08-19 16:27:22 UTC
No.  The wording isn't great, but

"Only variables output from a shader (including those that are then input to a subsequent shader) can be candidates for invariance."

implies to me that you can only mark outputs as invariant.  This would also make it match the GLSL ES 3xx rules.  GLSL ES 3.20 has similar text, but also says in the issues section:

"Do invariance qualifiers for declarations in the vertex and fragment shaders need to match?
Option 1: Only allow invariance declarations on outputs. If a vertex shader output is declared as invariant, it implies that the corresponding input to the fragment shader is also invariant.
Option 2: Specify that they must match.
RESOLUTION: Only allow invariant declarations on outputs."

The resolution is pretty clear there.  You only get to use 'invariant' on outputs with the new rules.

Are you running into an issue with the new code I implemented?  Or just spec reading and wondering if we should have done something else?
Comment 5 Qiankun Miao 2016-11-25 07:49:51 UTC
(In reply to Kenneth Graunke from comment #4)
> No.  The wording isn't great, but
> 
> "Only variables output from a shader (including those that are then input to
> a subsequent shader) can be candidates for invariance."
> 
> implies to me that you can only mark outputs as invariant.  This would also
> make it match the GLSL ES 3xx rules.  GLSL ES 3.20 has similar text, but
> also says in the issues section:
> 
> "Do invariance qualifiers for declarations in the vertex and fragment
> shaders need to match?
> Option 1: Only allow invariance declarations on outputs. If a vertex shader
> output is declared as invariant, it implies that the corresponding input to
> the fragment shader is also invariant.
> Option 2: Specify that they must match.
> RESOLUTION: Only allow invariant declarations on outputs."
> 
> The resolution is pretty clear there.  You only get to use 'invariant' on
> outputs with the new rules.
> 
> Are you running into an issue with the new code I implemented?  Or just spec
> reading and wondering if we should have done something else?

I just found some differences between ESSL and GLSL. These differences should be handled by WebGL since webgl is based on ES 3.0 API, but WebGL also should run on top of OpenGL driver. WebGL soloved the differences, and run well on Mesa.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.