<div dir="ltr">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.<br>
<br>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):<br><br><br>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()?<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 glTransformFeedbackVaryings(), what should happen?<br>
<br>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.  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.<br>
<br>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."<br>
<br><br>2. Should it be possible to capture an element of a varying struct using transform feedback, by using "." in a string passed to 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 glTransformFeedbackVaryings(), what should happen?<br><br>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:<br>
<br>- This sort of thing is allowed for glGetUniformLocation(), and it seems reasonable to expect that glGetUniformLocation() and glTransformFeedbackVaryings() should behave similarly.<br>- "." 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.<br>
- 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.<br>
<br>The nVidia proprietary driver for Linux *does* not permit an element of 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:<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 by passing the strings "Foo.var.f" and "Foo.var.v" to glTransformFeedbackVaryings().<br>
<br>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.<br><br></div>