<div dir="ltr">On 6 August 2013 10:19, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div class=""><div class="h5">On 08/02/2013 07:52 PM, Paul Berry wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
1. Is it ok to declare an unsized array in an interface block?  In other<br>
words, is this ok?<br>
<br>
     out blk {<br>
         vec4 foo[];<br>
     };<br>
<br>
The nVidia Linux driver allows this, but Mesa currently doesn't.  AFAICT<br>
the spec says it's ok.  In fact, the spec defines the built-in interface<br>
block gl_PerVertex this way:<br>
<br>
     out gl_PerVertex {<br>
         vec4 gl_Position;<br>
         float gl_PointSize;<br>
         float gl_ClipDistance[];<br>
     };<br>
<br>
So it seems like it ought to be allowed for user-defined interface<br>
blocks too.<br>
<br>
2. If you declare an unsized array in an interface block, is it legal to<br>
redeclare that interface block later and specify an array size?  E.g.:<br>
<br>
     out blk {<br>
         vec4 foo[];<br>
     };<br>
     out blk {<br>
         vec4 foo[2];<br>
     };<br>
<br>
I can't find any text in the spec saying whether this is allowed, but it<br>
seems reasonable that if the answer to question 1 is yes, then this<br>
should be allowed too, since it's parallel to what's allowed outside of<br>
interface blocks.<br>
<br>
3. How about redeclaring a named interface block and specifying a size?<br>
<br>
     out blk {<br>
         vec4 foo[];<br>
     } ifc_name;<br>
     out blk {<br>
         vec4 foo[2];<br>
     } ifc_name;<br>
<br>
It seems to me that this should have the same answer as question 2, but<br>
nVidia disallows this (it gives a compile error: declaration of<br>
"ifc_name" conflicts with previous declaration at ...).<br>
<br>
4. How about if you redeclare an interface block that has some arrays<br>
and some non-arrays?  E.g.:<br>
<br>
     out blk {<br>
         vec4 foo[];<br>
         vec4 bar;<br>
     };<br>
     out blk {<br>
         vec4 foo[2];<br>
         vec4 bar;<br>
     };<br>
<br>
It seems to me that this should also have the same answer as question 2,<br>
but nVidia rejects this with a compile error too (declaration of "bar"<br>
conflicts with previous declaration at ...).<br>
<br>
5. How about if you redeclare an interface block and give it different<br>
members?  E.g.:<br>
<br>
     out blk {<br>
         vec4 foo[];<br>
         vec4 bar;<br>
     };<br>
     out blk {<br>
         vec3 baz;<br>
     };<br>
<br>
This seems like it should definitely give an error, since the spec says<br>
"Matched block names within an interface ... must match in terms of<br>
having the same number of declarations with the same sequence of types<br>
and the same sequence of member names, as well as having the same<br>
member-wise layout qualification ...".<br>
<br>
But the nVidia driver allows this.<br>
<br>
<br>
I'm baffled as to what behaviour I should implement in Mesa.  At the<br>
very least I'm pretty sure I have to allow gl_PerVertex to be<br>
redeclared, since (a) that's the only way to give the gl_ClipDistance<br>
input a size in a geometry shader, and (b) redeclaring gl_PerVertex is<br>
explicitly permitted by GLSL 4.10 section 7.1.1 (and I'm pretty sure the<br>
text there is meant as a clarification, rather than a new rule).<br>
<br>
But for anything beyond that, the spec seems open to interpretation.<br>
And I don't feel like I can use nVidia's implementation for guidance,<br>
because of the inconsistencies and non-compliant behaviour I noted above.<br></blockquote></div></div></blockquote><div><br></div><div>FYI, Ken and I just did some experiments on AMD's Catalyst driver, and here's what we found:<br>
</div><div><br>out blk {<br>    vec4 foo[];<br>};<br><br>CATALYST: ok!<br><br>out blk {<br>    vec4 foo[];<br>};<br>out blk {<br>    vec4 foo[2];<br>};<br><br>CATALYST: "The blk definition contradicts."<br><br>out blk {<br>
    vec4 foo[];<br>};<br>out blk {<br>    vec4 foo[];<br>};<br><br>CATALYST: "Re-declaration error blk"<br><br>out blk {<br>    vec4 foo[];<br>} ifc_name;<br>out blk {<br>    vec4 foo[2];<br>} ifc_name;<br><br>CATALYST: "The blk definition contradicts."<br>
<br>out blk {<br>    vec4 foo[];<br>} ifc_name;<br>out blk {<br>    vec4 foo[2];<br>} ifc_name;<br><br>CATALYST: "Re-declaration error ifc_name"<br><br>out blk {<br>    vec4 foo[];<br>    vec4 bar;<br>};<br>out blk {<br>
    vec4 foo[2];<br>    vec4 bar;<br>};<br><br>CATALYST: "The blk definition contradicts."<br><br>out blk {<br>    vec4 foo[];<br>    vec4 bar;<br>};<br>out blk {<br>    vec3 baz;<br>};<br><br>We also tested a lot of the rules for redeclaraing gl_PerVertex 
which appear in GLSL 4.10.  Catalyst seems to get these rules mostly 
correct when it comes to accepting correct shaders.  It fails to reject a
 lot of incorrect shaders, though. <br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

</blockquote>
<br></div></div>
I definitely think NVIDIA has some bugs. :) <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
I spent most of the train ride home last night digging through the GLSL specs and trying to remember any relevant Khronos discussions.  I could only find one bit of text that even hinted at anything.  The bottom of page 50 (page 56 of the PDF) of the GLSL 4.40 spec says:<br>

<br>
    "A block name is allowed to have different definitions in<br>
    different interfaces within the same shader, allowing, for<br>
    example, an input block and output block to have the same<br>
    name."<br>
<br>
That /suggests/ that you can't redeclare a block for the same interface, but I don't feel very comfortable relying on that.  I'll submit a bug.<br></blockquote><div><br></div><div>Cool, thanks.<br><br></div><br>
Based on what we've seen with AMD and nVidia so far, it seems like the intended behaviour is probably: redeclarations of interface blocks are prohibited, with the exception of gl_PerVertex (which may only be redeclared once in a given compilation unit).<br>
<br></div><div class="gmail_quote">I propose to implement the above rule in Mesa unless we hear otherwise from Khronos.</div></div></div>