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