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.
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev