[v1] Porting the OpenGL shading language from Glean to Piglit.

Submitted by Juliet Fru on Oct. 7, 2015, 8:48 a.m.

Details

Message ID 1444207738-13507-1-git-send-email-julietfru@gmail.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Juliet Fru Oct. 7, 2015, 8:48 a.m.
This test replaces the original tglsl1.cpp test
---
 tests/all.py                        |    1 +
 tests/spec/gl-1.0/CMakeLists.gl.txt |    1 +
 tests/spec/gl-1.0/shading-lang.c    | 1939 +++++++++++++++++++++++++++++++++++
 3 files changed, 1941 insertions(+)
 create mode 100644 tests/spec/gl-1.0/shading-lang.c

Patch hide | download patch | download mbox

diff --git a/tests/all.py b/tests/all.py
index fe088f5..6140320 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -999,6 +999,7 @@  with profile.group_manager(
     g(['gl-1.0-fpexceptions'])
     g(['gl-1.0-ortho-pos'])
     g(['gl-1.0-readpixsanity'])
+    g(['gl-1.0-shading-lang'])
     g(['gl-1.0-logicop'])
 
 with profile.group_manager(
diff --git a/tests/spec/gl-1.0/CMakeLists.gl.txt b/tests/spec/gl-1.0/CMakeLists.gl.txt
index d04b835..28a1d42 100644
--- a/tests/spec/gl-1.0/CMakeLists.gl.txt
+++ b/tests/spec/gl-1.0/CMakeLists.gl.txt
@@ -26,6 +26,7 @@  piglit_add_executable (gl-1.0-polygon-line-aa polygon-line-aa.c)
 piglit_add_executable (gl-1.0-push-no-attribs push-no-attribs.c)
 piglit_add_executable (gl-1.0-readpixsanity readpix.c)
 piglit_add_executable (gl-1.0-rendermode-feedback rendermode-feedback.c)
+piglit_add_executable (gl-1.0-shading-lang shading-lang.c)
 piglit_add_executable (gl-1.0-swapbuffers-behavior swapbuffers-behavior.c)
 
 # vim: ft=cmake:
diff --git a/tests/spec/gl-1.0/shading-lang.c b/tests/spec/gl-1.0/shading-lang.c
new file mode 100644
index 0000000..5b8ed9a
--- /dev/null
+++ b/tests/spec/gl-1.0/shading-lang.c
@@ -0,0 +1,1939 @@ 
+/*
+ * 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
+ */
+
+/** @file shading-lang.c
+ *
+ * Test OpenGL shading language
+ *
+ * 	Authors:
+ *		Brian Paul <brianp@valinux.com>
+ * 		Adapted to Piglit by Juliet Fru <julietfru@gmail.com>, October 2015.
+ */
+
+#include "piglit-util-gl.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+
+PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 20;
+
+config.window_visual =
+	PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DEPTH |
+	PIGLIT_GL_VISUAL_STENCIL;
+
+PIGLIT_GL_TEST_CONFIG_END
+#define GL_GLEXT_PROTOTYPES
+#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_WINDING_CW       0x20	/* clockwise-winding polygon */
+#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
+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 };
+
+GLfloat tolerance[5];
+GLfloat looseTolerance[5];
+bool glsl_120;			/* GLSL 1.20 or higher supported? */
+bool glsl_130;			/* GLSL 1.30 or higher supported? */
+
+
+typedef struct
+{
+	const char *name;
+	const char *vertShaderString;
+	const char *fragShaderString;
+	GLfloat expectedColor[4];
+	GLfloat expectedZ;
+	int flags;
+} ShaderProgram;
+
+
+/* Shader program test cases */
+static const 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 ============================================================
+	{
+	 "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
+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);
+}
+
+
+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);
+}
+
+
+void
+reportFailure(const char *programName,
+	      const GLfloat expectedColor[4], const GLfloat actualColor[4])
+{
+	printf("FAILURE:\n");
+	printf("  Shader test: %s\n", programName);
+	printf("  Expected color: %f, %f, %f, %f\n", expectedColor[0],
+	       expectedColor[1], expectedColor[2], expectedColor[3]);
+	printf("  Observed color: %f, %f, %f, %f\n", actualColor[0],
+	       actualColor[1], actualColor[2], actualColor[3]);
+}
+
+
+void
+reportZFailure(const char *programName, GLfloat expectedZ, GLfloat actualZ)
+{
+	printf("FAILURE:\n");
+	printf("  Shader test: %s\n", programName);
+	printf("  Expected Z: %f\n", expectedZ);
+	printf("  Observed Z: %f\n", actualZ);
+}
+
+
+/* Compare actual and expected colors */
+bool
+equalColors(const GLfloat act[4], const GLfloat exp[4], int flags)
+{
+	const GLfloat *tol;
+	if (flags & FLAG_LOOSE)
+		tol = looseTolerance;
+	else
+		tol = tolerance;
+	if ((fabsf(act[0] - exp[0]) > tol[0]) ||
+	    (fabsf(act[1] - exp[1]) > tol[1]) ||
+	    (fabsf(act[2] - exp[2]) > tol[2]) ||
+	    (fabsf(act[3] - exp[3]) > tol[3]))
+		return false;
+	else
+		return true;
+}
+
+
+bool
+equalDepth(GLfloat z0, GLfloat z1)
+{
+	if (fabsf(z0 - z1) > tolerance[4])
+		return false;
+	else
+		return true;
+}
+
+
+GLuint
+loadAndCompileShader(GLenum target, const char *str)
+{
+	GLuint shader;
+	shader = glCreateShader(target);
+	glShaderSource(shader, 1, (const GLchar **) &str, NULL);
+	glCompileShader(shader);
+	return shader;
+}
+
+
+/* Check the compile status of the just compiled shader.
+ * If the outcome is unexpected, report an error.
+ */
+bool
+checkCompileStatus(GLenum target, GLuint shader, const ShaderProgram p)
+{
+	GLint stat;
+	GLchar infoLog[1000];
+	GLsizei len;
+
+	glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
+	if (!stat) {
+		glGetShaderInfoLog(shader, 1000, &len, infoLog);
+		/* printf(" %s\n", 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: %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;
+}
+
+
+bool
+testProgram(const 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 */
+	};
+	const GLfloat r = 0.62;	/* XXX draw 16x16 pixel quad */
+	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;
+
+	if (p.flags & FLAG_ARB_DRAW_BUFFERS &&
+	    !piglit_dispatch_glGetString("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 error */
+		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 */
+	{
+		GLint stat;
+		glGetProgramiv(program, GL_LINK_STATUS, &stat);
+		if (!stat) {
+			if (p.flags & FLAG_ILLEGAL_LINK) {
+				/* this is the expected outcome */
+				retVal = true;
+				goto cleanup;
+			} else {
+				GLchar log[1000];
+				GLsizei len;
+				glGetProgramInfoLog(program, 1000, &len, log);
+				printf("FAILURE:\n");
+				printf("  Shader test: %s\n", p.name);
+				printf("  Link error: %s", 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);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	if (p.flags & FLAG_WINDING_CW) {
+		/* Clockwise */
+		glBegin(GL_POLYGON);
+		glTexCoord2f(0, 0);
+		glVertex2f(-r, -r);
+		glTexCoord2f(0, 1);
+		glVertex2f(-r, r);
+		glTexCoord2f(1, 1);
+		glVertex2f(r, r);
+		glTexCoord2f(1, 0);
+		glVertex2f(r, -r);
+		glEnd();
+	} else {
+		/* Counter Clockwise */
+		glBegin(GL_POLYGON);
+		glTexCoord2f(0, 0);
+		glVertex2f(-r, -r);
+		glTexCoord2f(1, 0);
+		glVertex2f(r, -r);
+		glTexCoord2f(1, 1);
+		glVertex2f(r, r);
+		glTexCoord2f(0, 1);
+		glVertex2f(-r, r);
+		glEnd();
+	}
+
+	/* printf("  Shader test: %s\n", p.name); */
+
+	/* read a pixel from lower-left corder of rendered quad */
+	GLfloat pixel[4];
+	glReadPixels(piglit_width / 2 - 2, piglit_width / 2 - 2, 1, 1,
+		     GL_RGBA, GL_FLOAT, pixel);
+	if (0)			// debug
+		printf("%s: Expect: %.3f %.3f %.3f %.3f  found: %.3f %.3f %.3f %.3f\n", p.name, p.expectedColor[0], p.expectedColor[1], p.expectedColor[2], p.expectedColor[3], pixel[0], pixel[1], pixel[2], pixel[3]);
+
+	if (!equalColors(pixel, p.expectedColor, p.flags)) {
+		reportFailure(p.name, p.expectedColor, pixel);
+		retVal = false;
+		goto cleanup;
+	}
+
+	if (p.expectedZ != DONT_CARE_Z) {
+		GLfloat z;
+		/* read z at center of quad */
+		glReadPixels(piglit_width / 2, piglit_width / 2, 1, 1,
+			     GL_DEPTH_COMPONENT, GL_FLOAT, &z);
+		if (!equalDepth(z, p.expectedZ)) {
+			reportZFailure(p.name, p.expectedZ, z);
+			retVal = false;
+			goto cleanup;
+		}
+	}
+
+	/* passed! */
+	retVal = true;
+
+	if (0)			// debug
+		printf("%s passed\n", p.name);
+
+      cleanup:
+	if (fragShader)
+		glDeleteShader(fragShader);
+	if (vertShader)
+		glDeleteShader(vertShader);
+	glDeleteProgram(program);
+
+	return retVal;
+}
+
+
+bool
+setup(void)
+{
+	/* 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);
+
+	GLenum err = glGetError();
+	assert(!err);		/* should be OK */
+
+	/* setup vertex transform (we'll draw a quad in middle of window) */
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(-4.0, 4.0, -4.0, 4.0, 0.0, 1.0);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+	glDrawBuffer(GL_FRONT);
+	glReadBuffer(GL_FRONT);
+
+	/* compute error tolerances (may need fine-tuning) */
+	int bufferBits[5];
+	glGetIntegerv(GL_RED_BITS, &bufferBits[0]);
+	glGetIntegerv(GL_GREEN_BITS, &bufferBits[1]);
+	glGetIntegerv(GL_BLUE_BITS, &bufferBits[2]);
+	glGetIntegerv(GL_ALPHA_BITS, &bufferBits[3]);
+	glGetIntegerv(GL_DEPTH_BITS, &bufferBits[4]);
+
+	tolerance[0] = 2.0 / (1 << bufferBits[0]);
+	tolerance[1] = 2.0 / (1 << bufferBits[1]);
+	tolerance[2] = 2.0 / (1 << bufferBits[2]);
+	if (bufferBits[3])
+		tolerance[3] = 2.0 / (1 << bufferBits[3]);
+	else
+		tolerance[3] = 1.0;
+	if (bufferBits[4])
+		tolerance[4] = 16.0 / (1 << bufferBits[4]);
+	else
+		tolerance[4] = 1.0;
+
+	/* Some tests request a looser tolerance:
+	 * XXX a factor of 4 may be too much...
+	 */
+	for (int i = 0; i < 5; i++)
+		looseTolerance[i] = 4.0 * tolerance[i];
+
+	return true;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+	/* no initialization */
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+	bool pass = true;
+
+	if (!setup()) {
+		pass = false;
+		return PIGLIT_FAIL;
+	}
+
+	/* If you just want to run a single sub-test, assign the name to singleTest. */
+	const char *singleTest = getenv("PIGLIT_TEST");
+	if (singleTest) {
+		printf("glsl1: Running single test: %s\n", singleTest);
+		for (int 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]) && pass;
+				break;
+			}
+		}
+	} else {
+		/* loop over all tests */
+		for (int 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 */
+			else {
+				pass = testProgram(Programs[i]) && pass;
+			}
+		}
+	}
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}

Comments

Hi Juliet,

I only have time for a quick review for now.  See comments below.  I'll 
try to look closer tomorrow.


On 10/07/2015 02:48 AM, Juliet Fru wrote:
> This test replaces the original tglsl1.cpp test
> ---
>   tests/all.py                        |    1 +
>   tests/spec/gl-1.0/CMakeLists.gl.txt |    1 +
>   tests/spec/gl-1.0/shading-lang.c    | 1939 +++++++++++++++++++++++++++++++++++
>   3 files changed, 1941 insertions(+)
>   create mode 100644 tests/spec/gl-1.0/shading-lang.c
>
> diff --git a/tests/all.py b/tests/all.py
> index fe088f5..6140320 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -999,6 +999,7 @@ with profile.group_manager(
>       g(['gl-1.0-fpexceptions'])
>       g(['gl-1.0-ortho-pos'])
>       g(['gl-1.0-readpixsanity'])
> +    g(['gl-1.0-shading-lang'])
>       g(['gl-1.0-logicop'])
>
>   with profile.group_manager(
> diff --git a/tests/spec/gl-1.0/CMakeLists.gl.txt b/tests/spec/gl-1.0/CMakeLists.gl.txt
> index d04b835..28a1d42 100644
> --- a/tests/spec/gl-1.0/CMakeLists.gl.txt
> +++ b/tests/spec/gl-1.0/CMakeLists.gl.txt

The test should go in tests/spec/gl-2.0/ instead.  There was no GLSL 
support in GL 1.0


> @@ -26,6 +26,7 @@ piglit_add_executable (gl-1.0-polygon-line-aa polygon-line-aa.c)
>   piglit_add_executable (gl-1.0-push-no-attribs push-no-attribs.c)
>   piglit_add_executable (gl-1.0-readpixsanity readpix.c)
>   piglit_add_executable (gl-1.0-rendermode-feedback rendermode-feedback.c)
> +piglit_add_executable (gl-1.0-shading-lang shading-lang.c)
>   piglit_add_executable (gl-1.0-swapbuffers-behavior swapbuffers-behavior.c)
>
>   # vim: ft=cmake:
> diff --git a/tests/spec/gl-1.0/shading-lang.c b/tests/spec/gl-1.0/shading-lang.c
> new file mode 100644
> index 0000000..5b8ed9a
> --- /dev/null
> +++ b/tests/spec/gl-1.0/shading-lang.c
> @@ -0,0 +1,1939 @@
> +/*
> + * 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
> + */
> +
> +/** @file shading-lang.c
> + *
> + * Test OpenGL shading language
> + *
> + * 	Authors:
> + *		Brian Paul <brianp@valinux.com>
> + * 		Adapted to Piglit by Juliet Fru <julietfru@gmail.com>, October 2015.
> + */
> +
> +#include "piglit-util-gl.h"
> +
> +#include <stdlib.h>
> +#include <assert.h>
> +#include <string.h>
> +#include <math.h>
> +
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 20;
> +
> +config.window_visual =
> +	PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DEPTH |
> +	PIGLIT_GL_VISUAL_STENCIL;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +#define GL_GLEXT_PROTOTYPES
> +#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_WINDING_CW       0x20	/* clockwise-winding polygon */
> +#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
> +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 };
> +
> +GLfloat tolerance[5];
> +GLfloat looseTolerance[5];
> +bool glsl_120;			/* GLSL 1.20 or higher supported? */
> +bool glsl_130;			/* GLSL 1.30 or higher supported? */
> +
> +
> +typedef struct
> +{
> +	const char *name;
> +	const char *vertShaderString;
> +	const char *fragShaderString;
> +	GLfloat expectedColor[4];
> +	GLfloat expectedZ;
> +	int flags;
> +} ShaderProgram;
> +
> +
> +/* Shader program test cases */
> +static const 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 ============================================================
> +	{
> +	 "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
> +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);
> +}
> +
> +
> +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);
> +}
> +
> +
> +void
> +reportFailure(const char *programName,
> +	      const GLfloat expectedColor[4], const GLfloat actualColor[4])
> +{
> +	printf("FAILURE:\n");
> +	printf("  Shader test: %s\n", programName);
> +	printf("  Expected color: %f, %f, %f, %f\n", expectedColor[0],
> +	       expectedColor[1], expectedColor[2], expectedColor[3]);
> +	printf("  Observed color: %f, %f, %f, %f\n", actualColor[0],
> +	       actualColor[1], actualColor[2], actualColor[3]);
> +}
> +
> +
> +void
> +reportZFailure(const char *programName, GLfloat expectedZ, GLfloat actualZ)
> +{
> +	printf("FAILURE:\n");
> +	printf("  Shader test: %s\n", programName);
> +	printf("  Expected Z: %f\n", expectedZ);
> +	printf("  Observed Z: %f\n", actualZ);
> +}
> +
> +
> +/* Compare actual and expected colors */
> +bool
> +equalColors(const GLfloat act[4], const GLfloat exp[4], int flags)
> +{
> +	const GLfloat *tol;
> +	if (flags & FLAG_LOOSE)
> +		tol = looseTolerance;
> +	else
> +		tol = tolerance;
> +	if ((fabsf(act[0] - exp[0]) > tol[0]) ||
> +	    (fabsf(act[1] - exp[1]) > tol[1]) ||
> +	    (fabsf(act[2] - exp[2]) > tol[2]) ||
> +	    (fabsf(act[3] - exp[3]) > tol[3]))
> +		return false;
> +	else
> +		return true;
> +}
> +
> +
> +bool
> +equalDepth(GLfloat z0, GLfloat z1)
> +{
> +	if (fabsf(z0 - z1) > tolerance[4])
> +		return false;
> +	else
> +		return true;
> +}
> +
> +
> +GLuint
> +loadAndCompileShader(GLenum target, const char *str)
> +{
> +	GLuint shader;
> +	shader = glCreateShader(target);
> +	glShaderSource(shader, 1, (const GLchar **) &str, NULL);
> +	glCompileShader(shader);
> +	return shader;
> +}
> +
> +
> +/* Check the compile status of the just compiled shader.
> + * If the outcome is unexpected, report an error.
> + */
> +bool
> +checkCompileStatus(GLenum target, GLuint shader, const ShaderProgram p)
> +{
> +	GLint stat;
> +	GLchar infoLog[1000];
> +	GLsizei len;
> +
> +	glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
> +	if (!stat) {
> +		glGetShaderInfoLog(shader, 1000, &len, infoLog);
> +		/* printf(" %s\n", 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: %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;
> +}
> +
> +
> +bool
> +testProgram(const 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 */
> +	};
> +	const GLfloat r = 0.62;	/* XXX draw 16x16 pixel quad */
> +	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;
> +
> +	if (p.flags & FLAG_ARB_DRAW_BUFFERS &&
> +	    !piglit_dispatch_glGetString("GL_ARB_draw_buffers")) {

Let's put a piglit_require_extension("GL_ARB_draw_buffers") in the 
piglit_init() function and drop this test.


> +		/* 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 error */
> +		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 */
> +	{
> +		GLint stat;
> +		glGetProgramiv(program, GL_LINK_STATUS, &stat);
> +		if (!stat) {
> +			if (p.flags & FLAG_ILLEGAL_LINK) {
> +				/* this is the expected outcome */
> +				retVal = true;
> +				goto cleanup;
> +			} else {
> +				GLchar log[1000];
> +				GLsizei len;
> +				glGetProgramInfoLog(program, 1000, &len, log);
> +				printf("FAILURE:\n");
> +				printf("  Shader test: %s\n", p.name);
> +				printf("  Link error: %s", 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);
> +
> +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> +	if (p.flags & FLAG_WINDING_CW) {
> +		/* Clockwise */
> +		glBegin(GL_POLYGON);
> +		glTexCoord2f(0, 0);
> +		glVertex2f(-r, -r);
> +		glTexCoord2f(0, 1);
> +		glVertex2f(-r, r);
> +		glTexCoord2f(1, 1);
> +		glVertex2f(r, r);
> +		glTexCoord2f(1, 0);
> +		glVertex2f(r, -r);
> +		glEnd();
> +	} else {
> +		/* Counter Clockwise */
> +		glBegin(GL_POLYGON);
> +		glTexCoord2f(0, 0);
> +		glVertex2f(-r, -r);
> +		glTexCoord2f(1, 0);
> +		glVertex2f(r, -r);
> +		glTexCoord2f(1, 1);
> +		glVertex2f(r, r);
> +		glTexCoord2f(0, 1);
> +		glVertex2f(-r, r);
> +		glEnd();
> +	}
> +
> +	/* printf("  Shader test: %s\n", p.name); */
> +
> +	/* read a pixel from lower-left corder of rendered quad */
> +	GLfloat pixel[4];
> +	glReadPixels(piglit_width / 2 - 2, piglit_width / 2 - 2, 1, 1,
> +		     GL_RGBA, GL_FLOAT, pixel);
> +	if (0)			// debug
> +		printf("%s: Expect: %.3f %.3f %.3f %.3f  found: %.3f %.3f %.3f %.3f\n", p.name, p.expectedColor[0], p.expectedColor[1], p.expectedColor[2], p.expectedColor[3], pixel[0], pixel[1], pixel[2], pixel[3]);
> +
> +	if (!equalColors(pixel, p.expectedColor, p.flags)) {
> +		reportFailure(p.name, p.expectedColor, pixel);
> +		retVal = false;
> +		goto cleanup;
> +	}
> +
> +	if (p.expectedZ != DONT_CARE_Z) {
> +		GLfloat z;
> +		/* read z at center of quad */
> +		glReadPixels(piglit_width / 2, piglit_width / 2, 1, 1,
> +			     GL_DEPTH_COMPONENT, GL_FLOAT, &z);
> +		if (!equalDepth(z, p.expectedZ)) {
> +			reportZFailure(p.name, p.expectedZ, z);
> +			retVal = false;
> +			goto cleanup;
> +		}
> +	}
> +
> +	/* passed! */
> +	retVal = true;
> +
> +	if (0)			// debug
> +		printf("%s passed\n", p.name);
> +
> +      cleanup:
> +	if (fragShader)
> +		glDeleteShader(fragShader);
> +	if (vertShader)
> +		glDeleteShader(vertShader);
> +	glDeleteProgram(program);
> +
> +	return retVal;
> +}
> +
> +
> +bool
> +setup(void)
> +{
> +	/* 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);
> +
> +	GLenum err = glGetError();
> +	assert(!err);		/* should be OK */
> +
> +	/* setup vertex transform (we'll draw a quad in middle of window) */
> +	glMatrixMode(GL_PROJECTION);
> +	glLoadIdentity();
> +	glOrtho(-4.0, 4.0, -4.0, 4.0, 0.0, 1.0);
> +	glMatrixMode(GL_MODELVIEW);
> +	glLoadIdentity();
> +	glDrawBuffer(GL_FRONT);
> +	glReadBuffer(GL_FRONT);
> +
> +	/* compute error tolerances (may need fine-tuning) */
> +	int bufferBits[5];
> +	glGetIntegerv(GL_RED_BITS, &bufferBits[0]);
> +	glGetIntegerv(GL_GREEN_BITS, &bufferBits[1]);
> +	glGetIntegerv(GL_BLUE_BITS, &bufferBits[2]);
> +	glGetIntegerv(GL_ALPHA_BITS, &bufferBits[3]);
> +	glGetIntegerv(GL_DEPTH_BITS, &bufferBits[4]);
> +
> +	tolerance[0] = 2.0 / (1 << bufferBits[0]);
> +	tolerance[1] = 2.0 / (1 << bufferBits[1]);
> +	tolerance[2] = 2.0 / (1 << bufferBits[2]);
> +	if (bufferBits[3])
> +		tolerance[3] = 2.0 / (1 << bufferBits[3]);
> +	else
> +		tolerance[3] = 1.0;
> +	if (bufferBits[4])
> +		tolerance[4] = 16.0 / (1 << bufferBits[4]);
> +	else
> +		tolerance[4] = 1.0;
> +
> +	/* Some tests request a looser tolerance:
> +	 * XXX a factor of 4 may be too much...
> +	 */
> +	for (int i = 0; i < 5; i++)

Can't declare int i inside the loop in C.


> +		looseTolerance[i] = 4.0 * tolerance[i];
> +
> +	return true;
> +}
> +
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	/* no initialization */
> +}
> +
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	bool pass = true;
> +
> +	if (!setup()) {
> +		pass = false;
> +		return PIGLIT_FAIL;
> +	}
> +
> +	/* If you just want to run a single sub-test, assign the name to singleTest. */
> +	const char *singleTest = getenv("PIGLIT_TEST");
> +	if (singleTest) {
> +		printf("glsl1: Running single test: %s\n", singleTest);
> +		for (int i = 0; Programs[i].name; i++) {

Can't declare int i there.


> +			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]) && pass;
> +				break;
> +			}
> +		}
> +	} else {
> +		/* loop over all tests */
> +		for (int i = 0; Programs[i].name; i++) {

Same thing there.


> +			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 */
> +			else {
> +				pass = testProgram(Programs[i]) && pass;
> +			}
> +		}
> +	}
> +
> +	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
>
On Wed, Oct 7, 2015 at 1:48 AM, Juliet Fru <julietfru@gmail.com> wrote:
> This test replaces the original tglsl1.cpp test
> ---
>  tests/all.py                        |    1 +
>  tests/spec/gl-1.0/CMakeLists.gl.txt |    1 +
>  tests/spec/gl-1.0/shading-lang.c    | 1939 +++++++++++++++++++++++++++++++++++
>  3 files changed, 1941 insertions(+)
>  create mode 100644 tests/spec/gl-1.0/shading-lang.c

