ARB prog parser: fix parameter binding type
[mesa.git] / progs / slang / vstest.c
1 /*
2 * GL_ARB_vertex_shader test application. Feeds a vertex shader with attributes that
3 * that have magic values and check if the values received by the shader are the same.
4 *
5 * Requires specific support on the GL implementation side. A special function printMESA()
6 * must be supported in the language that prints variable's current value of generic type
7 * to the appropriate shader's info log, and optionally to the screen.
8 *
9 * Perfectly valid behaviour produces output that does not have a line
10 * beginning with three stars (***).
11 *
12 * Author: Michal Krol
13 */
14
15 #include "framework.h"
16
17 #define EPSILON 0.0001f
18
19 static GLhandleARB vert = 0;
20 static GLhandleARB prog = 0;
21
22 enum SUBMIT_MODE
23 {
24 SM_IM,
25 SM_VA,
26 SM_IM_DL,
27 SM_VA_DL,
28 SM_MAX
29 };
30
31 static enum SUBMIT_MODE submit_method = SM_IM;
32
33 #define C 0
34 #define S 1
35 #define N 2
36 #define V 3
37 #define T 4
38 #define F 5
39 #define A 6
40
41 struct ATTRIB_DATA
42 {
43 const char *name;
44 GLuint dispatch;
45 GLint index;
46 GLint bind;
47 GLuint size;
48 GLfloat data[4];
49 };
50
51 static struct ATTRIB_DATA attribs[] = {
52 { "gl_Color", C, -1, -1, 4, { 4.2f, 0.56f, -2.1f, 0.29f } },
53 { "gl_SecondaryColor", S, -1, -1, 4, { 0.38f, 2.0f, 0.99f, 1.0f } },
54 { "gl_Normal", N, -1, -1, 3, { 54.0f, 77.0f, 1.15f, 0.0f } },
55 { "gl_MultiTexCoord0", T, 0, -1, 4, { 11.1f, 11.2f, 11.3f, 11.4f } },
56 { "gl_MultiTexCoord1", T, 1, -1, 4, { 22.1f, 22.2f, 22.3f, 22.4f } },
57 { "gl_MultiTexCoord2", T, 2, -1, 4, { 33.1f, 33.2f, 33.3f, 33.4f } },
58 { "gl_MultiTexCoord3", T, 3, -1, 4, { 44.1f, 44.2f, 44.3f, 44.4f } },
59 { "gl_MultiTexCoord4", T, 4, -1, 4, { 55.1f, 55.2f, 55.3f, 55.4f } },
60 { "gl_MultiTexCoord5", T, 5, -1, 4, { 66.1f, 66.2f, 66.3f, 66.4f } },
61 { "gl_MultiTexCoord6", T, 6, -1, 4, { 77.1f, 77.2f, 77.3f, 77.4f } },
62 { "gl_MultiTexCoord7", T, 7, -1, 4, { 88.1f, 88.2f, 88.3f, 88.4f } },
63 { "gl_FogCoord", F, -1, -1, 1, { 0.63f, 0.0f, 0.0f, 0.0f } },
64 { "Attribute1", A, 1, 1, 4, { 1.11f, 1.22f, 1.33f, 1.44f } },
65 { "Attribute2", A, 2, 2, 4, { 2.11f, 2.22f, 2.33f, 2.44f } },
66 { "Attribute3", A, 3, 3, 4, { 3.11f, 3.22f, 3.33f, 3.44f } },
67 { "Attribute4", A, 4, 4, 1, { 4.11f, 0.0f, 0.0f, 0.0f } },
68 { "Attribute5", A, 5, 5, 2, { 5.11f, 5.22f, 0.0f, 0.0f } },
69 { "Attribute6", A, 6, 6, 3, { 6.11f, 6.22f, 6.33f, 0.0f } },
70 { "Attribute7", A, 7, 7, 2, { 7.11f, 7.22f, 0.0f, 0.0f } },
71 { "Attribute7", A, 8, -1, 2, { 8.11f, 8.22f, 0.0f, 0.0f } },
72 { "Attribute9", A, 9, 9, 3, { 9.11f, 9.22f, 9.33f, 0.0f } },
73 { "Attribute9", A, 10, -1, 3, { 10.11f, 10.22f, 10.33f, 0.0f } },
74 { "Attribute9", A, 11, -1, 3, { 11.11f, 11.22f, 11.33f, 0.0f } },
75 { "Attribute12", A, 12, 12, 4, { 12.11f, 12.22f, 12.33f, 12.44f } },
76 { "Attribute12", A, 13, -1, 4, { 13.11f, 13.22f, 13.33f, 13.44f } },
77 { "Attribute12", A, 14, -1, 4, { 14.11f, 14.22f, 14.33f, 14.44f } },
78 { "Attribute12", A, 15, -1, 4, { 15.11f, 15.22f, 15.33f, 15.44f } },
79 { "gl_Vertex", V, 16, -1, 4, { 0.25f, -0.14f, 0.01f, 1.0f } }
80 };
81
82 static void im_render ()
83 {
84 GLint i;
85
86 glBegin (GL_POINTS);
87 for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
88 struct ATTRIB_DATA *att = &attribs[i];
89 switch (att->dispatch)
90 {
91 case C:
92 glColor4fv (att->data);
93 break;
94 case S:
95 glSecondaryColor3fvEXT (att->data);
96 break;
97 case N:
98 glNormal3fv (att->data);
99 break;
100 case V:
101 glVertex4fv (att->data);
102 break;
103 case T:
104 assert (att->index >= 0 && att->index < 8);
105 glMultiTexCoord4fvARB (GL_TEXTURE0_ARB + att->index, att->data);
106 break;
107 case F:
108 glFogCoordfvEXT (att->data);
109 break;
110 case A:
111 assert (att->index > 0 && att->index < 16);
112 glVertexAttrib4fvARB (att->index, att->data);
113 break;
114 default:
115 assert (0);
116 }
117 }
118 glEnd ();
119 }
120
121 static void va_render ()
122 {
123 GLint i;
124
125 for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
126 struct ATTRIB_DATA *att = &attribs[i];
127 switch (att->dispatch)
128 {
129 case C:
130 glColorPointer (4, GL_FLOAT, 0, att->data);
131 glEnableClientState (GL_COLOR_ARRAY);
132 break;
133 case S:
134 glSecondaryColorPointerEXT (4, GL_FLOAT, 0, att->data);
135 glEnableClientState (GL_SECONDARY_COLOR_ARRAY_EXT);
136 break;
137 case N:
138 glNormalPointer (GL_FLOAT, 0, att->data);
139 glEnableClientState (GL_NORMAL_ARRAY);
140 break;
141 case V:
142 glVertexPointer (4, GL_FLOAT, 0, att->data);
143 glEnableClientState (GL_VERTEX_ARRAY);
144 break;
145 case T:
146 assert (att->index >= 0 && att->index < 8);
147 glClientActiveTextureARB (GL_TEXTURE0_ARB + att->index);
148 glTexCoordPointer (4, GL_FLOAT, 0, att->data);
149 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
150 break;
151 case F:
152 glFogCoordPointerEXT (GL_FLOAT, 0, att->data);
153 glEnableClientState (GL_FOG_COORDINATE_ARRAY_EXT);
154 break;
155 case A:
156 assert (att->index > 0 && att->index < 16);
157 glVertexAttribPointerARB (att->index, 4, GL_FLOAT, GL_FALSE, 0, att->data);
158 glEnableVertexAttribArrayARB (att->index);
159 break;
160 default:
161 assert (0);
162 }
163 }
164
165 glDrawArrays (GL_POINTS, 0, 1);
166
167 for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
168 struct ATTRIB_DATA *att = &attribs[i];
169 switch (att->dispatch)
170 {
171 case C:
172 glDisableClientState (GL_COLOR_ARRAY);
173 break;
174 case S:
175 glDisableClientState (GL_SECONDARY_COLOR_ARRAY_EXT);
176 break;
177 case N:
178 glDisableClientState (GL_NORMAL_ARRAY);
179 break;
180 case V:
181 glDisableClientState (GL_VERTEX_ARRAY);
182 break;
183 case T:
184 glClientActiveTextureARB (GL_TEXTURE0_ARB + att->index);
185 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
186 break;
187 case F:
188 glDisableClientState (GL_FOG_COORDINATE_ARRAY_EXT);
189 break;
190 case A:
191 glDisableVertexAttribArrayARB (att->index);
192 break;
193 default:
194 assert (0);
195 }
196 }
197 }
198
199 static void dl_start ()
200 {
201 glNewList (GL_COMPILE, 1);
202 }
203
204 static void dl_end ()
205 {
206 glEndList ();
207 glCallList (1);
208 }
209
210 static void load_test_file (const char *filename)
211 {
212 FILE *f;
213 GLint size;
214 char *code;
215 GLint i;
216
217 f = fopen (filename, "r");
218 if (f == NULL)
219 return;
220
221 fseek (f, 0, SEEK_END);
222 size = ftell (f);
223
224 if (size == -1) {
225 fclose (f);
226 return;
227 }
228
229 fseek (f, 0, SEEK_SET);
230
231 code = (char *) (malloc (size));
232 if (code == NULL) {
233 fclose (f);
234 return;
235 }
236 size = fread (code, 1, size, f);
237 fclose (f);
238
239 glShaderSourceARB (vert, 1, (const GLcharARB **) (&code), &size);
240 glCompileShaderARB (vert);
241 if (!CheckObjectStatus (vert))
242 exit (0);
243
244 for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++)
245 if (attribs[i].dispatch == A && attribs[i].bind != -1)
246 glBindAttribLocationARB (prog, attribs[i].bind, attribs[i].name);
247 }
248
249 void InitScene (void)
250 {
251 prog = glCreateProgramObjectARB ();
252 vert = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB);
253 glAttachObjectARB (prog, vert);
254 glDeleteObjectARB (vert);
255 load_test_file ("vstest.txt");
256 glLinkProgramARB (prog);
257 if (!CheckObjectStatus (prog))
258 exit (0);
259 glUseProgramObjectARB (prog);
260 }
261
262 void RenderScene (void)
263 {
264 GLint info_length, length;
265 char output[65000], *p;
266 GLint i;
267
268 if (submit_method == SM_MAX)
269 exit (0);
270
271 /*
272 * Get the current size of the info log. Any text output produced by executed
273 * shader will be appended to the end of log.
274 */
275 glGetObjectParameterivARB (vert, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_length);
276
277 switch (submit_method)
278 {
279 case SM_IM:
280 printf ("\n--- TESTING IMMEDIATE MODE\n");
281 im_render ();
282 break;
283 case SM_VA:
284 printf ("\n--- TESTING VERTEX ARRAY MODE\n");
285 va_render ();
286 break;
287 case SM_IM_DL:
288 printf ("\n--- TESTING IMMEDIATE + DISPLAY LIST MODE\n");
289 dl_start ();
290 im_render ();
291 dl_end ();
292 break;
293 case SM_VA_DL:
294 printf ("\n--- TESTING VERTEX ARRAY + DISPLAY LIST MODE\n");
295 dl_start ();
296 va_render ();
297 dl_end ();
298 break;
299 default:
300 assert (0);
301 }
302
303 glFlush ();
304
305 /*
306 * Get the info log and set the pointer to the beginning of the output.
307 */
308 glGetInfoLogARB (vert, sizeof (output), &length, output);
309 p = output + info_length - 1;
310
311 for (i = 0; i < sizeof (attribs) / sizeof (*attribs); i++) {
312 GLuint j;
313 for (j = 0; j < attribs[i].size; j++) {
314 GLfloat value;
315 if (p == NULL) {
316 printf ("*** %s\n", "I/O error");
317 break;
318 }
319 if (strncmp (p, "true", 4) == 0)
320 value = 1.0f;
321 else if (strncmp (p, "false", 5) == 0)
322 value = 0.0f;
323 else if (sscanf (p, "%f", &value) != 1) {
324 printf ("*** %s\n", "I/O error");
325 p = NULL;
326 break;
327 }
328 if (fabs (value - attribs[i].data[j]) > EPSILON)
329 printf ("*** %s, is %f, should be %f\n", "Values are different", value, attribs[i].data[j]);
330 p = strchr (p, '\n');
331 if (p != NULL)
332 p++;
333 }
334 if (p == NULL)
335 break;
336 }
337
338 submit_method++;
339 }
340
341 int main (int argc, char *argv[])
342 {
343 InitFramework (&argc, argv);
344 return 0;
345 }
346