Before I get into the bulk of my comments, I want to talk about the general approach you&#39;re taking here.  To make the discussion easier, here&#39;s the shaders your code produces if GL_MAX_VARYING_FLOATS=16, the command line args are &quot;0.25 0.25 0.25 0.25&quot;, and data_varying=7:<br>
<br>VS:<br>varying float v0;<br>varying float v1;<br>varying float v2;<br>varying float v3;<br>varying vec2 v4;<br>varying vec2 v5;<br>varying vec3 v6;<br>varying vec4 v7;<br>attribute vec4 green;<br>attribute float v_zero;<br>
void main()<br>{<br>    gl_Position = (gl_ModelViewProjectionMatrix * <br>            gl_Vertex);<br>    v0 = v_zero;<br>    v1 = v_zero;<br>    v2 = v_zero;<br>    v3 = v_zero;<br>    v4.x = v_zero;<br>    v4.y = v_zero;<br>
    v5.x = v_zero;<br>    v5.y = green.x;<br>    v6.x = green.y;<br>    v6.y = green.z;<br>    v6.z = green.w;<br>}<br><br>FS:<br>varying float v0;<br>varying float v1;<br>varying float v2;<br>varying float v3;<br>varying vec2 v4;<br>
varying vec2 v5;<br>varying vec3 v6;<br>varying vec4 v7;<br>uniform float zero;<br>uniform float one;<br>void main()<br>{<br>    vec4 val = vec4(0.0);<br>    val.x += zero * v0;<br>    val.y += zero * v1;<br>    val.z += zero * v2;<br>
    val.w += zero * v3;<br>    val.x += zero * v4.x;<br>    val.y += zero * v4.y;<br>    val.z += zero * v5.x;<br>    val.x += one * v5.y;<br>    val.y += one * v6.x;<br>    val.z += one * v6.y;<br>    val.w += one * v6.z;<br>
    gl_FragColor = val;<br>}<br><br>What the VS does is: set up 8 varyings that use up 15 varying components.  It fills the first 7 varying components with zero, the next 4 components (which span two of the varyings) with the components of &quot;green&quot;, and then leaves the remaining varyings uninitialized.  Then, the FS reconstitutes the green color by multiplying the first 7 varying components by zero and accumulating them into &quot;val&quot;, then adding one times the next four components (to get green back), and then ignoring the remaining varyings.<br>
<br>This is problematic because:<br><br>(a) some varyings are neither written by the vertex shader nor read by the fragment shader, which means the linker can ignore them, so they won&#39;t contribute to testing that varyings have been packed effectively.  (I suspect this is an easily fixable bug though)<br>
(b) since the FS only checks four components at a time, it will fail to notice if we have a bug that causes some of the varyings to accidentally be packed in overlapping locations.<br>(c) since &quot;green&quot; is the pattern { 0.0, 1.0, 0.0, 0.0 }, we are effectively only testing one varying component at a time, even though it looks like we are testing four.<br>
(d) the test is going to be time consuming because new vertex and fragment shaders need to be compiled for each value of data_varying.<br><br>I would recommend switching to a technique where the VS writes a known pattern into *all* varyings, and the FS checks that the proper pattern is present.  Something like this:<br>
<br>VS:<br>varying float v0;<br>varying float v1;<br>varying float v2;<br>varying float v3;<br>varying vec2 v4;<br>varying vec2 v5;<br>varying vec3 v6;<br>varying vec4 v7;<br>void main()<br>{<br>    gl_Position = (gl_ModelViewProjectionMatrix * <br>
            gl_Vertex);<br>    v0 = 1.0;<br>    v1 = 2.0;<br>    v2 = 3.0;<br>    v3 = 4.0;<br>    v4 = vec2(5.0, 6.0);<br>    v5 = vec2(7.0, 8.0);<br>    v6 = vec3(9.0, 10.0, 11.0);<br>    v7 = vec4(12.0, 13.0, 14.0, 15.0);<br>
}<br><br>FS:<br>varying float v0;<br>varying float v1;<br>varying float v2;<br>varying float v3;<br>varying vec2 v4;<br>varying vec2 v5;<br>varying vec3 v6;<br>varying vec4 v7;<br>void main()<br>{<br>    if (v0 == 1.0 &amp;&amp;<br>
        v1 == 2.0 &amp;&amp;<br>        v2 == 3.0 &amp;&amp;<br>        v3 == 4.0 &amp;&amp;<br>        v4 == vec2(5.0, 6.0) &amp;&amp;<br>        v5 == vec2(7.0, 8.0) &amp;&amp;<br>        v6 == vec3(9.0, 10.0, 11.0) &amp;&amp;<br>
        v7 == vec4(12.0, 13.0, 14.0, 15.0)) {<br>        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); /* green */<br>    } else {<br>        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); /* red */<br>    }<br>}<br><br>I also have some comments about coding style and some of the implementation choices you made (see below).  Some of them may be irrelevant if you decide to follow my suggestions above.<br>