I don't like this at all. These tests should become shader_test files
-- not just a straight port from glean to the piglit framework.
Hi,

Alright, I  will make these changes and send in the patch.

Thanks,
Juliet

On Thu, Oct 8, 2015 at 3:31 AM, Matt Turner <mattst88@gmail.com> wrote:

> On Wed, Oct 7, 2015 at 1:48 AM, Juliet Fru <julietfru@gmail.com> wrote:
> > This test replaces the original tglsl1.cpp test
> > ---
> >  tests/all.py                        |    1 +
> >  tests/spec/gl-1.0/CMakeLists.gl.txt |    1 +
> >  tests/spec/gl-1.0/shading-lang.c    | 1939
> +++++++++++++++++++++++++++++++++++
> >  3 files changed, 1941 insertions(+)
> >  create mode 100644 tests/spec/gl-1.0/shading-lang.c
>
> I don't like this at all. These tests should become shader_test files
> -- not just a straight port from glean to the piglit framework.
>
Please post a plan for what you're doing before you do all the work to 
make sure you don't do anything unnecessary.

Like I said before, most of the glsl1 tests should already be covered by 
existing shader runner tests.  There's probably not too many that need 
to be ported.

-Brian

On 10/10/2015 12:43 PM, Juliet Fru wrote:
> Hi,
>
> Alright, I  will make these changes and send in the patch.
>
> Thanks,
> Juliet
>
> On Thu, Oct 8, 2015 at 3:31 AM, Matt Turner <mattst88@gmail.com
> <mailto:mattst88@gmail.com>> wrote:
>
>     On Wed, Oct 7, 2015 at 1:48 AM, Juliet Fru <julietfru@gmail.com
>     <mailto:julietfru@gmail.com>> wrote:
>     > This test replaces the original tglsl1.cpp test
>     > ---
>     >  tests/all.py                        |    1 +
>     >  tests/spec/gl-1.0/CMakeLists.gl.txt |    1 +
>     >  tests/spec/gl-1.0/shading-lang.c    | 1939 +++++++++++++++++++++++++++++++++++
>     >  3 files changed, 1941 insertions(+)
>     >  create mode 100644 tests/spec/gl-1.0/shading-lang.c
>
>     I don't like this at all. These tests should become shader_test files
>     -- not just a straight port from glean to the piglit framework.
>
>
>
>
> _______________________________________________
> Piglit mailing list
> Piglit@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
>
Hello Brian,

