[1/2] Ported the glsl1 test from Glean to Piglit.

Submitted by Laura Ekstrand on Oct. 14, 2014, 1:12 a.m.

Details

Message ID 1413249154-18700-1-git-send-email-laura@jlekstrand.net
State New
Headers show

Not browsing as part of any series.

Commit Message

Laura Ekstrand Oct. 14, 2014, 1:12 a.m.
---
 tests/all.py                                     |    1 +
 tests/spec/glsl-1.10/execution/CMakeLists.gl.txt |    1 +
 tests/spec/glsl-1.10/execution/glean-glsl1.c     | 2104 ++++++++++++++++++++++
 3 files changed, 2106 insertions(+)
 create mode 100644 tests/spec/glsl-1.10/execution/glean-glsl1.c

Patch hide | download patch | download mbox

diff --git a/tests/all.py b/tests/all.py
index 831af29..ca6639c 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -1038,6 +1038,7 @@  add_shader_test_dir(spec['glsl-1.10']['execution'],
                     recursive=True)
 add_concurrent_test(spec['glsl-1.10']['execution'], 'glsl-render-after-bad-attach')
 add_concurrent_test(spec['glsl-1.10']['execution'], 'glsl-1.10-fragdepth')
+add_concurrent_test(spec['glsl-1.10']['execution'], 'glsl-1.10-glean')
 spec['glsl-1.10']['execution']['clipping'] = {}
 for mode in ['fixed', 'pos_clipvert', 'clipvert_pos']:
     cmdline = 'clip-plane-transformation ' + mode
