[Mesa-dev] Questions about arrays in GLSL 1.50 interface blocks

Paul Berry stereotype441 at gmail.com
Tue Aug 6 12:11:53 PDT 2013


On 6 August 2013 10:19, Ian Romanick <idr at freedesktop.org> wrote:

> On 08/02/2013 07:52 PM, Paul Berry wrote:
>
>> 1. Is it ok to declare an unsized array in an interface block?  In other
>> words, is this ok?
>>
>>      out blk {
>>          vec4 foo[];
>>      };
>>
>> The nVidia Linux driver allows this, but Mesa currently doesn't.  AFAICT
>> the spec says it's ok.  In fact, the spec defines the built-in interface
>> block gl_PerVertex this way:
>>
>>      out gl_PerVertex {
>>          vec4 gl_Position;
>>          float gl_PointSize;
>>          float gl_ClipDistance[];
>>      };
>>
>> So it seems like it ought to be allowed for user-defined interface
>> blocks too.
>>
>> 2. If you declare an unsized array in an interface block, is it legal to
>> redeclare that interface block later and specify an array size?  E.g.:
>>
>>      out blk {
>>          vec4 foo[];
>>      };
>>      out blk {
>>          vec4 foo[2];
>>      };
>>
>> I can't find any text in the spec saying whether this is allowed, but it
>> seems reasonable that if the answer to question 1 is yes, then this
>> should be allowed too, since it's parallel to what's allowed outside of
>> interface blocks.
>>
>> 3. How about redeclaring a named interface block and specifying a size?
>>
>>      out blk {
>>          vec4 foo[];
>>      } ifc_name;
>>      out blk {
>>          vec4 foo[2];
>>      } ifc_name;
>>
>> It seems to me that this should have the same answer as question 2, but
>> nVidia disallows this (it gives a compile error: declaration of
>> "ifc_name" conflicts with previous declaration at ...).
>>
>> 4. How about if you redeclare an interface block that has some arrays
>> and some non-arrays?  E.g.:
>>
>>      out blk {
>>          vec4 foo[];
>>          vec4 bar;
>>      };
>>      out blk {
>>          vec4 foo[2];
>>          vec4 bar;
>>      };
>>
>> It seems to me that this should also have the same answer as question 2,
>> but nVidia rejects this with a compile error too (declaration of "bar"
>> conflicts with previous declaration at ...).
>>
>> 5. How about if you redeclare an interface block and give it different
>> members?  E.g.:
>>
>>      out blk {
>>          vec4 foo[];
>>          vec4 bar;
>>      };
>>      out blk {
>>          vec3 baz;
>>      };
>>
>> This seems like it should definitely give an error, since the spec says
>> "Matched block names within an interface ... must match in terms of
>> having the same number of declarations with the same sequence of types
>> and the same sequence of member names, as well as having the same
>> member-wise layout qualification ...".
>>
>> But the nVidia driver allows this.
>>
>>
>> I'm baffled as to what behaviour I should implement in Mesa.  At the
>> very least I'm pretty sure I have to allow gl_PerVertex to be
>> redeclared, since (a) that's the only way to give the gl_ClipDistance
>> input a size in a geometry shader, and (b) redeclaring gl_PerVertex is
>> explicitly permitted by GLSL 4.10 section 7.1.1 (and I'm pretty sure the
>> text there is meant as a clarification, rather than a new rule).
>>
>> But for anything beyond that, the spec seems open to interpretation.
>> And I don't feel like I can use nVidia's implementation for guidance,
>> because of the inconsistencies and non-compliant behaviour I noted above.
>>
>
FYI, Ken and I just did some experiments on AMD's Catalyst driver, and
here's what we found:

out blk {
    vec4 foo[];
};

CATALYST: ok!

out blk {
    vec4 foo[];
};
out blk {
    vec4 foo[2];
};

CATALYST: "The blk definition contradicts."

out blk {
    vec4 foo[];
};
out blk {
    vec4 foo[];
};

CATALYST: "Re-declaration error blk"

out blk {
    vec4 foo[];
} ifc_name;
out blk {
    vec4 foo[2];
} ifc_name;

CATALYST: "The blk definition contradicts."

out blk {
    vec4 foo[];
} ifc_name;
out blk {
    vec4 foo[2];
} ifc_name;

CATALYST: "Re-declaration error ifc_name"

out blk {
    vec4 foo[];
    vec4 bar;
};
out blk {
    vec4 foo[2];
    vec4 bar;
};

CATALYST: "The blk definition contradicts."

out blk {
    vec4 foo[];
    vec4 bar;
};
out blk {
    vec3 baz;
};

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.


> I definitely think NVIDIA has some bugs. :)
>

> 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:
>
>     "A block name is allowed to have different definitions in
>     different interfaces within the same shader, allowing, for
>     example, an input block and output block to have the same
>     name."
>
> 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.
>

Cool, thanks.


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).

I propose to implement the above rule in Mesa unless we hear otherwise from
Khronos.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130806/2e8b9251/attachment.html>


More information about the mesa-dev mailing list