Please post a plan for what you're doing before you do all the work to make
> sure you don't do anything unnecessary.
>
> Like I said before, most of the glsl1 tests should already be covered by
> existing shader runner tests.  There's probably not too many that need to
> be ported.
>
>
>>     I don't like this at all. These tests should become shader_test files
>>     -- not just a straight port from glean to the piglit framework.
>>
>
I have been looking at the shader_test files and the shader_lang tests I
see they're covered in the shader directory. I don't know if porting this
test is necessary if not I'll like to know which tests should be moved as
the shader_test files.

Thanks for the assistance,
Juliet
On 10/14/2015 02:33 AM, Juliet Fru wrote:
> Hello Brian,
>
>     Please post a plan for what you're doing before you do all the work
>     to make sure you don't do anything unnecessary.
>
>     Like I said before, most of the glsl1 tests should already be
>     covered by existing shader runner tests.  There's probably not too
>     many that need to be ported.
>
>
>              I don't like this at all. These tests should become
>         shader_test files
>              -- not just a straight port from glean to the piglit framework.
>
>
> I have been looking at the shader_test files and the shader_lang tests I
> see they're covered in the shader directory. I don't know if porting
> this test is necessary if not I'll like to know which tests should be
> moved as the shader_test files.

I think just a hand-full of tests could be ported to shader_runner tests.