diff --git a/tests/spec/glsl-1.10/execution/CMakeLists.gl.txt b/tests/spec/glsl-1.10/execution/CMakeLists.gl.txt
index 0ddc221..328425e 100644
--- a/tests/spec/glsl-1.10/execution/CMakeLists.gl.txt
+++ b/tests/spec/glsl-1.10/execution/CMakeLists.gl.txt
@@ -13,3 +13,4 @@  link_libraries (
 
 piglit_add_executable (glsl-render-after-bad-attach glsl-render-after-bad-attach.c)
 piglit_add_executable (glsl-1.10-fragdepth fragdepth.c)
+piglit_add_executable (glsl-1.10-glean glean-glsl1.c)
diff --git a/tests/spec/glsl-1.10/execution/glean-glsl1.c b/tests/spec/glsl-1.10/execution/glean-glsl1.c
new file mode 100644
index 0000000..67b8f81
--- /dev/null
+++ b/tests/spec/glsl-1.10/execution/glean-glsl1.c
@@ -0,0 +1,2104 @@ 
+/*
+ * BEGIN_COPYRIGHT -*- glean -*-
+ * 
+ * Copyright (C) 1999  Allen Akin   All Rights Reserved.
+ * Copyright (C) 2008  VMware, Inc.  All Rights Reserved.
+ * 
+ * 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 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 ALLEN AKIN 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.
+ * 
+ * END_COPYRIGHT
+ */
+
+/*
+ * Copyright 2014 Intel Corporation
+ *
+ * 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.
+ */
+
+/**
+ * tglsl1.h:  Test OpenGL basic shading language functionality.
+ * Brian Paul  6 March 2007
+ * Ported to Piglit by Laura Ekstrand, 7 October 2014
+ */
+
+#define GL_GLEXT_PROTOTYPES
+
+#include "piglit-util-gl.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#define ELEMENTS(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
+
+#define FLAG_NONE             0x0
+#define FLAG_LOOSE            0x1   /* to indicate a looser tolerance test is needed */
+#define FLAG_ILLEGAL_SHADER   0x2   /* the shader test should not compile */
+#define FLAG_ILLEGAL_LINK     0x4   /* the shaders should not link */
+#define FLAG_VERSION_1_20     0x8   /* GLSL 1.20 test */
+#define FLAG_VERSION_1_30     0x10  /* GLSL 1.30 test */
+#define FLAG_VERTEX_TEXTURE   0x40
+#define FLAG_ARB_DRAW_BUFFERS 0x80
+
+#define DONT_CARE_Z -1.0
+
+#define NO_VERTEX_SHADER NULL
+#define NO_FRAGMENT_SHADER NULL
+
+#define PRIMARY_R 0.25
+#define PRIMARY_G 0.75
+#define PRIMARY_B 0.5
+#define PRIMARY_A 0.25
+#define SECONDARY_R 0.0
+#define SECONDARY_G 0.25
+#define SECONDARY_B 0.25
+#define SECONDARY_A 1.0
+
+#define AMBIENT { 0.2, 0.4, 0.6, 0.8 }
+#define LIGHT_DIFFUSE { 0.1, 0.3, 0.5, 0.7 }
+#define MAT_DIFFUSE { 0.1, 0.3, 0.5, 0.7 }
+#define DIFFUSE_PRODUCT { 0.01, 0.09, 0.25, 0.7 } /* note alpha! */
+
+#define UNIFORM1 {1.0, 0.25, 0.75, 0.0 }  /* don't change! */
+
+#define PSIZE 3.0
+#define PSIZE_MIN 2.0
+#define PSIZE_MAX 8.0
+#define PSIZE_THRESH 1.5
+#define PSIZE_ATTEN0 4.0
+#define PSIZE_ATTEN1 5.0
+#define PSIZE_ATTEN2 6.0
+
+#define FOG_START 100.0
+#define FOG_END   200.0
+#define FOG_R 1.0
+#define FOG_G 0.5
+#define FOG_B 1.0
+#define FOG_A 0.0
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+
+	config.window_width = 100;
+	config.window_height = 100;
+
+	config.window_visual = PIGLIT_GL_VISUAL_RGBA | 
+		PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_DEPTH;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+
+bool glsl_120;   /* GLSL 1.20 or higher supported? */
+bool glsl_130;   /* GLSL 1.30 or higher supported? */
+
+struct ShaderProgram {
+	const char *name;
+	const char *vertShaderString;
+	const char *fragShaderString;
+	GLfloat expectedColor[4];
+	GLfloat expectedZ;
+	int flags;
+};
+
+static const GLfloat PrimaryColor[4] = { PRIMARY_R, PRIMARY_G,
+					 PRIMARY_B, PRIMARY_A };
+static const GLfloat SecondaryColor[4] = { SECONDARY_R, SECONDARY_G,
+					   SECONDARY_B, SECONDARY_A };
+
+static const GLfloat Ambient[4] = AMBIENT;
+static const GLfloat MatDiffuse[4] = MAT_DIFFUSE;
+static const GLfloat LightDiffuse[4] = LIGHT_DIFFUSE;
+
+static const GLfloat Uniform1[4] = UNIFORM1;
+static const GLfloat UniformArray[4] = { 0.1, 0.25, 0.5, 0.75 };
+static const GLfloat UniformArray4[4][4] = {
+   { 0.1, 0.2, 0.3, 0.4 },
+   { 0.9, 0.8, 0.7, 0.6 },
+   { 0.5, 0.6, 0.7, 0.5 },
+   { 0.3, 0.4, 0.5, 0.6 }
+};
+
+static const GLfloat PointAtten[3] = { PSIZE_ATTEN0, PSIZE_ATTEN1, PSIZE_ATTEN2 };
+static const GLfloat FogColor[4] = { FOG_R, FOG_G, FOG_B, FOG_A };
+
+/* Shader program test cases */
+static const struct ShaderProgram Programs[] = {
+	/* Simple tests ======================================================= */
+	{
+		"Primary plus secondary color",
+		/* vert shader: */
+		"void main() { \n"
+		"   gl_Position = ftransform(); \n"
+		"   gl_FrontColor = gl_Color + gl_SecondaryColor; \n"
+		"} \n",
+		/* frag shader: */
+		"void main() { \n"
+		"   gl_FragColor = gl_Color; \n"
+		"} \n",
+		{ PRIMARY_R + SECONDARY_R,
+		  PRIMARY_G + SECONDARY_G,
+		  PRIMARY_B + SECONDARY_B,
+		  1.0 /*PRIMARY_A + SECONDARY_A*/ },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Global vars and initializers",
+		NO_VERTEX_SHADER,
+		"vec4 c = vec4(1.0, 0.5, 0.25, 0.0); \n"
+		"void main() { \n"
+		"   gl_FragColor = c; \n"
+		"} \n",
+		{ 1.0, 0.5, 0.25, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Global vars and initializers (2)",
+		NO_VERTEX_SHADER,
+		"vec4 c1 = vec4(0.4, 0.5, 0.25, 0.0); \n"
+		"vec4 c2 = vec4(0.3, 0.5, 0.5,  0.4); \n"
+		"vec4 c3 = c1 + c2; \n"
+		"void main() { \n"
+		"   gl_FragColor = c3; \n"
+		"} \n",
+		{ 0.7, 1.0, 0.75, 0.4 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Swizzle, writemask ================================================= */
+	{
+		"Swizzle",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 a = vec4(0.5,  0.25, 0.0, 1.0); \n"
+		"   gl_FragColor = a.yxxz; \n"
+		"} \n",
+		{ 0.25, 0.5, 0.5, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzle (rgba)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 a = vec4(0.5,  0.25, 0.0, 1.0); \n"
+		"   gl_FragColor = a.grrb; \n"
+		"} \n",
+		{ 0.25, 0.5, 0.5, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzle (stpq)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 a = vec4(0.5,  0.25, 0.0, 1.0); \n"
+		"   gl_FragColor = a.tssp; \n"
+		"} \n",
+		{ 0.25, 0.5, 0.5, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Writemask",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor = vec4(1.0); \n"
+		"   gl_FragColor.x = 0.5; \n"
+		"   gl_FragColor.z = 0.25; \n"
+		"} \n",
+		{ 0.5, 1.0, 0.25, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzled writemask",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor.zwxy = vec4(1.0, 0.5, 0.25, 0.75); \n"
+		"} \n",
+		{ 0.25, 0.75, 1.0, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzled writemask (2)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor.zy = vec2(1.0, 0.5); \n"
+		"   gl_FragColor.wx = vec2(0.25, 0.75); \n"
+		"} \n",
+		{ 0.75, 0.5, 1.0, 0.25 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzled writemask (rgba)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor.bg = vec2(1.0, 0.5); \n"
+		"   gl_FragColor.ar = vec2(0.25, 0.75); \n"
+		"} \n",
+		{ 0.75, 0.5, 1.0, 0.25 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzled writemask (stpq)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor.pt = vec2(1.0, 0.5); \n"
+		"   gl_FragColor.qs = vec2(0.25, 0.75); \n"
+		"} \n",
+		{ 0.75, 0.5, 1.0, 0.25 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzled expression",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 a = vec4(1, 1, 1, 1); \n"
+		"   vec4 b = vec4(0.5, 0.2, 0.1, 0.8); \n"
+		"   vec4 c = (a * b).wzyx; \n"
+		"   gl_FragColor = c; \n"
+		"} \n",
+		{ 0.8, 0.1, 0.2, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		/*
+		 * This test targets SOA implementations where we have to
+		 * check for SOA dependencies.
+		 */
+		"Swizzle in-place",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 a = vec4(0.5, 0.2, 0.1, 0.8); \n"
+		"   a = a.yxwz; \n"
+		"   gl_FragColor = a; \n"
+		"} \n",
+		{ 0.2, 0.5, 0.8, 0.1 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzled swizzle",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 a = vec4(0.1, 0.2, 0.3, 0.4); \n"
+		"   vec4 b = a.wzyx.yxwz; \n"
+		"   gl_FragColor = b; \n"
+		"} \n",
+		{ 0.3, 0.4, 0.1, 0.2 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Swizzled swizzled swizzle",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 a = vec4(0.1, 0.2, 0.3, 0.4); \n"
+		"   vec4 b = a.wzyx.yxwz.xxyz; \n"
+		"   gl_FragColor = b; \n"
+		"} \n",
+		{ 0.3, 0.3, 0.4, 0.1 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+
+	/* Z-write ============================================================ */
+	/* This is the ONLY test that tests depth. */
+	{
+		"gl_FragDepth writing",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"   gl_FragDepth = 0.25; \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		0.25,  /* Z value */
+		FLAG_NONE
+	},
+
+	/* Basic arithmetic =================================================== */
+	{
+		"chained assignment",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   float x, y, z; \n"
+		"   x = y = z = 0.25; \n"
+		"   gl_FragColor = vec4(x + y + z); \n"
+		"} \n",
+		{ 0.75, 0.75, 0.75, 0.75 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* built-in functions ================================================ */
+	{
+		/* This is a Mesa regression test (bump.c) */
+		"cross() function, in-place",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec3 u,v ; \n"
+		"   u.x = 0.8; \n"
+		"   u.y = -0.5; \n"
+		"   u.z = 1.0; \n"
+		"   v.x = 0.1; \n"
+		"   v.y = 0.5; \n"
+		"   v.z = -2.0; \n"
+		"   u = cross(u, v); \n"
+		"   gl_FragColor.xyz = u; \n"
+		"   gl_FragColor.w = 1.0; \n"
+		"} \n",
+		{ 0.502, 1.0, 0.4509, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Flow Control ====================================================== */
+	{
+		"sequence (comma) operator",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   float x, y, z; \n"
+		"   x = 1.0, y = 0.5, z = x * y; \n"
+		"   gl_FragColor = vec4(z); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Logical operators ================================================= */
+	{
+		"&& operator, short-circuit",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   float x = 0.75; \n"
+		"   // this should always be false \n"
+		"   if (x <= 0.5 && ++x > 0.0) { \n"
+		"      x += 0.1; \n"
+		"   } \n"
+		"   gl_FragColor = vec4(x); \n"
+		"} \n",
+		{ 0.75, 0.75, 0.75, 0.75 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"|| operator, short-circuit",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   float x = 0.75; \n"
+		"   // this should always be true \n"
+		"   if (x >= 0.5 || ++x >= 0.0) { \n"
+		"      x += 0.1; \n"
+		"   } \n"
+		"   gl_FragColor = vec4(x); \n"
+		"} \n",
+		{ 0.85, 0.85, 0.85, 0.85 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* GL state refs ===================================================== */
+	{
+		"GL state variable reference (gl_FrontMaterial.ambient)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor = gl_FrontMaterial.ambient; \n"
+		"} \n",
+		AMBIENT,
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+	{
+		"GL state variable reference (gl_LightSource[0].diffuse)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor = gl_LightSource[0].diffuse; \n"
+		"} \n",
+		LIGHT_DIFFUSE,
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"GL state variable reference (diffuse product)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   gl_FragColor = gl_FrontLightProduct[0].diffuse; \n"
+		"} \n",
+		DIFFUSE_PRODUCT,
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"GL state variable reference (point size)",
+		"void main() { \n"
+		"   gl_Position = ftransform(); \n"
+		"   gl_FrontColor.x = gl_Point.size * 0.1; \n"
+		"   gl_FrontColor.y = gl_Point.sizeMin * 0.1; \n"
+		"   gl_FrontColor.z = gl_Point.sizeMax * 0.1; \n"
+		"   gl_FrontColor.w = 0.0; \n"
+		"} \n",
+		NO_FRAGMENT_SHADER,
+		{ PSIZE * 0.1, PSIZE_MIN * 0.1, PSIZE_MAX * 0.1, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"GL state variable reference (point attenuation)",
+		"void main() { \n"
+		"   gl_Position = ftransform(); \n"
+		"   gl_FrontColor.x = gl_Point.distanceConstantAttenuation * 0.1; \n"
+		"   gl_FrontColor.y = gl_Point.distanceLinearAttenuation * 0.1; \n"
+		"   gl_FrontColor.z = gl_Point.distanceQuadraticAttenuation * 0.1; \n"
+		"   gl_FrontColor.w = 0.0; \n"
+		"} \n",
+		NO_FRAGMENT_SHADER,
+		{ PSIZE_ATTEN0 * 0.1, PSIZE_ATTEN1 * 0.1,
+		  PSIZE_ATTEN2 * 0.1, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"linear fog",
+		/* vertex prog: */
+		"void main() { \n"
+		"   gl_Position = ftransform(); \n"
+		"   gl_FogFragCoord = 125.0; \n"
+		"   gl_FrontColor = gl_Color; \n"
+		"} \n",
+		/* fragment prog: */
+		"void main() { \n"
+		"   float bf = (gl_FogFragCoord - gl_Fog.start) * gl_Fog.scale; \n"
+		"   gl_FragColor = mix(gl_Color, gl_Fog.color, bf); \n"
+		"} \n",
+#define BF (125.0 - FOG_START) / (FOG_END - FOG_START)  /* Blend Factor */
+		{ PRIMARY_R + BF * (FOG_R - PRIMARY_R),
+		  PRIMARY_G + BF * (FOG_G - PRIMARY_G),
+		  PRIMARY_B + BF * (FOG_B - PRIMARY_B),
+		  PRIMARY_A + BF * (FOG_A - PRIMARY_A) },
+#undef BF
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"built-in constants",
+		/* vertex shader: */
+		"void main() { \n"
+		"   gl_Position = ftransform(); \n"
+		"   // front color values should all be >= 1.0 \n"
+		"   gl_FrontColor = vec4(gl_MaxLights, gl_MaxClipPlanes,\n"
+		"        		gl_MaxTextureUnits, \n"
+		"        		gl_MaxTextureCoords); \n"
+		"} \n",
+		NO_FRAGMENT_SHADER,
+		{ 1.0, 1.0, 1.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Texture functions ================================================== */
+	{
+		"texture2D()",
+		NO_VERTEX_SHADER,
+		"uniform sampler2D tex2d; \n"
+		"void main() { \n"
+		"   gl_FragColor = texture2D(tex2d, gl_TexCoord[0].xy);\n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"texture2D(), computed coordinate",
+		NO_VERTEX_SHADER,
+		"uniform sampler2D tex2d; \n"
+		"void main() { \n"
+		"   vec2 coord = gl_TexCoord[0].xy + vec2(0.5); \n"
+		"   gl_FragColor = texture2D(tex2d, coord, 0.0); \n"
+		"} \n",
+		{ 1.0, 1.0, 1.0, 1.0 },  /* upper-right tex color */
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"texture2D(), with bias",
+		NO_VERTEX_SHADER,
+		"uniform sampler2D tex2d; \n"
+		"void main() { \n"
+		"   gl_FragColor = texture2D(tex2d, gl_TexCoord[0].xy, 1.0);\n"
+		"} \n",
+		{ 0.5, 0.0, 0.0, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"2D Texture lookup with explicit lod (Vertex shader)",
+		"uniform sampler2D tex2d; \n"
+		"void main() { \n"
+		"   gl_FrontColor = texture2DLod(tex2d, gl_MultiTexCoord0.xy, 2.0);\n"
+		"   gl_Position = ftransform(); \n"
+		"} \n",
+		NO_FRAGMENT_SHADER,
+		{ 0.25, 0.0, 0.0, 0.25 },
+		DONT_CARE_Z,
+		FLAG_VERTEX_TEXTURE
+	},
+
+	{
+		"texture2DProj()",
+		NO_VERTEX_SHADER,
+		"uniform sampler2D tex2d; \n"
+		"void main() { \n"
+		"   vec4 coord = gl_TexCoord[0] * vec4(2.25); \n"
+		"   // 'proj' will divide components by w (=2.25) \n"
+		"   gl_FragColor = texture2DProj(tex2d, coord);\n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"texture1D()",
+		NO_VERTEX_SHADER,
+		"uniform sampler1D tex1d; \n"
+		"void main() { \n"
+		"   gl_FragColor = texture1D(tex1d, gl_TexCoord[0].x);\n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"texture3D()",
+		NO_VERTEX_SHADER,
+		"uniform sampler3D tex3d; \n"
+		"void main() { \n"
+		"   gl_FragColor = texture3D(tex3d, gl_TexCoord[0].xyz);\n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"texture3D(), computed coord",
+		NO_VERTEX_SHADER,
+		"uniform sampler3D tex3d; \n"
+		"void main() { \n"
+		"   vec3 coord = gl_TexCoord[0].xyz; \n"
+		"   coord.y = 0.75; \n"
+		"   coord.z = 0.75; \n"
+		"   gl_FragColor = texture3D(tex3d, coord); \n"
+		"} \n",
+		{ 0.0, 0.0, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"shadow2D(): 1",
+		NO_VERTEX_SHADER,
+		"uniform sampler2DShadow texZ; \n"
+		"void main() { \n"
+		"   vec3 coord = vec3(0.1, 0.1, 0.5); \n"
+		"   // shadow map value should be 0.25 \n"
+		"   gl_FragColor = shadow2D(texZ, coord) + vec4(0.25); \n"
+		"   // color = (0.5 <= 0.25) ? 1.25 : 0.25\n"
+		"} \n",
+		{ 0.25, 0.25, 0.25, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"shadow2D(): 2",
+		NO_VERTEX_SHADER,
+		"uniform sampler2DShadow texZ; \n"
+		"void main() { \n"
+		"   vec3 coord = vec3(0.1, 0.1, 0.2); \n"
+		"   // shadow map value should be 0.25 \n"
+		"   gl_FragColor = shadow2D(texZ, coord); \n"
+		"   // color = (0.2 <= 0.25) ? 1 : 0\n"
+		"} \n",
+		{ 1.0, 1.0, 1.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"shadow2D(): 3",
+		NO_VERTEX_SHADER,
+		"uniform sampler2DShadow texZ; \n"
+		"void main() { \n"
+		"   vec3 coord = vec3(0.9, 0.9, 0.95); \n"
+		"   // shadow map value should be 0.75 \n"
+		"   gl_FragColor = shadow2D(texZ, coord) + vec4(0.25); \n"
+		"   // color = (0.95 <= 0.75) ? 1.25 : 0.25\n"
+		"} \n",
+		{ 0.25, 0.25, 0.25, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"shadow2D(): 4",
+		NO_VERTEX_SHADER,
+		"uniform sampler2DShadow texZ; \n"
+		"void main() { \n"
+		"   vec3 coord = vec3(0.9, 0.9, 0.65); \n"
+		"   // shadow map value should be 0.75 \n"
+		"   gl_FragColor = shadow2D(texZ, coord); \n"
+		"   // color = (0.65 <= 0.75) ? 1 : 0\n"
+		"} \n",
+		{ 1.0, 1.0, 1.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Function calls ==================================================== */
+	{
+		"nested function calls (1)",
+		NO_VERTEX_SHADER,
+		"float Half(const in float x) { \n"
+		"   return 0.5 * x; \n"
+		"} \n"
+		"\n"
+		"float square(const in float x) { \n"
+		"   return x * x; \n"
+		"} \n"
+		"\n"
+		"void main() { \n"
+		"   float a = 0.5; \n"
+		"   float b = square(Half(1.0)); \n"
+		"   gl_FragColor = vec4(b); \n"
+		"} \n",
+		{ 0.25, 0.25, 0.25, 0.25 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"nested function calls (2)",
+		NO_VERTEX_SHADER,
+		"float Half(const in float x) { \n"
+		"   return 0.5 * x; \n"
+		"} \n"
+		"\n"
+		"float square_half(const in float x) { \n"
+		"   float y = Half(x); \n"
+		"   return y * y; \n"
+		"} \n"
+		"\n"
+		"void main() { \n"
+		"   float a = 1.0; \n"
+		"   float b = square_half(a); \n"
+		"   gl_FragColor = vec4(b); \n"
+		"} \n",
+		{ 0.25, 0.25, 0.25, 0.25 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"nested function calls (3)",
+		NO_VERTEX_SHADER,
+		"float Half(const in float x) { \n"
+		"   return 0.5 * x; \n"
+		"} \n"
+		"\n"
+		"void main() { \n"
+		"   float a = 0.5; \n"
+		"   float b = Half(Half(a)); \n"
+		"   gl_FragColor = vec4(b); \n"
+		"} \n",
+		{ 0.125, 0.125, 0.125, 0.125 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"TPPStreamCompiler::assignOperands",
+		NO_VERTEX_SHADER,
+		"struct S { \n"
+		"   float f; \n"
+		"}; \n"
+		"\n"
+		"void F(S s) {} \n"
+		"\n"
+		"const S s = S(0.0); \n"
+		"\n"
+		"void F() { \n"
+		"   F(s); \n"
+		"} \n"
+		"\n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); \n"
+		"} \n",
+		{ 0.0, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Matrix tests ====================================================== */
+	{
+		"matrix column check (1)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   mat4 m = gl_TextureMatrix[1]; \n"
+		"   gl_FragColor = m[0]; \n"
+		"} \n",
+		{ 1.0, 0.5, 0.6, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"matrix column check (2)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   mat4 m = gl_TextureMatrix[1]; \n"
+		"   gl_FragColor = m[3]; \n"
+		"} \n",
+		{ 0.1, 0.2, 0.3, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"matrix, vector multiply (1)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   mat4 m = mat4(0.5); // scale by 0.5 \n"
+		"   vec4 color = gl_Color * m; \n"
+		"   gl_FragColor = color; \n"
+		"} \n",
+		{ 0.5 * PRIMARY_R, 0.5 * PRIMARY_G,
+		  0.5 * PRIMARY_B, 0.5 * PRIMARY_A },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"matrix, vector multiply (2)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 color = gl_TextureMatrix[1] * gl_Color; \n"
+		"   gl_FragColor = color; \n"
+		"} \n",
+		{ 0.2745, 0.9255, 0.7294, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"matrix, vector multiply (3)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec4 color = gl_Color * gl_TextureMatrix[1]; \n"
+		"   gl_FragColor = color; \n"
+		"} \n",
+		{ 0.925, 0.925, 0.6999, .5750 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"uniform matrix",
+		NO_VERTEX_SHADER,
+		"uniform mat4 uniformMat4; \n"
+		"void main() { \n"
+		"   gl_FragColor = uniformMat4[3]; \n"
+		"} \n",
+		{ 0.6, 0.7, 0.8, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"uniform matrix, transposed",
+		NO_VERTEX_SHADER,
+		"uniform mat4 uniformMat4t; \n"
+		"void main() { \n"
+		"   gl_FragColor = uniformMat4t[2]; \n"
+		"} \n",
+		{ 0.2, 0.0, 1.0, 0.8 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Struct tests ====================================================== */
+	{
+		"struct (1)",
+		NO_VERTEX_SHADER,
+		"struct s1 { \n"
+		"  float f1; \n"
+		"  vec4 v4; \n"
+		"}; \n"
+		"\n"
+		"void main() { \n"
+		"   s1 a, b; \n"
+		"   a.v4 = vec4(0.25, 0.5, 0.75, 1.0); \n"
+		"   a.f1 = 0.0; \n"
+		"   b = a; \n"
+		"   gl_FragColor = b.v4; \n"
+		"} \n",
+		{ 0.25, 0.5, 0.75, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"struct (2)",
+		NO_VERTEX_SHADER,
+		"struct s1 { \n"
+		"  float f1; \n"
+		"  vec4 v4; \n"
+		"}; \n"
+		"\n"
+		"void main() { \n"
+		"   s1 a[2]; \n"
+		"   a[0].v4 = vec4(0.25, 0.5, 0.75, 1.0); \n"
+		"   a[0].f1 = 0.0; \n"
+		"   a[1] = a[0]; \n"
+		"   gl_FragColor = a[1].v4; \n"
+		"} \n",
+		{ 0.25, 0.5, 0.75, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"struct (3)",
+		NO_VERTEX_SHADER,
+		"struct s1 { \n"
+		"  float f1; \n"
+		"  vec4 v4; \n"
+		"}; \n"
+		"\n"
+		"void main() { \n"
+		"   vec4 scale = vec4(0.5); \n"
+		"   vec4 bias = vec4(0.1); \n"
+		"   s1 a; \n"
+		"   a.v4 = vec4(0.25, 0.5, 0.75, 1.0); \n"
+		"   a.f1 = 0.0; \n"
+		"   gl_FragColor = a.v4 * scale + bias; \n"
+		"} \n",
+		{ 0.225, 0.35, 0.475, 0.6 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"struct (4)",
+		NO_VERTEX_SHADER,
+		"struct s1 { \n"
+		"  float foo; \n"
+		"  vec4 v4; \n"
+		"}; \n"
+		"struct s2 { \n"
+		"  float bar; \n"
+		"  s1 s; \n"
+		"  float baz; \n"
+		"}; \n"
+		"\n"
+		"void main() { \n"
+		"   s2 a; \n"
+		"   a.s.v4 = vec4(0.25, 0.5, 0.75, 1.0); \n"
+		"   a.bar = 0.0; \n"
+		"   a.baz = 0.0; \n"
+		"   a.s.foo = 0.0; \n"
+		"   gl_FragColor = a.s.v4; \n"
+		"} \n",
+		{ 0.25, 0.5, 0.75, 1.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Preprocessor tests ================================================ */
+	{
+		"Preprocessor test 1 (#if 0)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"#if 0 \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(0.3); \n"
+		"#endif \n"
+		"} \n",
+		{ 0.3, 0.3, 0.3, 0.3 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 2 (#if 1)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"#if 1 \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(0.3); \n"
+		"#endif \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 3 (#if ==)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"#define SYMBOL 3 \n"
+		"#if SYMBOL == 3 \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(0.3); \n"
+		"#endif \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 4 (#if 1, #define macro)",
+		NO_VERTEX_SHADER,
+		"#if 1 \n"
+		"#define FOO(x) x \n"
+		"#else \n"
+		"#define FOO(x) (0.5 * (x)) \n"
+		"#endif \n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(FOO(0.25)); \n"
+		"} \n",
+		{ 0.25, 0.25, 0.25, 0.25 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 5 (#if 1, #define macro)",
+		NO_VERTEX_SHADER,
+		"#define BAR(x) x \n"
+		"#if 1 \n"
+		"#define FOO(x) BAR(x) \n"
+		"#else \n"
+		"#define FOO(x) (BAR(x) + BAR(x)) \n"
+		"#endif \n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(FOO(0.25)); \n"
+		"} \n",
+		{ 0.25, 0.25, 0.25, 0.25 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 6 (#if 0, #define macro)",
+		NO_VERTEX_SHADER,
+		"#define BAR(x) x \n"
+		"#if 0 \n"
+		"#define FOO(x) BAR(x) \n"
+		"#else \n"
+		"#define FOO(x) (BAR(x) + BAR(x)) \n"
+		"#endif \n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(FOO(0.25)); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 7 (multi-line #define)",
+		NO_VERTEX_SHADER,
+		"#define FOO(x) \\\n"
+		" ((x) + (x)) \n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(FOO(0.25)); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 8 (#ifdef)",
+		NO_VERTEX_SHADER,
+		"#define FOO \n"
+		"void main() { \n"
+		"#ifdef FOO \n"
+		"   gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 9 (#ifndef)",
+		NO_VERTEX_SHADER,
+		"#define FOO \n"
+		"void main() { \n"
+		"#ifndef FOO \n"
+		"   gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 10 (#if defined())",
+		NO_VERTEX_SHADER,
+		"#define FOO \n"
+		"void main() { \n"
+		"#if defined(FOO) \n"
+		"   gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 11 (#elif)",
+		NO_VERTEX_SHADER,
+		"#define FOO 1\n"
+		"void main() { \n"
+		"#if FOO == 1 \n"
+		"   vec4 r = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#elif FOO == 2\n"
+		"   vec4 r = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   vec4 r = vec4(1.0, 1.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"   gl_FragColor = r; \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 12 (#elif)",
+		NO_VERTEX_SHADER,
+		"#define FOO 2\n"
+		"void main() { \n"
+		"#if FOO == 1 \n"
+		"   vec4 r = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#elif FOO == 2\n"
+		"   vec4 r = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   vec4 r = vec4(1.0, 1.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"   gl_FragColor = r; \n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 13 (nested #if)",
+		NO_VERTEX_SHADER,
+		"#define FOO 1\n"
+		"#define BAR 0\n"
+		"void main() { \n"
+		"#if FOO == 1 \n"
+		"#if BAR == 1 \n"
+		"   vec4 r = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   vec4 r = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"#else \n"
+		"   vec4 r = vec4(0.0, 0.0, 1.0, 0.0); \n"
+		"#endif \n"
+		"   gl_FragColor = r; \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 14 (nested #if)",
+		NO_VERTEX_SHADER,
+		"#define FOO 0\n"
+		"#define BAR 0\n"
+		"void main() { \n"
+		"#if FOO == 1 \n"
+		"   vec4 r = vec4(0.0, 0.0, 1.0, 0.0); \n"
+		"#else \n"
+		"#if BAR == 1 \n"
+		"   vec4 r = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   vec4 r = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"#endif \n"
+		"   gl_FragColor = r; \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		"Preprocessor test 15 (nested #if, #elif)",
+		NO_VERTEX_SHADER,
+		"#define FOO 0\n"
+		"#define BAR 2\n"
+		"void main() { \n"
+		"#if FOO == 1 \n"
+		"   vec4 r = vec4(0.0, 0.0, 1.0, 0.0); \n"
+		"#else \n"
+		"#if BAR == 1 \n"
+		"   vec4 r = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#elif BAR == 2 \n"
+		"   vec4 r = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   vec4 r = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"#endif \n"
+		"   gl_FragColor = r; \n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{
+		/*
+		 * This test will only be run if we have the GL_ARB_draw_buffers
+		 * extension.  Note the FLAG_ARB_DRAW_BUFFERS flag.
+		 */
+		"Preprocessor test (extension test 1)",
+		NO_VERTEX_SHADER,
+		"#extension GL_ARB_draw_buffers: enable\n"
+		"void main() { \n"
+		"#if defined(GL_ARB_draw_buffers) \n"
+		"   gl_FragData[0] = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_ARB_DRAW_BUFFERS
+	},
+
+	{
+		/* As above, but use #if == 1 test. */
+		"Preprocessor test (extension test 2)",
+		NO_VERTEX_SHADER,
+		"#extension GL_ARB_draw_buffers: enable\n"
+		"void main() { \n"
+		"#if GL_ARB_draw_buffers == 1\n"
+		"   gl_FragData[0] = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_ARB_DRAW_BUFFERS
+	},
+
+	{
+		/* Test using a non-existant function.  Should not compile. */
+		"Preprocessor test (extension test 3)",
+		NO_VERTEX_SHADER,
+		"#extension GL_FOO_bar: require\n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"} \n",
+		{ 0.0, 1.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"Preprocessor test (11)",
+		NO_VERTEX_SHADER,
+		"#define FOO \n"
+		"void main() { \n"
+		"#if !defined(FOO) \n"
+		"   gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n"
+		"#else \n"
+		"   gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n"
+		"#endif \n"
+		"} \n",
+		{ 1.0, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	/* Illegal shaders ================================================== */
+	{
+		"undefined variable",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec3 v = u; \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"if (boolean-scalar) check",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   vec3 v; \n"
+		"   if (v) { \n"
+		"   } \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"break with no loop",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   break; \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"continue with no loop",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   continue; \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"illegal assignment",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   float x = main; \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"syntax error check (1)",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   float x = ; \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"syntax error check (2)",
+		NO_VERTEX_SHADER,
+		"main() { \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"syntax error check (3)",
+		NO_VERTEX_SHADER,
+		"main() { \n"
+		"   float x = 1.0 2.0; \n"
+		"   gl_FragColor = vec4(0.5); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	{
+		"TIntermediate::addUnaryMath",
+		NO_VERTEX_SHADER,
+		"void main() { \n"
+		"   -vec4(x ? 1.0 : -1.0); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_SHADER
+	},
+
+	/* Other new GLSL 1.20, 1.30 features (just parse/compile tests) ====== */
+	{
+		"GLSL 1.30 precision qualifiers",
+		NO_VERTEX_SHADER,
+		"#version 130 \n"
+		"highp float f1; \n"
+		"mediump float f2; \n"
+		"lowp float f3; \n"
+		"precision mediump float; \n"
+		"precision lowp int; \n"
+		"precision highp float; \n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(1); \n"
+		"} \n",
+		{ 1.0, 1.0, 1.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_VERSION_1_30
+	},
+	{
+		"GLSL 1.20 invariant, centroid qualifiers",
+		NO_VERTEX_SHADER,
+		"#version 120 \n"
+		"invariant varying vec4 v1; \n"
+		"centroid varying vec4 v2; \n"
+		"invariant centroid varying vec4 v3; \n"
+		"varying vec4 v4; \n"
+		"invariant v4; \n"
+		"void main() { \n"
+		"   gl_FragColor = vec4(1); \n"
+		"} \n",
+		{ 1.0, 1.0, 1.0, 1.0 },
+		DONT_CARE_Z,
+		FLAG_VERSION_1_20
+	},
+
+#if 0
+	/* Check behaviour of inf/nan ========================================= */
+	{
+		"Divide by zero",
+		NO_VERTEX_SHADER,
+		"uniform vec4 uniform1; \n"
+		"void main() { \n"
+		"   float div = uniform1.y / uniform1.w; // div by zero\n"
+		"   div = div * uniform1.w; // mul by zero \n"
+		"   gl_FragColor = vec4(0.5 + div); \n"
+		"} \n",
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+#endif
+
+	/* Illegal link test ================================================== */
+	{
+		"gl_Position not written check",
+		"void main() { \n"
+		"   gl_FrontColor = vec4(0.3); \n"
+		"} \n",
+		NO_FRAGMENT_SHADER,
+		{ 0.5, 0.5, 0.5, 0.5 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_LINK
+	},
+
+	{
+		"varying var mismatch",
+		/* vert shader: */
+		"varying vec4 foo; \n"
+		"void main() { \n"
+		"   foo = gl_Color; \n"
+		"   gl_Position = ftransform(); \n"
+		"} \n",
+		/* frag shader: */
+		"varying vec4 bar; \n"
+		"void main() { \n"
+		"   gl_FragColor = bar; \n"
+		"} \n",
+		{ 0.0, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_LINK
+	},
+
+	{
+		"varying read but not written",
+		/* vert shader: */
+		"varying vec4 foo; \n"
+		"void main() { \n"
+		"   gl_Position = ftransform(); \n"
+		"} \n",
+		/* frag shader: */
+		"varying vec4 foo; \n"
+		"void main() { \n"
+		"   gl_FragColor = foo; \n"
+		"} \n",
+		{ 0.0, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_ILLEGAL_LINK
+	},
+
+	{
+		"texcoord varying",
+		/*
+		 * Does the linker correctly recognize that texcoord[1] is
+		 * written by the vertex shader and read by the fragment shader?
+		 * vert shader:
+		 */
+		"varying vec4 gl_TexCoord[4]; \n"
+		"void main() { \n"
+		"   int i = 1; \n"
+		"   gl_TexCoord[i] = vec4(0.5, 0, 0, 0); \n"
+		"   gl_Position = ftransform(); \n"
+		"} \n",
+		/* frag shader: */
+		"varying vec4 gl_TexCoord[4]; \n"
+		"void main() { \n"
+		"   gl_FragColor = gl_TexCoord[1]; \n"
+		"} \n",
+		{ 0.5, 0.0, 0.0, 0.0 },
+		DONT_CARE_Z,
+		FLAG_NONE
+	},
+
+	{ NULL, NULL, NULL, {0,0,0,0}, 0, FLAG_NONE } /* end of list sentinal */
+};
+
+void
+piglit_init(int argc, char **argv) {
+	/* No init */
+} /* piglit_init */
+
+void
+setupTextures(void)
+{
+	GLubyte teximage0[16][16][4];
+	GLubyte teximage1[8][8][4];
+	GLubyte teximage2[4][4][4];
+	GLubyte teximage3D[16][16][16][4];
+	GLfloat teximageZ[16][16];
+	GLint i, j, k;
+	GLuint obj1D, obj2D, obj3D, objZ;
+
+	glGenTextures(1, &obj1D);
+	glGenTextures(1, &obj2D);
+	glGenTextures(1, &obj3D);
+	glGenTextures(1, &objZ);
+
+	glActiveTexture(GL_TEXTURE0);
+
+	/*
+	 *
+	 * 2D texture, w/ mipmap
+	 *
+	 */
+	glBindTexture(GL_TEXTURE_2D, obj2D);
+	/*
+	 *  +-------+-------+
+	 *  | blue  | white |
+	 *  +-------+-------+
+	 *  | red   | green |
+	 *  +-------+-------+
+	 */
+	for (i = 0; i < 16; i++) {
+		for (j = 0; j < 16; j++) {
+			if (i < 8) { /* bottom half */
+				if (j < 8) {
+					/* red */
+					teximage0[i][j][0] = 255;
+					teximage0[i][j][1] = 0;
+					teximage0[i][j][2] = 0;
+					teximage0[i][j][3] = 255;
+				}
+				else {
+					/* green */
+					teximage0[i][j][0] = 0;
+					teximage0[i][j][1] = 255;
+					teximage0[i][j][2] = 0;
+					teximage0[i][j][3] = 255;
+				}
+			}
+			else { /* top half */
+				if (j < 8) {
+					/* blue */
+					teximage0[i][j][0] = 0;
+					teximage0[i][j][1] = 0;
+					teximage0[i][j][2] = 255;
+					teximage0[i][j][3] = 255;
+				}
+				else {
+					/* white */
+					teximage0[i][j][0] = 255;
+					teximage0[i][j][1] = 255;
+					teximage0[i][j][2] = 255;
+					teximage0[i][j][3] = 255;
+				}
+			}
+		}
+	}
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, teximage0);
+
+	/* level 1: same colors, half intensity */
+	for (i = 0; i < 8; i++) {
+		for (j = 0; j < 8; j++) {
+			teximage1[i][j][0] = teximage0[i*2][j*2][0] / 2;
+			teximage1[i][j][1] = teximage0[i*2][j*2][1] / 2;
+			teximage1[i][j][2] = teximage0[i*2][j*2][2] / 2;
+			teximage1[i][j][3] = teximage0[i*2][j*2][3] / 2;
+		}
+	}
+	glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, teximage1);
+
+	/* level 2: 1/4 intensity */
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 4; j++) {
+			teximage2[i][j][0] = teximage0[i*4][j*4][0] / 4;
+			teximage2[i][j][1] = teximage0[i*4][j*4][1] / 4;
+			teximage2[i][j][2] = teximage0[i*4][j*4][2] / 4;
+			teximage2[i][j][3] = teximage0[i*4][j*4][3] / 4;
+		}
+	}
+	glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 4, 4, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, teximage2);
+
+	/* level 3, 4: don't care */
+	glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 2, 2, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, teximage0);
+	glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA, 1, 1, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, teximage0);
+
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	/*
+	 *
+	 * 1D texture: just bottom row of the 2D texture
+	 *
+	 */
+	glBindTexture(GL_TEXTURE_1D, obj1D);
+	glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 16, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, teximage0);
+
+	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	/*
+	 *
+	 * 3D texture: 2D texture, depth = 1
+	 *
+	 */
+	for (i = 0; i < 16; i++) {
+		for (j = 0; j < 16; j++) {
+			for (k = 0; k < 16; k++) {
+				if (i < 8) {
+					teximage3D[i][j][k][0] = teximage0[j][k][0];
+					teximage3D[i][j][k][1] = teximage0[j][k][1];
+					teximage3D[i][j][k][2] = teximage0[j][k][2];
+					teximage3D[i][j][k][3] = teximage0[j][k][3];
+				}
+				else {
+					/* back half: half intensity */
+					teximage3D[i][j][k][0] = teximage0[j][k][0] / 2;
+					teximage3D[i][j][k][1] = teximage0[j][k][1] / 2;
+					teximage3D[i][j][k][2] = teximage0[j][k][2] / 2;
+					teximage3D[i][j][k][3] = teximage0[j][k][3] / 2;
+				}
+			}
+		}
+	}
+	glBindTexture(GL_TEXTURE_3D, obj3D);
+	glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 16, 0,
+		     GL_RGBA, GL_UNSIGNED_BYTE, teximage3D);
+
+	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	/*
+	 *
+	 * 2D GL_DEPTH_COMPONENT texture (for shadow sampler tests)
+	 * Left half = 0.25, right half = 0.75
+	 *
+	 */
+	for (i = 0; i < 16; i++) {
+		for (j = 0; j < 16; j++) {
+			if (j < 8)
+				teximageZ[i][j] = 0.25;
+			else
+				teximageZ[i][j] = 0.75;
+		}
+	}
+	glActiveTexture(GL_TEXTURE1); /* NOTE: Unit 1 */
+	glBindTexture(GL_TEXTURE_2D, objZ);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 16, 16, 0,
+		     GL_DEPTH_COMPONENT, GL_FLOAT, teximageZ);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
+					GL_COMPARE_R_TO_TEXTURE_ARB);
+	
+	glActiveTexture(GL_TEXTURE0);
+} /* setupTextures */
+
+
+void
+setupTextureMatrix1(void)
+{
+	/* This matrix is used by some of the general matrix tests */
+	static const GLfloat m[16] = {
+		1.0, 0.5, 0.6, 0.0,  /* col 0 */
+		0.0, 1.0, 0.0, 0.7,  /* col 1 */
+		0.0, 0.0, 1.0, 0.8,  /* col 2 */
+		0.1, 0.2, 0.3, 1.0   /* col 3 */
+	};
+	glMatrixMode(GL_TEXTURE);
+	glActiveTexture(GL_TEXTURE1);
+	glLoadMatrixf(m);
+	glActiveTexture(GL_TEXTURE0);
+	glMatrixMode(GL_MODELVIEW);
+} /* setupTextureMatrix1 */
+
+
+bool
+setup(void)
+{
+	GLenum err;
+
+	/* check GLSL version */
+#ifdef GL_SHADING_LANGUAGE_VERSION
+	const char *glslVersion = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
+#else
+	const char *glslVersion = NULL;
+#endif
+	const float version = atof(glslVersion);
+	if (version < 1.00) {
+		printf("GLSL 1.x not supported\n");
+		return false;
+	}
+	glsl_120 = version >= 1.20;
+	glsl_130 = version >= 1.30;
+
+	setupTextures();
+	setupTextureMatrix1();
+
+	/* load program inputs */
+	glColor4fv(PrimaryColor);
+	glSecondaryColor3fv(SecondaryColor);
+
+	/* other GL state */
+	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient);
+	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
+	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MatDiffuse);
+	glPointSize(PSIZE);
+	glPointParameterf(GL_POINT_SIZE_MIN, PSIZE_MIN);
+	glPointParameterf(GL_POINT_SIZE_MAX, PSIZE_MAX);
+	glPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, PSIZE_THRESH);
+	glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, PointAtten);
+	glFogf(GL_FOG_START, FOG_START);
+	glFogf(GL_FOG_END, FOG_END);
+	glFogfv(GL_FOG_COLOR, FogColor);
+
+	err = glGetError();
+	assert(!err);  /* should be OK */
+
+	/* setup vertex transform (we'll draw a quad in middle of window) */
+	glOrtho(-4.0, 4.0, -4.0, 4.0, 0.0, 1.0);
+
+	return true;
+} /* setup */
+
+
+GLuint
+loadAndCompileShader(GLenum target, const char *str)
+{
+	GLuint shader;
+	shader = glCreateShader(target);
+	glShaderSource(shader, 1, (const GLchar **) &str, NULL);
+	glCompileShader(shader);
+	return shader;
+} /* loadAndCompileShader */
+
+
+/*
+ * Check the compile status of the just compiled shader.
+ * If the outcome is unexpected, report an error.
+ */
+bool
+checkCompileStatus(GLenum target, GLuint shader,
+			     const struct ShaderProgram* p)
+{
+	GLint stat;
+	GLchar infoLog[1000];
+	GLsizei len;
+
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
+	if (!stat) {
+		glGetShaderInfoLog(shader, 1000, &len, infoLog);
+	}
+
+	if (!stat && (p->flags & FLAG_ILLEGAL_SHADER) == 0) {
+		/* this _should_ have compiled */
+		printf("FAILURE:\n");
+		printf("  Shader test: %s\n", p->name);
+		if (target == GL_FRAGMENT_SHADER)
+			printf("Fragment shader did not compile:\n");
+		else
+			printf("Vertex shader did not compile:\n");
+		printf("%s\n", infoLog);
+		return false;
+	}
+	else if (stat && (p->flags & FLAG_ILLEGAL_SHADER)) {
+		/* this should _not_ have compiled! */
+		printf("FAILURE:\n");
+		printf("  Shader test: %s\n", p->name);
+		printf("  Shader should not have compiled, but it did.\n");
+		return false;
+	}
+	return true;
+} /* checkCompileStatus */
+
+
+bool
+testProgram(const struct ShaderProgram* p)
+{
+	static const GLfloat uniformMatrix[16] = {
+		1.0, 0.1, 0.2, 0.3,  /* col 0 */
+		0.0, 1.0, 0.0, 0.4,  /* col 1 */
+		0.0, 1.0, 1.0, 0.5,  /* col 2 */
+		0.6, 0.7, 0.8, 1.0   /* col 3 */
+	};
+	static const GLfloat uniformMatrix2x4[8] = {
+		0.0, 0.1, 0.2, 0.3,  /* col 0 */
+		0.4, 0.5, 0.6, 0.7   /* col 1 */
+	};
+	static const GLfloat uniformMatrix4x3[12] = {
+		0.0, 0.1, 0.2,  /* col 0 */
+		0.3, 0.4, 0.5,  /* col 1 */
+		0.6, 0.7, 0.8,  /* col 2 */
+		0.9, 1.0, 0.0   /* col 3 */
+	};
+	GLuint fragShader = 0, vertShader = 0, program = 0;
+	GLint u1, uArray, uArray4, utex1d, utex2d, utex3d, utexZ, umat4, umat4t;
+	GLint umat2x4, umat2x4t, umat4x3, umat4x3t;
+	bool retVal = false;
+	GLint stat;
+	GLchar log[1000];
+	GLsizei len;
+	const GLfloat r = 0.62; // XXX draw 16x16 pixel quad
+
+	if (p->flags & FLAG_ARB_DRAW_BUFFERS &&
+	    !piglit_is_extension_supported("GL_ARB_draw_buffers")) {
+		/* skip */
+		retVal = true;
+		goto cleanup;
+	}
+
+
+	if (p->fragShaderString) {
+		fragShader = loadAndCompileShader(GL_FRAGMENT_SHADER,
+						  p->fragShaderString);
+		if (!checkCompileStatus(GL_FRAGMENT_SHADER, fragShader, p)) {
+			retVal = false;
+			goto cleanup;
+		}
+	}
+	if (p->vertShaderString) {
+		vertShader = loadAndCompileShader(GL_VERTEX_SHADER,
+						  p->vertShaderString);
+		if (!checkCompileStatus(GL_VERTEX_SHADER, vertShader, p)) {
+			retVal = false;
+			goto cleanup;
+		}
+	}
+	if (!fragShader && !vertShader) {
+		/* must have had a compilation errror */
+		retVal = false;
+		goto cleanup;
+	}
+
+	if (p->flags & FLAG_ILLEGAL_SHADER) {
+		/* don't render/test */
+		retVal = true;
+		goto cleanup;
+	}
+
+	program = glCreateProgram();
+	if (fragShader)
+		glAttachShader(program, fragShader);
+	if (vertShader)
+		glAttachShader(program, vertShader);
+	glLinkProgram(program);
+
+	/* check link */
+	{
+		glGetProgramiv(program, GL_LINK_STATUS, &stat);
+		if (!stat) {
+			if (p->flags & FLAG_ILLEGAL_LINK) {
+				/* this is the expected outcome */
+				retVal = true;
+				goto cleanup;
+			}
+			else {
+				glGetProgramInfoLog(program, 1000, &len, log);
+				printf("FAILURE:\n");
+				printf("  Shader test: %s\n", p->name);
+				printf("  Link error: %s\n", log);
+				retVal = false;
+				goto cleanup;
+			}
+		}
+		else {
+			/* link successful */
+			if (p->flags & FLAG_ILLEGAL_LINK) {
+				/* the shaders should _not_ have linked */
+				printf("FAILURE:\n");
+				printf("  Shader test: %s\n", p->name);
+				printf("  Program linked, but shouldn't have.\n");
+				retVal = false;
+				goto cleanup;
+			}
+		}
+	}
+
+	glUseProgram(program);
+
+	if (p->flags & FLAG_VERTEX_TEXTURE) {
+		/* check if vertex texture units are available */
+		GLint n;
+		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &n);
+		if (n == 0) {
+			/* can't run the test */
+			retVal = true;
+			goto cleanup;
+		}
+	}
+
+	/* load uniform vars */
+	u1 = glGetUniformLocation(program, "uniform1");
+	if (u1 >= 0)
+		glUniform4fv(u1, 1, Uniform1);
+
+	uArray = glGetUniformLocation(program, "uniformArray");
+	if (uArray >= 0)
+		glUniform1fv(uArray, 4, UniformArray);
+
+	uArray4 = glGetUniformLocation(program, "uniformArray4");
+	if (uArray4 >= 0)
+		glUniform4fv(uArray4, 4, (float *) UniformArray4);
+
+	utex1d = glGetUniformLocation(program, "tex1d");
+	if (utex1d >= 0)
+		glUniform1i(utex1d, 0);  /* bind to tex unit 0 */
+
+	utex2d = glGetUniformLocation(program, "tex2d");
+	if (utex2d >= 0)
+		glUniform1i(utex2d, 0);  /* bind to tex unit 0 */
+
+	utex3d = glGetUniformLocation(program, "tex3d");
+	if (utex3d >= 0)
+		glUniform1i(utex3d, 0);  /* bind to tex unit 0 */
+
+	utexZ = glGetUniformLocation(program, "texZ");
+	if (utexZ >= 0)
+		glUniform1i(utexZ, 1);  /* bind to tex unit 1 */
+
+	umat4 = glGetUniformLocation(program, "uniformMat4");
+	if (umat4 >= 0)
+		glUniformMatrix4fv(umat4, 1, GL_FALSE, uniformMatrix);
+
+	umat4t = glGetUniformLocation(program, "uniformMat4t");
+	if (umat4t >= 0)
+		glUniformMatrix4fv(umat4t, 1, GL_TRUE, uniformMatrix);
+
+	umat2x4 = glGetUniformLocation(program, "uniformMat2x4");
+	if (umat2x4 >= 0)
+		glUniformMatrix2x4fv(umat2x4, 1, GL_FALSE, uniformMatrix2x4);
+
+	umat2x4t = glGetUniformLocation(program, "uniformMat2x4t");
+	if (umat2x4t >= 0)
+		glUniformMatrix2x4fv(umat2x4t, 1, GL_TRUE, uniformMatrix2x4);
+
+	umat4x3 = glGetUniformLocation(program, "uniformMat4x3");
+	if (umat4x3 >= 0)
+		glUniformMatrix4x3fv(umat4x3, 1, GL_FALSE, uniformMatrix4x3);
+
+	umat4x3t = glGetUniformLocation(program, "uniformMat4x3t");
+	if (umat4x3t >= 0)
+		glUniformMatrix4x3fv(umat4x3t, 1, GL_TRUE, uniformMatrix4x3);
+
+
+	/* to avoid potential issue with undefined result.depth.z */
+	if (p->expectedZ == DONT_CARE_Z)
+		glDisable(GL_DEPTH_TEST);
+	else
+	{
+		glEnable(GL_DEPTH_TEST);
+		printf("================ Depth buffer enabled.\n");
+	}
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	piglit_draw_rect_tex(-r, -r, 2 * r, 2 * r, 0, 0, 1, 1);
+	piglit_check_gl_error(GL_NO_ERROR);
+
+	printf("Shader test: %s\n", p->name);
+
+	/* Check the lower-left hand square in the textured quad to make sure it is the
+	 * right color. */
+	if (!piglit_probe_pixel_rgba(piglit_width / 2 - 2, piglit_height / 2 - 2, p->expectedColor)) {
+		retVal = false;
+		goto cleanup;
+	}
+
+	/* Check the depth at the center of the textured quad. */
+	if (p->expectedZ != DONT_CARE_Z) {
+		if (!piglit_probe_pixel_depth(piglit_width / 2, piglit_height / 2, p->expectedZ)) {
+			retVal = false;
+			goto cleanup;
+		}
+	}
+
+	/* passed! */
+	retVal = true;
+
+ cleanup:
+	if (fragShader)
+		glDeleteShader(fragShader);
+	if (vertShader)
+		glDeleteShader(vertShader);
+	glDeleteProgram(program);
+
+	if (!piglit_automatic) {
+		piglit_present_results();
+	}
+	return retVal;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	bool pass = true;
+	int i;
+	const char *singleTest;
+	
+	if (!setup())
+		return PIGLIT_FAIL;
+	
+	/* If you just want to run a single sub-test, assign the name to singleTest. */
+	/* for loops run until Programs[i].name because the last name in the array is NULL */
+	singleTest = getenv("PIGLIT_TEST");
+	if (singleTest) {
+		printf("glsl1: Running single test: %s\n", singleTest);
+		for (i = 0; Programs[i].name; i++) {
+			if (strcmp(Programs[i].name, singleTest) == 0) {
+
+				if ((Programs[i].flags & FLAG_VERSION_1_20) && !glsl_120)
+					break; /* skip non-applicable tests */
+				if ((Programs[i].flags & FLAG_VERSION_1_30) && !glsl_130)
+					break; /* skip non-applicable tests */
+
+				pass &= testProgram(&Programs[i]);
+				break;
+			}
+		}
+	}
+	else {
+		/* loop over all tests */
+		for (i = 0; Programs[i].name; i++) {
+			if ((Programs[i].flags & FLAG_VERSION_1_20) && !glsl_120)
+				continue; /* skip non-applicable tests */
+			if ((Programs[i].flags & FLAG_VERSION_1_30) && !glsl_130)
+				continue; /* skip non-applicable tests */
+			pass &= testProgram(&Programs[i]);
+		}
+	}
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+} /* piglit_display */

Comments

I applied the style fixes pointed out by Brian Paul and Dylan Baker in the
blend func patch to my local repo (see
http://cgit.freedesktop.org/~ldeks/piglit/?h=glsl1).

Laura

P.S.: I apologize if this is a repeat email.
On 10/13/2014 07:12 PM, Laura Ekstrand wrote:
> ---
>   tests/all.py                                     |    1 +
>   tests/spec/glsl-1.10/execution/CMakeLists.gl.txt |    1 +
>   tests/spec/glsl-1.10/execution/glean-glsl1.c     | 2104 ++++++++++++++++++++++
>   3 files changed, 2106 insertions(+)
>   create mode 100644 tests/spec/glsl-1.10/execution/glean-glsl1.c
>


I'm not sure that porting this test to Piglit is worthwhile.  I'd bet 
that most of the little subtests here are already sufficiently covered 
by existing piglit shader tests.  It would probably be simpler to make 
shader test scripts for the few cases here that might not be covered 
already.

-Brian
On Wed, Oct 15, 2014 at 8:13 AM, Brian Paul <brianp@vmware.com> wrote:
> I'm not sure that porting this test to Piglit is worthwhile.  I'd bet that
> most of the little subtests here are already sufficiently covered by
> existing piglit shader tests.  It would probably be simpler to make shader
> test scripts for the few cases here that might not be covered already.

I've already deleted probably a hundred tests from this that are clear
duplicated of existing shader_tests (though there might be some more
as well).

I completely agree that we'd really like to replace these tests with
individual shader_tests where possible.
It's really not a good use of time to check for overlaps between the glsl1
tests and the shader runner tests, because that would take a lot of
searching.  So, the basic question is: do we want to convert these tests to
shader runner (and not care about overlap), keep glsl1.c, or just throw
glsl1.c away?

I'm honestly not sure how to answer this question.  These shader tests are
pretty basic, but there are a lot of them, and they might hit on places
that piglit doesn't already cover.

On Wed, Oct 15, 2014 at 9:39 AM, Matt Turner <mattst88@gmail.com> wrote:

> On Wed, Oct 15, 2014 at 8:13 AM, Brian Paul <brianp@vmware.com> wrote:
> > I'm not sure that porting this test to Piglit is worthwhile.  I'd bet
> that
> > most of the little subtests here are already sufficiently covered by
> > existing piglit shader tests.  It would probably be simpler to make
> shader
> > test scripts for the few cases here that might not be covered already.
>
> I've already deleted probably a hundred tests from this that are clear
> duplicated of existing shader_tests (though there might be some more
> as well).
>
> I completely agree that we'd really like to replace these tests with
> individual shader_tests where possible.
>
On Wed, Oct 15, 2014 at 11:24 AM, Laura Ekstrand <laura@jlekstrand.net> wrote:
> It's really not a good use of time to check for overlaps between the glsl1
> tests and the shader runner tests, because that would take a lot of
> searching.

I don't really think so. I've already deleted a pile of these tests:
check git log tests/glean/tglsl1.cpp. It's usually a grep or two for
each set of tests to conclusively determine that we're already testing
that functionality.

I made a small list of categories of remaining tests and things we
should test in piglit a while back when looking through tglsl1.cpp
(i.e., things that aren't tested elsewhere):

Swizzles: swizzles can be .rgba/.xyzw/.stpq but not a mix of them.
Probably a generator to test all possible combinations? Or just some
parser tests would probably be sufficient.
Make sure to test swizzling expressions, e.g., (a + b).zyx
Writemasks: Maybe part of the previous generator

----

Nested function calls

----

Chained assignments
a = b = c;

----

Short circuit evaluation
a && b -> set a = false. make b a function call with side-effects
a || b -> set a = true.  ...

----

But most of the tglsl1.cpp tests can just be deleted outright.