<br>On 8 February 2012 12:20, Vincent Lejeune <span dir="ltr">&lt;<a href="mailto:vljn@ovi.com" target="_blank">vljn@ovi.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><div>---<br>
 tests/shaders/CMakeLists.gl.txt     |    1 +<br>
 tests/shaders/glsl-max-varyings-2.c |  452 +++++++++++++++++++++++++++++++++++<br></div></div></blockquote><div><br>We&#39;re trying to move away from naming tests using numbers, since it&#39;s hard to remember what variant 2 of a given test means.  Can we rename this to something more descriptive, perhaps &quot;glsl-max-varyings-mixed&quot;?<br>

 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
 2 files changed, 453 insertions(+), 0 deletions(-)<br>
 create mode 100644 tests/shaders/glsl-max-varyings-2.c<br>
<br>
diff --git a/tests/shaders/CMakeLists.gl.txt b/tests/shaders/CMakeLists.gl.txt<br>
index 9d72260..b00219e 100644<br>
--- a/tests/shaders/CMakeLists.gl.txt<br>
+++ b/tests/shaders/CMakeLists.gl.txt<br>
@@ -143,6 +143,7 @@ add_executable (vp-ignore-input vp-ignore-input.c)<br>
 add_executable (glsl-empty-vs-no-fs glsl-empty-vs-no-fs.c)<br>
 add_executable (glsl-mat-attribute glsl-mat-attribute.c)<br>
 add_executable (glsl-max-varyings glsl-max-varyings.c)<br>
+add_executable (glsl-max-varyings-2 glsl-max-varyings-2.c)<br>
 add_executable (glsl-useprogram-displaylist glsl-useprogram-displaylist.c)<br>
 add_executable (glsl-routing glsl-routing.c)<br>
 add_executable (shader_runner shader_runner.c)<br>
diff --git a/tests/shaders/glsl-max-varyings-2.c b/tests/shaders/glsl-max-varyings-2.c<br>
new file mode 100644<br>
index 0000000..45e7396<br>
--- /dev/null<br>
+++ b/tests/shaders/glsl-max-varyings-2.c<br>
@@ -0,0 +1,452 @@<br>
+/*<br>
+ * Copyright © 2010 Intel Corporation<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the &quot;Software&quot;),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
+ * IN THE SOFTWARE.<br>
+ *<br>
+ * Authors:<br>
+ *    Eric Anholt &lt;<a href="mailto:eric@anholt.net" target="_blank">eric@anholt.net</a>&gt;<br>
+ *    Vincent Lejeune &lt;<a href="mailto:vljn@ovi.com" target="_blank">vljn@ovi.com</a>&gt;<br>
+ *<br>
+ */<br>
+<br>
+/** @file glsl-max-varyings-2.c<br>
+ *<br>
+ * Tests whether GL_MAX_VARYING_FLOATS varying components can be used when packed<br>
+ * as vec4, vec3, vec2, or float. Drivers have to pack varyings to pass this test.<br></div></div></blockquote><div><br>Can we add some documentation here about the expected command-line arguments? <br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+ */<br>
+<br>
+#include &quot;piglit-util.h&quot;<br>
+<br>
+#define MAX_VARYING 128<br>
+<br>
+/* 10x10 rectangles with 2 pixels of pad.  Deal with up to 32 varyings. */<br>
+int piglit_width = (2 + MAX_VARYING * 12), piglit_height = (2 + MAX_VARYING * 12);<br></div></div></blockquote><div><br>This leads to a window size that is too large for most screens (1538x1538).  This seems particularly wasteful since the test only draws one row of rectangles.<br>
 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