"current name" and (place to put new test):

"gl_Position not written check"  (tests/spec/glsl-1.10/linker/)

"varying var mismatch"    (tests/spec/glsl-1.10/linker/)

"varying read but not written"  (tests/spec/glsl-1.10/linker/)

"illegal assignment"   (tests/spec/glsl-1.10/compiler/)

"continue with no loop"   (tests/spec/glsl-1.10/compiler/)

"break with no loop"      (tests/spec/glsl-1.10/compiler/)

"if (boolean-scalar) check"  (tests/spec/glsl-1.10/compiler/)


There _may_ be shader runner tests already for some of these, but I 
didn't find them with a quick search.

-Brian
Thanks, I will look at them As soon as possible.

On Wed, Oct 14, 2015 at 6:09 PM, Brian Paul <brianp@vmware.com> wrote:

> On 10/14/2015 02:33 AM, Juliet Fru wrote:
>
>> Hello Brian,
>>
>>     Please post a plan for what you're doing before you do all the work
>>     to make sure you don't do anything unnecessary.
>>
>>     Like I said before, most of the glsl1 tests should already be
>>     covered by existing shader runner tests.  There's probably not too
>>     many that need to be ported.
>>
>>
>>              I don't like this at all. These tests should become
>>         shader_test files
>>              -- not just a straight port from glean to the piglit
>> framework.
>>
>>
>> I have been looking at the shader_test files and the shader_lang tests I
>> see they're covered in the shader directory. I don't know if porting
>> this test is necessary if not I'll like to know which tests should be
>> moved as the shader_test files.
>>
>
> I think just a hand-full of tests could be ported to shader_runner tests.
>
> "current name" and (place to put new test):
>
> "gl_Position not written check"  (tests/spec/glsl-1.10/linker/)
>
> "varying var mismatch"    (tests/spec/glsl-1.10/linker/)
>
> "varying read but not written"  (tests/spec/glsl-1.10/linker/)
>
> "illegal assignment"   (tests/spec/glsl-1.10/compiler/)
>
> "continue with no loop"   (tests/spec/glsl-1.10/compiler/)
>
> "break with no loop"      (tests/spec/glsl-1.10/compiler/)
>
> "if (boolean-scalar) check"  (tests/spec/glsl-1.10/compiler/)
>
>
> There _may_ be shader runner tests already for some of these, but I didn't
> find them with a quick search.
>
> -Brian
>
>
Hi Brian,

