[Piglit] [PATCH] gl-3.0: add a test to stress the bound resource limits

Matthew McClure mcclurem at vmware.com
Tue Jul 8 10:01:19 PDT 2014


I ran this on Ubuntu 12.04.3 with:

OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GTX 650/PCIe/SSE2
OpenGL version string: 4.2.0 NVIDIA 304.116
OpenGL shading language version string: 4.20 NVIDIA via Cg compiler
OpenGL extensions:

.../Devel/fdo.piglit$ bin/gl-3.0-bound-resource-limits -auto
GL_MAX_VARYING_FLOATS: 124
GL_MAX_VERTEX_ATTRIBS: 16
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 32
GL_MAX_TEXTURE_IMAGE_UNITS: 32
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 160
GL_AUX_BUFFERS: 4
GL_MAX_DRAW_BUFFERS: 8
GL_MAX_COLOR_ATTACHMENTS: 8
g_expected[0]=(23921766400.000000, 86156951552.000000, 480410238976.000000, 1425854431232.000000)
g_expected[1]=(6227219709952.000000, 11347125338112.000000, 27230952488960.000000, 41933363740672.000000)
g_expected[2]=(81694296113152.000000, 171963293106176.000000, 241784881938432.000000, 428522141122560.000000)
g_expected[3]=(623247401943040.000000, 751236219404288.000000, 1125101110034432.000000, 1856184336252928.000000)
g_expected[4]=(2735942485934080.000000, 3101938392498176.000000, 4440612589797376.000000, 5674358320136192.000000)
g_expected[5]=(6377906712346624.000000, 8903007106236416.000000, 11072865923235840.000000, 14685310302552064.000000)
g_expected[6]=(20124361323184128.000000, 23577553683873792.000000, 26507988395098112.000000, 31646100720975872.000000)
g_expected[7]=(178482200576.000000, 207579496448.000000, 313797935104.000000, 351675613184.000000)
PIGLIT: {"result": "pass" }

Below are my replies:

> > +static char *
> > +get_packed_decl(PackedDesc *desc,
> > +                char *str,
> > +                unsigned strSize,
> > +                char *tmpStr,
> > +                unsigned tmpStrSize)
> 
> Here and elsewhere, can you const-qualify any pointer args to help
> understand which are inputs vs. outputs?
> 

Sounds good. I'll make the changes.

> > +setup_vertex_element_buffers()
> 
> I think MSVC warns on () so we use (void) usually.

Thanks, I'll go ahead and add that.

> The code generally looks good, but is a bit dense.  It would take me a
> while to understand the intricacies.
> 
> In any case, when I tested it with my nvidia driver I got a failure:
> 
> $ bin/gl-3.0-bound-resource-limits -auto
> GL_MAX_VARYING_FLOATS: 124
> GL_MAX_VERTEX_ATTRIBS: 16
> GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 32
> GL_MAX_TEXTURE_IMAGE_UNITS: 32
> GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 192
> GL_AUX_BUFFERS: 4
> GL_MAX_DRAW_BUFFERS: 8
> GL_MAX_COLOR_ATTACHMENTS: 8
> Failed to link: Fragment info
> -------------
> 0(8) : warning C7533: global variable gl_FragData is deprecated after
> version 120
> 0(2) : error C5041: cannot locate suitable resource to bind variable
> "Variable". Possibly large array.
> 
> PIGLIT: {"result": "fail" }

What was your NVIDIA driver version?