+int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;<br>
+<br>
+<br>
+enum varyings_type {<br>
+   FLT = 0,<br>
+   V2 = 1,<br>
+   V3 = 2,<br>
+   V4 = 3<br>
+};<br>
+<br>
+const char* names[] = { &quot;float&quot;, &quot;vec2&quot;, &quot;vec3&quot;, &quot;vec4&quot; };<br></div></div></blockquote><div><br>A more descriptive name would be helpful here, perhaps something like &quot;glsl_type_names&quot;<br>

 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
+<br>
+char temp[2048];<br></div></div></blockquote><div><br>temp is only used within functions--it doesn&#39;t communicate data between functions.  For maintainability, it should be moved into the particular functions that need it.<br>

 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
+<br>
+float ratio[4];<br>
+unsigned amounts[4]; <br></div></div></blockquote><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
+int max_components;<br></div></div></blockquote><div><br>
amounts and max_components don&#39;t need to be global--the code would be easier to follow if
 we passed them as parameters to the functions that need it.<br><br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>

+<br>
+static void generate_varyings_decl(char* code)<br>
+{<br>
+<br>
+   unsigned index = 0, i;<br>
+<br>
+   static const char * varying_decl[] = {<br>
+       &quot;varying float v%d;\n&quot;,<br>
+       &quot;varying vec2 v%d;\n&quot;,<br>
+       &quot;varying vec3 v%d;\n&quot;,<br>
+       &quot;varying vec4 v%d;\n&quot;,<br>
+   };<br></div></div></blockquote><div><br>This array shouldn&#39;t be necessary, since we already have the names[] array.  We should be able to just use the string &quot;varying %s v%d;\n&quot;.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+<br>
+   for (i = 0; i &lt; amounts[FLT]; i++) {<br>
+       sprintf(temp, varying_decl[FLT], index);<br>
+       strcat(code, temp);<br>
+       index ++;<br>
+   }<br>
+<br>
+   for (i = 0; i &lt; amounts[V2]; i++) {<br>
+       sprintf(temp, varying_decl[V2], index);<br>
+       strcat(code, temp);<br>
+       index ++;<br>
+   }<br>
+<br>
+   for (i = 0; i &lt; amounts[V3]; i++) {<br>
+       sprintf(temp, varying_decl[V3], index);<br>
+       strcat(code, temp);<br>
+       index ++;<br>
+   }<br>
+<br>
+   for (i = 0; i &lt; amounts[V4]; i++) {<br>
+       sprintf(temp, varying_decl[V4], index);<br>
+       strcat(code, temp);<br>
+       index ++;<br>
+   }<br></div></div></blockquote><div><br>This would be simpler as a nested loop:<br><br>for (varying_type = 0; varying_type &lt; 4; ++varying_type) {<br>  for (i = 0; i &lt; amounts[varying_type]; ++i) {<br>
    sprintf(temp, &quot;varying %s v%d;\n&quot;, names[varying_type], index++);<br>    strcat(code, temp);<br>  }<br>}<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+<br>
+   return;<br></div></div></blockquote><div><br>This return statement isn&#39;t necessary.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+}<br>
+<br>
+static void<br>
+get_varying_and_component_from_index(unsigned index, unsigned *varying, unsigned *component)<br>
+{<br>
+   // Accessing a varying float<br>
+   if (index &lt; amounts[FLT]) {<br>
+       *varying = index;<br>
+       *component = 4;<br></div></div></blockquote><div><br>The use of 4 as a magic number to mean &quot;no component, just use the whole float&quot; should be documented somewhere.  Perhaps create an enum:<br><br>enum {<br>

  COMPONENT_X = 0,<br>  COMPONENT_Y = 1,<br>  COMPONENT_Z = 2,<br>  COMPONENT_W = 3,<br>  COMPONENT_ALL = 4,<br>};<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+       return;<br>
+   }<br>
+<br>
+   // Accessing a component of a vec2<br>
+   if (index &lt; amounts[FLT] + 2 *amounts[V2]) {<br>
+       unsigned index_from_v2_start = index - amounts[FLT];<br>
+       *varying = index_from_v2_start / 2;<br>
+       *varying += amounts[FLT];<br>
+       *component = index_from_v2_start % 2;<br>
+       return;<br>
+   }<br>
+<br>
+   // Accessing a component of a vec3<br>
+   if (index &lt; amounts[FLT] + 2 *amounts[V2] + 3 * amounts [V3]) {<br>
+       unsigned index_from_v3_start = index - amounts[FLT] - 2 * amounts[V2];<br>
+       *varying = index_from_v3_start / 3;<br>
+       *varying += amounts[FLT] + amounts[V2];<br>
+       *component = index_from_v3_start % 3;<br>
+       return;<br>
+   }<br>
+<br>
+   // Accessing a component of a vec4<br>
+   if (index &lt; amounts[FLT] + 2 * amounts[V2] + 3 *amounts[V3] + 4 * amounts[V4]) {<br>
+       unsigned index_from_v4_start = index - amounts[FLT] - 2 * amounts[V2] - 3 * amounts[V3];<br>
+       *varying = index_from_v4_start / 4;<br>
+       *varying += amounts[FLT] + amounts[V2] + amounts[V4];<br>
+       *component = index_from_v4_start % 4;<br>
+       return;<br>
+   }<br>
+}<br></div></div></blockquote><div><br>This function is unnecessarily complex.  I&#39;d recommend modifying generate_varyings_decl() so that as a side effect it populates two arrays:<br><br>index_to_varying[];<br>index_to_component[];<br>

<br>Then just look up the values you need in those arrays rather than call generate_varyings_decl().<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+<br>
+static void<br>
+write_zero(char *code, unsigned index, int component) {<br>
+<br>
+   switch (component) {<br>
+   case 0:<br>
+       sprintf(temp,<br>
+               &quot;       v%d.x = v_zero;\n&quot;, index);<br>
+       break;<br>
+   case 1:<br>
+       sprintf(temp,<br>
+               &quot;       v%d.y = v_zero;\n&quot;, index);<br>
+       break;<br>
+   case 2:<br>
+       sprintf(temp,<br>
+               &quot;       v%d.z = v_zero;\n&quot;, index);<br>
+       break;<br>
+   case 3:<br>
+       sprintf(temp,<br>
+               &quot;       v%d.w = v_zero;\n&quot;, index);<br>
+       break;<br>
+   default:<br>
+       sprintf(temp,<br>
+               &quot;       v%d = v_zero;\n&quot;, index);<br>
+       break;<br>
+   }<br></div></div></blockquote><div><br>This doesn&#39;t need to be a switch statement.  Do what you do in write_green_component (use a static string array and index into it using component).<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+<br>
+   strcat(code, temp);<br>
+}<br>
+<br>
+static void<br>
+write_green_component(char *code, unsigned index, int component_dst, unsigned component_src) {<br>
+<br>
+   static const char * component_suffix[] = { &quot;.x&quot;, &quot;.y&quot;, &quot;.z&quot;, &quot;.w&quot;, &quot;&quot;};<br>
+   sprintf(temp,<br>
+           &quot;   v%d%s = green%s;\n&quot;, index, component_suffix[component_dst], component_suffix[component_src]);<br>
+   strcat(code, temp);<br>
+}<br>
+<br>
+/* Generate a VS that writes to num_varyings vec4s, and put<br>
+ * interesting data in data_varying with 0.0 everywhere else.<br></div></div></blockquote><div><br>This comment can&#39;t be right.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+ */<br>
+static GLint get_vs(int data_varying)<br>
+{<br>
+       GLuint shader;<br>
+       unsigned i, j;<br>
+       char *code;<br>
+<br>
+       code =  malloc(2048 * 4);<br>
+       code[0] = 0;<br>
+<br>
+       generate_varyings_decl(code);<br>
+<br>
+       sprintf(temp,<br>
+               &quot;attribute vec4 green;\n&quot;<br>
+               &quot;attribute float v_zero;\n&quot;<br>
+               &quot;void main()\n&quot;<br>
+               &quot;{\n&quot;<br>
+               &quot;       gl_Position = (gl_ModelViewProjectionMatrix * \n&quot;<br>
+               &quot;                       gl_Vertex);\n&quot;<br>
+               );<br>
+       strcat(code, temp);<br>
+<br>
+       for (i = 0; i &lt; data_varying; i++) {<br>
+          unsigned index, component;<br>
+          get_varying_and_component_from_index(i, &amp;index, &amp;component);<br>
+          write_zero(code, index, component);<br>
+       }<br>
+<br>
+       j = 0;<br>
+       for (i = data_varying; i &lt; data_varying + 4; i++) {<br>
+          unsigned index, component;<br>
+          get_varying_and_component_from_index(i, &amp;index, &amp;component);<br>
+          write_green_component(code, index, component, j);<br>
+          j++;<br>
+       }<br>
+<br>
+       for (i = data_varying + 4; i &lt; max_components - 4; i++) {<br></div></div></blockquote><div><br>I think this was meant to be &quot;for (i = data_varying + 4; i &lt; max_components; i++) {&quot;.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div>
+          unsigned index, component;<br>
+          get_varying_and_component_from_index(i, &amp;index, &amp;component);<br>
+          write_zero(code, index, component);<br>
+       }<br>
+<br>
+       sprintf(temp,<br>
+               &quot;}\n&quot;<br>
+               );<br>
+       strcat(code, temp);<br>
+<br>
+       shader = piglit_compile_shader_text(GL_VERTEX_SHADER, code);<br>
+      /* printf(&quot;%s\n&quot;, code); */<br>
+      free(code);<br>
+<br>
+       return shader;<br>
+}<br></div></div></blockquote><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
+<br>
+static void<br>
+read_to_val_component(char *code, unsigned index, int component_src, unsigned component_dst, const char *coeff) {<br>
+<br>
+   static const char * component_suffix[] = { &quot;.x&quot;, &quot;.y&quot;, &quot;.z&quot;, &quot;.w&quot;, &quot;&quot;};<br>
+   sprintf(temp,<br>
+           &quot;   val%s += %s * v%d%s;\n&quot;, component_suffix[component_dst], coeff, index, component_suffix[component_src]);<br>
+   strcat(code, temp);<br>
+}<br>
+<br>
+/* Generate a FS that does operations on num_varyings, yet makes only<br>
+ * data_varying contribute to the output.<br>
+ *<br>
+ * We could make a single FS per num_varyings that did this by using a<br>
+ * uniform for data_varying and some multiplication by comparisons<br>
+ * (see glsl-routing for an example), but since we&#39;re linking a new<br>
+ * shader each time anyway, this produces a simpler FS to read and<br>
+ * verify.<br>
+ */<br>
+static GLint get_fs(int data_varying)<br>
+{<br>
+       GLuint shader;<br>
+       unsigned i, j;<br>
+       char temp[2048];<br>
+       char *code;<br>
+<br>
+       code = malloc(2048 * 4);<br>
+       code[0] = 0;<br>
+<br>
+       generate_varyings_decl(code);<br>
+<br>
+<br>
+       sprintf(temp,<br>
+               &quot;uniform float zero;\n&quot;<br>
+               &quot;uniform float one;\n&quot;<br>
+               &quot;void main()\n&quot;<br>
+               &quot;{\n&quot;<br>
+               &quot;       vec4 val = vec4(0.0);\n&quot;<br>
+               );<br>
+       strcat(code, temp);<br>
+<br>
+       for (i = 0; i &lt; data_varying; i++) {<br>
+          unsigned index, component;<br>
+          get_varying_and_component_from_index(i, &amp;index, &amp;component);<br>
+          read_to_val_component(code, index, component, i % 4, &quot;zero&quot;);<br>
+       }<br>
+<br>
+       j = 0;<br>
+       for (i = data_varying; i &lt; data_varying + 4; i++) {<br>
+          unsigned index, component;<br>
+          get_varying_and_component_from_index(i, &amp;index, &amp;component);<br>
+          read_to_val_component(code, index, component, j, &quot;one&quot;);<br>
+          j++;<br>
+       }<br>
+<br>
+       for (i = data_varying + 4; i &lt; max_components - 4; i++) {<br>
+          unsigned index, component;<br>
+          get_varying_and_component_from_index(i, &amp;index, &amp;component);<br>
+          read_to_val_component(code, index, component, i % 4, &quot;zero&quot;);<br>
+       }<br>
+<br>
+       sprintf(temp,<br>
+               &quot;       gl_FragColor = val;\n&quot;<br>
+               &quot;}\n&quot;<br>
+               );<br>
+       strcat(code, temp);<br>
+      /* printf(&quot;%s\n&quot;, code);  */<br>
+       shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, code);<br>
+       free(code);<br>
+<br>
+       return shader;<br>
+}<br>
+<br>
+static int<br>
+coord_from_index(int index)<br>
+{<br>
+       return 2 + 12 * index;<br>
+}<br>
+<br>
+static void<br>
+draw()<br>
+{<br>
+       int data_varying;<br>
+       float green[4][4] = { {0.0, 1.0, 0.0, 0.0},<br>
+                             {0.0, 1.0, 0.0, 0.0},<br>
+                             {0.0, 1.0, 0.0, 0.0},<br>
+                             {0.0, 1.0, 0.0, 0.0} };<br>
+<br>
+       glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float),<br>
+                             green);<br>
+       glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float),<br>
+                             green);<br>
+       glEnableVertexAttribArray(1);<br>
+       glEnableVertexAttribArray(2);<br>
+<br>
+       for (data_varying = 0; data_varying &lt; max_components - 4; data_varying ++) {<br>
+               GLuint prog, vs, fs;<br>
+               GLint loc;<br>
+<br>
+            vs = get_vs(data_varying);<br>
+            fs = get_fs(data_varying);<br>
+<br>
+               prog = glCreateProgram();<br>
+               glAttachShader(prog, vs);<br>
+               glAttachShader(prog, fs);<br>
+<br>
+               glBindAttribLocation(prog, 1, &quot;green&quot;);<br>
+               glBindAttribLocation(prog, 2, &quot;v_zero&quot;);<br>
+<br>
+               glLinkProgram(prog);<br>
+               if (!piglit_link_check_status(prog))<br>
+                       piglit_report_result(PIGLIT_FAIL);<br>
+<br>
+               glUseProgram(prog);<br>
+<br>
+               loc = glGetUniformLocation(prog, &quot;zero&quot;);<br>
+               if (loc != -1) /* not used for num_varyings == 1 */<br>
+                       glUniform1f(loc, 0.0);<br>
+<br>
+               loc = glGetUniformLocation(prog, &quot;one&quot;);<br>
+               assert(loc != -1); /* should always be used */<br>
+               glUniform1f(loc, 1.0);<br>
+<br>
+<br>
+               piglit_draw_rect(coord_from_index(data_varying),<br>
+                                coord_from_index(0),<br>
+                                10,<br>
+                                10);<br>
+<br>
+               glDeleteShader(vs);<br>
+               glDeleteShader(fs);<br>
+               glDeleteProgram(prog);<br>
+       }<br>
+}<br>
+<br>
+enum piglit_result<br>
+piglit_display(void)<br>
+{<br>
+       int col;<br>
+       GLboolean pass = GL_TRUE, warned = GL_FALSE;<br>
+<br>
+       piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);<br>
+<br>
+       glGetIntegerv(GL_MAX_VARYING_FLOATS, &amp;max_components);<br>
+<br>
+       printf(&quot;GL_MAX_VARYING_FLOATS = %i\n&quot;, max_components);<br>
+<br>
+       if (max_components &gt; MAX_VARYING) {<br>
+               printf(&quot;test not designed to handle &gt;%d varying vec4s.\n&quot;<br>
+                      &quot;(implementation reports %d components)\n&quot;,<br>
+                      max_components, MAX_VARYING);<br>
+               max_components = MAX_VARYING;<br>
+               warned = GL_TRUE;<br>
+       }<br>
+<br>
+       amounts[FLT] = max_components * ratio[FLT];<br>
+       amounts[V2] = (max_components * ratio[V2]) / 2;<br>
+       amounts[V3] = (max_components * ratio[V3]) / 4;<br></div></div></blockquote><div><br>Was this meant to be &quot;/ 3&quot;?  Or are you trying to make the test lenient, to account for the fact that the GLES 2.0 varying packing algorithm sometimes wastes space when packing vec3s?  I would recommend using &quot;/ 3&quot;.  We can always be lenient my just supplying smaller values for the third ratio on the command line.<br>
 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