I have been working on the "gl_Position not written check"
(tests/spec/glsl-1.10/linker/) test from glean to shader_test files. Here
<http://lpaste.net/143421> is what I have so far.  I'm sure there may be
some errors since this test does not have the fragment shader aspects. I am
not very familiar with shader_test files. I will appreciate if you could
correct this sample test so I could submit the patch and move on to the
others.

Thanks,
Juliet

On Wed, Oct 14, 2015 at 9:18 PM, Juliet Fru <julietfru@gmail.com> wrote:

> Thanks, I will look at them As soon as possible.
>
> On Wed, Oct 14, 2015 at 6:09 PM, Brian Paul <brianp@vmware.com> wrote:
>
>> On 10/14/2015 02:33 AM, Juliet Fru wrote:
>>
>>> Hello Brian,
>>>
>>>     Please post a plan for what you're doing before you do all the work
>>>     to make sure you don't do anything unnecessary.
>>>
>>>     Like I said before, most of the glsl1 tests should already be
>>>     covered by existing shader runner tests.  There's probably not too
>>>     many that need to be ported.
>>>
>>>
>>>              I don't like this at all. These tests should become
>>>         shader_test files
>>>              -- not just a straight port from glean to the piglit
>>> framework.
>>>
>>>
>>> I have been looking at the shader_test files and the shader_lang tests I
>>> see they're covered in the shader directory. I don't know if porting
>>> this test is necessary if not I'll like to know which tests should be
>>> moved as the shader_test files.
>>>
>>
>> I think just a hand-full of tests could be ported to shader_runner tests.
>>
>> "current name" and (place to put new test):
>>
>> "gl_Position not written check"  (tests/spec/glsl-1.10/linker/)
>>
>> "varying var mismatch"    (tests/spec/glsl-1.10/linker/)
>>
>> "varying read but not written"  (tests/spec/glsl-1.10/linker/)
>>
>> "illegal assignment"   (tests/spec/glsl-1.10/compiler/)
>>
>> "continue with no loop"   (tests/spec/glsl-1.10/compiler/)
>>
>> "break with no loop"      (tests/spec/glsl-1.10/compiler/)
>>
>> "if (boolean-scalar) check"  (tests/spec/glsl-1.10/compiler/)
>>
>>
>> There _may_ be shader runner tests already for some of these, but I
>> didn't find them with a quick search.
>>
>> -Brian
>>
>>
>
For that particular test, we want to check that glLinkProgram() fails if 
the vertex shader(s) do not write anything to gl_Position.

