<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Hi Jason,<br>
    </p>
    <div class="moz-cite-prefix">On 8/22/18 7:07 PM, Jason Ekstrand
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAOFGe96JDeA8Z1aMAkKobXw_NXgGez5xp2EnETxfaNL2df6F2Q@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">I think this would be correct to do and would fix
        the bug at hand but there may be other bugs lurking deeper.  In
        particular, if you have multiple shaders for the same stage that
        share some global variables and get linked together, I think you
        could run into the same issue only with a read-write global.  If
        this is indeed possible, then I'm not sure what to do.  We have
        to run this pass prior to doing any optimization because we
        depend on it to get precise and invariant correct.  On the other
        hand, it has to be run after linking. :-/  Maybe we just have to
        assume precise and invariant for all pre-linking optimizations
        and then run this post-linking.<br>
      </div>
    </blockquote>
    <p>I didn't check this case, thanks for pointing it out. Now I have
      looked at relevant code and saw that invariant propagation
      (linker.cpp:5024 in <font size="+1"><tt>linker_optimisation_loop</tt></font>)
      is done after '<font size="+1"><tt>link_intrastage_shaders</tt></font>'
      (linker.cpp:4868) which combines a group of shaders for a single
      stage. Actually invariant propagation is also done once before
      linking. In addition I've done some tests and invariance from
      variable in one vertex shader is propagated on variables directly
      used only in other vertex shader. <br>
    </p>
    <p>However I have found other issue - <font size="+1"><tt>cross_validate_globals</tt></font>
      is called in <font size="+1"><tt>link_intrastage_shaders</tt></font>
      and throws error if 'invariant' qualifier doesn't match between
      shaders in same stage which happens when variable in one shader
      becomes invariant before the '<font size="+1"><tt>link_intrastage_shaders</tt></font>'
      call. This could be fixed separately.<br>
    </p>
    <p>Or there is another way to solve these issues: divide 'invariant'
      qualifier into explicit and implicit 'invariant', where explicit
      is for 'invariant' set by user in shader and implicit is for
      'invariant' propagated from other invariants. Thus in interface
      checking we will be able to check only for explicit invariance
      which besides two previous issues with solve another one: if out
      variable is marked as invariant due to invariance propagation this
      variable will be required to have invariant qualifier in the next
      stage even though user never marked it as such anywhere. And when
      the invariance will actually matter we will check both implicit
      and explicit one. What do you think about such solution?<br>
    </p>
    <p>- Danil.<br>
    </p>
    <blockquote type="cite"
cite="mid:CAOFGe96JDeA8Z1aMAkKobXw_NXgGez5xp2EnETxfaNL2df6F2Q@mail.gmail.com"><br>
      <div class="gmail_quote">
        <div dir="ltr">On Wed, Aug 22, 2018 at 7:51 AM Danylo Piliaiev
          <<a href="mailto:danylo.piliaiev@gmail.com"
            moz-do-not-send="true">danylo.piliaiev@gmail.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0 0 0
          .8ex;border-left:1px #ccc solid;padding-left:1ex">Read-only
          variables could be considered inherently invariant and precise<br>
          since no expression in shader affects them.<br>
          Explicitly marking them as such is unnecessary and can cause
          issues,<br>
          e.g. uniform marked as invariant may require the same uniform
          in other<br>
          stage to be invariant too but uniforms cannot have "invariant"
          qualifier.<br>
          <br>
          Bugzilla: <a
            href="https://bugs.freedesktop.org/show_bug.cgi?id=100316"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://bugs.freedesktop.org/show_bug.cgi?id=100316</a><br>
          <br>
          Signed-off-by: Danylo Piliaiev <<a
            href="mailto:danylo.piliaiev@globallogic.com"
            target="_blank" moz-do-not-send="true">danylo.piliaiev@globallogic.com</a>><br>
          ---<br>
          My assumption is that variable being read_only means that it
          either<br>
          loads a value from an external source or is initialized from
          constant value.<br>
          From what I saw in code it's true but it may be wrong to
          depend on it.<br>
          <br>
           src/compiler/glsl/propagate_invariance.cpp | 10 ++++++++++<br>
           1 file changed, 10 insertions(+)<br>
          <br>
          diff --git a/src/compiler/glsl/propagate_invariance.cpp
          b/src/compiler/glsl/propagate_invariance.cpp<br>
          index b3f1d810cd..0e4233aa9f 100644<br>
          --- a/src/compiler/glsl/propagate_invariance.cpp<br>
          +++ b/src/compiler/glsl/propagate_invariance.cpp<br>
          @@ -96,6 +96,16 @@
          ir_invariance_propagation_visitor::visit(ir_dereference_variable
          *ir)<br>
              if (this->dst_var == NULL)<br>
                 return visit_continue;<br>
          <br>
          +   /* Read-only variables could be considered inherently<br>
          +    * invariant and precise since no expression in shader
          affects them.<br>
          +    * Explicitly marking them as such is unnecessary and can
          cause<br>
          +    * issues, e.g. uniform marked as invariant may require
          the same<br>
          +    * uniform in other stage to be invariant too but uniforms
          cannot<br>
          +    * have "invariant" qualifier.<br>
          +    */<br>
          +   if (ir->var->data.read_only)<br>
          +      return visit_continue;<br>
          +<br>
              if (this->dst_var->data.invariant) {<br>
                 if (!ir->var->data.invariant)<br>
                    this->progress = true;<br>
          -- <br>
          2.18.0<br>
          <br>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>