+       amounts[V4] = (max_components * ratio[V4]) /4;<br></div></div></blockquote><div><br>Rounding errors will sometimes prevent us from using up all varying components.  I would recommend adding some code here that detects if that happened, and increments some of the elements of the &quot;amounts&quot; array to ensure that in a test that is trying to use up all available varying components, we actually do use up all available varying components.<br>
 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
+<br>
+       max_components = amounts[FLT] + amounts[V2] + amounts[V3] + amounts[V4];<br>
+<br>
+       glClearColor(0.5, 0.5, 0.5, 0.5);<br>
+       glClear(GL_COLOR_BUFFER_BIT);<br>
+<br>
+       draw();<br>
+<br>
+          for (col = 0; col &lt; max_components - 4; col ++) {<br>
+               GLboolean ok;<br>
+               float green[3] = {0.0, 1.0, 0.0};<br>
+<br>
+               ok = piglit_probe_rect_rgb(coord_from_index(col),<br>
+                                          coord_from_index(0),<br>
+                                          10, 10,<br>
+                                          green);<br>
+               if (!ok) {<br>
+                  unsigned index, component;<br>
+                  get_varying_and_component_from_index(col, &amp;index, &amp;component);<br>
+                  printf(&quot;  Failure with v%d varyings\n&quot;, index);<br>
+                  pass = GL_FALSE;<br>
+                  break;<br>
+               }<br>
+          }<br>
+<br>
+       glutSwapBuffers();<br>
+<br>
+       if (!pass)<br>
+               return PIGLIT_FAIL;<br>
+       if (warned)<br>
+               return PIGLIT_WARN;<br>
+       else<br>
+               return PIGLIT_PASS;<br>
+}<br>
+<br>
+<br>
+void piglit_init(int argc, char **argv)<br>
+{<br>
+   unsigned i;<br>
+<br>
+       if (!GLEW_VERSION_2_0) {<br>
+               printf(&quot;Requires OpenGL 2.0\n&quot;);<br>
+               piglit_report_result(PIGLIT_SKIP);<br>
+       }<br></div></div></blockquote><div><br>The standard way to do this check is:<br><br>piglit_require_gl_version(20);<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+<br>
+   if (argc &lt; 5) {<br>
+       fprintf(stderr, &quot;Not enough args.\n&quot;);<br>
+       exit(1);<br>
+   }<br></div></div></blockquote><div><br>I&#39;d suggest changing this to &quot;if (argc != 5)&quot;, because if more than 4 args are supplied, that&#39;s a problem too.<br> <br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><div>
+<br>
+   for (i = 1; i &lt; argc; i++) {<br>
+       sscanf(argv[i], &quot;%f&quot;,&amp;ratio[i - 1]);<br>
+       if (ratio[i - 1] &lt; 0) {<br>
+          fprintf(stderr, &quot;Ratio must be positive.\n&quot;);<br>
+          exit(1);<br>
+       }<br>
+   }<br>
+<br>
+   if (ratio[FLT] + ratio[V2] + ratio[V3] + ratio[V4] &gt; 1.0) {<br>
+          fprintf(stderr, &quot;Ratio are not normalised.\n&quot;);<br>
+          exit(1);<br>
+   }<br>
+}<br>
+<br>
+<br></div></div></blockquote><div><br>One final comment: in order for the test to be run by piglit-run.py, it needs to be added to the file tests/all.tests.  In that file, you can specify the test multiple times with different command-line arguments, for example:<br>
<br>shaders[&#39;glsl-max-varyings-mixed floats&#39;] = concurrent_test(&#39;glsl-max-varyings-mixed 1.0 0.0 0.0 0.0&#39;)<br>shaders[&#39;glsl-max-varyings-mixed floats vec2s&#39;] = concurrent_test(&#39;glsl-max-varyings-mixed 0.5 0.5 0.0 0.0&#39;)<br>
<br>...and so on.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>
--<br>
1.7.7<br>
<br>
_______________________________________________<br>
Piglit mailing list<br>
<a href="mailto:Piglit@lists.freedesktop.org" target="_blank">Piglit@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/piglit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/piglit</a><br>
</div></div></blockquote></div><br><br>