> And with softpipe/llvmpipe I see a different failure:
> 
> $ bin/gl-3.0-bound-resource-limits -auto
> ...
> Failed to compile vertex shader: 0:3(1): error: interpolation qualifier
> `flat' cannot be applied to vertex shader inputs or fragment shader outputs

That is a porting error from the OpenGL 3.2/GLSL 1.50 version of the test. The NVIDIA driver allowed it, but it is semantically incorrect without GLSL 1.50. I'll remove it and send out a new patch.

Thanks,
Matthew

----- Original Message -----
> From: "Brian Paul" <brianp at vmware.com>
> To: "Matthew McClure" <mcclurem at vmware.com>
> Cc: piglit at lists.freedesktop.org
> Sent: Tuesday, July 8, 2014 8:12:59 AM
> Subject: Re: [Piglit] [PATCH] gl-3.0: add a test to stress the bound resource limits
> 
> On 07/07/2014 07:51 AM, Matthew McClure wrote:
> > With this patch, we add a test that will stress the bound resource limits
> > as determined by the GL API getInteger values. The bound resources are
> > populated with floats given a table of primes. Each contribution is
> > multiplied into the final expression, and uniquely represents the
> > successful
> > reference of the resource's memory.
> > ---
> >   tests/all.py                              |    1 +
> >   tests/spec/gl-3.0/CMakeLists.gl.txt       |    1 +
> >   tests/spec/gl-3.0/bound-resource-limits.c | 1136
> >   +++++++++++++++++++++++++++++
> >   3 files changed, 1138 insertions(+)
> >   create mode 100644 tests/spec/gl-3.0/bound-resource-limits.c
> >
> > diff --git a/tests/all.py b/tests/all.py
> > index 7ce90d8..27d620e 100644
> > --- a/tests/all.py
> > +++ b/tests/all.py
> > @@ -927,6 +927,7 @@ gl30['attribs'] = concurrent_test('attribs GL3')
> >   add_concurrent_test(gl30, 'bindfragdata-invalid-parameters')
> >   add_concurrent_test(gl30, 'bindfragdata-link-error')
> >   add_concurrent_test(gl30, 'bindfragdata-nonexistent-variable')
> > +gl30['bound-resource-limits'] =
> > concurrent_test('gl-3.0-bound-resource-limits')
> >   add_concurrent_test(gl30, 'clearbuffer-depth')
> >   add_concurrent_test(gl30, 'clearbuffer-depth-stencil')
> >   add_plain_test(gl30, 'clearbuffer-display-lists')
> > diff --git a/tests/spec/gl-3.0/CMakeLists.gl.txt
> > b/tests/spec/gl-3.0/CMakeLists.gl.txt
> > index 29c59ee..a802da3 100644
> > --- a/tests/spec/gl-3.0/CMakeLists.gl.txt
> > +++ b/tests/spec/gl-3.0/CMakeLists.gl.txt
> > @@ -9,6 +9,7 @@ link_libraries (
> >   	${OPENGL_glu_LIBRARY}
> >   )
> >
> > +piglit_add_executable (gl-3.0-bound-resource-limits
> > bound-resource-limits.c)
> >   piglit_add_executable (gl-3.0-minmax minmax.c)
> >   piglit_add_executable (gl-3.0-render-integer render-integer.c)
> >   piglit_add_executable (gl-3.0-required-sized-texture-formats
> >   required-sized-texture-formats.c)
> > diff --git a/tests/spec/gl-3.0/bound-resource-limits.c
> > b/tests/spec/gl-3.0/bound-resource-limits.c
> > new file mode 100644
> > index 0000000..b89a9f6
> > --- /dev/null
> > +++ b/tests/spec/gl-3.0/bound-resource-limits.c
> > @@ -0,0 +1,1136 @@
> > +/*
> > + * Copyright 2014 VMware, Inc.
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the
> > "Software"),
> > + * to deal in the Software without restriction, including without
> > limitation
> > + * the rights to use, copy, modify, merge, publish, distribute,
> > sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the
> > next
> > + * paragraph) shall be included in all copies or substantial portions of
> > the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> > OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> > MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
> > SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> > OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> > + * DEALINGS IN THE SOFTWARE.
> > + */
> > +
> > +/**
> > + * Test resource limits given the maximum supported by the implementation.
> > + *
> > + * Each component of the fragment output is derived using the following
> > + * expression (indexed at the scalar level):
> > + *
> > + *   result[i] = texture[i] * texture[i] * ... * attrib[i + l *
> > numOutputs]
> > + *
> > + * Depending on the limits for vertex/fragment image units, the texture
> > + * contribution will vary. See the generation of g_expected at the end of
> > + * piglit_init.
> > + *
> > + * Since the scalar inputs are primes, multiplication will yield a unique
> > + * result. Results can be diagnosed by evaluating for their missing
> > factor(s).
> > + *
> > + * Matthew McClure
> > + * 7 July 2014
> > + */
> > +
> > +#include "piglit-util-gl-common.h"
> > +
> > +PIGLIT_GL_TEST_CONFIG_BEGIN
> > +
> > +  config.supports_gl_compat_version = 30;
> > +  config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
> > +
> > +PIGLIT_GL_TEST_CONFIG_END
> > +
> > +
> > +/*
> > + * Definitions for the runtime behavior.
> > + */
> > +#define GLSL_VERSION              "#version 130"
> > +#define BUFFER_WIDTH              32
> > +#define BUFFER_HEIGHT             32
> > +#define MAX_SHADER_LINE_CHARS     256
> > +#define MAX_SHADER_TEXT_CHARS     16*1024
> > +#define MAX_COMPONENTS            4
> > +#define MAX_EXPRESSION_OUTPUTS    1
> > +#define MAX_EXPRESSION_ARGUMENTS  2
> > +#define MAX_EXPRESSION_TEMPS      1
> > +#define TEMP_TEXT_SIZE            (MAX_EXPRESSION_OUTPUTS +  \
> > +                                   MAX_EXPRESSION_ARGUMENTS +  \
> > +                                   MAX_EXPRESSION_ARGUMENTS)
> > +
> > +#define NUM_PRIMES                512
> > +#define NUM_VERTICES              3
> > +#define DRAW_ARRAYS               0
> > +#define DRAW_ELEMENTS             1
> > +#define DRAW_IMMEDIATE            0
> > +
> > +#define DEBUG_INPUT               0
> > +#define DEBUG_READBACK            0
> > +#define DEBUG_SHADERS             0
> > +
> > +/*
> > + * Type definitions for our working set.
> > + */
> > +typedef struct MyVector4 {
> > +   float x, y, z, w;
> > +} MyVector4;
> > +
> > +typedef struct PackedTypeDesc {
> > +   char *typeName;
> > +   unsigned numComponents;
> > +   char *componentNames[MAX_COMPONENTS];
> > +   char *defaultValue;
> > +} PackedTypeDesc;
> > +
> > +typedef struct PackedDesc {
> > +   char *semanticName;
> > +   char *variableName;
> > +   bool isArray;
> > +   unsigned count;
> > +   const PackedTypeDesc *typeDesc;
> > +} PackedDesc;
> > +
> > +
> > +/*
> > + * Global variables for the test's state.
> > + */
> > +static GLint g_maxVaryingFloats = 0;
> > +static GLint g_maxVertexAttribs = 0;
> > +static GLint g_maxVertexTextureImageUnits = 0;
> > +static GLint g_maxTextureImageUnits = 0;
> > +static GLint g_maxCombinedTextureImageUnits = 0;
> > +
> > +static GLint g_maxAuxBuffers = 0;
> > +static GLint g_maxDrawBuffers = 0;
> > +static GLint g_maxColorAttachments = 0;
> > +
> > +static char *g_fragColor = "gl_FragColor";
> > +static char *g_fragData = "gl_FragData";
> > +
> > +static GLfloat g_primes[NUM_PRIMES] = {
> > +2.0, 3.0, 5.0, 7.0, 11.0, 13.0, 17.0, 19.0,
> > +23.0, 29.0, 31.0, 37.0, 41.0, 43.0, 47.0, 53.0,
> > +59.0, 61.0, 67.0, 71.0, 73.0, 79.0, 83.0, 89.0,
> > +97.0, 101.0, 103.0, 107.0, 109.0, 113.0, 127.0, 131.0,
> > +137.0, 139.0, 149.0, 151.0, 157.0, 163.0, 167.0, 173.0,
> > +179.0, 181.0, 191.0, 193.0, 197.0, 199.0, 211.0, 223.0,
> > +227.0, 229.0, 233.0, 239.0, 241.0, 251.0, 257.0, 263.0,
> > +269.0, 271.0, 277.0, 281.0, 283.0, 293.0, 307.0, 311.0,
> > +313.0, 317.0, 331.0, 337.0, 347.0, 349.0, 353.0, 359.0,
> > +367.0, 373.0, 379.0, 383.0, 389.0, 397.0, 401.0, 409.0,
> > +419.0, 421.0, 431.0, 433.0, 439.0, 443.0, 449.0, 457.0,
> > +461.0, 463.0, 467.0, 479.0, 487.0, 491.0, 499.0, 503.0,
> > +509.0, 521.0, 523.0, 541.0, 547.0, 557.0, 563.0, 569.0,
> > +571.0, 577.0, 587.0, 593.0, 599.0, 601.0, 607.0, 613.0,
> > +617.0, 619.0, 631.0, 641.0, 643.0, 647.0, 653.0, 659.0,
> > +661.0, 673.0, 677.0, 683.0, 691.0, 701.0, 709.0, 719.0,
> > +727.0, 733.0, 739.0, 743.0, 751.0, 757.0, 761.0, 769.0,
> > +773.0, 787.0, 797.0, 809.0, 811.0, 821.0, 823.0, 827.0,
> > +829.0, 839.0, 853.0, 857.0, 859.0, 863.0, 877.0, 881.0,
> > +883.0, 887.0, 907.0, 911.0, 919.0, 929.0, 937.0, 941.0,
> > +947.0, 953.0, 967.0, 971.0, 977.0, 983.0, 991.0, 997.0,
> > +1009.0, 1013.0, 1019.0, 1021.0, 1031.0, 1033.0, 1039.0, 1049.0,
> > +1051.0, 1061.0, 1063.0, 1069.0, 1087.0, 1091.0, 1093.0, 1097.0,
> > +1103.0, 1109.0, 1117.0, 1123.0, 1129.0, 1151.0, 1153.0, 1163.0,
> > +1171.0, 1181.0, 1187.0, 1193.0, 1201.0, 1213.0, 1217.0, 1223.0,
> > +1229.0, 1231.0, 1237.0, 1249.0, 1259.0, 1277.0, 1279.0, 1283.0,
> > +1289.0, 1291.0, 1297.0, 1301.0, 1303.0, 1307.0, 1319.0, 1321.0,
> > +1327.0, 1361.0, 1367.0, 1373.0, 1381.0, 1399.0, 1409.0, 1423.0,
> > +1427.0, 1429.0, 1433.0, 1439.0, 1447.0, 1451.0, 1453.0, 1459.0,
> > +1471.0, 1481.0, 1483.0, 1487.0, 1489.0, 1493.0, 1499.0, 1511.0,
> > +1523.0, 1531.0, 1543.0, 1549.0, 1553.0, 1559.0, 1567.0, 1571.0,
> > +1579.0, 1583.0, 1597.0, 1601.0, 1607.0, 1609.0, 1613.0, 1619.0,
> > +1621.0, 1627.0, 1637.0, 1657.0, 1663.0, 1667.0, 1669.0, 1693.0,
> > +1697.0, 1699.0, 1709.0, 1721.0, 1723.0, 1733.0, 1741.0, 1747.0,
> > +1753.0, 1759.0, 1777.0, 1783.0, 1787.0, 1789.0, 1801.0, 1811.0,
> > +1823.0, 1831.0, 1847.0, 1861.0, 1867.0, 1871.0, 1873.0, 1877.0,
> > +1879.0, 1889.0, 1901.0, 1907.0, 1913.0, 1931.0, 1933.0, 1949.0,
> > +1951.0, 1973.0, 1979.0, 1987.0, 1993.0, 1997.0, 1999.0, 2003.0,
> > +2011.0, 2017.0, 2027.0, 2029.0, 2039.0, 2053.0, 2063.0, 2069.0,
> > +2081.0, 2083.0, 2087.0, 2089.0, 2099.0, 2111.0, 2113.0, 2129.0,
> > +2131.0, 2137.0, 2141.0, 2143.0, 2153.0, 2161.0, 2179.0, 2203.0,
> > +2207.0, 2213.0, 2221.0, 2237.0, 2239.0, 2243.0, 2251.0, 2267.0,
> > +2269.0, 2273.0, 2281.0, 2287.0, 2293.0, 2297.0, 2309.0, 2311.0,
> > +2333.0, 2339.0, 2341.0, 2347.0, 2351.0, 2357.0, 2371.0, 2377.0,
> > +2381.0, 2383.0, 2389.0, 2393.0, 2399.0, 2411.0, 2417.0, 2423.0,
> > +2437.0, 2441.0, 2447.0, 2459.0, 2467.0, 2473.0, 2477.0, 2503.0,
> > +2521.0, 2531.0, 2539.0, 2543.0, 2549.0, 2551.0, 2557.0, 2579.0,
> > +2591.0, 2593.0, 2609.0, 2617.0, 2621.0, 2633.0, 2647.0, 2657.0,
> > +2659.0, 2663.0, 2671.0, 2677.0, 2683.0, 2687.0, 2689.0, 2693.0,
> > +2699.0, 2707.0, 2711.0, 2713.0, 2719.0, 2729.0, 2731.0, 2741.0,
> > +2749.0, 2753.0, 2767.0, 2777.0, 2789.0, 2791.0, 2797.0, 2801.0,
> > +2803.0, 2819.0, 2833.0, 2837.0, 2843.0, 2851.0, 2857.0, 2861.0,
> > +2879.0, 2887.0, 2897.0, 2903.0, 2909.0, 2917.0, 2927.0, 2939.0,
> > +2953.0, 2957.0, 2963.0, 2969.0, 2971.0, 2999.0, 3001.0, 3011.0,
> > +3019.0, 3023.0, 3037.0, 3041.0, 3049.0, 3061.0, 3067.0, 3079.0,
> > +3083.0, 3089.0, 3109.0, 3119.0, 3121.0, 3137.0, 3163.0, 3167.0,
> > +3169.0, 3181.0, 3187.0, 3191.0, 3203.0, 3209.0, 3217.0, 3221.0,
> > +3229.0, 3251.0, 3253.0, 3257.0, 3259.0, 3271.0, 3299.0, 3301.0,
> > +3307.0, 3313.0, 3319.0, 3323.0, 3329.0, 3331.0, 3343.0, 3347.0,
> > +3359.0, 3361.0, 3371.0, 3373.0, 3389.0, 3391.0, 3407.0, 3413.0,
> > +3433.0, 3449.0, 3457.0, 3461.0, 3463.0, 3467.0, 3469.0, 3491.0,
> > +3499.0, 3511.0, 3517.0, 3527.0, 3529.0, 3533.0, 3539.0, 3541.0,
> > +3547.0, 3557.0, 3559.0, 3571.0, 3581.0, 3583.0, 3593.0, 3607.0,
> > +3613.0, 3617.0, 3623.0, 3631.0, 3637.0, 3643.0, 3659.0, 3671.0,
> > +};
> > +
> > +static const PackedTypeDesc g_rgbaDesc =
> > +   {
> > +      "vec4", 4, { ".r", ".g", ".b", ".a" },
> > +      "vec4(1.0, 1.0, 1.0, 1.0)"
> > +   };
> > +static const PackedTypeDesc g_vec4Desc =
> > +   {
> > +      "vec4", 4, { ".x", ".y", ".z", ".w" },
> > +      "vec4(1.0, 1.0, 1.0, 1.0)"
> > +   };
> > +static const PackedTypeDesc g_floatDesc =
> > +   {
> > +      "float", 1, { "" },
> > +      "1.0"
> > +   };
> > +static const PackedTypeDesc g_sampler2DDesc =
> > +   {
> > +      "sampler2D", 4, { "" },
> > +      "vec4(1.0, 1.0, 1.0, 1.0)"
> > +   };
> > +
> > +static const char *g_vectorComponents[MAX_COMPONENTS] =
> > +   {
> > +      ".x", ".y", ".z", ".w"
> > +   };
> > +//static MyVector4 one = { 1.0f, 1.0f, 1.0f, 1.0f };
> > +//static MyVector4 zero = { 0.0f, 0.0f, 0.0f, 0.0f };
> > +static MyVector4 g_positionBuffer[NUM_VERTICES] =
> > +   {
> > +      { -1.0, -1.0, 0.0, 0.0 },
> > +      { -1.0, 1.0, 0.0, 0.0 },
> > +      { 1.0, 1.0, 0.0, 0.0 },
> > +   };
> > +
> > +static GLuint g_elementVBO;
> > +static ushort g_elementBuffer[NUM_VERTICES] = { 0, 1, 2 };
> > +static char *g_vertexShaderText =
> > +   "#version 110 \n"
> > +   " \n"
> > +   "void main() \n"
> > +   "{ \n"
> > +   "   gl_Position = gl_Vertex; \n"
> > +   "} \n";
> > +
> > +//static char *g_geometryShaderText = NULL;
> > +
> > +static char *g_fragmentShaderText =
> > +   "#version 110 \n"
> > +   " \n"
> > +   "void main()\n"
> > +   "{ \n"
> > +   "    gl_FragData[0] = vec4(1.0, 2.0, 3.0, 4.0);\n"
> > +   "    gl_FragData[1] = vec4(5.0, 6.0, 7.0, 8.0);\n"
> > +   "} \n";
> > +
> > +static GLuint g_program = 0;
> > +static GLfloat *g_expected;
> > +
> > +
> > +static char *
> > +get_packed_decl(PackedDesc *desc,
> > +                char *str,
> > +                unsigned strSize,
> > +                char *tmpStr,
> > +                unsigned tmpStrSize)
> 
> Here and elsewhere, can you const-qualify any pointer args to help
> understand which are inputs vs. outputs?
> 
> 
> 
> > +{
> > +   int i = 0;
> > +
> > +   if (NULL == str) {
> > +      return "";
> > +   }
> > +
> > +   if (desc->isArray) {
> > +      snprintf(tmpStr, tmpStrSize,
> > +               "%s %s %s%s%u%s;\n",
> > +               desc->semanticName,
> > +               desc->typeDesc->typeName,
> > +               desc->variableName,
> > +               desc->isArray ? "[" : "",
> > +               desc->count,
> > +               desc->isArray ? "]" : "");
> > +      strncat(str, tmpStr, strSize - strlen(str));
> > +   } else if (desc->count > 1) {
> > +      for (i = 0; i < desc->count; i++) {
> > +         snprintf(tmpStr, tmpStrSize,
> > +                  "%s %s %s%u;\n",
> > +                  desc->semanticName,
> > +                  desc->typeDesc->typeName,
> > +                  desc->variableName, i);
> > +         strncat(str, tmpStr, strSize - strlen(str));
> > +      }
> > +   } else {
> > +      snprintf(tmpStr, tmpStrSize,
> > +               "%s %s %s;\n",
> > +               desc->semanticName,
> > +               desc->typeDesc->typeName,
> > +               desc->variableName);
> > +      strncat(str, tmpStr, strSize - strlen(str));
> > +   }
> > +
> > +   return str;
> > +}
> > +
> > +
> > +static char *
> > +get_packed_reference(PackedDesc *desc,
> > +                     char *str,
> > +                     unsigned strSize,
> > +                     unsigned arrayIndex,
> > +                     unsigned componentIndex)
> > +{
> > +#if DEBUG_INPUT
> > +   printf("desc=%p componentIndex=%u\n", desc, componentIndex);
> > +   printf("desc->typeDesc=%p\n", desc->typeDesc);
> > +   printf("desc->typeDesc->componentNames=%p\n",
> > +          desc->typeDesc->componentNames);
> > +#endif
> > +
> > +   if (componentIndex > desc->typeDesc->numComponents) {
> > +      snprintf(str, strSize, "%s", g_floatDesc.defaultValue);
> > +      return str;
> > +   }
> > +
> > +   if (arrayIndex > desc->count) {
> > +      snprintf(str, strSize, "%s%s",
> > +               desc->typeDesc->defaultValue,
> > +               desc->typeDesc->componentNames[componentIndex]);
> > +      return str;
> > +   }
> > +
> > +   if (desc->count > 1) {
> > +      snprintf(str, strSize, "%s%s%u%s%s",
> > +               desc->variableName,
> > +               desc->isArray ? "[" : "",
> > +               arrayIndex,
> > +               desc->isArray ? "]" : "",
> > +               desc->typeDesc->componentNames[componentIndex]);
> > +   } else {
> > +      snprintf(str, strSize, "%s%s",
> > +               desc->variableName,
> > +               desc->typeDesc->componentNames[componentIndex]);
> > +   }
> > +
> > +   return str;
> > +}
> > +
> > +
> > +static bool
> > +setup_fbo_2d(GLuint colorTarget,
> > +             GLenum format,
> > +             GLenum type,
> > +             GLenum format_type,
> > +             GLuint width,
> > +             GLuint height,
> > +             GLuint fbo,
> > +             GLuint *pTexture)
> > +{
> > +   GLenum status;
> > +
> > +   glGenTextures(1, pTexture);
> > +   glBindTexture(GL_TEXTURE_2D, *pTexture);
> > +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> > +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> > +   glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
> > +                type, format_type, NULL);
> > +
> > +   /*
> > +    * Framebuffer object is implied to be bound.
> > +    */
> > +   glFramebufferTexture2D(GL_FRAMEBUFFER,
> > +                          GL_COLOR_ATTACHMENT0 + colorTarget,
> > +                          GL_TEXTURE_2D, *pTexture, 0);
> > +
> > +   if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +      fprintf(stderr, "Failed to create FBO %u.\n", colorTarget);
> > +      piglit_report_result(PIGLIT_FAIL);
> > +      return false;
> > +   }
> > +
> > +   status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
> > +   if (status != GL_FRAMEBUFFER_COMPLETE) {
> > +      fprintf(stderr, "Incomplete fbo for format %s.%s (status %s)\n",
> > +              piglit_get_gl_enum_name(format),
> > +              piglit_get_gl_enum_name(type),
> > +              piglit_get_gl_enum_name(status));
> > +      piglit_report_result(PIGLIT_FAIL);
> > +      return false;
> > +   }
> > +
> > +   return true;
> > +}
> > +
> > +
> > +static bool
> > +setup_vertex_element_buffers()
> 
> I think MSVC warns on () so we use (void) usually.
> 
> 
> > +{
> > +   MyVector4 attrib[NUM_VERTICES];
> > +   GLuint buf;
> > +   GLuint attribLoc;
> > +   int i;
> > +
> > +   /*
> > +    * Setup the gl_Position attribute buffer.
> > +    */
> > +   glGenBuffers(1, &buf);
> > +   glBindBuffer(GL_ARRAY_BUFFER, buf);
> > +   glBufferData(GL_ARRAY_BUFFER, NUM_VERTICES*sizeof(MyVector4),
> > +                g_positionBuffer, GL_STATIC_DRAW);
> > +
> > +   attribLoc = glGetAttribLocation(g_program, "InPosition");
> > +   glEnableVertexAttribArray(attribLoc);
> > +   glVertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);
> > +   glBindBuffer(GL_ARRAY_BUFFER, 0);
> > +
> > +   /*
> > +    * Setup the vertex buffer objects.
> > +    */
> > +   for (i = 0; i < g_maxVertexAttribs - 1; i++) {
> > +      char strTemp[16];
> > +
> > +      if ((i + 1) * MAX_COMPONENTS < NUM_PRIMES) {
> > +         attrib[0].x = attrib[1].x = attrib[2].x =
> > g_primes[i*MAX_COMPONENTS + 0];
> > +         attrib[0].y = attrib[1].y = attrib[2].y =
> > g_primes[i*MAX_COMPONENTS + 1];
> > +         attrib[0].z = attrib[1].z = attrib[2].z =
> > g_primes[i*MAX_COMPONENTS + 2];
> > +         attrib[0].w = attrib[1].w = attrib[2].w =
> > g_primes[i*MAX_COMPONENTS + 3];
> > +      } else {
> > +         attrib[0].x = attrib[1].x = attrib[2].x = 1.0;
> > +         attrib[0].y = attrib[1].y = attrib[2].y = 1.0;
> > +         attrib[0].z = attrib[1].z = attrib[2].z = 1.0;
> > +         attrib[0].w = attrib[1].w = attrib[2].w = 1.0;
> > +      }
> > +
> > +      glGenBuffers(1, &buf);
> > +      glBindBuffer(GL_ARRAY_BUFFER, buf);
> > +      glBufferData(GL_ARRAY_BUFFER, sizeof(MyVector4)*NUM_VERTICES,
> > +                   attrib, GL_STATIC_DRAW);
> > +
> > +      snprintf(strTemp, sizeof(strTemp), "InValue%u", i);
> > +      attribLoc = glGetAttribLocation(g_program, strTemp);
> > +      glEnableVertexAttribArray(attribLoc);
> > +      glVertexAttribPointer(attribLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);
> > +      glBindBuffer(GL_ARRAY_BUFFER, 0);
> > +
> > +      if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +         fprintf(stderr, "Failed to create VBO %u.\n", i);
> > +         piglit_report_result(PIGLIT_FAIL);
> > +         return false;
> > +      }
> > +   }
> > +
> > +   /*
> > +    * Setup the element buffers.
> > +    */
> > +   glGenBuffers(1, &g_elementVBO);
> > +   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_elementVBO);
> > +   glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_elementBuffer),
> > +                g_elementBuffer, GL_STATIC_DRAW);
> > +   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
> > +
> > +   if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +      fprintf(stderr, "Failed to create IBO.\n");
> > +      piglit_report_result(PIGLIT_FAIL);
> > +      return false;
> > +   }
> > +
> > +   return true;
> > +}
> > +
> > +
> > +static bool
> > +build_reduce_glsl_shader(char **pShaderText,
> > +                         PackedDesc *packedInput,
> > +                         PackedDesc *packedUniform,
> > +                         PackedDesc *packedOutput,
> > +                         char *outputDefaultSystemValue,
> > +                         char *defaultSystemValueDecl,
> > +                         char *defaultSystemValue)
> > +{
> > +   char *shaderTempText[TEMP_TEXT_SIZE];
> > +   char *shaderText = NULL;
> > +   unsigned shaderTextFree = 0;
> > +   unsigned numScalarInputs =
> > +      packedInput->count * packedInput->typeDesc->numComponents;
> > +   unsigned numScalarUniforms =
> > +      packedUniform->count * packedUniform->typeDesc->numComponents;
> > +   unsigned numScalarOutputs =
> > +      packedOutput->count * packedOutput->typeDesc->numComponents;
> > +
> > +   /* Prepare for reduction of input contributions to the output slots */
> > +   unsigned di_do = numScalarInputs / numScalarOutputs;
> > +   unsigned r = numScalarInputs % numScalarOutputs;
> > +   int i, j, k, l;
> > +
> > +#if DEBUG_INPUT
> > +   printf("di_do=%u r=%u\n", di_do, r);
> > +#endif
> > +
> > +   for (i = 0; i < sizeof(shaderTempText) / sizeof(char *); i++) {
> > +      shaderTempText[i] = calloc(MAX_SHADER_LINE_CHARS, sizeof(char));
> > +
> > +      if (NULL == shaderTempText[i]) {
> > +         fprintf(stderr, "Failed to allocate shader temporary text
> > area\n");
> > +         piglit_report_result(PIGLIT_FAIL);
> > +         return false;
> > +      }
> > +   }
> > +
> > +   shaderText = calloc(MAX_SHADER_TEXT_CHARS, sizeof(char));
> > +   if (NULL == shaderText) {
> > +      fprintf(stderr, "Failed to allocate space for shader text\n");
> > +      piglit_report_result(PIGLIT_FAIL);
> > +      return false;
> > +   }
> > +
> > +   shaderTextFree = MAX_SHADER_TEXT_CHARS;
> > +
> > +   snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +            "%s\n", GLSL_VERSION);
> > +   strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +   shaderTextFree -= strlen(shaderTempText[0]);
> > +
> > +   /*
> > +    * Declare the default system value input.
> > +    */
> > +   if (outputDefaultSystemValue) {
> > +      snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +               "%s\n", defaultSystemValueDecl);
> > +      strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +      shaderTextFree -= strlen(defaultSystemValueDecl);
> > +   }
> > +
> > +   /*
> > +    * Declare the input attributes.
> > +    */
> > +   get_packed_decl(packedInput,
> > +                   shaderText, MAX_SHADER_TEXT_CHARS,
> > +                   shaderTempText[0], MAX_SHADER_LINE_CHARS);
> > +
> > +   /*
> > +    * Declare the uniform samplers using the vertex texture functionality.
> > +    */
> > +   get_packed_decl(packedUniform,
> > +                   shaderText, MAX_SHADER_TEXT_CHARS,
> > +                   shaderTempText[0], MAX_SHADER_LINE_CHARS);
> > +
> > +   /*
> > +    * Declare the outputs.
> > +    */
> > +   if (packedOutput->semanticName) {
> > +      get_packed_decl(packedOutput,
> > +                      shaderText, MAX_SHADER_TEXT_CHARS,
> > +                      shaderTempText[0], MAX_SHADER_LINE_CHARS);
> > +   }
> > +
> > +   shaderTextFree = MAX_SHADER_TEXT_CHARS - strlen(shaderText);
> > +
> > +   /*
> > +    * Begin main program block.
> > +    */
> > +   snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +            "void main()\n{\n");
> > +   strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +   shaderTextFree -= strlen(shaderTempText[0]);
> > +
> > +   snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +            "  vec4 texel;\n");
> > +   strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +   shaderTextFree -= strlen(shaderTempText[0]);
> > +
> > +   /*
> > +    * Passthru the attributes to the outputs.
> > +    */
> > +   i = j = k = l = 0;
> > +
> > +   while (i < numScalarOutputs)  {
> > +      char *resultStr = " ", *srcStr = " ";
> > +
> > +      if ((i <
> > packedUniform->count*packedUniform->typeDesc->numComponents) &&
> > +          (j % packedUniform->typeDesc->numComponents) == 0) {
> > +         snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +                  "  texel = texture2D(Texture[%u], vec2(0.0, 0.0));\n",
> > +                  i / packedUniform->typeDesc->numComponents);
> > +         strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +         shaderTextFree -= strlen(shaderTempText[0]);
> > +      }
> > +
> > +      /*
> > +       * Iterate through the contents of the texel
> > +       */
> > +      resultStr = get_packed_reference(packedOutput,
> > +                     shaderTempText[1], MAX_SHADER_LINE_CHARS,
> > +                     (i / packedOutput->typeDesc->numComponents),
> > +                     (i % packedOutput->typeDesc->numComponents));
> > +
> > +      /* Reset the temp string to avoid cumulative contributions. */
> > +      memset(shaderTempText[2], 0, MAX_SHADER_LINE_CHARS);
> > +
> > +      if (k < numScalarInputs) {
> > +         /* Reduce the scalar multiple of the input contributions. */
> > +         for (l = 0; l < di_do; l++) {
> > +            srcStr = get_packed_reference(packedInput,
> > +                        shaderTempText[3], MAX_SHADER_LINE_CHARS,
> > +                        (i + (l * numScalarOutputs)) /
> > +                           packedInput->typeDesc->numComponents,
> > +                        (i + (l * numScalarOutputs)) %
> > +                           packedInput->typeDesc->numComponents);
> > +
> > +            if (l > 0) {
> > +               strncat(shaderTempText[2], " * ",
> > +                       MAX_SHADER_LINE_CHARS - strlen(shaderTempText[2]));
> > +            }
> > +            strncat(shaderTempText[2], srcStr,
> > +                    MAX_SHADER_LINE_CHARS - strlen(shaderTempText[2]));
> > +
> > +            k++;
> > +         }
> > +
> > +         /* Reduce the remaining scalar contributions until exhausted */
> > +         if (r) {
> > +            srcStr = get_packed_reference(packedInput,
> > +                        shaderTempText[3], MAX_SHADER_LINE_CHARS,
> > +                        (i + (l * numScalarOutputs)) /
> > +                           packedInput->typeDesc->numComponents,
> > +                        (i + (l * numScalarOutputs)) %
> > +                           packedInput->typeDesc->numComponents);
> > +            if (l > 0) {
> > +               strncat(shaderTempText[2], " * ",
> > +                       MAX_SHADER_LINE_CHARS - strlen(shaderTempText[2]));
> > +            }
> > +            strncat(shaderTempText[2], srcStr,
> > +                    MAX_SHADER_LINE_CHARS - strlen(shaderTempText[2]));
> > +            k++;
> > +            r--;
> > +         }
> > +         srcStr = shaderTempText[2];
> > +      } else {
> > +         snprintf(shaderTempText[2], MAX_SHADER_LINE_CHARS,
> > +                  "%s", g_floatDesc.defaultValue);
> > +         srcStr = shaderTempText[2];
> > +      }
> > +
> > +      if (j < numScalarUniforms) {
> > +         if (DEBUG_INPUT && outputDefaultSystemValue) {
> > +            snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +                     "  %s = texel%s;\n", resultStr,
> > +                     g_vectorComponents[j %
> > packedUniform->typeDesc->numComponents]);
> > +         } else {
> > +            snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +                     "  %s = texel%s * %s;\n", resultStr,
> > +                     g_vectorComponents[j %
> > packedUniform->typeDesc->numComponents],
> > +                     srcStr);
> > +         }
> > +         strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +         shaderTextFree -= strlen(shaderTempText[0]);
> > +         j++;
> > +      } else {
> > +         snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +                  "  %s = %s%s * %s;\n", resultStr,
> > +                  packedUniform->typeDesc->defaultValue,
> > +                  g_vectorComponents[0],
> > +                  srcStr);
> > +         strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +         shaderTextFree -= strlen(shaderTempText[0]);
> > +      }
> > +
> > +      /* Increment to the next output. */
> > +      i++;
> > +   }
> > +
> > +   /*
> > +    * End the main program block.
> > +    */
> > +   if (outputDefaultSystemValue) {
> > +      snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS,
> > +               "  %s = %s;\n",
> > +               outputDefaultSystemValue, defaultSystemValue);
> > +      strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +      shaderTextFree -= strlen(shaderTempText[0]);
> > +   }
> > +
> > +   snprintf(shaderTempText[0], MAX_SHADER_LINE_CHARS, "}\n");
> > +   strncat(shaderText, shaderTempText[0], shaderTextFree);
> > +   shaderTextFree -= strlen(shaderTempText[0]);
> > +
> > +   for (i = 0; i < sizeof(shaderTempText) / sizeof(char *); i++) {
> > +      if (shaderTempText[i]) {
> > +         free(shaderTempText[i]);
> > +      }
> > +   }
> > +
> > +   *pShaderText = shaderText;
> > +   return true;
> > +}
> > +
> > +
> > +enum piglit_result
> > +piglit_display(void)
> > +{
> > +   GLuint vao = 0;
> > +   GLuint fbo = 0;
> > +   GLuint *fboTextures = NULL;
> > +   GLenum *colorBuffers = NULL;
> > +   GLuint attribLoc;
> > +   GLfloat result[4];
> > +   int i = 0;
> > +
> > +   /*
> > +    * Reserve memory for the FBO texture objects.
> > +    */
> > +   fboTextures = calloc(g_maxColorAttachments, sizeof(GLuint));
> > +
> > +   if (NULL == fboTextures) {
> > +      fprintf(stderr, "Failed to create FBO texture object container.\n");
> > +      goto fail;
> > +   }
> > +
> > +   /*
> > +    * Build the color attachments
> > +    */
> > +   colorBuffers = calloc(g_maxColorAttachments, sizeof(GLenum));
> > +
> > +   if (NULL == colorBuffers) {
> > +      fprintf(stderr, "Failed to create draw buffers descriptor.\n");
> > +      goto fail;
> > +   }
> > +
> > +   /*
> > +    * Generate an FBO container to hold the color attachment hierarchy.
> > +    */
> > +   glGenFramebuffers(1, &fbo);
> > +   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
> > +
> > +   for (i = 0; i < g_maxColorAttachments; i++) {
> > +      setup_fbo_2d(i, GL_RGBA32F, GL_RGBA, GL_FLOAT,
> > +                   BUFFER_WIDTH, BUFFER_HEIGHT,
> > +                   fbo, &fboTextures[i]);
> > +      colorBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
> > +   }
> > +
> > +   /*
> > +    * Build the textures sampled by the shaders
> > +    */
> > +   for (i = 0; i < g_maxCombinedTextureImageUnits; i++) {
> > +      GLuint tex;
> > +      GLuint uniformLoc;
> > +      char strTemp[16];
> > +
> > +      glGenTextures(1, &tex);
> > +      glActiveTexture(GL_TEXTURE0 + i);
> > +      glBindTexture(GL_TEXTURE_2D, tex);
> > +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> > +      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> > +
> > +      if (((i+1) * MAX_COMPONENTS) > sizeof(g_primes)) {
> > +         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0,
> > +                      GL_RGBA, GL_UNSIGNED_BYTE, NULL);
> > +      } else {
> > +         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0,
> > +                      GL_RGBA, GL_FLOAT, &g_primes[i * MAX_COMPONENTS]);
> > +      }
> > +
> > +      if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +         fprintf(stderr, "Failed to create texture %u.\n", i);
> > +         goto fail;
> > +      }
> > +
> > +      snprintf(strTemp, sizeof(strTemp), "Texture[%u]", i);
> > +      uniformLoc = glGetUniformLocation(g_program, strTemp);
> > +      glUniform1i(uniformLoc, i);
> > +
> > +      if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +         fprintf(stderr, "Unable to assign texture %u uniform.\n", i);
> > +         goto fail;
> > +      }
> > +   }
> > +
> > +   /*
> > +    * Setup the vertex and element buffers for drawing our points.
> > +    */
> > +   glGenVertexArrays(1, &vao);
> > +   glBindVertexArray(vao);
> > +
> > +   if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +      fprintf(stderr, "Unable to create VAO.\n");
> > +      goto fail;
> > +   }
> > +
> > +   setup_vertex_element_buffers();
> > +
> > +   /*
> > +    * Setup the raster state.
> > +    */
> > +   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
> > +   glDrawBuffers(g_maxColorAttachments, colorBuffers);
> > +
> > +   if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +      fprintf(stderr, "Unable to assign draw buffers.\n");
> > +      goto fail;
> > +   }
> > +
> > +   glClearColor(0.0, 1.0, 0.0, 0.0);
> > +   glClear(GL_COLOR_BUFFER_BIT);
> > +
> > +   /*
> > +    * Bind the vertex array and enable each attribute.
> > +    */
> > +   glBindVertexArray(vao);
> > +   attribLoc = glGetAttribLocation(g_program, "InPosition");
> > +   glEnableVertexAttribArray(attribLoc);
> > +
> > +   if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +      fprintf(stderr, "Unable to enable vertex array attribute %u.\n",
> > attribLoc);
> > +      goto fail;
> > +   }
> > +
> > +   /*
> > +    * Enable the rest of the attributes.
> > +    */
> > +   for (i = 0; i < g_maxVertexAttribs - 1; i++) {
> > +      char strTemp[16];
> > +
> > +      snprintf(strTemp, sizeof(strTemp), "InValue%u", i);
> > +      attribLoc = glGetAttribLocation(g_program, strTemp);
> > +      glEnableVertexAttribArray(attribLoc);
> > +
> > +      if (!piglit_check_gl_error(GL_NO_ERROR)) {
> > +         fprintf(stderr, "Unable to enable vertex array attribute %u.\n",
> > attribLoc);
> > +         goto fail;
> > +      }
> > +   }
> > +
> > +#if DRAW_ARRAYS
> > +   glDrawArrays(GL_TRIANGLES, 0, NUM_VERTICES);
> > +#endif
> > +
> > +#if DRAW_ELEMENTS
> > +   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_elementVBO);
> > +   glDrawElements(GL_TRIANGLES, NUM_VERTICES, GL_UNSIGNED_SHORT, 0);
> > +   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
> > +#endif
> > +
> > +   /*
> > +    * Blindly reset all the attributes.
> > +    */
> > +   for (i = 0; i < g_maxVertexAttribs; i++) {
> > +      glDisableVertexAttribArray(i);
> > +   }
> > +
> > +#if DRAW_IMMEDIATE
> > +   glBegin(GL_TRIANGLES);
> > +      glVertex3f(-1.0, -1.0, 0.0);
> > +      glVertex3f(-1.0, 1.0, 0.0);
> > +      glVertex3f(1.0, 1.0, 0.0);
> > +   glEnd();
> > +#endif
> > +
> > +   if (!piglit_check_gl_error(GL_NO_ERROR))
> > +      goto fail;
> > +
> > +   /*
> > +    * Read back the FBO contents.
> > +    */
> > +
> > +   /*
> > +    * Disable color clamping so we don't encounter result
> > +    * collisions attempting to use a normalized color space.
> > +    *
> > +    * Requires OpenGL 3.0
> > +    */
> > +   glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE);
> > +
> > +   for (i = 0; i < g_maxColorAttachments; i++) {
> > +#if DEBUG_READBACK
> > +      printf("GL_READ_FRAMEBUFFER <- fbo=%u\n", fbo);
> > +#endif
> > +
> > +      glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
> > +
> > +      if (!piglit_check_gl_error(GL_NO_ERROR))
> > +         goto fail;
> > +
> > +      glFramebufferTexture2D(GL_READ_FRAMEBUFFER,
> > +                             GL_COLOR_ATTACHMENT0,
> > +                             GL_TEXTURE_2D,
> > +                             fboTextures[i],
> > +                             0);
> > +
> > +      if (!piglit_check_gl_error(GL_NO_ERROR))
> > +         goto fail;
> > +
> > +      glPixelStorei(GL_PACK_ALIGNMENT, 1);
> > +      glReadBuffer(GL_COLOR_ATTACHMENT0);
> > +
> > +      if (!piglit_check_gl_error(GL_NO_ERROR))
> > +         goto fail;
> > +
> > +      glReadPixels(0, BUFFER_HEIGHT - 1,
> > +                   1, 1, GL_RGBA, GL_FLOAT, result);
> > +
> > +      if ((g_expected[(i * MAX_COMPONENTS) + 0] != result[0]) ||
> > +          (g_expected[(i * MAX_COMPONENTS) + 1] != result[1]) ||
> > +          (g_expected[(i * MAX_COMPONENTS) + 2] != result[2]) ||
> > +          (g_expected[(i * MAX_COMPONENTS) + 3] != result[3])) {
> > +         fprintf(stderr, "GL_COLOR_ATTACHMENT%u: expected (%f, %f, %f, %f)
> > != (%f, %f, %f, %f)\n",
> > +                 i, g_expected[(i * MAX_COMPONENTS) + 0],
> > +                 g_expected[(i * MAX_COMPONENTS) + 1],
> > +                 g_expected[(i * MAX_COMPONENTS) + 2],
> > +                 g_expected[(i * MAX_COMPONENTS) + 3],
> > +                 result[0], result[1], result[2], result[3]);
> > +
> > +         goto fail;
> > +      }
> > +   }
> > +
> > +   piglit_present_results();
> > +
> > +   /*
> > +    * Cleanup the allocations.
> > +    */
> > +   free(colorBuffers);
> > +   free(fboTextures);
> > +
> > +   piglit_report_result(PIGLIT_PASS);
> > +
> > +   return PIGLIT_PASS;
> > +
> > +fail:
> > +
> > +   if (colorBuffers)
> > +      free(colorBuffers);
> > +
> > +   if (fboTextures)
> > +      free(fboTextures);
> > +
> > +   piglit_report_result(PIGLIT_FAIL);
> > +
> > +   return PIGLIT_FAIL;
> > +}
> > +
> > +
> > +void
> > +piglit_init(int argc, char **argv)
> > +{
> > +   GLfloat *var;
> > +   PackedDesc vsInput = { "flat in", "InValue", false, 0, &g_vec4Desc };
> > +   PackedDesc vsUniform = { "uniform", "Texture", true, 0,
> > &g_sampler2DDesc };
> > +   PackedDesc vsOutput = { "flat out", "Variable", true, 0, &g_floatDesc
> > };
> > +   PackedDesc fsInput = { "flat in", "Variable", true, 0, &g_floatDesc };
> > +   PackedDesc fsUniform = { "uniform", "Texture", true, 0,
> > &g_sampler2DDesc };
> > +   PackedDesc fsOutput = { NULL, g_fragData, true, 0, &g_rgbaDesc };
> > +   char shaderTempText[MAX_SHADER_LINE_CHARS];
> > +   char *vertexShaderText = g_vertexShaderText;
> > +   char *fragmentShaderText = g_fragmentShaderText;
> > +   int i = 0;
> > +
> > +   piglit_require_gl_version(30);
> > +
> > +   /*
> > +    * Query the sampler capabilities.
> > +    */
> > +   glGetIntegerv(GL_MAX_VARYING_FLOATS, &g_maxVaryingFloats);
> > +   glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &g_maxVertexAttribs);
> > +   glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
> > +                 &g_maxVertexTextureImageUnits);
> > +   glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
> > +                 &g_maxTextureImageUnits);
> > +   glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
> > +                 &g_maxCombinedTextureImageUnits);
> > +
> > +   printf("GL_MAX_VARYING_FLOATS: %d\n", g_maxVaryingFloats);
> > +   printf("GL_MAX_VERTEX_ATTRIBS: %d\n", g_maxVertexAttribs);
> > +   printf("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: %d\n",
> > +          g_maxVertexTextureImageUnits);
> > +   printf("GL_MAX_TEXTURE_IMAGE_UNITS: %d\n",
> > +          g_maxTextureImageUnits);
> > +   printf("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d\n",
> > +          g_maxCombinedTextureImageUnits);
> > +
> > +   /*
> > +    * Query the render target capabilities.
> > +    */
> > +   glGetIntegerv(GL_AUX_BUFFERS, &g_maxAuxBuffers);
> > +   glGetIntegerv(GL_MAX_DRAW_BUFFERS, &g_maxDrawBuffers);
> > +   glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &g_maxColorAttachments);
> > +
> > +   if (g_maxColorAttachments == 1) {
> > +      fsOutput.variableName = g_fragColor;
> > +   }
> > +
> > +   printf("GL_AUX_BUFFERS: %d\n", g_maxAuxBuffers);
> > +   printf("GL_MAX_DRAW_BUFFERS: %d\n", g_maxDrawBuffers);
> > +   printf("GL_MAX_COLOR_ATTACHMENTS: %d\n", g_maxColorAttachments);
> > +
> > +   if ((g_maxColorAttachments * MAX_COMPONENTS > NUM_PRIMES) ||
> > +       (g_maxVaryingFloats > NUM_PRIMES) ||
> > +       (g_maxVertexAttribs * MAX_COMPONENTS > NUM_PRIMES) ||
> > +       (g_maxVertexTextureImageUnits * MAX_COMPONENTS > NUM_PRIMES) ||
> > +       (g_maxTextureImageUnits * MAX_COMPONENTS > NUM_PRIMES)) {
> > +      fprintf(stderr, "Unable to uniquely represent a result path\n.");
> > +      piglit_report_result(PIGLIT_SKIP);
> > +   }
> > +
> > +   /*
> > +    * Build the shaders based upon the queried limits.
> > +    */
> > +   vsInput.count = g_maxVertexAttribs - 1;
> > +   vsUniform.count = g_maxVertexTextureImageUnits;
> > +   vsOutput.count = g_maxVaryingFloats;
> > +   if (!build_reduce_glsl_shader(&vertexShaderText,
> > +                                 &vsInput,
> > +                                 &vsUniform,
> > +                                 &vsOutput,
> > +                                 "gl_Position",
> > +                                 "in vec4 InPosition;",
> > +                                 "InPosition")) {
> > +      fprintf(stderr, "Failed to build GLSL vertex shader\n");
> > +      piglit_report_result(PIGLIT_SKIP);
> > +   }
> > +
> > +#if DEBUG_SHADERS
> > +   printf("g_vertexShaderText:\n%s", g_vertexShaderText);
> > +#endif
> > +
> > +   fsInput.count = g_maxVaryingFloats;
> > +   fsUniform.count = g_maxTextureImageUnits;
> > +   fsOutput.count = g_maxColorAttachments;
> > +   if (!build_reduce_glsl_shader(&fragmentShaderText,
> > +                                 &fsInput,
> > +                                 &fsUniform,
> > +                                 &fsOutput,
> > +                                 NULL,
> > +                                 NULL,
> > +                                 NULL)) {
> > +      fprintf(stderr, "Failed to build GLSL vertex shader\n");
> > +      piglit_report_result(PIGLIT_SKIP);
> > +   }
> > +
> > +#if DEBUG_SHADERS
> > +   printf("g_fragmentShaderText:\n%s", g_fragmentShaderText);
> > +#endif
> > +
> > +   /*
> > +    * Build the vertex and fragment shaders.
> > +    */
> > +   g_program = piglit_build_simple_program(vertexShaderText,
> > +                                           fragmentShaderText);
> > +   if (!g_program) {
> > +      fprintf(stderr, "Failed to compile/link program\n");
> > +      piglit_report_result(PIGLIT_SKIP);
> > +   }
> > +
> > +   snprintf(shaderTempText, sizeof(shaderTempText), "InPosition");
> > +   glBindAttribLocation(g_program, 0, shaderTempText);
> > +
> > +   for (i = 0; i < g_maxVertexAttribs - 1; i++) {
> > +      snprintf(shaderTempText, sizeof(shaderTempText), "InValue%u", i);
> > +      glBindAttribLocation(g_program, i+1, shaderTempText);
> > +   }
> > +
> > +#if DEBUG_SHADERS
> > +   printf("Linking program...\n");
> > +#endif
> > +
> > +   glLinkProgram(g_program);
> > +   glUseProgram(g_program);
> > +
> > +#if DEBUG_SHADERS
> > +   printf("Using program %u...\n", g_program);
> > +#endif
> > +
> > +   /* Delete the interim copies generated by build_reduce_glsl_shader */
> > +   free(vertexShaderText);
> > +   free(fragmentShaderText);
> > +
> > +   /*
> > +    * Calculate the expected results for the bound resource limits.
> > +    */
> > +   var = calloc(g_maxVaryingFloats, sizeof(GLfloat));
> > +
> > +   if (NULL == var) {
> > +      fprintf(stderr, "Failed to allocate temporary array for expected
> > calculation.\n");
> > +      piglit_report_result(PIGLIT_FAIL);
> > +   }
> > +
> > +   g_expected = calloc(g_maxColorAttachments,
> > sizeof(GLfloat)*MAX_COMPONENTS);
> > +
> > +   if (NULL == g_expected) {
> > +      fprintf(stderr, "Failed to allocate array for expected
> > calculation.\n");
> > +      piglit_report_result(PIGLIT_FAIL);
> > +   }
> > +
> > +   /*
> > +    * Sampler cover up to the total number of varying floats.
> > +    */
> > +   for (i = 0; i < g_maxVaryingFloats; i++) {
> > +      if ((i < g_maxVertexTextureImageUnits*MAX_COMPONENTS) &&
> > +          (i < NUM_PRIMES)) {
> > +         var[i] = g_primes[i];
> > +      } else {
> > +         var[i] = 1.0;
> > +      }
> > +   }
> > +
> > +   /*
> > +    * Multiply in all vertex attributes.
> > +    */
> > +   i = 0;
> > +   while (i < (g_maxVertexAttribs-1)*MAX_COMPONENTS) {
> > +      if (i < NUM_PRIMES) {
> > +         var[i % g_maxVaryingFloats] *= g_primes[i];
> > +      } else {
> > +         var[i % g_maxVaryingFloats] *= 1.0;
> > +      }
> > +      i++;
> > +   }
> > +
> > +   /*
> > +    * Calculate the expected values for the FS stage.
> > +    *
> > +    * Sampler cover up to the total number of varying floats.
> > +    */
> > +   for (i = 0; i < g_maxColorAttachments*MAX_COMPONENTS; i++) {
> > +      if ((i < g_maxVertexTextureImageUnits*MAX_COMPONENTS) &&
> > +          (i < NUM_PRIMES)) {
> > +         g_expected[i] = g_primes[i];
> > +      } else {
> > +         g_expected[i] = 1.0;
> > +      }
> > +   }
> > +
> > +   /*
> > +    * Multiply in all the varying contributions generated by the VS.
> > +    */
> > +   i = 0;
> > +   while (i < g_maxVaryingFloats) {
> > +      g_expected[i % (g_maxColorAttachments*MAX_COMPONENTS)] *= var[i];
> > +      i++;
> > +   }
> > +
> > +   for (i = 0; i < g_maxColorAttachments; i++) {
> > +      printf("g_expected[%u]=(%f, %f, %f, %f)\n", i,
> > +             g_expected[(i * MAX_COMPONENTS) + 0],
> > +             g_expected[(i * MAX_COMPONENTS) + 1],
> > +             g_expected[(i * MAX_COMPONENTS) + 2],
> > +             g_expected[(i * MAX_COMPONENTS) + 3]);
> > +   }
> > +
> > +   free(var);
> > +
> > +   if (!piglit_check_gl_error(GL_NO_ERROR))
> > +      piglit_report_result(PIGLIT_FAIL);
> > +}
> >
> 
> The code generally looks good, but is a bit dense.  It would take me a
> while to understand the intricacies.
> 
> In any case, when I tested it with my nvidia driver I got a failure:
> 
> $ bin/gl-3.0-bound-resource-limits -auto
> GL_MAX_VARYING_FLOATS: 124
> GL_MAX_VERTEX_ATTRIBS: 16
> GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 32
> GL_MAX_TEXTURE_IMAGE_UNITS: 32
> GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 192
> GL_AUX_BUFFERS: 4
> GL_MAX_DRAW_BUFFERS: 8
> GL_MAX_COLOR_ATTACHMENTS: 8
> Failed to link: Fragment info
> -------------
> 0(8) : warning C7533: global variable gl_FragData is deprecated after
> version 120
> 0(2) : error C5041: cannot locate suitable resource to bind variable
> "Variable". Possibly large array.
> 
> PIGLIT: {"result": "fail" }
> 
> 
> And with softpipe/llvmpipe I see a different failure:
> 
> $ bin/gl-3.0-bound-resource-limits -auto
> GL_MAX_VARYING_FLOATS: 128
> GL_MAX_VERTEX_ATTRIBS: 16
> GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 16
> GL_MAX_TEXTURE_IMAGE_UNITS: 16
> GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 48
> GL_AUX_BUFFERS: 0
> GL_MAX_DRAW_BUFFERS: 8
> GL_MAX_COLOR_ATTACHMENTS: 8
> Failed to compile vertex shader: 0:3(1): error: interpolation qualifier
> `flat' cannot be applied to vertex shader inputs or fragment shader outputs
> 0:3(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:4(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:4(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:5(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:5(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:6(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:6(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:7(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:7(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:8(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:8(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:9(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:9(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:10(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:10(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:11(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:11(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:12(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:12(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:13(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:13(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:14(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:14(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:15(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:15(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:16(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:16(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 0:17(1): error: interpolation qualifier `flat' cannot be applied to
> vertex shader inputs or fragment shader outputs
> 0:17(1): error: qualifier 'flat' cannot be applied to vertex shader inputs
> 
> source:
> #version 130
> in vec4 InPosition;
> flat in vec4 InValue0;
> flat in vec4 InValue1;
> flat in vec4 InValue2;
> flat in vec4 InValue3;
> flat in vec4 InValue4;
> flat in vec4 InValue5;
> flat in vec4 InValue6;
> flat in vec4 InValue7;
> flat in vec4 InValue8;
> flat in vec4 InValue9;
> flat in vec4 InValue10;
> flat in vec4 InValue11;
> flat in vec4 InValue12;
> flat in vec4 InValue13;
> flat in vec4 InValue14;
> uniform sampler2D Texture[16];
> flat out float Variable[128];
> void main()
> {
>    vec4 texel;
>    texel = texture2D(Texture[0], vec2(0.0, 0.0));
>    Variable[0] = texel.x * InValue0.x;
>    Variable[1] = texel.y * InValue0.y;
>    Variable[2] = texel.z * InValue0.z;
>    Variable[3] = texel.w * InValue0.w;
>    texel = texture2D(Texture[1], vec2(0.0, 0.0));
>    Variable[4] = texel.x * InValue1.x;
>    Variable[5] = texel.y * InValue1.y;
>    Variable[6] = texel.z * InValue1.z;
>    Variable[7] = texel.w * InValue1.w;
>    texel = texture2D(Texture[2], vec2(0.0, 0.0));
>    Variable[8] = texel.x * InValue2.x;
>    Variable[9] = texel.y * InValue2.y;
>    Variable[10] = texel.z * InValue2.z;
>    Variable[11] = texel.w * InValue2.w;
>    texel = texture2D(Texture[3], vec2(0.0, 0.0));
>    Variable[12] = texel.x * InValue3.x;
>    Variable[13] = texel.y * InValue3.y;
>    Variable[14] = texel.z * InValue3.z;
>    Variable[15] = texel.w * InValue3.w;
>    texel = texture2D(Texture[4], vec2(0.0, 0.0));
>    Variable[16] = texel.x * InValue4.x;
>    Variable[17] = texel.y * InValue4.y;
>    Variable[18] = texel.z * InValue4.z;
>    Variable[19] = texel.w * InValue4.w;
>    texel = texture2D(Texture[5], vec2(0.0, 0.0));
>    Variable[20] = texel.x * InValue5.x;
>    Variable[21] = texel.y * InValue5.y;
>    Variable[22] = texel.z * InValue5.z;
>    Variable[23] = texel.w * InValue5.w;
>    texel = texture2D(Texture[6], vec2(0.0, 0.0));
>    Variable[24] = texel.x * InValue6.x;
>    Variable[25] = texel.y * InValue6.y;
>    Variable[26] = texel.z * InValue6.z;
>    Variable[27] = texel.w * InValue6.w;
>    texel = texture2D(Texture[7], vec2(0.0, 0.0));
>    Variable[28] = texel.x * InValue7.x;
>    Variable[29] = texel.y * InValue7.y;
>    Variable[30] = texel.z * InValue7.z;
>    Variable[31] = texel.w * InValue7.w;
>    texel = texture2D(Texture[8], vec2(0.0, 0.0));
>    Variable[32] = texel.x * InValue8.x;
>    Variable[33] = texel.y * InValue8.y;
>    Variable[34] = texel.z * InValue8.z;
>    Variable[35] = texel.w * InValue8.w;
>    texel = texture2D(Texture[9], vec2(0.0, 0.0));
>    Variable[36] = texel.x * InValue9.x;
>    Variable[37] = texel.y * InValue9.y;
>    Variable[38] = texel.z * InValue9.z;
>    Variable[39] = texel.w * InValue9.w;
>    texel = texture2D(Texture[10], vec2(0.0, 0.0));
>    Variable[40] = texel.x * InValue10.x;
>    Variable[41] = texel.y * InValue10.y;
>    Variable[42] = texel.z * InValue10.z;
>    Variable[43] = texel.w * InValue10.w;
>    texel = texture2D(Texture[11], vec2(0.0, 0.0));
>    Variable[44] = texel.x * InValue11.x;
>    Variable[45] = texel.y * InValue11.y;
>    Variable[46] = texel.z * InValue11.z;
>    Variable[47] = texel.w * InValue11.w;
>    texel = texture2D(Texture[12], vec2(0.0, 0.0));
>    Variable[48] = texel.x * InValue12.x;
>    Variable[49] = texel.y * InValue12.y;
>    Variable[50] = texel.z * InValue12.z;
>    Variable[51] = texel.w * InValue12.w;
>    texel = texture2D(Texture[13], vec2(0.0, 0.0));
>    Variable[52] = texel.x * InValue13.x;
>    Variable[53] = texel.y * InValue13.y;
>    Variable[54] = texel.z * InValue13.z;
>    Variable[55] = texel.w * InValue13.w;
>    texel = texture2D(Texture[14], vec2(0.0, 0.0));
>    Variable[56] = texel.x * InValue14.x;
>    Variable[57] = texel.y * InValue14.y;
>    Variable[58] = texel.z * InValue14.z;
>    Variable[59] = texel.w * InValue14.w;
>    texel = texture2D(Texture[15], vec2(0.0, 0.0));
>    Variable[60] = texel.x * 1.0;
>    Variable[61] = texel.y * 1.0;
>    Variable[62] = texel.z * 1.0;
>    Variable[63] = texel.w * 1.0;
>    Variable[64] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[65] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[66] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[67] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[68] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[69] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[70] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[71] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[72] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[73] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[74] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[75] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[76] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[77] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[78] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[79] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[80] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[81] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[82] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[83] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[84] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[85] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[86] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[87] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[88] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[89] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[90] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[91] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[92] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[93] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[94] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[95] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[96] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[97] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[98] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[99] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[100] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[101] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[102] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[103] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[104] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[105] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[106] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[107] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[108] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[109] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[110] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[111] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[112] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[113] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[114] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[115] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[116] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[117] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[118] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[119] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[120] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[121] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[122] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[123] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[124] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[125] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[126] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    Variable[127] = vec4(1.0, 1.0, 1.0, 1.0).x * 1.0;
>    gl_Position = InPosition;
> }
> PIGLIT: {"result": "fail" }
> 
> 
> Which driver(s) are you using and what results do you get?
> 
> -Brian
> 


More information about the Piglit mailing list