In tests/all.py, look for 'glsl-link-test'.  For example:

     g(['glsl-link-test',
        os.path.join('shaders', 'glsl-link-initializer-06a.vert'),
        os.path.join('shaders', 'glsl-link-initializer-06b.vert'),
        'fail'],
       'GLSL link mismatched global initializer expression')

That's an example of a test that checks for linker failure.

So, you basically have to write a "no_gl_Position_written.vert" file 
something like:

void main()
{
    // no gl_Position writen
    gl_Color = vec4(1,0,0,0);
}

Then, add a new glsl-link-test entry to tests/all.py something like:

g(['glsl-link-test',
    os.path.join('shaders', 'no_gl_Position_written.vert'),
    'fail'],
    'GLSL no gl_Position written')

-Brian



On 10/20/2015 01:16 AM, Juliet Fru wrote:
> Hi Brian,
>
> I have been working on the "gl_Position not written check"
> (tests/spec/glsl-1.10/linker/) test from glean to shader_test files.Here
> <https://urldefense.proofpoint.com/v2/url?u=http-3A__lpaste.net_143421&d=BQMFaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=T0t4QG7chq2ZwJo6wilkFznRSFy-8uDKartPGbomVj8&m=yfrQSo9Fno7mAdRZoONhd1wCWAt7NnrVz7Fiq5aYTII&s=AWRlfQv7r-bCgVf2cWbOD9ApCYGLhMBjLUIpYtcLUo4&e=>
> is what I have so far.  I'm sure there may be some errors since this
> test does not have the fragment shader aspects. I am not very familiar
> with shader_test files. I will appreciate if you could correct this
> sample test so I could submit the patch and move on to the others.
>
> Thanks,
> Juliet
>
> On Wed, Oct 14, 2015 at 9:18 PM, Juliet Fru <julietfru@gmail.com
> <mailto:julietfru@gmail.com>> wrote:
>
>     Thanks, I will look at them As soon as possible.
>
>     On Wed, Oct 14, 2015 at 6:09 PM, Brian Paul <brianp@vmware.com
>     <mailto:brianp@vmware.com>> wrote:
>
>         On 10/14/2015 02:33 AM, Juliet Fru wrote:
>
>             Hello Brian,
>
>                  Please post a plan for what you're doing before you do
>             all the work
>                  to make sure you don't do anything unnecessary.
>
>                  Like I said before, most of the glsl1 tests should
>             already be
>                  covered by existing shader runner tests.  There's
>             probably not too
>                  many that need to be ported.
>
>
>                           I don't like this at all. These tests should
>             become
>                      shader_test files
>                           -- not just a straight port from glean to the
>             piglit framework.
>
>
>             I have been looking at the shader_test files and the
>             shader_lang tests I
>             see they're covered in the shader directory. I don't know if
>             porting
>             this test is necessary if not I'll like to know which tests
>             should be
>             moved as the shader_test files.
>
>
>         I think just a hand-full of tests could be ported to
>         shader_runner tests.
>
>         "current name" and (place to put new test):
>
>         "gl_Position not written check"  (tests/spec/glsl-1.10/linker/)
>
>         "varying var mismatch"    (tests/spec/glsl-1.10/linker/)
>
>         "varying read but not written"  (tests/spec/glsl-1.10/linker/)
>
>         "illegal assignment"   (tests/spec/glsl-1.10/compiler/)
>
>         "continue with no loop"   (tests/spec/glsl-1.10/compiler/)
>
>         "break with no loop"      (tests/spec/glsl-1.10/compiler/)
>
>         "if (boolean-scalar) check"  (tests/spec/glsl-1.10/compiler/)
>
>
>         There _may_ be shader runner tests already for some of these,
>         but I didn't find them with a quick search.
>
>         -Brian
>
>
>
On Tue, Oct 20, 2015 at 12:16 AM, Juliet Fru <julietfru@gmail.com> wrote:
> Hi Brian,
>
> I have been working on the "gl_Position not written check"
> (tests/spec/glsl-1.10/linker/) test from glean to shader_test files. Here is
> what I have so far.  I'm sure there may be some errors since this test does
> not have the fragment shader aspects. I am not very familiar with
> shader_test files. I will appreciate if you could correct this sample test
> so I could submit the patch and move on to the others.

