[Mesa-dev] Looking for advice on how transform feedback should work with varying structs
Kenneth Graunke
kenneth at whitecape.org
Sun Jan 13 15:25:01 PST 2013
On 01/13/2013 10:15 AM, Paul Berry wrote:
> I'm working on a patch series to implement varying structs in Mesa, and
> I'm trying to figure out how to adjust transform feedback accordingly.
> Varying structs are a requirement of GLES 3.0 and GL 3.2. The specs
> aren't very helpful, and I'm considering filing a bug with Khronos, but
> I wanted to check here first and see if anyone sees anything I missed.
>
> Here are the questions I'm trying to answer, and what I've discovered by
> reading the specs and experimenting with an existing implementation (the
> nVidia proprietary driver for Linux):
>
>
> 1. Should it be possible to capture a full varying struct using
> transform feedback, by simply passing the name of that variable to
> glTransformFeedbackVaryings()? If so, how should the structure be
> packed as it is captured in the transform feedback buffer, and what data
> should be returned from glGetTransformFeedbackVarying()?
>
> In other words, if the vertex shader contains:
>
> struct S {
> float f;
> vec4 v;
> };
> out S var;
>
> and the client code passes the string "var" to
> glTransformFeedbackVaryings(), what should happen?
>
> The documentation of glTransformFeedbackVaryings() (section 2.11.8 of
> GLES 3.0, section 2.14.6 of GL 3.2) simply says "varyings is an array of
> count zero-terminated strings specifying the names of outputs to use for
> transform feedback." Which seems to indicate that this should work.
> But there is no mention of how the data should be packed.
Since a packing hasn't been defined, it doesn't seem like any
applications could safely use the feature.
> Furthermore,
> the documentation of glGetTransformFeedbackVarying() says that "The type
> returned can be any of the scalar, vector, or matrix attribute types
> returned by GetActiveAttrib." There is no mention of how structs should
> be dealt with, and the documentation of GetActiveAttrib makes no
> provision for structs either.
Both of these considerations suggest that transform feedback on whole
structs should not be allowed, at least without further specification by
Khronos.
> The nVidia proprietary driver for Linux does not permit a full varying
> struct to be captured using transform feedback. If you try to do so,
> you get a link error claiming "error: Varying (named var) specified but
> not present in the program object."
This is further evidence that no application will use it.
> 2. Should it be possible to capture an element of a varying struct using
> transform feedback, by using "." in a string passed to
> glTransformFeedbackVaryings()?
>
> In other words, if the vertex shader contains:
>
> struct S {
> float f;
> vec4 v;
> };
> out S var;
>
> and the client code passes the strings "var.f" and "var.v" to
> glTransformFeedbackVaryings(), what should happen?
This seems much more reasonable - at least there's a clear expectation
of what data the application should get back.
> I can't find text in any spec that specifically allows this for
> glTransformFeedbackVaryings(). However, there are several reasons to
> suspect that it might work:
>
> - This sort of thing is allowed for glGetUniformLocation(), and it seems
> reasonable to expect that glGetUniformLocation() and
> glTransformFeedbackVaryings() should behave similarly.
> - "." is allowed in the strings passed to glTransformFeedbackVaryings()
> for selecting elements of interface blocks. Permitting it for selecting
> the elements of structs is not a very big leap.
> - Both Mesa and the nVidia proprietary driver already permit individual
> array elements to be selected for transform feedback by passing a string
> like "foo[3]" to glTransformFeedbackVaryings(). (However, I can't find
> any spec text to justify this either, other than the similarity to
> glGetUniformLocation()). Again, it's not a very big leap from here to
> permitting "." for selecting struct elements.
>
> The nVidia proprietary driver for Linux *does* not permit an element of
"does", you mean?
> a varying struct to be captured using transform feedback using ".", but
> only if the varying occurs in an interface block. So the example above
> fails, but if the vertex shader instead contains:
>
> struct S {
> float f;
> vec4 v;
> };
> out Foo {
> S var;
> };
>
> Then the client code may capture the two elements of the varying struct
> by passing the strings "Foo.var.f" and "Foo.var.v" to
> glTransformFeedbackVaryings().
>
> Unfortunately, it's hard to use the behaviour of the nVidia driver as a
> guide for what to do in GLES 3.0, since GLES 3.0 does not support
> interface blocks for shader inputs or outputs.
I'd probably take this up with Khronos but propose disallowing
whole-struct transform feedback, but allowing individual members.
More information about the mesa-dev
mailing list