<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<div dir="auto">
<div dir="auto"><span style="font-family: sans-serif; font-size: 10pt;">On November 9, 2018 06:39:25 Alejandro Piñeiro <apinheiro@igalia.com> wrote:</span></div><div id="aqm-original" style="color: black;"><div text="#000000" bgcolor="#ffffff" class="aqm-original-body"><div style="color: black;">
<blockquote type="cite" class="gmail_quote" style="margin: 0 0 0 0.75ex; border-left: 1px solid #808080; padding-left: 0.75ex;">
    On 08/11/18 23:14, Jason Ekstrand wrote:<br>
    <blockquote type="cite" cite="mid:CAOFGe944TmGLLemDQuP_=QpMj03MHGx2UNsqGUHCfMc6c2ed1g@mail.gmail.com">
      
      <div dir="ltr">
        <div class="gmail_quote">
          <div dir="ltr">On Thu, Nov 8, 2018 at 7:22 AM Alejandro
            Piñeiro <<a href="mailto:apinheiro@igalia.com" moz-do-not-send="true">apinheiro@igalia.com</a>> wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">On OpenGL,
            a array of a simple type adds just one varying. So<br>
            gl_transform_feedback_varying_info struct defined at
            mtypes.h includes<br>
            the parameters Type (base_type) and Size (number of
            elements).<br>
            <br>
            This commit checks this when the recursive
            add_var_xfb_outputs call<br>
            handles arrays, to ensure that just one is addded.<br>
            <br>
            RFC: Until this point, all changes were reasonable, but this
            change is<br>
            (imho) ugly. My idea was introducing as less as possible
            changes on<br>
            the code, specially on its logic/flow. But this commit is
            almost a<br>
            hack. The ideal solution would be to change the focus of the
            recursive<br>
            function, focusing on varyings, and at each varying,
            recursively add<br>
            outputs. But that seems like an overkill for a pass that was<br>
            originally intended for consumers only caring about the
            outputs. So<br>
            perhaps ARB_gl_spirv should keep their own gathering pass,
            with<br>
            vayings and outputs, and let this one untouched for those
            that only<br>
            care on outputs.<br>
            ---<br>
             src/compiler/nir/nir_gather_xfb_info.c | 52
            ++++++++++++++++++++++++++++------<br>
             1 file changed, 43 insertions(+), 9 deletions(-)<br>
            <br>
            diff --git a/src/compiler/nir/nir_gather_xfb_info.c
            b/src/compiler/nir/nir_gather_xfb_info.c<br>
            index 948b802a815..cb0e2724cab 100644<br>
            --- a/src/compiler/nir/nir_gather_xfb_info.c<br>
            +++ b/src/compiler/nir/nir_gather_xfb_info.c<br>
            @@ -36,23 +36,59 @@ nir_gather_xfb_info_create(void
            *mem_ctx, uint16_t output_count, uint16_t varyin<br>
                return xfb;<br>
             }<br>
            <br>
            +static bool<br>
            +glsl_type_is_leaf(const struct glsl_type *type)<br>
            +{<br>
            +   if (glsl_type_is_struct(type) ||<br>
            +       (glsl_type_is_array(type) &&<br>
            +        (glsl_type_is_array(glsl_get_array_element(type))
            ||<br>
            +       
             glsl_type_is_struct(glsl_get_array_element(type))))) {<br>
          </blockquote>
          <div><br>
          </div>
          <div>I'm trying to understand exactly what this means.  From
            what you wrote here it looks like the following are all one
            varying:</div>
          <div><br>
          </div>
          <div>float var[3];</div>
          <div>vec2 var[3];</div>
          <div>mat4 var[3];</div>
        </div>
      </div>
    </blockquote>
    <br>
    Yes, GLSL returns one varying per each one (Size 3).</blockquote></div></div></div><div dir="auto"><br></div><div dir="auto">Just to be clear, a matrix it array of matrices is one varying?</div><div dir="auto"><br></div><div id="aqm-original" style="color: black;" dir="auto"><div text="#000000" bgcolor="#ffffff" class="aqm-original-body"><div style="color: black;"><blockquote type="cite" class="gmail_quote" style="margin: 0 0 0 0.75ex; border-left: 1px solid #808080; padding-left: 0.75ex;"><br>
    <blockquote type="cite" cite="mid:CAOFGe944TmGLLemDQuP_=QpMj03MHGx2UNsqGUHCfMc6c2ed1g@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div><br>
          </div>
          <div>but the following are not</div>
          <div><br>
          </div>
          <div>struct S {</div>
          <div>   float f;</div>
          <div>   vec4 v;<br>
          </div>
          <div>};</div>
          <div><br>
          </div>
          <div>S var[3];</div>
        </div>
      </div>
    </blockquote>
    <br>
    <blockquote type="cite" cite="mid:CAOFGe944TmGLLemDQuP_=QpMj03MHGx2UNsqGUHCfMc6c2ed1g@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div>float var[3][5];</div>
        </div>
      </div>
    </blockquote>
    <br>
    I guess that you are asking for thos two cases because this code is 
    not handling it properly. You are right. For the array of structs,
    our code is crashing. For the array of arrays, it is enumerating
    four varyings. One with three GL_FLOAT components, and three with
    five GL_FLOAT components, instead of just three varyings with five
    components. In my defense, I already mentioned that it was wip code,
    but preferred to agree on the way to go before keep working on it.<br>
    <br>
    For the GLSL case, the array of struct returns 6 varyings. And funny
    thing, for the array of arrays, GLSL is handling the situation even
    worse. It returns the following link error: "Failed to link: error:
    Transform feedback varying var[0] undeclared." Just a quick skim on
    the spec, I didn't see anything preventing using aoa with transform
    feedback varyings, so I guess that this is a bug due all the rules
    OpenGL has in relation with variable names.<br>
    <br>
    <blockquote type="cite" cite="mid:CAOFGe944TmGLLemDQuP_=QpMj03MHGx2UNsqGUHCfMc6c2ed1g@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div><br>
          </div>
          <div>Is this correct?<br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    Yes. FWIW, I will give you another two examples, from the tests Im
    using as reference.<br>
    <br>
    ## example 1 ##<br>
      struct Array {<br>
        float x2_out;<br>
       };<br>
       struct AoA {<br>
         Array x2_Array[2];<br>
       };<br>
       struct S {<br>
         float x1_out;<br>
         AoA x2_AoA[2];<br>
         float x3_out;<br>
        };<br>
       layout(xfb_offset = 0) out S s1;<br>
       layout(xfb_offset = 0, xfb_buffer = 2) out struct S2 {<br>
         float y1_out;<br>
         vec4 y2_out;<br>
       } s2;<br>
    <br>
    GLSL returns the following varyings (on ARB_gl_spirv we target to
    get the same, although without the names)<br>
           NumVarying=8, (Offset, Type, BufferIndex, Size, Name) <br>
                0:( 0,        GL_FLOAT,  0,  1, s1.x1_out)<br>
                1:( 4,        GL_FLOAT,  0,  1,
    s1.x2_AoA[0].x2_Array[0].x2_out)<br>
                2:( 8,        GL_FLOAT,  0,  1,
    s1.x2_AoA[0].x2_Array[1].x2_out)<br>
                3:(12,        GL_FLOAT,  0,  1,
    s1.x2_AoA[1].x2_Array[0].x2_out)<br>
                4:(16,        GL_FLOAT,  0,  1,
    s1.x2_AoA[1].x2_Array[1].x2_out)<br>
                5:(20,        GL_FLOAT,  0,  1, s1.x3_out)<br>
                6:( 0,        GL_FLOAT,  1,  1, s2.y1_out)<br>
                7:( 4,   GL_FLOAT_VEC4,  1,  1, s2.y2_out)<br>
    <br>
    ## example 2 ##<br>
    layout(xfb_offset = 0) out float x1_out;<br>
    layout(xfb_offset = 4) out float x2_out[2];<br>
    layout(xfb_offset = 12) out vec3 x3_out;<br>
    layout(xfb_buffer = 2) out;<br>
    layout(xfb_offset = 0, xfb_buffer = 2) out float y1_out;<br>
    layout(xfb_offset = 4) out vec4 y2_out<br>
    <br>
    GLSL returns the following varyings (on ARB_gl_spirv we target to
    get the same, although without the names)<br>
        NumVarying=5, (Offset, Type, BufferIndex, Size, Name) <br>
                0:( 0,        GL_FLOAT,  0,  1, x1_out)<br>
                1:( 4,        GL_FLOAT,  0,  2, x2_out)<br>
                2:(12,   GL_FLOAT_VEC3,  0,  1, x3_out)<br>
                3:( 0,        GL_FLOAT,  1,  1, y1_out)<br>
                4:( 4,   GL_FLOAT_VEC4,  1,  1, y2_out)<br>
    <br>
    <blockquote type="cite" cite="mid:CAOFGe944TmGLLemDQuP_=QpMj03MHGx2UNsqGUHCfMc6c2ed1g@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_quote">
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            +      return false;<br>
            +   } else {<br>
            +      return true;<br>
            +   }<br>
            +}<br>
            +<br>
            +static void<br>
            +add_var_xfb_varying(nir_xfb_info *xfb,<br>
            +                    nir_variable *var,<br>
            +                    unsigned offset,<br>
            +                    const struct glsl_type *type)<br>
            +{<br>
            +   nir_xfb_varying_info *varying =
            &xfb->varyings[xfb->varying_count++];<br>
            +<br>
            +   varying->type = type;<br>
            +   varying->buffer = var->data.xfb_buffer;<br>
            +   varying->offset = offset;<br>
            + 
             xfb->buffers[var->data.xfb_buffer].varying_count++;<br>
            +}<br>
            +<br>
             static void<br>
             add_var_xfb_outputs(nir_xfb_info *xfb,<br>
                                 nir_variable *var,<br>
                                 unsigned *location,<br>
                                 unsigned *offset,<br>
            -                    const struct glsl_type *type)<br>
            +                    const struct glsl_type *type,<br>
            +                    bool varying_added)<br>
             {<br>
                if (glsl_type_is_array(type) ||
            glsl_type_is_matrix(type)) {<br>
                   unsigned length = glsl_get_length(type);<br>
            +      bool local_varying_added = varying_added;<br>
            +<br>
                   const struct glsl_type *child_type =
            glsl_get_array_element(type);<br>
            +      if (glsl_type_is_leaf(child_type)) {<br>
            +<br>
            +         add_var_xfb_varying(xfb, var, *offset, type);<br>
            +         local_varying_added = true;<br>
            +      }<br>
            +<br>
                   for (unsigned i = 0; i < length; i++)<br>
            -         add_var_xfb_outputs(xfb, var, location, offset,
            child_type);<br>
            +         add_var_xfb_outputs(xfb, var, location, offset,
            child_type, local_varying_added);<br>
                } else if (glsl_type_is_struct(type)) {<br>
                   unsigned length = glsl_get_length(type);<br>
                   for (unsigned i = 0; i < length; i++) {<br>
                      const struct glsl_type *child_type =
            glsl_get_struct_field(type, i);<br>
            -         add_var_xfb_outputs(xfb, var, location, offset,
            child_type);<br>
            +         add_var_xfb_outputs(xfb, var, location, offset,
            child_type, varying_added);<br>
                   }<br>
                } else {<br>
                   assert(var->data.xfb_buffer <
            NIR_MAX_XFB_BUFFERS);<br>
            @@ -83,11 +119,9 @@ add_var_xfb_outputs(nir_xfb_info *xfb,<br>
                   uint8_t comp_mask = ((1 << comp_slots) - 1)
            << var->data.location_frac;<br>
                   unsigned location_frac = var->data.location_frac;<br>
            <br>
            -      nir_xfb_varying_info *varying =
            &xfb->varyings[xfb->varying_count++];<br>
            -      varying->type = type;<br>
            -      varying->buffer = var->data.xfb_buffer;<br>
            -      varying->offset = *offset;<br>
            -     
            xfb->buffers[var->data.xfb_buffer].varying_count++;<br>
            +      if (!varying_added) {<br>
            +         add_var_xfb_varying(xfb, var, *offset, type);<br>
            +      }<br>
            <br>
                   assert(attrib_slots <= 2);<br>
                   for (unsigned s = 0; s < attrib_slots; s++) {<br>
            @@ -171,7 +205,7 @@ nir_gather_xfb_info(const nir_shader
            *shader, void *mem_ctx)<br>
            <br>
                      unsigned location = var->data.location;<br>
                      unsigned offset = var->data.offset;<br>
            -         add_var_xfb_outputs(xfb, var, &location,
            &offset, var->type);<br>
            +         add_var_xfb_outputs(xfb, var, &location,
            &offset, var->type, false);<br>
                   }<br>
                }<br>
                assert(xfb->output_count == num_outputs);<br>
            -- <br>
            2.14.1<br>
            <br>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </blockquote>
</div>
</div>
<!-- body end -->

</div><div dir="auto"><br></div>
</div></body>
</html>