summaryrefslogtreecommitdiffstats
path: root/progs/slang
diff options
context:
space:
mode:
authorMichal Krol <[email protected]>2006-05-16 09:32:30 +0000
committerMichal Krol <[email protected]>2006-05-16 09:32:30 +0000
commit32c2f939e6ddf840285c40253f78e025d4377d61 (patch)
tree9cbe9be9bd33a24e4fdde18fe8aae3a0be10daeb /progs/slang
parent2ca741ad4b95ce5c91b99c4628e5e5e256f3e1d9 (diff)
GLSL regression test suite.
Diffstat (limited to 'progs/slang')
-rw-r--r--progs/slang/cltest.c253
-rw-r--r--progs/slang/cltest.txt1402
-rw-r--r--progs/slang/framework.c144
-rw-r--r--progs/slang/framework.h79
-rw-r--r--progs/slang/sotest.c439
-rw-r--r--progs/slang/vstest.c340
-rw-r--r--progs/slang/vstest.txt68
-rw-r--r--progs/slang/windows/vc60/cltest.dsp94
-rw-r--r--progs/slang/windows/vc60/framework.dsp92
-rw-r--r--progs/slang/windows/vc60/slang.dsw74
-rw-r--r--progs/slang/windows/vc60/sotest.dsp90
-rw-r--r--progs/slang/windows/vc60/vstest.dsp93
12 files changed, 3168 insertions, 0 deletions
diff --git a/progs/slang/cltest.c b/progs/slang/cltest.c
new file mode 100644
index 00000000000..5736f3eab10
--- /dev/null
+++ b/progs/slang/cltest.c
@@ -0,0 +1,253 @@
+/*
+ * GL_ARB_shading_language_100 test application.
+ *
+ * Tests correctness of emited code. Runs multiple well-formed shaders and checks if
+ * they produce valid results.
+ *
+ * Requires specific support on the GL implementation side. A special function printMESA()
+ * must be supported in the language that prints current values of generic type
+ * to the appropriate shader's info log, and optionally to the screen.
+ *
+ * Author: Michal Krol
+ */
+
+#include "framework.h"
+
+#define EPSILON 0.0001f
+
+static GLhandleARB vert = 0;
+static GLhandleARB prog = 0;
+
+static int get_line (FILE *f, char *line, int size)
+{
+ if (fgets (line, size, f) == NULL)
+ return 0;
+ if (line[strlen (line) - 1] == '\n')
+ line[strlen (line) - 1] = '\0';
+ return 1;
+}
+
+struct ATTRIB
+{
+ char name[32];
+ GLfloat value[64][4];
+ GLuint count;
+};
+
+struct ATTRIBS
+{
+ struct ATTRIB attrib[32];
+ GLuint count;
+};
+
+struct SHADER
+{
+ char code[16000];
+ GLfloat output[1000];
+ GLuint count;
+};
+
+enum SHADER_LOAD_STATE
+{
+ SLS_NONE,
+ SLS_CODE,
+ SLS_OUTPUT
+};
+
+struct PROGRAM
+{
+ struct PROGRAM *next;
+ char name[256];
+ struct ATTRIBS attribs;
+ struct SHADER vertex;
+};
+
+enum PROGRAM_LOAD_STATE
+{
+ PLS_NONE,
+ PLS_ATTRIB,
+ PLS_VERTEX
+};
+
+static struct PROGRAM *program = NULL;
+
+static void load_test_file (const char *filename, struct PROGRAM **program)
+{
+ struct PROGRAM **currprog = program;
+ FILE *f;
+ char line[256];
+ enum PROGRAM_LOAD_STATE pls;
+ enum SHADER_LOAD_STATE sls;
+
+ f = fopen (filename, "r");
+ if (f == NULL)
+ return;
+
+ while (get_line (f, line, sizeof (line))) {
+ if (line[0] == '$') {
+ if (strncmp (line + 1, "program", 7) == 0) {
+ if (*currprog != NULL)
+ currprog = &(**currprog).next;
+ *currprog = (struct PROGRAM *) (malloc (sizeof (struct PROGRAM)));
+ if (*currprog == NULL)
+ break;
+ (**currprog).next = NULL;
+ strcpy ((**currprog).name, line + 9);
+ (**currprog).attribs.count = 0;
+ (**currprog).vertex.code[0] = '\0';
+ (**currprog).vertex.count = 0;
+ pls = PLS_NONE;
+ }
+ else if (strncmp (line + 1, "attrib", 6) == 0) {
+ if (*currprog == NULL)
+ break;
+ strcpy ((**currprog).attribs.attrib[(**currprog).attribs.count].name, line + 8);
+ (**currprog).attribs.attrib[(**currprog).attribs.count].count = 0;
+ (**currprog).attribs.count++;
+ pls = PLS_ATTRIB;
+ }
+ else if (strcmp (line + 1, "vertex") == 0) {
+ if (*currprog == NULL)
+ break;
+ pls = PLS_VERTEX;
+ sls = SLS_NONE;
+ }
+ else if (strcmp (line + 1, "code") == 0) {
+ if (*currprog == NULL || pls != PLS_VERTEX)
+ break;
+ sls = SLS_CODE;
+ }
+ else if (strcmp (line + 1, "output") == 0) {
+ if (*currprog == NULL || pls != PLS_VERTEX)
+ break;
+ sls = SLS_OUTPUT;
+ }
+ }
+ else {
+ if ((*currprog == NULL || pls == PLS_NONE || sls == SLS_NONE) && line[0] != '\0')
+ break;
+ if (*currprog != NULL && pls == PLS_VERTEX) {
+ if (sls == SLS_CODE) {
+ strcat ((**currprog).vertex.code, line);
+ strcat ((**currprog).vertex.code, "\n");
+ }
+ else if (sls == SLS_OUTPUT && line[0] != '\0') {
+ if (strcmp (line, "true") == 0)
+ (**currprog).vertex.output[(**currprog).vertex.count] = 1.0f;
+ else if (strcmp (line, "false") == 0)
+ (**currprog).vertex.output[(**currprog).vertex.count] = 0.0f;
+ else
+ sscanf (line, "%f", &(**currprog).vertex.output[(**currprog).vertex.count]);
+ (**currprog).vertex.count++;
+ }
+ }
+ else if (*currprog != NULL && pls == PLS_ATTRIB && line[0] != '\0') {
+ struct ATTRIB *att = &(**currprog).attribs.attrib[(**currprog).attribs.count - 1];
+ GLfloat *vec = att->value[att->count];
+ sscanf (line, "%f %f %f %f", &vec[0], &vec[1], &vec[2], &vec[3]);
+ att->count++;
+ }
+ }
+ }
+
+ fclose (f);
+}
+
+void InitScene (void)
+{
+ prog = glCreateProgramObjectARB ();
+ vert = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
+ glAttachObjectARB (prog, vert);
+ glDeleteObjectARB (vert);
+ load_test_file ("cltest.txt", &program);
+}
+
+void RenderScene (void)
+{
+ struct PROGRAM *nextprogram;
+ char *code;
+ GLint info_length, length;
+ char output[65000], *p;
+ GLuint i;
+
+ if (program == NULL)
+ exit (0);
+
+ code = program->vertex.code;
+ glShaderSourceARB (vert, 1, &code, NULL);
+ glCompileShaderARB (vert);
+ CheckObjectStatus (vert);
+
+ for (i = 0; i < program->attribs.count; i++) {
+ const char *name = program->attribs.attrib[i].name;
+ if (strcmp (name, "gl_Vertex") != 0)
+ glBindAttribLocationARB (prog, i, name);
+ }
+
+ glLinkProgramARB (prog);
+ CheckObjectStatus (prog);
+ glUseProgramObjectARB (prog);
+
+ printf ("\n--- %s\n", program->name);
+
+ glGetObjectParameterivARB (vert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_length);
+
+ glBegin (GL_POINTS);
+ if (program->attribs.count == 0) {
+ glVertex2f (0.0f, 0.0f);
+ }
+ else {
+ for (i = 0; i < program->attribs.attrib[0].count; i++) {
+ GLuint j;
+ for (j = 0; j < program->attribs.count; j++) {
+ GLuint n = (j + 1) % program->attribs.count;
+ GLfloat *vec = program->attribs.attrib[n].value[i];
+ const char *name = program->attribs.attrib[n].name;
+ if (strcmp (name, "gl_Vertex") == 0)
+ glVertex4fv (vec);
+ else
+ glVertexAttrib4fvARB (n, vec);
+ }
+ }
+ }
+ glEnd ();
+ glFlush ();
+
+ glGetInfoLogARB (vert, sizeof (output), &length, output);
+ p = output + info_length - 1;
+ for (i = 0; i < program->vertex.count; i++) {
+ GLfloat value;
+ if (p == NULL) {
+ printf ("*** %s\n", "I/O error");
+ break;
+ }
+ if (strncmp (p, "true", 4) == 0)
+ value = 1.0f;
+ else if (strncmp (p, "false", 5) == 0)
+ value = 0.0f;
+ else if (sscanf (p, "%f", &value) != 1) {
+ printf ("*** %s\n", "I/O error");
+ break;
+ }
+ if (fabs (value - program->vertex.output[i]) > EPSILON) {
+ printf ("*** Values are different, is %f, should be %f\n", value,
+ program->vertex.output[i]);
+ }
+ p = strchr (p, '\n');
+ if (p != NULL)
+ p++;
+ }
+ if (*p != '\0')
+ printf ("*** %s\n", "I/O error");
+
+ nextprogram = program->next;
+ free (program);
+ program = nextprogram;
+}
+
+int main (int argc, char *argv[])
+{
+ InitFramework (&argc, argv);
+ return 0;
+}
+
diff --git a/progs/slang/cltest.txt b/progs/slang/cltest.txt
new file mode 100644
index 00000000000..7d87e74a11e
--- /dev/null
+++ b/progs/slang/cltest.txt
@@ -0,0 +1,1402 @@
+$ /*
+$ Shader test script.
+$
+$ Author: Michal Krol
+$
+$ Comment line starts with dollar sign and white space.
+$
+$ $program <name> starts a new test program section called <name>. Contains all other sections.
+$
+$ $attrib <name> starts vertex data input section for attrib called <name>. Each line consists of
+$ four values that form single vertex attrib.
+$
+$ $vertex starts vertex shader section. Contains $code and &output sections.
+$
+$ $code starts source code section. All text in this section gets compiled into appropriate
+$ shader object.
+$
+$ $output starts shader execution results section. These are compared, value-by-value,
+$ with results of executing printMESA() functions within a shader.
+$ */
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test printMESA() function.
+$ */
+
+$program PRINT TEST
+
+$vertex
+
+$code
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (11.1);
+ printMESA (111);
+ printMESA (true);
+
+ printMESA (vec2 (22.1, 22.2));
+ printMESA (vec3 (33.1, 33.2, 33.3));
+ printMESA (vec4 (44.1, 44.2, 44.3, 44.4));
+
+ printMESA (ivec2 (221, 222));
+ printMESA (ivec3 (331, 332, 333));
+ printMESA (ivec4 (441, 442, 443, 444));
+
+ printMESA (bvec2 (false, true));
+ printMESA (bvec3 (true, true, false));
+ printMESA (bvec4 (true, false, true, false));
+
+ printMESA (mat2 (55.11, 55.12, 55.21, 55.22));
+ printMESA (mat3 (66.11, 66.12, 66.13,
+ 66.21, 66.22, 66.23,
+ 66.31, 66.32, 66.33));
+ printMESA (mat4 (77.11, 77.12, 77.13, 77.14,
+ 77.21, 77.22, 77.23, 77.24,
+ 77.31, 77.32, 77.33, 77.34,
+ 77.41, 77.42, 77.43, 77.44));
+}
+
+$output
+
+11.1
+111
+true
+
+22.1
+22.2
+33.1
+33.2
+33.3
+44.1
+44.2
+44.3
+44.4
+
+221
+222
+331
+332
+333
+441
+442
+443
+444
+
+false
+true
+true
+true
+false
+true
+false
+true
+false
+
+55.11
+55.12
+55.21
+55.22
+
+66.11
+66.12
+66.13
+66.21
+66.22
+66.23
+66.31
+66.32
+66.33
+
+77.11
+77.12
+77.13
+77.14
+77.21
+77.22
+77.23
+77.24
+77.31
+77.32
+77.33
+77.34
+77.41
+77.42
+77.43
+77.44
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test type casting.
+$ */
+
+$program TYPE CAST TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _Zero
+0.0 0.0 0.0 0.0
+
+$attrib _One
+1.1 0.0 0.0 0.0
+
+$attrib _Two
+2.2 0.0 0.0 0.0
+
+$attrib _MinusThree
+-3.3 0.0 0.0 0.0
+
+$vertex
+
+$code
+
+attribute float _Zero;
+attribute float _One;
+attribute float _Two;
+attribute float _MinusThree;
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (_Zero);
+ printMESA (_One);
+ printMESA (_Two);
+ printMESA (_MinusThree);
+
+ printMESA (float (_Zero));
+ printMESA (float (_One));
+ printMESA (float (_Two));
+ printMESA (float (_MinusThree));
+ printMESA (float (45.99));
+ printMESA (float (-6.17));
+
+ printMESA (bool (_Zero));
+ printMESA (bool (_One));
+ printMESA (bool (_Two));
+ printMESA (bool (_MinusThree));
+ printMESA (bool (45.99));
+ printMESA (bool (-6.17));
+ printMESA (bool (0.0001));
+ printMESA (bool (0.0));
+
+ printMESA (int (_Zero));
+ printMESA (int (_One));
+ printMESA (int (_Two));
+ printMESA (int (_MinusThree));
+ printMESA (int (45.99));
+ printMESA (int (45.22));
+ printMESA (int (-6.17));
+ printMESA (int (-6.87));
+}
+
+$output
+
+0.0
+1.1
+2.2
+-3.3
+
+0.0
+1.1
+2.2
+-3.3
+45.99
+-6.17
+
+false
+true
+true
+true
+true
+true
+true
+false
+
+0
+1
+2
+-3
+45
+45
+-6
+-6
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test vector swizzles.
+$ */
+
+$program SWIZZLE TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _One
+1.1 1.2 1.3 1.4
+
+$attrib _Two
+2.1 2.2 2.3 2.4
+
+$vertex
+
+$code
+
+attribute vec4 _One;
+attribute vec4 _Two;
+
+void assign5678 (out vec4 v)
+{
+ v.x = 5.5;
+ v.y = 6.6;
+ v.z = 7.7;
+ v.w = 8.8;
+}
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (_One);
+ printMESA (_Two);
+
+ printMESA (_One.x);
+ printMESA (_One.y);
+ printMESA (_One.z);
+ printMESA (_One.w);
+
+ printMESA (_Two.xy);
+ printMESA (_Two.yx);
+ printMESA (_Two.xw);
+ printMESA (_Two.wx);
+ printMESA (_Two.yz);
+ printMESA (_Two.zy);
+ printMESA (_Two.xz);
+ printMESA (_Two.zx);
+ printMESA (_Two.zw);
+ printMESA (_Two.wz);
+
+ printMESA (_One.xyz);
+ printMESA (_One.yzx);
+ printMESA (_One.zxy);
+ printMESA (_One.xzy);
+ printMESA (_One.yzw);
+ printMESA (_One.zwx);
+
+ printMESA (_Two.xyzw);
+ printMESA (_Two.yzwx);
+ printMESA (_Two.wzyx);
+ printMESA (_Two.zwyx);
+
+ printMESA (_One.xx);
+ printMESA (_One.zz);
+ printMESA (_One.ww);
+
+ printMESA (_Two.xxx);
+ printMESA (_Two.yyy);
+ printMESA (_Two.www);
+
+ printMESA (_One.xxxx);
+ printMESA (_One.zzzz);
+
+ printMESA (_Two.xxyy);
+ printMESA (_Two.wwxx);
+ printMESA (_Two.zxxw);
+
+ vec4 v;
+
+ v.zxwy = vec4 (5.5, 6.6, 7.7, 8.8);
+ printMESA (v);
+
+ assign5678 (v.ywxz);
+ printMESA (v);
+}
+
+$output
+
+1.1
+1.2
+1.3
+1.4
+2.1
+2.2
+2.3
+2.4
+
+1.1
+1.2
+1.3
+1.4
+
+2.1
+2.2
+2.2
+2.1
+2.1
+2.4
+2.4
+2.1
+2.2
+2.3
+2.3
+2.2
+2.1
+2.3
+2.3
+2.1
+2.3
+2.4
+2.4
+2.3
+
+1.1
+1.2
+1.3
+1.2
+1.3
+1.1
+1.3
+1.1
+1.2
+1.1
+1.3
+1.2
+1.2
+1.3
+1.4
+1.3
+1.4
+1.1
+
+2.1
+2.2
+2.3
+2.4
+2.2
+2.3
+2.4
+2.1
+2.4
+2.3
+2.2
+2.1
+2.3
+2.4
+2.2
+2.1
+
+1.1
+1.1
+1.3
+1.3
+1.4
+1.4
+
+2.1
+2.1
+2.1
+2.2
+2.2
+2.2
+2.4
+2.4
+2.4
+
+1.1
+1.1
+1.1
+1.1
+1.3
+1.3
+1.3
+1.3
+
+2.1
+2.1
+2.2
+2.2
+2.4
+2.4
+2.1
+2.1
+2.3
+2.1
+2.1
+2.4
+
+6.6
+8.8
+5.5
+7.7
+
+7.7
+5.5
+8.8
+6.6
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test relational operators.
+$ */
+
+$program RELATIONAL OPERATOR TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _Two
+2.0 0.0 0.0 0.0
+
+$attrib _Two2
+2.0 0.0 0.0 0.0
+
+$attrib _MinusThree
+-3.0 0.0 0.0 0.0
+
+$vertex
+
+$code
+
+attribute float _Two;
+attribute float _Two2;
+attribute float _MinusThree;
+
+struct foo
+{
+ float f;
+ vec4 v4;
+ vec3 v3;
+ mat4 m4;
+ int i;
+ bool b;
+};
+
+void printMESA (const in foo bar)
+{
+ printMESA (bar.f);
+ printMESA (bar.v4);
+ printMESA (bar.v3);
+ printMESA (bar.m4);
+ printMESA (bar.i);
+ printMESA (bar.b);
+}
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ int iTwo = int (_Two);
+ int iTwo2 = int (_Two2);
+ int iMinusThree = int (_MinusThree);
+
+ printMESA (_Two <= _Two);
+ printMESA (_Two <= _Two2);
+ printMESA (_Two <= _MinusThree);
+ printMESA (_MinusThree <= _Two);
+ printMESA (iTwo <= iTwo);
+ printMESA (iTwo <= iTwo2);
+ printMESA (iTwo <= iMinusThree);
+ printMESA (iMinusThree <= iTwo);
+
+ printMESA (_Two >= _Two);
+ printMESA (_Two >= _Two2);
+ printMESA (_Two >= _MinusThree);
+ printMESA (_MinusThree >= _Two);
+ printMESA (iTwo >= iTwo);
+ printMESA (iTwo >= iTwo2);
+ printMESA (iTwo >= iMinusThree);
+ printMESA (iMinusThree >= iTwo);
+
+ printMESA (_Two < _Two);
+ printMESA (_Two < _Two2);
+ printMESA (_Two < _MinusThree);
+ printMESA (_MinusThree < _Two);
+ printMESA (iTwo < iTwo);
+ printMESA (iTwo < iTwo2);
+ printMESA (iTwo < iMinusThree);
+ printMESA (iMinusThree < iTwo);
+
+ printMESA (_Two > _Two);
+ printMESA (_Two > _Two2);
+ printMESA (_Two > _MinusThree);
+ printMESA (_MinusThree > _Two);
+ printMESA (iTwo > iTwo);
+ printMESA (iTwo > iTwo2);
+ printMESA (iTwo > iMinusThree);
+ printMESA (iMinusThree > iTwo);
+
+ printMESA (_Two == _Two);
+ printMESA (_Two == _Two2);
+ printMESA (_Two == _MinusThree);
+ printMESA (_MinusThree == _MinusThree);
+ printMESA (iTwo == iTwo);
+ printMESA (iTwo == iTwo2);
+ printMESA (iTwo == iMinusThree);
+ printMESA (iMinusThree == iMinusThree);
+
+ printMESA (_Two != _Two);
+ printMESA (_Two != _Two2);
+ printMESA (_Two != _MinusThree);
+ printMESA (_MinusThree != _MinusThree);
+ printMESA (iTwo != iTwo);
+ printMESA (iTwo != iTwo2);
+ printMESA (iTwo != iMinusThree);
+ printMESA (iMinusThree != iMinusThree);
+
+ foo foo1;
+ foo1.f = 13.31;
+ foo1.v4 = vec4 (44.11, 44.22, 44.33, 44.44);
+ foo1.v3 = vec3 (33.11, 33.22, 33.33);
+ foo1.m4 = mat4 (17.88);
+ foo1.i = 666;
+ foo1.b = true;
+ printMESA (foo1);
+
+ // make foo2 the same as foo1
+ foo foo2;
+ foo2.f = 13.31;
+ foo2.v4 = vec4 (44.11, 44.22, 44.33, 44.44);
+ foo2.v3 = vec3 (33.11, 33.22, 33.33);
+ foo2.m4 = mat4 (17.88);
+ foo2.i = 666;
+ foo2.b = true;
+
+ printMESA (foo1 == foo2);
+ printMESA (foo1 != foo2);
+
+ // make them a little bit different
+ foo2.m4[2].y = 333.333;
+ printMESA (foo2);
+
+ printMESA (foo1 == foo2);
+ printMESA (foo1 != foo2);
+}
+
+$output
+
+true
+true
+false
+true
+true
+true
+false
+true
+
+true
+true
+true
+false
+true
+true
+true
+false
+
+false
+false
+false
+true
+false
+false
+false
+true
+
+false
+false
+true
+false
+false
+false
+true
+false
+
+true
+true
+false
+true
+true
+true
+false
+true
+
+false
+false
+true
+false
+false
+false
+true
+false
+
+13.31
+44.11
+44.22
+44.33
+44.44
+33.11
+33.22
+33.33
+17.88
+0.0
+0.0
+0.0
+0.0
+17.88
+0.0
+0.0
+0.0
+0.0
+17.88
+0.0
+0.0
+0.0
+0.0
+17.88
+666
+true
+
+true
+false
+
+13.31
+44.11
+44.22
+44.33
+44.44
+33.11
+33.22
+33.33
+17.88
+0.0
+0.0
+0.0
+0.0
+17.88
+0.0
+0.0
+0.0
+333.333
+17.88
+0.0
+0.0
+0.0
+0.0
+17.88
+666
+true
+
+false
+true
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test logical operators.
+$ */
+
+$program LOGICAL OPERATOR TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _False
+0.0 0.0 0.0 0.0
+
+$attrib _True
+1.0 0.0 0.0 0.0
+
+$attrib _False2
+0.0 0.0 0.0 0.0
+
+$attrib _True2
+1.0 0.0 0.0 0.0
+
+$vertex
+
+$code
+
+attribute float _False;
+attribute float _True;
+attribute float _False2;
+attribute float _True2;
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (_False);
+ printMESA (_True);
+ printMESA (_False2);
+ printMESA (_True2);
+
+ bool False = bool (_False);
+ bool True = bool (_True);
+ bool False2 = bool (_False2);
+ bool True2 = bool (_True2);
+
+ //
+ // It is important to test each operator with the following argument types:
+ // * Both arguments are different variables, even if they have the same values.
+ // False and False2 are distinct attributes, but are the same in value.
+ // * Both arguments may be the same variables. This case tests possible
+ // optimizations, e.g. X && X --> X.
+ // * Both arguments are constant. This tests constant folding.
+ //
+
+ printMESA (!False);
+ printMESA (!True);
+ printMESA (!false);
+ printMESA (!true);
+
+ printMESA (False ^^ False2);
+ printMESA (False ^^ True2);
+ printMESA (True ^^ False2);
+ printMESA (True ^^ True2);
+ printMESA (False ^^ False);
+ printMESA (False ^^ True);
+ printMESA (True ^^ False);
+ printMESA (True ^^ True);
+ printMESA (false ^^ false);
+ printMESA (false ^^ true);
+ printMESA (true ^^ false);
+ printMESA (true ^^ true);
+
+ printMESA (False && False2);
+ printMESA (False && True2);
+ printMESA (True && False2);
+ printMESA (True && True2);
+ printMESA (False && False);
+ printMESA (False && True);
+ printMESA (True && False);
+ printMESA (True && True);
+ printMESA (false && false);
+ printMESA (false && true);
+ printMESA (true && false);
+ printMESA (true && true);
+
+ printMESA (False || False2);
+ printMESA (False || True2);
+ printMESA (True || False2);
+ printMESA (True || True2);
+ printMESA (False || False);
+ printMESA (False || True);
+ printMESA (True || False);
+ printMESA (True || True);
+ printMESA (false || false);
+ printMESA (false || true);
+ printMESA (true || false);
+ printMESA (true || true);
+
+ //
+ // Test short-circuit evaluation of && and ||. The right expression evaluation depends
+ // on the value of the left expression. If the right expression has side effects, we
+ // can easily test if it happened.
+ //
+
+ bool x;
+
+ x = false;
+ printMESA (x);
+ printMESA (False && (x = true));
+ printMESA (x);
+
+ x = false;
+ printMESA (x);
+ printMESA (false && (x = true));
+ printMESA (x);
+
+ x = true;
+ printMESA (x);
+ printMESA (True || (x = false));
+ printMESA (x);
+
+ x = true;
+ printMESA (x);
+ printMESA (true || (x = false));
+ printMESA (x);
+}
+
+$output
+
+0.0
+1.0
+0.0
+1.0
+
+true
+false
+true
+false
+
+false
+true
+true
+false
+false
+true
+true
+false
+false
+true
+true
+false
+
+false
+false
+false
+true
+false
+false
+false
+true
+false
+false
+false
+true
+
+false
+true
+true
+true
+false
+true
+true
+true
+false
+true
+true
+true
+
+false
+false
+false
+
+false
+false
+false
+
+true
+true
+true
+
+true
+true
+true
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test subscript operator/array access.
+$ */
+
+$program ARRAY ACCESS TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _Zero
+0.0 0.0 0.0 0.0
+
+$attrib _One
+1.1 0.0 0.0 0.0
+
+$attrib _Two
+2.9 0.0 0.0 0.0
+
+$attrib _Vec
+11.11 22.22 33.33 44.44
+
+$vertex
+
+$code
+
+attribute float _Zero;
+attribute float _One;
+attribute float _Two;
+attribute vec4 _Vec;
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (_Zero);
+ printMESA (_One);
+ printMESA (_Two);
+ printMESA (_Vec);
+
+ printMESA (_Vec[0]);
+ printMESA (_Vec[1]);
+ printMESA (_Vec[2]);
+ printMESA (_Vec[3]);
+
+ printMESA (_Vec[int (_Zero)]);
+ printMESA (_Vec[int (_One)]);
+ printMESA (_Vec[int (_Two)]);
+}
+
+$output
+
+0.0
+1.1
+2.9
+11.11
+22.22
+33.33
+44.44
+
+11.11
+22.22
+33.33
+44.44
+
+11.11
+22.22
+33.33
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test pre/post-increment/decrement operators.
+$ Note: assumes relational operators being correct.
+$ */
+
+$program PRE/POST-INC/DEC OPERATOR TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _Zero
+0.0 0.0 0.0 0.0
+
+$attrib _One
+1.1 0.0 0.0 0.0
+
+$attrib _Two4
+2.1 2.2 2.3 2.4
+
+$vertex
+
+$code
+
+attribute float _Zero;
+attribute float _One;
+attribute vec4 _Two4;
+
+float fZero, fOne;
+vec4 fTwo4;
+int iZero, iOne;
+ivec4 iTwo4;
+
+void reset () {
+ fZero = _Zero;
+ fOne = _One;
+ fTwo4 = _Two4;
+ iZero = int (_Zero);
+ iOne = int (_One);
+ iTwo4 = ivec4 (_Two4);
+}
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (_Zero);
+ printMESA (_One);
+ printMESA (_Two4);
+
+ // pre-increment
+ reset ();
+ printMESA (++fZero);
+ printMESA (++fOne);
+ printMESA (++iZero);
+ printMESA (++iOne);
+ printMESA (fZero);
+ printMESA (fOne);
+ printMESA (iZero);
+ printMESA (iOne);
+ printMESA (++fTwo4 == _Two4 + 1.0);
+ printMESA (++iTwo4 == ivec4 (_Two4) + 1);
+
+ // pre-decrement
+ reset ();
+ printMESA (--fZero);
+ printMESA (--fOne);
+ printMESA (--iZero);
+ printMESA (--iOne);
+ printMESA (fZero);
+ printMESA (fOne);
+ printMESA (iZero);
+ printMESA (iOne);
+ printMESA (--fTwo4 == _Two4 - 1.0);
+ printMESA (--iTwo4 == ivec4 (_Two4) - 1);
+
+ // post-increment
+ reset ();
+ printMESA (fZero++);
+ printMESA (fOne++);
+ printMESA (iZero++);
+ printMESA (iOne++);
+ printMESA (fZero);
+ printMESA (fOne);
+ printMESA (iZero);
+ printMESA (iOne);
+ printMESA (fTwo4++ == _Two4);
+ printMESA (iTwo4++ == ivec4 (_Two4));
+
+ // post-decrement
+ reset ();
+ printMESA (fZero--);
+ printMESA (fOne--);
+ printMESA (iZero--);
+ printMESA (iOne--);
+ printMESA (fZero);
+ printMESA (fOne);
+ printMESA (iZero);
+ printMESA (iOne);
+ printMESA (fTwo4-- == _Two4);
+ printMESA (iTwo4-- == ivec4 (_Two4));
+}
+
+$output
+
+0.0
+1.1
+2.1
+2.2
+2.3
+2.4
+
+1.0
+2.1
+1
+2
+1.0
+2.1
+1
+2
+true
+true
+
+-1.0
+0.1
+-1
+0
+-1.0
+0.1
+-1
+0
+true
+true
+
+0.0
+1.1
+0
+1
+1.0
+2.1
+1
+2
+true
+true
+
+0.0
+1.1
+0
+1
+-1.0
+0.1
+-1
+0
+true
+true
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test arithmetical operators.
+$ */
+
+$program ARITHMETICAL OPERATOR TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _Zero
+0.0 0.0 0.0 0.0
+
+$attrib _One
+1.1 0.0 0.0 0.0
+
+$attrib _Two4
+2.1 2.2 2.3 2.4
+
+$vertex
+
+$code
+
+attribute float _Zero;
+attribute float _One;
+attribute vec4 _Two4;
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (_Zero);
+ printMESA (_One);
+ printMESA (_Two4);
+
+ int iZero = int (_Zero);
+ int iOne = int (_One);
+ ivec4 iTwo4 = ivec4 (_Two4);
+
+ printMESA (-_Zero);
+ printMESA (-_One);
+ printMESA (-_Two4);
+ printMESA (-_Two4.z);
+
+ printMESA (_Zero + 0.0);
+ printMESA (_One + 0.0);
+ printMESA (_Two4 + 0.0);
+ printMESA (_Two4.y + 0.0);
+
+ printMESA (_Zero + _Zero);
+ printMESA (_Zero + _One);
+ printMESA (_Zero + _Two4);
+ printMESA (_One + _Zero);
+ printMESA (_One + _Two4);
+ printMESA (_Two4 + _Two4);
+
+ printMESA (_Zero - 0.0);
+ printMESA (_One - 0.0);
+ printMESA (_Two4 - 0.0);
+ printMESA (_Two4.y - 0.0);
+
+ printMESA (_Zero - _Zero);
+ printMESA (_Zero - _One);
+ printMESA (_Zero - _Two4);
+ printMESA (_One - _Zero);
+ printMESA (_One - _Two4);
+ printMESA (_Two4 - _Two4);
+
+ printMESA (_Zero * 1.0);
+ printMESA (_One * 1.0);
+ printMESA (_Two4 * 1.0);
+ printMESA (_Two4.x * 1.0);
+
+ printMESA (_Zero * _Zero);
+ printMESA (_Zero * _One);
+ printMESA (_Zero * _Two4);
+ printMESA (_One * _Zero);
+ printMESA (_One * _One);
+ printMESA (_One * _Two4);
+ printMESA (_Two4 * _Two4);
+
+ printMESA (_Zero / 1.0);
+ printMESA (_One / 1.0);
+ printMESA (_Two4 / 1.0);
+ printMESA (_Two4.x / 1.0);
+
+ printMESA (_Zero / _One);
+ printMESA (_Zero / _Two4);
+ printMESA (_One / _One);
+ printMESA (_One / _Two4);
+ printMESA (_Two4 / _Two4);
+}
+
+$output
+
+0.0
+1.1
+2.1
+2.2
+2.3
+2.4
+
+0.0
+-1.1
+-2.1
+-2.2
+-2.3
+-2.4
+-2.3
+
+0.0
+1.1
+2.1
+2.2
+2.3
+2.4
+2.2
+
+0.0
+1.1
+2.1
+2.2
+2.3
+2.4
+1.1
+3.2
+3.3
+3.4
+3.5
+4.2
+4.4
+4.6
+4.8
+
+0.0
+1.1
+2.1
+2.2
+2.3
+2.4
+2.2
+
+0.0
+-1.1
+-2.1
+-2.2
+-2.3
+-2.4
+1.1
+-1.0
+-1.1
+-1.2
+-1.3
+0.0
+0.0
+0.0
+0.0
+
+0.0
+1.1
+2.1
+2.2
+2.3
+2.4
+2.1
+
+0.0
+0.0
+0.0
+0.0
+0.0
+0.0
+0.0
+1.21
+2.31
+2.42
+2.53
+2.64
+4.41
+4.84
+5.29
+5.76
+
+0.0
+1.1
+2.1
+2.2
+2.3
+2.4
+2.1
+
+0.0
+0.0
+0.0
+0.0
+0.0
+1.0
+0.52381
+0.5
+0.47826
+0.45833
+1.0
+1.0
+1.0
+1.0
+
+
+$ /*
+$ --------------------------------------------------------------------------------------------------
+$ Test matrix operations.
+$ Note: assumes relational operators being correct.
+$ */
+
+$program MATRIX TEST
+
+$attrib gl_Vertex
+0.0 0.0 0.0 1.0
+
+$attrib _Zero
+0.0 0.0 0.0 0.0
+
+$attrib _One
+1.0 1.0 1.0 1.0
+
+$attrib _Two
+2.0 2.0 2.0 2.0
+
+$vertex
+
+$code
+
+attribute vec4 _Zero;
+attribute vec4 _One;
+attribute vec4 _Two;
+
+void main () {
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ printMESA (_Zero);
+ printMESA (_One);
+ printMESA (_Two);
+
+ mat4 Identity = mat4 (_One.x);
+
+ printMESA (Identity == mat4 (1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0));
+ printMESA (Identity * _Two == _Two);
+
+ mat4 Matrix = mat4 (1.1, 1.2, 1.3, 1.4,
+ 2.1, 2.2, 2.3, 2.4,
+ 3.1, 3.2, 3.3, 3.4,
+ 4.1, 4.2, 4.3, 4.4);
+
+ printMESA (Matrix[2].y);
+ printMESA (Matrix[1]);
+}
+
+$output
+
+0.0
+0.0
+0.0
+0.0
+1.0
+1.0
+1.0
+1.0
+2.0
+2.0
+2.0
+2.0
+true
+true
+3.2
+2.1
+2.2
+2.3
+2.4
+
diff --git a/progs/slang/framework.c b/progs/slang/framework.c
new file mode 100644
index 00000000000..80ee37f637f
--- /dev/null
+++ b/progs/slang/framework.c
@@ -0,0 +1,144 @@
+#include "framework.h"
+
+/*
+ * GL_ARB_multitexture
+ */
+PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
+PFNGLMULTITEXCOORD4FVARBPROC glMultiTexCoord4fvARB;
+
+/*
+ * GL_ARB_shader_objects
+ */
+PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
+PFNGLGETHANDLEARBPROC glGetHandleARB;
+PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
+PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
+PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
+PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
+PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
+PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
+PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
+PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
+PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
+PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
+PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
+
+/*
+ * GL_ARB_vertex_shader
+ */
+PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB;
+PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
+PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
+PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
+PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
+
+/*
+ * GL_EXT_fog_coord
+ */
+PFNGLFOGCOORDFVEXTPROC glFogCoordfvEXT;
+PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointerEXT;
+
+/*
+ * GL_EXT_secondary_color
+ */
+PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT;
+PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT;
+
+static void Display (void)
+{
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ RenderScene ();
+ glutSwapBuffers ();
+}
+
+static void Idle (void)
+{
+ glutPostRedisplay ();
+}
+
+void InitFramework (int *argc, char *argv[])
+{
+ glutInit (argc, argv);
+ glutInitWindowPosition (0, 0);
+ glutInitWindowSize (200, 200);
+ glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ glutCreateWindow (argv[0]);
+
+ GETPROCADDR(glClientActiveTextureARB, PFNGLCLIENTACTIVETEXTUREARBPROC);
+ GETPROCADDR(glMultiTexCoord4fvARB, PFNGLMULTITEXCOORD4FVARBPROC);
+
+ GETPROCADDR(glDeleteObjectARB, PFNGLDELETEOBJECTARBPROC);
+ GETPROCADDR(glGetHandleARB, PFNGLGETHANDLEARBPROC);
+ GETPROCADDR(glDetachObjectARB, PFNGLDETACHOBJECTARBPROC);
+ GETPROCADDR(glCreateShaderObjectARB, PFNGLCREATESHADEROBJECTARBPROC);
+ GETPROCADDR(glShaderSourceARB, PFNGLSHADERSOURCEARBPROC);
+ GETPROCADDR(glCompileShaderARB, PFNGLCOMPILESHADERARBPROC);
+ GETPROCADDR(glCreateProgramObjectARB, PFNGLCREATEPROGRAMOBJECTARBPROC);
+ GETPROCADDR(glAttachObjectARB, PFNGLATTACHOBJECTARBPROC);
+ GETPROCADDR(glLinkProgramARB, PFNGLLINKPROGRAMARBPROC);
+ GETPROCADDR(glUseProgramObjectARB, PFNGLUSEPROGRAMOBJECTARBPROC);
+ GETPROCADDR(glGetObjectParameterivARB, PFNGLGETOBJECTPARAMETERIVARBPROC);
+ GETPROCADDR(glGetInfoLogARB, PFNGLGETINFOLOGARBPROC);
+ GETPROCADDR(glGetUniformLocationARB, PFNGLGETUNIFORMLOCATIONARBPROC);
+
+ GETPROCADDR(glVertexAttrib4fvARB, PFNGLVERTEXATTRIB4FVARBPROC);
+ GETPROCADDR(glVertexAttribPointerARB, PFNGLVERTEXATTRIBPOINTERARBPROC);
+ GETPROCADDR(glEnableVertexAttribArrayARB, PFNGLENABLEVERTEXATTRIBARRAYARBPROC);
+ GETPROCADDR(glDisableVertexAttribArrayARB, PFNGLDISABLEVERTEXATTRIBARRAYARBPROC);
+ GETPROCADDR(glBindAttribLocationARB, PFNGLBINDATTRIBLOCATIONARBPROC);
+ GETPROCADDR(glGetAttribLocationARB, PFNGLGETATTRIBLOCATIONARBPROC);
+
+ GETPROCADDR(glFogCoordfvEXT, PFNGLFOGCOORDFVEXTPROC);
+ GETPROCADDR(glFogCoordPointerEXT, PFNGLFOGCOORDPOINTEREXTPROC);
+
+ GETPROCADDR(glSecondaryColor3fvEXT, PFNGLSECONDARYCOLOR3FVEXTPROC);
+ GETPROCADDR(glSecondaryColorPointerEXT, PFNGLSECONDARYCOLORPOINTEREXTPROC);
+
+ printf ("VENDOR: %s\n", glGetString (GL_VENDOR));
+ printf ("RENDERER: %s\n", glGetString (GL_RENDERER));
+
+ InitScene ();
+
+ /*glutReshapeFunc (Reshape);
+ glutKeyboardFunc (Key);
+ glutSpecialFunc (SpecialKey);*/
+ glutDisplayFunc (Display);
+ glutIdleFunc (Idle);
+ glutMainLoop ();
+}
+
+GLboolean CheckObjectStatus (GLhandleARB handle)
+{
+ GLint type, status, length;
+ GLcharARB *infolog;
+
+ glGetObjectParameterivARB (handle, GL_OBJECT_TYPE_ARB, &type);
+ if (type == GL_SHADER_OBJECT_ARB)
+ glGetObjectParameterivARB (handle, GL_OBJECT_COMPILE_STATUS_ARB, &status);
+ else if (type == GL_PROGRAM_OBJECT_ARB)
+ glGetObjectParameterivARB (handle, GL_OBJECT_LINK_STATUS_ARB, &status);
+ else {
+ assert (0);
+ return GL_FALSE;
+ }
+
+ if (status)
+ return GL_TRUE;
+
+ printf ("\n%s FAILED. INFO LOG FOLLOWS:\n",
+ type == GL_SHADER_OBJECT_ARB ? "SHADER COMPILE" : "PROGRAM LINK");
+
+ glGetObjectParameterivARB (handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
+ infolog = (GLcharARB *) (malloc (length));
+ if (infolog != NULL) {
+ glGetInfoLogARB (handle, length, NULL, infolog);
+ printf ("%s", infolog);
+ free (infolog);
+ }
+
+ printf ("\n");
+
+ return GL_FALSE;
+}
+
diff --git a/progs/slang/framework.h b/progs/slang/framework.h
new file mode 100644
index 00000000000..fe1c4cbd383
--- /dev/null
+++ b/progs/slang/framework.h
@@ -0,0 +1,79 @@
+#ifndef _FRAMEWORK_H_
+#define _FRAMEWORK_H_
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <GL/glext.h>
+
+#ifdef WIN32
+#define GETPROCADDRESS(x) wglGetProcAddress (x)
+#else
+#define GETPROCADDRESS(x) glutGetProcAddress (x)
+#endif
+
+#define GETPROCADDR(x,T) do { x = (T) (GETPROCADDRESS(#x)); assert (x != NULL); } while (0)
+
+/*
+ * GL_ARB_multitexture
+ */
+extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
+extern PFNGLMULTITEXCOORD4FVARBPROC glMultiTexCoord4fvARB;
+
+/*
+ * GL_ARB_shader_objects
+ */
+extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
+extern PFNGLGETHANDLEARBPROC glGetHandleARB;
+extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
+extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
+extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
+extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
+extern PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
+extern PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
+extern PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
+extern PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
+extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
+extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
+extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
+/*static PFNGLUNIFORM4FVARBPROC glUniform4fvARB = NULL;*/
+
+/*
+ * GL_ARB_vertex_shader
+ */
+extern PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB;
+extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
+extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
+extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
+extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
+
+/*
+ * GL_EXT_fog_coord
+ */
+extern PFNGLFOGCOORDFVEXTPROC glFogCoordfvEXT;
+extern PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointerEXT;
+
+/*
+ * GL_EXT_secondary_color
+ */
+extern PFNGLSECONDARYCOLOR3FVEXTPROC glSecondaryColor3fvEXT;
+extern PFNGLSECONDARYCOLORPOINTEREXTPROC glSecondaryColorPointerEXT;
+
+void InitFramework (int *argc, char *argv[]);
+
+extern void InitScene (void);
+extern void RenderScene (void);
+
+GLboolean CheckObjectStatus (GLhandleARB);
+
+#endif
+
diff --git a/progs/slang/sotest.c b/progs/slang/sotest.c
new file mode 100644
index 00000000000..4bd3bc23c92
--- /dev/null
+++ b/progs/slang/sotest.c
@@ -0,0 +1,439 @@
+/*
+ * GL_ARB_shader_objects & GL_ARB_vertex_shader interface test application.
+ * Neither compiler nor executor is being tested here, although some simple shader
+ * compilation tests are performed.
+ *
+ * Perfectly valid behaviour produces output that does not have a line
+ * beginning with three stars (***).
+ *
+ * Author: Michal Krol
+ */
+
+#include "framework.h"
+
+enum TEST_TYPE
+{
+ TT_GETERROR_NOERROR,
+ TT_GETERROR_INVALIDVALUE,
+ TT_GETERROR_INVALIDOPERATION,
+ TT_PARAM1_ZERO,
+ TT_PARAM1_NONZERO
+};
+
+static enum TEST_TYPE current_test;
+
+static void begintest (enum TEST_TYPE type, const char *name)
+{
+ current_test = type;
+ printf ("\n BEGIN TEST: %s\n", name);
+ while (glGetError () != GL_NO_ERROR)
+ ;
+}
+
+static void endtest1 (GLuint param1)
+{
+ const char *msg = NULL;
+
+ switch (current_test)
+ {
+ case TT_GETERROR_NOERROR:
+ if (glGetError () != GL_NO_ERROR)
+ msg = "glGetError () does not return GL_NO_ERROR";
+ break;
+ case TT_GETERROR_INVALIDVALUE:
+ if (glGetError () != GL_INVALID_VALUE)
+ msg = "glGetError () does not return GL_INVALID_VALUE";
+ break;
+ case TT_GETERROR_INVALIDOPERATION:
+ if (glGetError () != GL_INVALID_OPERATION)
+ msg = "glGetError () does not return GL_INVALID_OPERATION";
+ break;
+ case TT_PARAM1_ZERO:
+ if (param1)
+ msg = "The parameter is not zero";
+ break;
+ case TT_PARAM1_NONZERO:
+ if (!param1)
+ msg = "The parameter is not non-zero";
+ break;
+ default:
+ assert (0);
+ }
+
+ if (msg == NULL)
+ printf (" OK\n");
+ else
+ printf ("*** %s\n", msg);
+
+ while (glGetError () != GL_NO_ERROR)
+ ;
+}
+
+static void endtest ()
+{
+ endtest1 (0);
+}
+
+static GLhandleARB vert = 0;
+static GLhandleARB frag = 0;
+static GLhandleARB prog = 0;
+
+static GLhandleARB find_invalid_handle ()
+{
+ GLhandleARB handle;
+
+ for (handle = 1; handle < 16; handle++)
+ if (handle != vert && handle != frag && handle != prog)
+ return handle;
+ assert (0);
+ return 0;
+}
+
+static const char *invsynvertsrc =
+ "void main () {\n"
+ " gl_Position = gl_ModelViewMatrix ! gl_Vertex;\n" /* unexpected token */
+ "}\n"
+;
+
+static const char *invsemvertsrc =
+ "void main () {\n"
+ " gl_Position = gl_ModelviewMatrix * gl_Vertex;\n" /* undeclared identifier */
+ "}\n"
+;
+
+static const char *uniforms =
+ "uniform vec4 CommonUniform;\n"
+;
+
+static const char *validvertsrc =
+ "uniform vec4 VertexUniform;\n"
+ "attribute vec4 FirstAttrib;\n"
+ "attribute vec4 SecondAttrib;\n"
+ "void main () {\n"
+ " gl_Position = gl_ModelViewMatrix * gl_Vertex + CommonUniform + VertexUniform\n"
+ " + FirstAttrib + SecondAttrib;\n"
+ "}\n"
+;
+
+static const char *invsynfragsrc =
+ "void main () {\n"
+ " gl_FragColor = gl_Color\n" /* missing ; */
+ "}\n"
+;
+
+static const char *invsemfragsrc =
+ "void main () {\n"
+ " gl_FragColor = gl_FrontColor;\n" /* gl_FrontColor only in vertex shader */
+ "}\n"
+;
+
+static const char *validfragsrc =
+ "uniform vec4 FragmentUniform;\n"
+ "void main () {\n"
+ " gl_FragColor = gl_Color + CommonUniform + FragmentUniform;\n"
+ "}\n"
+;
+
+void InitScene (void)
+{
+ GLint params[1];
+ const char *tab[2];
+
+ /*
+ * GL should silently ignore calls that delete object 0.
+ */
+ begintest (TT_GETERROR_NOERROR, "glDeleteObject(0)");
+ glDeleteObjectARB (0);
+ endtest ();
+
+ /*
+ * GL generates an error on invalid object handle.
+ */
+ begintest (TT_GETERROR_INVALIDVALUE, "Pass invalid non-zero object handle");
+ glDeleteObjectARB (find_invalid_handle ());
+ endtest ();
+ glUseProgramObjectARB (find_invalid_handle ());
+ endtest ();
+
+ /*
+ * Create object. GL should return unique non-zero values.
+ */
+ begintest (TT_PARAM1_NONZERO, "Create object");
+ vert = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
+ endtest1 (vert);
+ frag = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB);
+ endtest1 (frag);
+ prog = glCreateProgramObjectARB ();
+ endtest1 (prog);
+ endtest1 (vert != frag && frag != prog && prog != vert);
+
+ /*
+ * Link empty program.
+ */
+ begintest (TT_PARAM1_NONZERO, "Link empty program");
+ glLinkProgramARB (prog);
+ endtest1 (CheckObjectStatus (prog));
+
+ /*
+ * Use empty program object. Empty program objects are valid.
+ */
+ begintest (TT_GETERROR_NOERROR, "Use empty program object");
+ glUseProgramObjectARB (prog);
+ endtest ();
+
+ /*
+ * Attach invalid object handles. Program object 0 should not be accepted.
+ */
+ begintest (TT_GETERROR_INVALIDVALUE, "Attach invalid object handle");
+ glAttachObjectARB (0, find_invalid_handle ());
+ endtest ();
+ glAttachObjectARB (0, frag);
+ endtest ();
+ glAttachObjectARB (find_invalid_handle (), find_invalid_handle ());
+ endtest ();
+ glAttachObjectARB (find_invalid_handle (), frag);
+ endtest ();
+ glAttachObjectARB (prog, find_invalid_handle ());
+ endtest ();
+
+ /*
+ * Attach valid object handles with wrong semantics.
+ */
+ begintest (TT_GETERROR_INVALIDOPERATION, "Attach object badly");
+ glAttachObjectARB (vert, frag);
+ endtest ();
+ glAttachObjectARB (vert, prog);
+ endtest ();
+ glAttachObjectARB (prog, prog);
+ endtest ();
+
+ /*
+ * Detach non-attached object.
+ */
+ begintest (TT_GETERROR_INVALIDOPERATION, "Detach non-attached object");
+ glDetachObjectARB (prog, vert);
+ endtest ();
+ glDetachObjectARB (prog, frag);
+ endtest ();
+
+ /*
+ * Attach shader.
+ */
+ begintest (TT_GETERROR_NOERROR, "Attach shader to program object");
+ glAttachObjectARB (prog, vert);
+ endtest ();
+ glAttachObjectARB (prog, frag);
+ endtest ();
+
+ /*
+ * Attach object twice.
+ */
+ begintest (TT_GETERROR_INVALIDOPERATION, "Attach object twice");
+ glAttachObjectARB (prog, vert);
+ endtest ();
+ glAttachObjectARB (prog, frag);
+ endtest ();
+
+ /*
+ * Detach attached object.
+ */
+ begintest (TT_GETERROR_NOERROR, "Detach attached object");
+ glDetachObjectARB (prog, vert);
+ endtest ();
+ glDetachObjectARB (prog, frag);
+ endtest ();
+
+ /*
+ * Attach shader again.
+ */
+ begintest (TT_GETERROR_NOERROR, "Attach shader again");
+ glAttachObjectARB (prog, vert);
+ endtest ();
+ glAttachObjectARB (prog, frag);
+ endtest ();
+
+ /*
+ * Delete attached object.
+ */
+ begintest (TT_GETERROR_NOERROR, "Delete attached object");
+ glDeleteObjectARB (vert);
+ endtest ();
+ glDeleteObjectARB (frag);
+ endtest ();
+
+ /*
+ * Query delete status. It should return TRUE. Object handles are still valid
+ * as they are referenced by program object container.
+ */
+ begintest (TT_PARAM1_NONZERO, "Query delete status");
+ glGetObjectParameterivARB (vert, GL_OBJECT_DELETE_STATUS_ARB, params);
+ endtest1 (params[0]);
+ glGetObjectParameterivARB (frag, GL_OBJECT_DELETE_STATUS_ARB, params);
+ endtest1 (params[0]);
+
+ /*
+ * Delete already deleted attached object. The behaviour is undefined, but we
+ * check for no errors. The object still exists, so the handle value is okay.
+ * In other words, these calls should be silently ignored by GL.
+ */
+ begintest (TT_GETERROR_NOERROR, "Delete already deleted attached object");
+ glDeleteObjectARB (vert);
+ endtest ();
+ glDeleteObjectARB (frag);
+ endtest ();
+
+ /*
+ * Compile shader source with syntax error.
+ */
+ begintest (TT_PARAM1_ZERO, "Compile shader source with syntax error");
+ glShaderSourceARB (vert, 1, &invsynvertsrc, NULL);
+ glCompileShaderARB (vert);
+ endtest1 (CheckObjectStatus (vert));
+ glShaderSourceARB (frag, 1, &invsynfragsrc, NULL);
+ glCompileShaderARB (frag);
+ endtest1 (CheckObjectStatus (frag));
+
+ /*
+ * Compile shader source with semantic error.
+ */
+ begintest (TT_PARAM1_ZERO, "Compile shader source with semantic error");
+ glShaderSourceARB (vert, 1, &invsemvertsrc, NULL);
+ glCompileShaderARB (vert);
+ endtest1 (CheckObjectStatus (vert));
+ glShaderSourceARB (frag, 1, &invsemfragsrc, NULL);
+ glCompileShaderARB (frag);
+ endtest1 (CheckObjectStatus (frag));
+
+ /*
+ * Link ill-formed vertex-fragment program.
+ */
+ begintest (TT_PARAM1_ZERO, "Link ill-formed vertex-fragment program");
+ glLinkProgramARB (prog);
+ endtest1 (CheckObjectStatus (prog));
+
+ /*
+ * Use badly linked program object.
+ */
+ begintest (TT_GETERROR_INVALIDOPERATION, "Use badly linked program object");
+ glUseProgramObjectARB (prog);
+ endtest ();
+
+ /*
+ * Compile well-formed shader source. Check if multi-string sources can be handled.
+ */
+ begintest (TT_PARAM1_NONZERO, "Compile well-formed shader source");
+ tab[0] = uniforms;
+ tab[1] = validvertsrc;
+ glShaderSourceARB (vert, 2, tab, NULL);
+ glCompileShaderARB (vert);
+ endtest1 (CheckObjectStatus (vert));
+ tab[0] = uniforms;
+ tab[1] = validfragsrc;
+ glShaderSourceARB (frag, 2, tab, NULL);
+ glCompileShaderARB (frag);
+ endtest1 (CheckObjectStatus (frag));
+
+ /*
+ * Link vertex-fragment program.
+ */
+ begintest (TT_PARAM1_NONZERO, "Link vertex-fragment program");
+ glLinkProgramARB (prog);
+ endtest1 (CheckObjectStatus (prog));
+
+ /*
+ * Use valid linked program object.
+ */
+ begintest (TT_GETERROR_NOERROR, "Use linked program object");
+ glUseProgramObjectARB (prog);
+ endtest ();
+
+ /*
+ * Get current program.
+ */
+ begintest (TT_PARAM1_NONZERO, "Get current program");
+ endtest1 (glGetHandleARB (GL_PROGRAM_OBJECT_ARB) == prog);
+
+ /*
+ * Use 0 program object.
+ */
+ begintest (TT_GETERROR_NOERROR, "Use 0 program object");
+ glUseProgramObjectARB (0);
+ endtest ();
+
+ /*
+ * Query uniform location. Uniforms with gl_ prefix cannot be queried.
+ */
+ begintest (TT_PARAM1_NONZERO, "Query uniform location");
+ endtest1 (glGetUniformLocationARB (prog, "gl_ModelViewMatrix") == -1);
+ endtest1 (glGetUniformLocationARB (prog, "UniformThatDoesNotExist") == -1);
+ endtest1 (glGetUniformLocationARB (prog, "") == -1);
+ endtest1 (glGetUniformLocationARB (prog, "CommonUniform") != -1);
+ endtest1 (glGetUniformLocationARB (prog, "VertexUniform") != -1);
+ endtest1 (glGetUniformLocationARB (prog, "FragmentUniform") != -1);
+
+ /*
+ * Query attrib location. Attribs with gl_ prefix cannot be queried.
+ * When gl_Vertex is used, none of the generic attribs can have index 0.
+ */
+ begintest (TT_PARAM1_NONZERO, "Query attrib location");
+ endtest1 (glGetAttribLocationARB (prog, "gl_Vertex") == -1);
+ endtest1 (glGetAttribLocationARB (prog, "AttribThatDoesNotExist") == -1);
+ endtest1 (glGetAttribLocationARB (prog, "") == -1);
+ endtest1 (glGetAttribLocationARB (prog, "FirstAttrib") > 0);
+ endtest1 (glGetAttribLocationARB (prog, "SecondAttrib") > 0);
+
+ /*
+ * Bind attrib locations, link and check if locations are correct.
+ */
+ begintest (TT_PARAM1_NONZERO, "Bind attrib location #1");
+ glBindAttribLocationARB (prog, 1, "FirstAttrib");
+ glBindAttribLocationARB (prog, 2, "SecondAttrib");
+ glLinkProgramARB (prog);
+ endtest1 (CheckObjectStatus (prog));
+ endtest1 (glGetAttribLocationARB (prog, "FirstAttrib") == 1);
+ endtest1 (glGetAttribLocationARB (prog, "SecondAttrib") == 2);
+
+ /*
+ * Bind attrib locations in different order. Link and check if locations are correct.
+ */
+ begintest (TT_PARAM1_NONZERO, "Bind attrib location #2");
+ glBindAttribLocationARB (prog, 1, "SecondAttrib");
+ glBindAttribLocationARB (prog, 2, "FirstAttrib");
+ glLinkProgramARB (prog);
+ endtest1 (CheckObjectStatus (prog));
+ endtest1 (glGetAttribLocationARB (prog, "SecondAttrib") == 1);
+ endtest1 (glGetAttribLocationARB (prog, "FirstAttrib") == 2);
+
+ /*
+ * Detach deleted object.
+ */
+ begintest (TT_GETERROR_NOERROR, "Detach deleted object");
+ glDetachObjectARB (prog, vert);
+ endtest ();
+ glDetachObjectARB (prog, frag);
+ endtest ();
+
+ /*
+ * Delete deleted detached object.
+ */
+ begintest (TT_GETERROR_INVALIDVALUE, "Delete deleted detached object");
+ glDeleteObjectARB (vert);
+ endtest ();
+ glDeleteObjectARB (frag);
+ endtest ();
+
+ exit (0);
+}
+
+void RenderScene (void)
+{
+ /* never reached */
+ assert (0);
+}
+
+int main (int argc, char *argv[])
+{
+ InitFramework (&argc, argv);
+ return 0;
+}
+
diff --git a/progs/slang/vstest.c b/progs/slang/vstest.c
new file mode 100644
index 00000000000..95d2ed6b83b
--- /dev/null
+++ b/progs/slang/vstest.c
@@ -0,0 +1,340 @@
+/*
+ * GL_ARB_vertex_shader test application. Feeds a vertex shader with attributes that
+ * that have magic values and check if the values received by the shader are the same.
+ *
+ * Requires specific support on the GL implementation side. A special function printMESA()
+ * must be supported in the language that prints variable's current value of generic type
+ * to the appropriate shader's info log, and optionally to the screen.
+ *
+ * Perfectly valid behaviour produces output that does not have a line
+ * beginning with three stars (***).
+ *
+ * Author: Michal Krol
+ */
+
+#include "framework.h"
+
+#define EPSILON 0.0001f
+
+static GLhandleARB vert = 0;
+static GLhandleARB prog = 0;
+
+enum SUBMIT_MODE
+{
+ SM_IM,
+ SM_VA,
+ SM_IM_DL,
+ SM_VA_DL,
+ SM_MAX
+};
+
+static enum SUBMIT_MODE submit_method = SM_IM;
+
+#define C 0
+#define S 1
+#define N 2
+#define V 3
+#define T 4
+#define F 5
+#define A 6
+
+struct ATTRIB_DATA
+{
+ const char *name;
+ GLuint dispatch;
+ GLint index;
+ GLint bind;
+ GLuint size;
+ GLfloat data[4];
+};
+
+static struct ATTRIB_DATA attribs[] = {
+ { "gl_Color", C, -1, -1, 4, { 4.2f, 0.56f, -2.1f, 0.29f } },
+ { "gl_SecondaryColor", S, -1, -1, 4, { 0.38f, 2.0f, 0.99f, 1.0f } },
+ { "gl_Normal", N, -1, -1, 3, { 54.0f, 77.0f, 1.15f, 0.0f } },
+ { "gl_MultiTexCoord0", T, 0, -1, 4, { 11.1f, 11.2f, 11.3f, 11.4f } },
+ { "gl_MultiTexCoord1", T, 1, -1, 4, { 22.1f, 22.2f, 22.3f, 22.4f } },
+ { "gl_MultiTexCoord2", T, 2, -1, 4, { 33.1f, 33.2f, 33.3f, 33.4f } },
+ { "gl_MultiTexCoord3", T, 3, -1, 4, { 44.1f, 44.2f, 44.3f, 44.4f } },
+ { "gl_MultiTexCoord4", T, 4, -1, 4, { 55.1f, 55.2f, 55.3f, 55.4f } },
+ { "gl_MultiTexCoord5", T, 5, -1, 4, { 66.1f, 66.2f, 66.3f, 66.4f } },
+ { "gl_MultiTexCoord6", T, 6, -1, 4, { 77.1f, 77.2f, 77.3f, 77.4f } },
+ { "gl_MultiTexCoord7", T, 7, -1, 4, { 88.1f, 88.2f, 88.3f, 88.4f } },
+ { "gl_FogCoord", F, -1, -1, 1, { 0.63f, 0.0f, 0.0f, 0.0f } },
+ { "Attribute1", A, 1, 1, 4, { 1.11f, 1.22f, 1.33f, 1.44f } },
+ { "Attribute2", A, 2, 2, 4, { 2.11f, 2.22f, 2.33f, 2.44f } },
+ { "Attribute3", A, 3, 3, 4, { 3.11f, 3.22f, 3.33f, 3.44f } },
+ { "Attribute4", A, 4, 4, 1, { 4.11f, 0.0f, 0.0f, 0.0f } },
+ { "Attribute5", A, 5, 5, 2, { 5.11f, 5.22f, 0.0f, 0.0f } },
+ { "Attribute6", A, 6, 6, 3, { 6.11f, 6.22f, 6.33f, 0.0f } },
+ { "Attribute7", A, 7, 7, 2, { 7.11f, 7.22f, 0.0f, 0.0f } },
+ { "Attribute7", A, 8, -1, 2, { 8.11f, 8.22f, 0.0f, 0.0f } },
+ { "Attribute9", A, 9, 9, 3, { 9.11f, 9.22f, 9.33f, 0.0f } },
+ { "Attribute9", A, 10, -1, 3, { 10.11f, 10.22f, 10.33f, 0.0f } },
+ { "Attribute9", A, 11, -1, 3, { 11.11f, 11.22f, 11.33f, 0.0f } },
+ { "Attribute12", A, 12, 12, 4, { 12.11f, 12.22f, 12.33f, 12.44f } },
+ { "Attribute12", A, 13, -1, 4, { 13.11f, 13.22f, 13.33f, 13.44f } },
+ { "Attribute12", A, 14, -1, 4, { 14.11f, 14.22f, 14.33f, 14.44f } },
+ { "Attribute12", A, 15, -1, 4, { 15.11f, 15.22f, 15.33f, 15.44f } },
+ { "gl_Vertex", V, 16, -1, 4, { 0.25f, -0.14f, 0.01f, 1.0f } }
+};
+
+static void im_render ()
+{
+ GLint i;
+
+ glBegin (GL_POINTS);
+ for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
+ struct ATTRIB_DATA *att = &attribs[i];
+ switch (att->dispatch)
+ {
+ case C:
+ glColor4fv (att->data);
+ break;
+ case S:
+ glSecondaryColor3fvEXT (att->data);
+ break;
+ case N:
+ glNormal3fv (att->data);
+ break;
+ case V:
+ glVertex4fv (att->data);
+ break;
+ case T:
+ assert (att->index >= 0 && att->index < 8);
+ glMultiTexCoord4fvARB (GL_TEXTURE0_ARB + att->index, att->data);
+ break;
+ case F:
+ glFogCoordfvEXT (att->data);
+ break;
+ case A:
+ assert (att->index > 0 && att->index < 16);
+ glVertexAttrib4fvARB (att->index, att->data);
+ break;
+ default:
+ assert (0);
+ }
+ }
+ glEnd ();
+}
+
+static void va_render ()
+{
+ GLint i;
+
+ for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
+ struct ATTRIB_DATA *att = &attribs[i];
+ switch (att->dispatch)
+ {
+ case C:
+ glColorPointer (4, GL_FLOAT, 0, att->data);
+ glEnable (GL_COLOR_ARRAY);
+ break;
+ case S:
+ glSecondaryColorPointerEXT (4, GL_FLOAT, 0, att->data);
+ glEnable (GL_SECONDARY_COLOR_ARRAY_EXT);
+ break;
+ case N:
+ glNormalPointer (GL_FLOAT, 0, att->data);
+ glEnable (GL_NORMAL_ARRAY);
+ break;
+ case V:
+ glVertexPointer (4, GL_FLOAT, 0, att->data);
+ glEnable (GL_VERTEX_ARRAY);
+ break;
+ case T:
+ assert (att->index >= 0 && att->index < 8);
+ glClientActiveTextureARB (GL_TEXTURE0_ARB + att->index);
+ glTexCoordPointer (4, GL_FLOAT, 0, att->data);
+ glEnable (GL_TEXTURE_COORD_ARRAY);
+ break;
+ case F:
+ glFogCoordPointerEXT (GL_FLOAT, 0, att->data);
+ glEnable (GL_FOG_COORDINATE_ARRAY_EXT);
+ break;
+ case A:
+ assert (att->index > 0 && att->index < 16);
+ glVertexAttribPointerARB (att->index, 4, GL_FLOAT, GL_FALSE, 0, att->data);
+ glEnableVertexAttribArrayARB (att->index);
+ break;
+ default:
+ assert (0);
+ }
+ }
+
+ glDrawArrays (GL_POINTS, 0, 1);
+
+ for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
+ struct ATTRIB_DATA *att = &attribs[i];
+ switch (att->dispatch)
+ {
+ case C:
+ glDisable (GL_COLOR_ARRAY);
+ break;
+ case S:
+ glDisable (GL_SECONDARY_COLOR_ARRAY_EXT);
+ break;
+ case N:
+ glDisable (GL_NORMAL_ARRAY);
+ break;
+ case V:
+ glDisable (GL_VERTEX_ARRAY);
+ break;
+ case T:
+ glClientActiveTextureARB (GL_TEXTURE0_ARB + att->index);
+ glDisable (GL_TEXTURE_COORD_ARRAY);
+ break;
+ case F:
+ glDisable (GL_FOG_COORDINATE_ARRAY_EXT);
+ break;
+ case A:
+ glDisableVertexAttribArrayARB (att->index);
+ break;
+ default:
+ assert (0);
+ }
+ }
+}
+
+static void dl_start ()
+{
+ glNewList (GL_COMPILE, 1);
+}
+
+static void dl_end ()
+{
+ glEndList ();
+ glCallList (1);
+}
+
+static void load_test_file (const char *filename)
+{
+ FILE *f;
+ long size;
+ char *code;
+ GLint i;
+
+ f = fopen (filename, "r");
+ if (f == NULL)
+ return;
+
+ fseek (f, 0, SEEK_END);
+ size = ftell (f);
+ fseek (f, 0, SEEK_SET);
+
+ code = (char *) (malloc (size));
+ if (code == NULL) {
+ fclose (f);
+ return;
+ }
+ size = fread (code, 1, size, f);
+ fclose (f);
+
+ glShaderSourceARB (vert, 1, &code, &size);
+ glCompileShaderARB (vert);
+ if (!CheckObjectStatus (vert))
+ exit (0);
+
+ for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++)
+ if (attribs[i].dispatch == A && attribs[i].bind != -1)
+ glBindAttribLocationARB (prog, attribs[i].bind, attribs[i].name);
+}
+
+void InitScene (void)
+{
+ prog = glCreateProgramObjectARB ();
+ vert = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
+ glAttachObjectARB (prog, vert);
+ glDeleteObjectARB (vert);
+ load_test_file ("vstest.txt");
+ glLinkProgramARB (prog);
+ if (!CheckObjectStatus (prog))
+ exit (0);
+ glUseProgramObjectARB (prog);
+}
+
+void RenderScene (void)
+{
+ GLint info_length, length;
+ char output[65000], *p;
+ GLint i;
+
+ if (submit_method == SM_MAX)
+ exit (0);
+
+ /*
+ * Get the current size of the info log. Any text output produced by executed
+ * shader will be appended to the end of log.
+ */
+ glGetObjectParameterivARB (vert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_length);
+
+ switch (submit_method)
+ {
+ case SM_IM:
+ printf ("\n--- TESTING IMMEDIATE MODE\n");
+ im_render ();
+ break;
+ case SM_VA:
+ printf ("\n--- TESTING VERTEX ARRAY MODE\n");
+ va_render ();
+ break;
+ case SM_IM_DL:
+ printf ("\n--- TESTING IMMEDIATE + DISPLAY LIST MODE\n");
+ dl_start ();
+ im_render ();
+ dl_end ();
+ break;
+ case SM_VA_DL:
+ printf ("\n--- TESTING VERTEX ARRAY + DISPLAY LIST MODE\n");
+ dl_start ();
+ va_render ();
+ dl_end ();
+ break;
+ default:
+ assert (0);
+ }
+
+ glFlush ();
+
+ /*
+ * Get the info log and set the pointer to the beginning of the output.
+ */
+ glGetInfoLogARB (vert, sizeof (output), &length, output);
+ p = output + info_length - 1;
+
+ for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
+ GLuint j;
+ for (j = 0; j < attribs[i].size; j++) {
+ GLfloat value;
+ if (p == NULL) {
+ printf ("*** %s\n", "I/O error");
+ break;
+ }
+ if (strncmp (p, "true", 4) == 0)
+ value = 1.0f;
+ else if (strncmp (p, "false", 5) == 0)
+ value = 0.0f;
+ else if (sscanf (p, "%f", &value) != 1) {
+ printf ("*** %s\n", "I/O error");
+ p = NULL;
+ break;
+ }
+ if (fabs (value - attribs[i].data[j]) > EPSILON)
+ printf ("*** %s\n", "Values are different");
+ p = strchr (p, '\n');
+ if (p != NULL)
+ p++;
+ }
+ if (p == NULL)
+ break;
+ }
+
+ submit_method++;
+}
+
+int main (int argc, char *argv[])
+{
+ InitFramework (&argc, argv);
+ return 0;
+}
+
diff --git a/progs/slang/vstest.txt b/progs/slang/vstest.txt
new file mode 100644
index 00000000000..ac4fceb1c61
--- /dev/null
+++ b/progs/slang/vstest.txt
@@ -0,0 +1,68 @@
+/*
+ * Vertex shader test.
+ * Uses all conventional attributes and 15 generic attributes to print
+ * their values, using printMESA() extension function, to the debugger
+ * to compare them with the actual passed-in values.
+ * Use different types for generic attributes to check matrix handling.
+ *
+ * Author: Michal Krol
+ */
+
+#version 110
+
+//#extension MESA_shader_debug: require
+
+attribute vec4 Attribute1;
+attribute vec4 Attribute2;
+attribute vec4 Attribute3;
+attribute float Attribute4;
+attribute vec2 Attribute5;
+attribute vec3 Attribute6;
+attribute mat2 Attribute7;
+attribute mat3 Attribute9;
+attribute mat4 Attribute12;
+
+void main ()
+{
+ //
+ // Do some legal stuff.
+ //
+ gl_Position = gl_ModelViewMatrix * gl_Vertex;
+ gl_FrontColor = vec4 (1.0);
+
+ //
+ // Conventional attributes - except for gl_Vertex.
+ //
+ printMESA (gl_Color);
+ printMESA (gl_SecondaryColor);
+ printMESA (gl_Normal);
+ printMESA (gl_MultiTexCoord0);
+ printMESA (gl_MultiTexCoord1);
+ printMESA (gl_MultiTexCoord2);
+ printMESA (gl_MultiTexCoord3);
+ printMESA (gl_MultiTexCoord4);
+ printMESA (gl_MultiTexCoord5);
+ printMESA (gl_MultiTexCoord6);
+ printMESA (gl_MultiTexCoord7);
+ printMESA (gl_FogCoord);
+
+ //
+ // Generic attributes - attrib with index 0 is not used because it would
+ // alias with gl_Vertex, which is not allowed.
+ //
+ printMESA (Attribute1);
+ printMESA (Attribute2);
+ printMESA (Attribute3);
+ printMESA (Attribute4);
+ printMESA (Attribute5);
+ printMESA (Attribute6);
+ printMESA (Attribute7);
+ printMESA (Attribute9);
+ printMESA (Attribute12);
+
+ //
+ // Vertex position goes last.
+ //
+ printMESA (gl_Vertex);
+}
+
diff --git a/progs/slang/windows/vc60/cltest.dsp b/progs/slang/windows/vc60/cltest.dsp
new file mode 100644
index 00000000000..4c0c2e26b46
--- /dev/null
+++ b/progs/slang/windows/vc60/cltest.dsp
@@ -0,0 +1,94 @@
+# Microsoft Developer Studio Project File - Name="cltest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=cltest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "cltest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "cltest.mak" CFG="cltest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "cltest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "cltest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "cltest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "cltest_release"
+# PROP Intermediate_Dir "cltest_release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x415 /d "NDEBUG"
+# ADD RSC /l 0x415 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "cltest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "cltest_debug"
+# PROP Intermediate_Dir "cltest_debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x415 /d "_DEBUG"
+# ADD RSC /l 0x415 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "cltest - Win32 Release"
+# Name "cltest - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\cltest.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\cltest.txt
+# End Source File
+# End Target
+# End Project
diff --git a/progs/slang/windows/vc60/framework.dsp b/progs/slang/windows/vc60/framework.dsp
new file mode 100644
index 00000000000..76ed7d388c1
--- /dev/null
+++ b/progs/slang/windows/vc60/framework.dsp
@@ -0,0 +1,92 @@
+# Microsoft Developer Studio Project File - Name="framework" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=framework - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "framework.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "framework.mak" CFG="framework - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "framework - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "framework - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "framework - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "framework_release"
+# PROP Intermediate_Dir "framework_release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x415 /d "NDEBUG"
+# ADD RSC /l 0x415 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "framework - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "framework_debug"
+# PROP Intermediate_Dir "framework_debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x415 /d "_DEBUG"
+# ADD RSC /l 0x415 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ENDIF
+
+# Begin Target
+
+# Name "framework - Win32 Release"
+# Name "framework - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\framework.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\framework.h
+# End Source File
+# End Target
+# End Project
diff --git a/progs/slang/windows/vc60/slang.dsw b/progs/slang/windows/vc60/slang.dsw
new file mode 100644
index 00000000000..60536c1b0d9
--- /dev/null
+++ b/progs/slang/windows/vc60/slang.dsw
@@ -0,0 +1,74 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "cltest"=".\cltest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name framework
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "framework"=".\framework.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "sotest"=".\sotest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name framework
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "vstest"=".\vstest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name framework
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/progs/slang/windows/vc60/sotest.dsp b/progs/slang/windows/vc60/sotest.dsp
new file mode 100644
index 00000000000..105924943b7
--- /dev/null
+++ b/progs/slang/windows/vc60/sotest.dsp
@@ -0,0 +1,90 @@
+# Microsoft Developer Studio Project File - Name="sotest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=sotest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "sotest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "sotest.mak" CFG="sotest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "sotest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "sotest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "sotest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "sotest_release"
+# PROP Intermediate_Dir "sotest_release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x415 /d "NDEBUG"
+# ADD RSC /l 0x415 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "sotest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "sotest_debug"
+# PROP Intermediate_Dir "sotest_debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x415 /d "_DEBUG"
+# ADD RSC /l 0x415 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "sotest - Win32 Release"
+# Name "sotest - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\sotest.c
+# End Source File
+# End Target
+# End Project
diff --git a/progs/slang/windows/vc60/vstest.dsp b/progs/slang/windows/vc60/vstest.dsp
new file mode 100644
index 00000000000..a3a2c707f0c
--- /dev/null
+++ b/progs/slang/windows/vc60/vstest.dsp
@@ -0,0 +1,93 @@
+# Microsoft Developer Studio Project File - Name="vstest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=vstest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "vstest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "vstest.mak" CFG="vstest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "vstest - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "vstest - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "vstest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "vstest_release"
+# PROP Intermediate_Dir "vstest_release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x415 /d "NDEBUG"
+# ADD RSC /l 0x415 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "vstest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "vstest_debug"
+# PROP Intermediate_Dir "vstest_debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x415 /d "_DEBUG"
+# ADD RSC /l 0x415 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "vstest - Win32 Release"
+# Name "vstest - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\..\vstest.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\vstest.txt
+# End Source File
+# End Target
+# End Project