Hi Juliet,

I was going to port the fragment/vertex program (tfragprog1.cpp,
tvertprog1.cpp) tests in glean to regular shader_test files, but I
don't want to collide with anything you're doing. I haven't seen
anything from you in more than three weeks, so I think your project
might be complete? Can you confirm your status?

Thanks,
Matt
Hi Matt,

My project is complete, but I was working on porting some of these tests to
shader_test files. By all means you can port them, I'll take it from where
you end.

Thanks,
Juliet

On Sat, Nov 14, 2015 at 3:46 AM, Matt Turner <mattst88@gmail.com> wrote:

> On Tue, Oct 20, 2015 at 12:16 AM, Juliet Fru <julietfru@gmail.com> wrote:
> > Hi Brian,
> >
> > I have been working on the "gl_Position not written check"
> > (tests/spec/glsl-1.10/linker/) test from glean to shader_test files.
> Here is
> > what I have so far.  I'm sure there may be some errors since this test
> does
> > not have the fragment shader aspects. I am not very familiar with
> > shader_test files. I will appreciate if you could correct this sample
> test
> > so I could submit the patch and move on to the others.
>
> Hi Juliet,
>
> I was going to port the fragment/vertex program (tfragprog1.cpp,
> tvertprog1.cpp) tests in glean to regular shader_test files, but I
> don't want to collide with anything you're doing. I haven't seen
> anything from you in more than three weeks, so I think your project
> might be complete? Can you confirm your status?
>
> Thanks,
> Matt
>