progs/tests: also test stencil INCR_WRAP mode if supported
[mesa.git] / progs / tests / getprocaddress.c
1 /*
2 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22 /*
23 * Test that glXGetProcAddress works.
24 */
25
26 #define GLX_GLXEXT_PROTOTYPES
27
28 #include <X11/Xlib.h>
29 #include <X11/Xutil.h>
30 #include <GL/gl.h>
31 #include <GL/glx.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <math.h>
36
37
38 typedef void (*generic_func)();
39
40 #define EQUAL(X, Y) (fabs((X) - (Y)) < 0.001)
41
42 /* This macro simplifies the task of querying an extension function
43 * pointer and checking to see whether it resolved.
44 */
45 #define DECLARE_GLFUNC_PTR(name,type) \
46 type name = (type) glXGetProcAddressARB((const GLubyte *) "gl" #name)
47
48 /********************************************************************
49 * Generic helper functions used by the test functions.
50 */
51
52 static void CheckGLError(int line, const char *file, const char *function)
53 {
54 int errorCode;
55 glFinish();
56 errorCode = glGetError();
57 if (errorCode == GL_NO_ERROR) return;
58 while (errorCode != GL_NO_ERROR) {
59 fprintf(stderr, "OpenGL error 0x%x (%s) at line %d of file %s in function %s()\n",
60 errorCode,
61 errorCode == GL_INVALID_VALUE? "GL_INVALID_VALUE":
62 errorCode == GL_INVALID_ENUM? "GL_INVALID_ENUM":
63 errorCode == GL_INVALID_OPERATION? "GL_INVALID_OPERATION":
64 errorCode == GL_STACK_OVERFLOW? "GL_STACK_OVERFLOW":
65 errorCode == GL_STACK_UNDERFLOW? "GL_STACK_UNDERFLOW":
66 errorCode == GL_OUT_OF_MEMORY? "GL_OUT_OF_MEMORY":
67 "unknown",
68 line, file, function);
69 errorCode = glGetError();
70 }
71 fflush(stderr);
72 }
73
74 static GLboolean
75 compare_bytes(const char *errorLabel, GLuint expectedSize,
76 const GLubyte *expectedData, GLuint actualSize, const GLubyte *actualData)
77 {
78 int i;
79
80 if (expectedSize == actualSize &&
81 memcmp(expectedData, actualData, actualSize) == 0) {
82 /* All is well */
83 return GL_TRUE;
84 }
85
86 /* Trouble; we don't match. Print out why. */
87 fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
88 for (i = 0; i <= 1; i++) {
89 const GLubyte *ptr;
90 int size;
91 char *label;
92 int j;
93
94 switch(i) {
95 case 0:
96 label = "expected";
97 size = expectedSize;
98 ptr = expectedData;
99 break;
100 case 1:
101 label = " actual";
102 size = actualSize;
103 ptr = actualData;
104 break;
105 }
106
107 fprintf(stderr, " %s: size %d: {", label, size);
108 for (j = 0; j < size; j++) {
109 fprintf(stderr, "%s0x%02x", j > 0 ? ", " : "", ptr[j]);
110 }
111 fprintf(stderr, "}\n");
112 }
113
114 /* We fail if the data is unexpected. */
115 return GL_FALSE;
116 }
117
118
119 static GLboolean
120 compare_ints(const char *errorLabel, GLuint expectedSize,
121 const GLint *expectedData, GLuint actualSize, const GLint *actualData)
122 {
123 int i;
124
125 if (expectedSize == actualSize &&
126 memcmp(expectedData, actualData, actualSize*sizeof(*expectedData)) == 0) {
127 /* All is well */
128 return GL_TRUE;
129 }
130
131 /* Trouble; we don't match. Print out why. */
132 fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
133 for (i = 0; i <= 1; i++) {
134 const GLint *ptr;
135 int size;
136 char *label;
137 int j;
138
139 switch(i) {
140 case 0:
141 label = "expected";
142 size = expectedSize;
143 ptr = expectedData;
144 break;
145 case 1:
146 label = " actual";
147 size = actualSize;
148 ptr = actualData;
149 break;
150 }
151
152 fprintf(stderr, " %s: size %d: {", label, size);
153 for (j = 0; j < size; j++) {
154 fprintf(stderr, "%s%d", j > 0 ? ", " : "", ptr[j]);
155 }
156 fprintf(stderr, "}\n");
157 }
158
159 /* We fail if the data is unexpected. */
160 return GL_FALSE;
161 }
162
163 #define MAX_CONVERTED_VALUES 4
164 static GLboolean
165 compare_shorts_to_ints(const char *errorLabel, GLuint expectedSize,
166 const GLshort *expectedData, GLuint actualSize, const GLint *actualData)
167 {
168 int i;
169 GLint convertedValues[MAX_CONVERTED_VALUES];
170
171 if (expectedSize > MAX_CONVERTED_VALUES) {
172 fprintf(stderr, "%s: too much data [need %d values, have %d values]\n",
173 errorLabel, expectedSize, MAX_CONVERTED_VALUES);
174 return GL_FALSE;
175 }
176
177 for (i = 0; i < expectedSize; i++) {
178 convertedValues[i] = (GLint) expectedData[i];
179 }
180
181 return compare_ints(errorLabel, expectedSize, convertedValues,
182 actualSize, actualData);
183 }
184
185 static GLboolean
186 compare_floats(const char *errorLabel, GLuint expectedSize,
187 const GLfloat *expectedData, GLuint actualSize, const GLfloat *actualData)
188 {
189 int i;
190
191 if (expectedSize == actualSize &&
192 memcmp(expectedData, actualData, actualSize*sizeof(*expectedData)) == 0) {
193 /* All is well */
194 return GL_TRUE;
195 }
196
197 /* Trouble; we don't match. Print out why. */
198 fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
199 for (i = 0; i <= 1; i++) {
200 const GLfloat *ptr;
201 int size;
202 char *label;
203 int j;
204
205 switch(i) {
206 case 0:
207 label = "expected";
208 size = expectedSize;
209 ptr = expectedData;
210 break;
211 case 1:
212 label = " actual";
213 size = actualSize;
214 ptr = actualData;
215 break;
216 }
217
218 fprintf(stderr, " %s: size %d: {", label, size);
219 for (j = 0; j < size; j++) {
220 fprintf(stderr, "%s%f", j > 0 ? ", " : "", ptr[j]);
221 }
222 fprintf(stderr, "}\n");
223 }
224
225 /* We fail if the data is unexpected. */
226 return GL_FALSE;
227 }
228
229 static GLboolean
230 compare_doubles(const char *errorLabel, GLuint expectedSize,
231 const GLdouble *expectedData, GLuint actualSize, const GLdouble *actualData)
232 {
233 int i;
234
235 if (expectedSize == actualSize ||
236 memcmp(expectedData, actualData, actualSize*sizeof(*expectedData)) == 0) {
237 /* All is well */
238 return GL_TRUE;
239 }
240
241 /* Trouble; we don't match. Print out why. */
242 fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
243 for (i = 0; i <= 1; i++) {
244 const GLdouble *ptr;
245 int size;
246 char *label;
247 int j;
248
249 switch(i) {
250 case 0:
251 label = "expected";
252 size = expectedSize;
253 ptr = expectedData;
254 break;
255 case 1:
256 label = " actual";
257 size = actualSize;
258 ptr = actualData;
259 break;
260 }
261
262 fprintf(stderr, " %s: size %d: {", label, size);
263 for (j = 0; j < size; j++) {
264 fprintf(stderr, "%s%f", j > 0 ? ", " : "", ptr[j]);
265 }
266 fprintf(stderr, "}\n");
267 }
268
269 /* We fail if the data is unexpected. */
270 return GL_FALSE;
271 }
272
273 /********************************************************************
274 * Functions to assist with GL_ARB_texture_compressiong testing
275 */
276
277 static GLboolean
278 check_texture_format_supported(GLenum format)
279 {
280 GLint numFormats;
281 GLint *formats;
282 register int i;
283
284 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numFormats);
285 formats = malloc(numFormats * sizeof(GLint));
286 if (formats == NULL) {
287 fprintf(stderr, "check_texture_format_supported: could not allocate memory for %d GLints\n",
288 numFormats);
289 return GL_FALSE;
290 }
291
292 memset(formats, 0, numFormats * sizeof(GLint));
293 glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats);
294
295 for (i = 0; i < numFormats; i++) {
296 if (formats[i] == format) {
297 free(formats);
298 return GL_TRUE;
299 }
300 }
301
302 /* We didn't find the format we were looking for. Give an error. */
303 #define FORMAT_NAME(x) (\
304 x == GL_COMPRESSED_RGB_FXT1_3DFX ? "GL_COMPRESSED_RGB_FXT1_3DFX" : \
305 x == GL_COMPRESSED_RGBA_FXT1_3DFX ? "GL_COMPRESSED_RGBA_FXT1_3DFX" : \
306 x == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? "GL_COMPRESSED_RGB_S3TC_DXT1_EXT" : \
307 x == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" : \
308 x == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ? "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT" : \
309 x == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ? "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT" : \
310 x == GL_RGB_S3TC ? "GL_RGB_S3TC" : \
311 x == GL_RGB4_S3TC ? "GL_RGB4_S3TC" : \
312 x == GL_RGBA_S3TC ? "GL_RGBA_S3TC" : \
313 x == GL_RGBA4_S3TC ? "GL_RGBA4_S3TC" : \
314 "unknown")
315 fprintf(stderr, "check_texture_format_supported: unsupported format 0x%04x [%s]\n",
316 format, FORMAT_NAME(format));
317 fprintf(stderr, "supported formats:");
318 for (i = 0; i < numFormats; i++) {
319 fprintf(stderr, " 0x%04x [%s]", formats[i], FORMAT_NAME(formats[i]));
320 }
321 fprintf(stderr, "\n");
322 return GL_FALSE;
323 }
324
325 /* This helper function compresses an RGBA texture and compares it
326 * against the expected compressed data. It returns GL_TRUE if all
327 * went as expected, or GL_FALSE in the case of error.
328 */
329 static GLboolean
330 check_texture_compression(const char *message, GLenum dimension,
331 GLint width, GLint height, GLint depth, const GLubyte *texture,
332 int expectedCompressedSize, const GLubyte *expectedCompressedData)
333 {
334 /* These are the data we query about the texture. */
335 GLint isCompressed;
336 GLenum compressedFormat;
337 GLint compressedSize;
338 GLubyte *compressedData;
339
340 /* We need this function pointer to operate. */
341 DECLARE_GLFUNC_PTR(GetCompressedTexImageARB, PFNGLGETCOMPRESSEDTEXIMAGEARBPROC);
342 if (GetCompressedTexImageARB == NULL) {
343 fprintf(stderr,
344 "%s: could not query GetCompressedTexImageARB function pointer\n",
345 message);
346 return GL_FALSE;
347 }
348
349 /* Verify that we actually have the GL_COMPRESSED_RGBA_S3TC_DXT3_EXT format available. */
350 if (!check_texture_format_supported(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)) {
351 return GL_FALSE;
352 }
353
354 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
355 /* Set up the base image, requesting that the GL library compress it. */
356 switch(dimension) {
357 case GL_TEXTURE_1D:
358 glTexImage1D(GL_TEXTURE_1D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
359 width, 0,
360 GL_RGBA, GL_UNSIGNED_BYTE, texture);
361 break;
362 case GL_TEXTURE_2D:
363 glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
364 width, height, 0,
365 GL_RGBA, GL_UNSIGNED_BYTE, texture);
366 break;
367 case GL_TEXTURE_3D:
368 glTexImage3D(GL_TEXTURE_3D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
369 width, height, depth, 0,
370 GL_RGBA, GL_UNSIGNED_BYTE, texture);
371 break;
372 default:
373 fprintf(stderr, "%s: unknown dimension 0x%04x.\n", message, dimension);
374 return GL_FALSE;
375 }
376 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
377
378 /* Make sure the texture is compressed, and pull it out if it is. */
379 glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_ARB,
380 &isCompressed);
381 if (!isCompressed) {
382 fprintf(stderr, "%s: could not compress GL_COMPRESSED_RGBA_S3TC_DXT3_EXT texture\n",
383 message);
384 return GL_FALSE;
385 }
386 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
387 glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_INTERNAL_FORMAT,
388 (GLint *)&compressedFormat);
389 if (compressedFormat != GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) {
390 fprintf(stderr, "%s: got internal format 0x%04x, expected GL_COMPRESSED_RGBA_S3TC_DXT3_EXT [0x%04x]\n",
391 __FUNCTION__, compressedFormat, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
392 return GL_FALSE;
393 }
394 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
395 glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressedSize);
396 compressedData = malloc(compressedSize);
397 if (compressedData == NULL) {
398 fprintf(stderr, "%s: could not malloc %d bytes for compressed texture\n",
399 message, compressedSize);
400 return GL_FALSE;
401 }
402 memset(compressedData, 0, compressedSize);
403 (*GetCompressedTexImageARB)(dimension, 0, compressedData);
404 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
405
406 /* Compare it to the expected compressed data. The compare_bytes()
407 * call will print out diagnostics in the case of failure.
408 */
409 if (!compare_bytes(message,
410 expectedCompressedSize, expectedCompressedData,
411 compressedSize, compressedData)) {
412
413 free(compressedData);
414 return GL_FALSE;
415 }
416
417 /* All done. Free our allocated data and return success. */
418 free(compressedData);
419 return GL_TRUE;
420 }
421
422 /* We'll use one function to exercise 1D, 2D, and 3D textures. */
423
424 /* The test function for compressed 3D texture images requires several
425 * different function pointers that have to be queried. This function
426 * gets all the function pointers it needs itself, and so is suitable for
427 * use to test any and all of the incorporated functions.
428 */
429
430 static GLboolean
431 exercise_CompressedTextures(GLenum dimension)
432 {
433 /* Set up a basic (uncompressed) texture. We're doing a blue/yellow
434 * checkerboard. The 8x4/32-pixel board is well-suited to S3TC
435 * compression, which works on 4x4 blocks of pixels.
436 */
437 #define B 0,0,255,255
438 #define Y 255,255,0,255
439 #define TEXTURE_WIDTH 16
440 #define TEXTURE_HEIGHT 4
441 #define TEXTURE_DEPTH 1
442 static GLubyte texture[TEXTURE_WIDTH*TEXTURE_HEIGHT*TEXTURE_DEPTH*4] = {
443 B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y,
444 B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y,
445 Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B,
446 Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B,
447 };
448 #undef B
449 #undef Y
450 GLubyte uncompressedTexture[TEXTURE_WIDTH*TEXTURE_HEIGHT*TEXTURE_DEPTH*4];
451
452 /* We'll use this as a texture subimage. */
453 #define R 255,0,0,255
454 #define G 0,255,0,255
455 #define SUBTEXTURE_WIDTH 4
456 #define SUBTEXTURE_HEIGHT 4
457 #define SUBTEXTURE_DEPTH 1
458 static GLubyte subtexture[SUBTEXTURE_WIDTH*SUBTEXTURE_HEIGHT*SUBTEXTURE_DEPTH*4] = {
459 G, G, R, R,
460 G, G, R, R,
461 R, R, G, G,
462 R, R, G, G,
463 };
464 #undef R
465 #undef G
466
467 /* These are the expected compressed textures. (In the case of
468 * a failed comparison, the test program will print out the
469 * actual compressed data in a format that can be directly used
470 * here, if desired.) The brave of heart can calculate the compression
471 * themselves based on the formulae described at:
472 * http://en.wikipedia.org/wiki/S3_Texture_Compression
473 * In a nutshell, each group of 16 bytes encodes a 4x4 texture block.
474 * The first eight bytes of each group are 4-bit alpha values
475 * for each of the 16 pixels in the texture block.
476 * The next four bytes in each group are LSB-first RGB565 colors; the
477 * first two bytes are identified as the color C0, and the next two
478 * are the color C1. (Two more colors C2 and C3 will be calculated
479 * from these, but do not appear in the compression data.) The
480 * last 4 bytes of the group are sixteen 2-bit indices that, for
481 * each of the 16 pixels in the texture block, select one of the
482 * colors C0, C1, C2, or C3.
483 *
484 * For example, our blue/yellow checkerboard is made up of
485 * four identical 4x4 blocks. Each of those blocks will
486 * be encoded as: eight bytes of 0xff (16 alpha values, each 0xf),
487 * C0 as the RGB565 color yellow (0xffe0), encoded LSB-first;
488 * C1 as the RGB565 color blue (0x001f), encoded LSB-first;
489 * and 4 bytes of 16 2-bit color indices reflecting the
490 * choice of color for each of the 16 pixels:
491 * 00, 00, 01, 01, = 0x05
492 * 00, 00, 01, 01, = 0x05
493 * 01, 01, 00, 00, = 0x50
494 * 01, 01, 00, 00, = 0x50
495 */
496 static GLubyte compressedTexture[] = {
497 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
498 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
499 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
500 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
501 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
502 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
503 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
504 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50
505 };
506
507 /* The similar calculations for the 4x4 subtexture are left
508 * as an exercise for the reader.
509 */
510 static GLubyte compressedSubTexture[] = {
511 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
512 0x00, 0xf8, 0xe0, 0x07, 0x05, 0x05, 0x50, 0x50,
513 };
514
515 /* The combined texture replaces the initial blue/yellow
516 * block with the green/red block. (I'd wanted to do
517 * the more interesting exercise of putting the
518 * green/red block in the middle of the blue/yellow
519 * texture, which is a non-trivial replacement, but
520 * the attempt produces GL_INVALID_OPERATION, showing
521 * that you can only replace whole blocks of
522 * subimages with S3TC.) The combined texture looks
523 * like:
524 * G G R R B B Y Y B B Y Y B B Y Y
525 * G G R R B B Y Y B B Y Y B B Y Y
526 * R R G G Y Y B B Y Y B B Y Y B B
527 * R R G G Y Y B B Y Y B B Y Y B B
528 * which encodes just like the green/red block followed
529 * by 3 copies of the yellow/blue block.
530 */
531 static GLubyte compressedCombinedTexture[] = {
532 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
533 0x00, 0xf8, 0xe0, 0x07, 0x05, 0x05, 0x50, 0x50,
534 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
535 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
536 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
537 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
538 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
539 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50
540 };
541
542 /* These are the data we query about the texture. */
543 GLint queryIsCompressed;
544 GLenum queryCompressedFormat;
545 GLint queryCompressedSize;
546 GLubyte queryCompressedData[sizeof(compressedTexture)];
547
548 /* Query the function pointers we need. We actually won't need most
549 * of these (the "dimension" parameter dictates whether we're testing
550 * 1D, 2D, or 3D textures), but we'll have them all ready just in case.
551 */
552 DECLARE_GLFUNC_PTR(GetCompressedTexImageARB, PFNGLGETCOMPRESSEDTEXIMAGEARBPROC);
553 DECLARE_GLFUNC_PTR(CompressedTexImage3DARB, PFNGLCOMPRESSEDTEXIMAGE3DARBPROC);
554 DECLARE_GLFUNC_PTR(CompressedTexSubImage3DARB, PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC);
555 DECLARE_GLFUNC_PTR(CompressedTexImage2DARB, PFNGLCOMPRESSEDTEXIMAGE2DARBPROC);
556 DECLARE_GLFUNC_PTR(CompressedTexSubImage2DARB, PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC);
557 DECLARE_GLFUNC_PTR(CompressedTexImage1DARB, PFNGLCOMPRESSEDTEXIMAGE1DARBPROC);
558 DECLARE_GLFUNC_PTR(CompressedTexSubImage1DARB, PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC);
559
560 /* If the necessary functions are missing, we can't continue */
561 if (GetCompressedTexImageARB == NULL) {
562 fprintf(stderr, "%s: GetCompressedTexImageARB function is missing\n",
563 __FUNCTION__);
564 return GL_FALSE;
565 }
566 switch (dimension) {
567 case GL_TEXTURE_1D:
568 if (CompressedTexImage1DARB == NULL || CompressedTexSubImage1DARB == NULL) {
569 fprintf(stderr, "%s: 1D compressed texture functions are missing\n",
570 __FUNCTION__);
571 return GL_FALSE;
572 };
573 break;
574 case GL_TEXTURE_2D:
575 if (CompressedTexImage2DARB == NULL || CompressedTexSubImage2DARB == NULL) {
576 fprintf(stderr, "%s: 2D compressed texture functions are missing\n",
577 __FUNCTION__);
578 return GL_FALSE;
579 };
580 break;
581 case GL_TEXTURE_3D:
582 if (CompressedTexImage3DARB == NULL || CompressedTexSubImage3DARB == NULL) {
583 fprintf(stderr, "%s: 3D compressed texture functions are missing\n",
584 __FUNCTION__);
585 return GL_FALSE;
586 };
587 break;
588 default:
589 fprintf(stderr, "%s: unknown texture dimension 0x%04x passed.\n",
590 __FUNCTION__, dimension);
591 return GL_FALSE;
592 }
593
594 /* Check the compression of our base texture image. */
595 if (!check_texture_compression("texture compression", dimension,
596 TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH, texture,
597 sizeof(compressedTexture), compressedTexture)) {
598
599 /* Something's wrong with texture compression. The function
600 * above will have printed an appropriate error.
601 */
602 return GL_FALSE;
603 }
604
605 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
606
607 /* Do the same for our texture subimage */
608 if (!check_texture_compression("subtexture compression", dimension,
609 SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT, SUBTEXTURE_DEPTH, subtexture,
610 sizeof(compressedSubTexture), compressedSubTexture)) {
611
612 /* Something's wrong with texture compression. The function
613 * above will have printed an appropriate error.
614 */
615 return GL_FALSE;
616 }
617
618 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
619
620 /* Send the base compressed texture down to the hardware. */
621 switch(dimension) {
622 case GL_TEXTURE_3D:
623 (*CompressedTexImage3DARB)(GL_TEXTURE_3D, 0,
624 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
625 TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH, 0,
626 sizeof(compressedTexture), compressedTexture);
627 break;
628
629 case GL_TEXTURE_2D:
630 (*CompressedTexImage2DARB)(GL_TEXTURE_2D, 0,
631 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
632 TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
633 sizeof(compressedTexture), compressedTexture);
634 break;
635
636 case GL_TEXTURE_1D:
637 (*CompressedTexImage1DARB)(GL_TEXTURE_1D, 0,
638 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
639 TEXTURE_WIDTH, 0,
640 sizeof(compressedTexture), compressedTexture);
641 break;
642 }
643 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
644
645 /* For grins, query it to make sure it is as expected. */
646 glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_ARB,
647 &queryIsCompressed);
648 if (!queryIsCompressed) {
649 fprintf(stderr, "%s: compressed texture did not come back as compressed\n",
650 __FUNCTION__);
651 return GL_FALSE;
652 }
653 glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_INTERNAL_FORMAT,
654 (GLint *)&queryCompressedFormat);
655 if (queryCompressedFormat != GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) {
656 fprintf(stderr, "%s: got internal format 0x%04x, expected GL_COMPRESSED_RGBA_S3TC_DXT3_EXT [0x%04x]\n",
657 __FUNCTION__, queryCompressedFormat, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
658 return GL_FALSE;
659 }
660 glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB,
661 &queryCompressedSize);
662 if (queryCompressedSize != sizeof(compressedTexture)) {
663 fprintf(stderr, "%s: compressed 3D texture changed size: expected %lu, actual %d\n",
664 __FUNCTION__, (unsigned long) sizeof(compressedTexture), queryCompressedSize);
665 return GL_FALSE;
666 }
667 (*GetCompressedTexImageARB)(dimension, 0, queryCompressedData);
668 if (!compare_bytes(
669 "exercise_CompressedTextures:doublechecking compressed texture",
670 sizeof(compressedTexture), compressedTexture,
671 queryCompressedSize, queryCompressedData)) {
672 return GL_FALSE;
673 }
674
675 /* Now apply the texture subimage. The current implementation of
676 * S3TC requires that subimages be only applied to whole blocks.
677 */
678 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
679 switch(dimension) {
680 case GL_TEXTURE_3D:
681 (*CompressedTexSubImage3DARB)(GL_TEXTURE_3D, 0,
682 0, 0, 0, /* offsets */
683 SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT, SUBTEXTURE_DEPTH,
684 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
685 sizeof(compressedSubTexture), compressedSubTexture);
686 break;
687 case GL_TEXTURE_2D:
688 (*CompressedTexSubImage2DARB)(GL_TEXTURE_2D, 0,
689 0, 0, /* offsets */
690 SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT,
691 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
692 sizeof(compressedSubTexture), compressedSubTexture);
693 break;
694 case GL_TEXTURE_1D:
695 (*CompressedTexSubImage2DARB)(GL_TEXTURE_2D, 0,
696 0, 0, /* offsets */
697 SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT,
698 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
699 sizeof(compressedSubTexture), compressedSubTexture);
700 break;
701 }
702 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
703
704 /* Query the compressed texture back now, and see that it
705 * is as expected.
706 */
707 (*GetCompressedTexImageARB)(dimension, 0, queryCompressedData);
708 if (!compare_bytes("exercise_CompressedTextures:combined texture",
709 sizeof(compressedCombinedTexture), compressedCombinedTexture,
710 queryCompressedSize, queryCompressedData)) {
711 return GL_FALSE;
712 }
713 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
714
715 /* Just for the exercise, uncompress the texture and pull it out.
716 * We don't check it because the compression is lossy, so it won't
717 * compare exactly to the source texture; we just
718 * want to exercise the code paths that convert it.
719 */
720 glGetTexImage(dimension, 0, GL_RGBA, GL_UNSIGNED_BYTE, uncompressedTexture);
721 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
722
723 /* If we survived this far, we pass. */
724 return GL_TRUE;
725 }
726
727 /**************************************************************************
728 * Functions to assist with GL_EXT_framebuffer_object and
729 * GL_EXT_framebuffer_blit testing.
730 */
731
732 #define FB_STATUS_NAME(x) (\
733 x == GL_FRAMEBUFFER_COMPLETE_EXT ? "GL_FRAMEBUFFER_COMPLETE_EXT" : \
734 x == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT" : \
735 x == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT" : \
736 x == GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT" : \
737 x == GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT" : \
738 x == GL_FRAMEBUFFER_UNSUPPORTED_EXT ? "GL_FRAMEBUFFER_UNSUPPORTED_EXT" : \
739 x == GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT" : \
740 x == GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" : \
741 x == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" : \
742 "unknown")
743
744 static GLboolean
745 exercise_framebuffer(void)
746 {
747 GLuint framebufferID = 0;
748 GLuint renderbufferID = 0;
749
750 /* Dimensions of the framebuffer and renderbuffers are arbitrary.
751 * Since they won't be shown on-screen, we can use whatever we want.
752 */
753 const GLint Width = 100;
754 const GLint Height = 100;
755
756 /* Every function we use will be referenced through function pointers.
757 * This will allow this test program to run on OpenGL implementations
758 * that *don't* implement these extensions (though the implementation
759 * used to compile them must have up-to-date header files).
760 */
761 DECLARE_GLFUNC_PTR(GenFramebuffersEXT, PFNGLGENFRAMEBUFFERSEXTPROC);
762 DECLARE_GLFUNC_PTR(IsFramebufferEXT, PFNGLISFRAMEBUFFEREXTPROC);
763 DECLARE_GLFUNC_PTR(DeleteFramebuffersEXT, PFNGLDELETEFRAMEBUFFERSEXTPROC);
764 DECLARE_GLFUNC_PTR(BindFramebufferEXT, PFNGLBINDFRAMEBUFFEREXTPROC);
765 DECLARE_GLFUNC_PTR(GenRenderbuffersEXT, PFNGLGENRENDERBUFFERSEXTPROC);
766 DECLARE_GLFUNC_PTR(IsRenderbufferEXT, PFNGLISRENDERBUFFEREXTPROC);
767 DECLARE_GLFUNC_PTR(DeleteRenderbuffersEXT, PFNGLDELETERENDERBUFFERSEXTPROC);
768 DECLARE_GLFUNC_PTR(BindRenderbufferEXT, PFNGLBINDRENDERBUFFEREXTPROC);
769 DECLARE_GLFUNC_PTR(FramebufferRenderbufferEXT, PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC);
770 DECLARE_GLFUNC_PTR(RenderbufferStorageEXT, PFNGLRENDERBUFFERSTORAGEEXTPROC);
771 DECLARE_GLFUNC_PTR(CheckFramebufferStatusEXT, PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC);
772
773 /* The BlitFramebuffer function comes from a different extension.
774 * It's possible for an implementation to implement all the above,
775 * but not BlitFramebuffer; so it's okay if this one comes back
776 * NULL, as we can still test the rest.
777 */
778 DECLARE_GLFUNC_PTR(BlitFramebufferEXT, PFNGLBLITFRAMEBUFFEREXTPROC);
779
780 /* We cannot test unless we have all the function pointers. */
781 if (
782 GenFramebuffersEXT == NULL ||
783 IsFramebufferEXT == NULL ||
784 DeleteFramebuffersEXT == NULL ||
785 BindFramebufferEXT == NULL ||
786 GenRenderbuffersEXT == NULL ||
787 IsRenderbufferEXT == NULL ||
788 DeleteRenderbuffersEXT == NULL ||
789 BindRenderbufferEXT == NULL ||
790 FramebufferRenderbufferEXT == NULL ||
791 RenderbufferStorageEXT == NULL ||
792 CheckFramebufferStatusEXT == NULL
793 ) {
794 fprintf(stderr, "%s: could not locate all framebuffer functions\n",
795 __FUNCTION__);
796 return GL_FALSE;
797 }
798
799 /* Generate a framebuffer for us to play with. */
800 (*GenFramebuffersEXT)(1, &framebufferID);
801 if (framebufferID == 0) {
802 fprintf(stderr, "%s: failed to generate a frame buffer ID.\n",
803 __FUNCTION__);
804 return GL_FALSE;
805 }
806 /* The generated name is not a framebuffer object until bound. */
807 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, framebufferID);
808 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
809 if (!(*IsFramebufferEXT)(framebufferID)) {
810 fprintf(stderr, "%s: generated a frame buffer ID 0x%x that wasn't a framebuffer\n",
811 __FUNCTION__, framebufferID);
812 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
813 (*DeleteFramebuffersEXT)(1, &framebufferID);
814 return GL_FALSE;
815 }
816 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
817 {
818 GLint queriedFramebufferID;
819 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &queriedFramebufferID);
820 if (queriedFramebufferID != framebufferID) {
821 fprintf(stderr, "%s: bound frame buffer 0x%x, but queried 0x%x\n",
822 __FUNCTION__, framebufferID, queriedFramebufferID);
823 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
824 (*DeleteFramebuffersEXT)(1, &framebufferID);
825 return GL_FALSE;
826 }
827 }
828 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
829
830 /* Create a color buffer to attach to the frame buffer object, so
831 * we can actually operate on it. We go through the same basic checks
832 * with the renderbuffer that we do with the framebuffer.
833 */
834 (*GenRenderbuffersEXT)(1, &renderbufferID);
835 if (renderbufferID == 0) {
836 fprintf(stderr, "%s: could not generate a renderbuffer ID\n",
837 __FUNCTION__);
838 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
839 (*DeleteFramebuffersEXT)(1, &framebufferID);
840 return GL_FALSE;
841 }
842 (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, renderbufferID);
843 if (!(*IsRenderbufferEXT)(renderbufferID)) {
844 fprintf(stderr, "%s: generated renderbuffer 0x%x is not a renderbuffer\n",
845 __FUNCTION__, renderbufferID);
846 (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
847 (*DeleteRenderbuffersEXT)(1, &renderbufferID);
848 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
849 (*DeleteFramebuffersEXT)(1, &framebufferID);
850 return GL_FALSE;
851 }
852 {
853 GLint queriedRenderbufferID = 0;
854 glGetIntegerv(GL_RENDERBUFFER_BINDING_EXT, &queriedRenderbufferID);
855 if (renderbufferID != queriedRenderbufferID) {
856 fprintf(stderr, "%s: bound renderbuffer 0x%x, but got 0x%x\n",
857 __FUNCTION__, renderbufferID, queriedRenderbufferID);
858 (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
859 (*DeleteRenderbuffersEXT)(1, &renderbufferID);
860 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
861 (*DeleteFramebuffersEXT)(1, &framebufferID);
862 return GL_FALSE;
863 }
864 }
865 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
866
867 /* Add the renderbuffer as a color attachment to the current
868 * framebuffer (which is our generated framebuffer).
869 */
870 (*FramebufferRenderbufferEXT)(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,
871 GL_RENDERBUFFER_EXT, renderbufferID);
872 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
873
874 /* The renderbuffer will need some dimensions and storage space. */
875 (*RenderbufferStorageEXT)(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
876 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
877
878 /* That should be everything we need. If we set up to draw and to
879 * read from our color attachment, we should be "framebuffer complete",
880 * meaning the framebuffer is ready to go.
881 */
882 glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
883 glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
884 {
885 GLenum status = (*CheckFramebufferStatusEXT)(GL_FRAMEBUFFER_EXT);
886 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
887 fprintf(stderr, "%s: framebuffer not complete; status = %s [0x%x]\n",
888 __FUNCTION__, FB_STATUS_NAME(status), status);
889 glReadBuffer(0);
890 glDrawBuffer(0);
891 (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
892 (*DeleteRenderbuffersEXT)(1, &renderbufferID);
893 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
894 (*DeleteFramebuffersEXT)(1, &framebufferID);
895 return GL_FALSE;
896 }
897 }
898 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
899
900 /* Define the contents of the frame buffer */
901 glClearColor(0.5, 0.5, 0.5, 0.0);
902 glClear(GL_COLOR_BUFFER_BIT);
903
904 /* If the GL_EXT_framebuffer_blit is supported, attempt a framebuffer
905 * blit from (5,5)-(10,10) to (90,90)-(95,95). This is *not* an
906 * error if framebuffer_blit is *not* supported (as we can still
907 * effectively test the other functions).
908 */
909 if (BlitFramebufferEXT != NULL) {
910 (*BlitFramebufferEXT)(5, 5, 10, 10, 90, 90, 95, 95,
911 GL_COLOR_BUFFER_BIT, GL_NEAREST);
912 }
913 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
914
915 /* We could now test to see whether the framebuffer had the desired
916 * contents. As this is just a touch test, we'll leave that for now.
917 * Clean up and go home.
918 */
919 glReadBuffer(0);
920 glDrawBuffer(0);
921 (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
922 (*DeleteRenderbuffersEXT)(1, &renderbufferID);
923 (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
924 (*DeleteFramebuffersEXT)(1, &framebufferID);
925 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
926
927 return GL_TRUE;
928 }
929
930 /**************************************************************************
931 * Functions to assist with GL_ARB_shader_objects testing.
932 */
933
934 static void
935 print_info_log(const char *message, GLhandleARB object)
936 {
937 DECLARE_GLFUNC_PTR(GetObjectParameterivARB, PFNGLGETOBJECTPARAMETERIVARBPROC);
938 DECLARE_GLFUNC_PTR(GetInfoLogARB, PFNGLGETINFOLOGARBPROC);
939 int logLength, queryLength;
940 char *log;
941
942 if (GetObjectParameterivARB == NULL) {
943 fprintf(stderr, "%s: could not get GetObjectParameterivARB address\n",
944 message);
945 return;
946 }
947 if (GetInfoLogARB == NULL) {
948 fprintf(stderr, "%s: could not get GetInfoLogARB address\n",
949 message);
950 return;
951 }
952
953 (*GetObjectParameterivARB)(object, GL_OBJECT_INFO_LOG_LENGTH_ARB,
954 &logLength);
955 if (logLength == 0) {
956 fprintf(stderr, "%s: info log length is 0\n", message);
957 return;
958 }
959 log = malloc(logLength);
960 if (log == NULL) {
961 fprintf(stderr, "%s: could not malloc %d bytes for info log\n",
962 message, logLength);
963 }
964 else {
965 (*GetInfoLogARB)(object, logLength, &queryLength, log);
966 fprintf(stderr, "%s: info log says '%s'\n",
967 message, log);
968 }
969 free(log);
970 }
971
972 static GLboolean
973 exercise_uniform_start(const char *fragmentShaderText, const char *uniformName,
974 GLhandleARB *returnProgram, GLint *returnUniformLocation)
975 {
976 DECLARE_GLFUNC_PTR(CreateShaderObjectARB, PFNGLCREATESHADEROBJECTARBPROC);
977 DECLARE_GLFUNC_PTR(ShaderSourceARB, PFNGLSHADERSOURCEARBPROC);
978 DECLARE_GLFUNC_PTR(CompileShaderARB, PFNGLCOMPILESHADERARBPROC);
979 DECLARE_GLFUNC_PTR(CreateProgramObjectARB, PFNGLCREATEPROGRAMOBJECTARBPROC);
980 DECLARE_GLFUNC_PTR(AttachObjectARB, PFNGLATTACHOBJECTARBPROC);
981 DECLARE_GLFUNC_PTR(LinkProgramARB, PFNGLLINKPROGRAMARBPROC);
982 DECLARE_GLFUNC_PTR(UseProgramObjectARB, PFNGLUSEPROGRAMOBJECTARBPROC);
983 DECLARE_GLFUNC_PTR(ValidateProgramARB, PFNGLVALIDATEPROGRAMARBPROC);
984 DECLARE_GLFUNC_PTR(GetUniformLocationARB, PFNGLGETUNIFORMLOCATIONARBPROC);
985 DECLARE_GLFUNC_PTR(DeleteObjectARB, PFNGLDELETEOBJECTARBPROC);
986 DECLARE_GLFUNC_PTR(GetObjectParameterivARB, PFNGLGETOBJECTPARAMETERIVARBPROC);
987 GLhandleARB fs, program;
988 GLint uniformLocation;
989 GLint shaderCompiled, programValidated;
990
991 if (CreateShaderObjectARB == NULL ||
992 ShaderSourceARB == NULL ||
993 CompileShaderARB == NULL ||
994 CreateProgramObjectARB == NULL ||
995 AttachObjectARB == NULL ||
996 LinkProgramARB == NULL ||
997 UseProgramObjectARB == NULL ||
998 ValidateProgramARB == NULL ||
999 GetUniformLocationARB == NULL ||
1000 DeleteObjectARB == NULL ||
1001 GetObjectParameterivARB == NULL ||
1002 0) {
1003 return GL_FALSE;
1004 }
1005
1006 /* Create the trivial fragment shader and program. For safety
1007 * we'll check to make sure they compile and link correctly.
1008 */
1009 fs = (*CreateShaderObjectARB)(GL_FRAGMENT_SHADER_ARB);
1010 (*ShaderSourceARB)(fs, 1, &fragmentShaderText, NULL);
1011 (*CompileShaderARB)(fs);
1012 (*GetObjectParameterivARB)(fs, GL_OBJECT_COMPILE_STATUS_ARB,
1013 &shaderCompiled);
1014 if (!shaderCompiled) {
1015 print_info_log("shader did not compile", fs);
1016 (*DeleteObjectARB)(fs);
1017 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1018 return GL_FALSE;
1019 }
1020 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1021
1022 program = (*CreateProgramObjectARB)();
1023 (*AttachObjectARB)(program, fs);
1024 (*LinkProgramARB)(program);
1025 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1026
1027 /* Make sure we're going to run successfully */
1028 (*ValidateProgramARB)(program);
1029 (*GetObjectParameterivARB)(program, GL_OBJECT_VALIDATE_STATUS_ARB,
1030 &programValidated);
1031 if (!programValidated) {;
1032 print_info_log("program did not validate", program);
1033 (*DeleteObjectARB)(program);
1034 (*DeleteObjectARB)(fs);
1035 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1036 return GL_FALSE;
1037 }
1038
1039 /* Put the program in place. We're not allowed to assign to uniform
1040 * variables used by the program until the program is put into use.
1041 */
1042 (*UseProgramObjectARB)(program);
1043
1044 /* Once the shader is in place, we're free to delete it; this
1045 * won't affect the copy that's part of the program.
1046 */
1047 (*DeleteObjectARB)(fs);
1048
1049 /* Find the location index of the uniform variable we declared;
1050 * the caller will ned that to set the value.
1051 */
1052 uniformLocation = (*GetUniformLocationARB)(program, uniformName);
1053 if (uniformLocation == -1) {
1054 fprintf(stderr, "%s: could not determine uniform location\n",
1055 __FUNCTION__);
1056 (*DeleteObjectARB)(program);
1057 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1058 return GL_FALSE;
1059 }
1060
1061 /* All done with what we're supposed to do - return the program
1062 * handle and the uniform location to the caller.
1063 */
1064 *returnProgram = program;
1065 *returnUniformLocation = uniformLocation;
1066 return GL_TRUE;
1067 }
1068
1069 static void
1070 exercise_uniform_end(GLhandleARB program)
1071 {
1072 DECLARE_GLFUNC_PTR(UseProgramObjectARB, PFNGLUSEPROGRAMOBJECTARBPROC);
1073 DECLARE_GLFUNC_PTR(DeleteObjectARB, PFNGLDELETEOBJECTARBPROC);
1074 if (UseProgramObjectARB == NULL || DeleteObjectARB == NULL) {
1075 return;
1076 }
1077
1078 /* Turn off our program by setting the special value 0, and
1079 * then delete the program object.
1080 */
1081 (*UseProgramObjectARB)(0);
1082 (*DeleteObjectARB)(program);
1083 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1084 }
1085
1086 /**************************************************************************
1087 * Exercises for fences
1088 */
1089 static GLboolean
1090 exercise_fences(void)
1091 {
1092 DECLARE_GLFUNC_PTR(DeleteFencesNV, PFNGLDELETEFENCESNVPROC);
1093 DECLARE_GLFUNC_PTR(FinishFenceNV, PFNGLFINISHFENCENVPROC);
1094 DECLARE_GLFUNC_PTR(GenFencesNV, PFNGLGENFENCESNVPROC);
1095 DECLARE_GLFUNC_PTR(GetFenceivNV, PFNGLGETFENCEIVNVPROC);
1096 DECLARE_GLFUNC_PTR(IsFenceNV, PFNGLISFENCENVPROC);
1097 DECLARE_GLFUNC_PTR(SetFenceNV, PFNGLSETFENCENVPROC);
1098 DECLARE_GLFUNC_PTR(TestFenceNV, PFNGLTESTFENCENVPROC);
1099 GLuint fence;
1100 GLint fenceStatus, fenceCondition;
1101 int count;
1102
1103 /* Make sure we have all the function pointers we need. */
1104 if (GenFencesNV == NULL ||
1105 SetFenceNV == NULL ||
1106 IsFenceNV == NULL ||
1107 GetFenceivNV == NULL ||
1108 TestFenceNV == NULL ||
1109 FinishFenceNV == NULL ||
1110 DeleteFencesNV == NULL) {
1111 fprintf(stderr, "%s: don't have all the fence functions\n",
1112 __FUNCTION__);
1113 return GL_FALSE;
1114 }
1115
1116 /* Create and set a simple fence. */
1117 (*GenFencesNV)(1, &fence);
1118 (*SetFenceNV)(fence, GL_ALL_COMPLETED_NV);
1119 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1120
1121 /* Make sure it reads as a fence. */
1122 if (!(*IsFenceNV)(fence)) {
1123 fprintf(stderr, "%s: set fence is not a fence\n", __FUNCTION__);
1124 (*DeleteFencesNV)(1, &fence);
1125 return GL_FALSE;
1126 }
1127 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1128
1129 /* Try to read back its current status and condition. */
1130 (*GetFenceivNV)(fence, GL_FENCE_CONDITION_NV, &fenceCondition);
1131 if (fenceCondition != GL_ALL_COMPLETED_NV) {
1132 fprintf(stderr, "%s: expected fence condition 0x%x, got 0x%x\n",
1133 __FUNCTION__, GL_ALL_COMPLETED_NV, fenceCondition);
1134 (*DeleteFencesNV)(1, &fence);
1135 return GL_FALSE;
1136 }
1137 (*GetFenceivNV)(fence, GL_FENCE_STATUS_NV, &fenceStatus);
1138 if (fenceStatus != GL_TRUE && fenceStatus != GL_FALSE) {
1139 fprintf(stderr,"%s: fence status should be GL_TRUE or GL_FALSE, got 0x%x\n",
1140 __FUNCTION__, fenceStatus);
1141 (*DeleteFencesNV)(1, &fence);
1142 return GL_FALSE;
1143 }
1144 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1145
1146 /* Set the fence again, query its status, and wait for it to finish
1147 * two different ways: once by looping on TestFence(), and a
1148 * second time by a simple call to FinishFence();
1149 */
1150 (*SetFenceNV)(fence, GL_ALL_COMPLETED_NV);
1151 glFlush();
1152 count = 1;
1153 while (!(*TestFenceNV)(fence)) {
1154 count++;
1155 if (count == 0) {
1156 break;
1157 }
1158 }
1159 if (count == 0) {
1160 fprintf(stderr, "%s: fence never returned true\n", __FUNCTION__);
1161 (*DeleteFencesNV)(1, &fence);
1162 return GL_FALSE;
1163 }
1164 (*SetFenceNV)(fence, GL_ALL_COMPLETED_NV);
1165 (*FinishFenceNV)(fence);
1166 if ((*TestFenceNV)(fence) != GL_TRUE) {
1167 fprintf(stderr, "%s: finished fence does not have status GL_TRUE\n",
1168 __FUNCTION__);
1169 (*DeleteFencesNV)(1, &fence);
1170 return GL_FALSE;
1171 }
1172 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1173
1174 /* All done. Delete the fence and return. */
1175 (*DeleteFencesNV)(1, &fence);
1176 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1177 return GL_TRUE;
1178 }
1179
1180 /**************************************************************************
1181 * Exercises for buffer objects
1182 */
1183 enum Map_Buffer_Usage{ Use_Map_Buffer, Use_Map_Buffer_Range};
1184 static GLboolean
1185 exercise_buffer_objects(enum Map_Buffer_Usage usage)
1186 {
1187 #define BUFFER_DATA_SIZE 1024
1188 GLuint bufferID;
1189 GLint bufferMapped;
1190 static GLubyte data[BUFFER_DATA_SIZE] = {0};
1191 float *dataPtr = NULL;
1192
1193 /* Get the function pointers we need. These are from
1194 * GL_ARB_vertex_buffer_object and are required in all
1195 * cases.
1196 */
1197 DECLARE_GLFUNC_PTR(GenBuffersARB, PFNGLGENBUFFERSARBPROC);
1198 DECLARE_GLFUNC_PTR(BindBufferARB, PFNGLBINDBUFFERARBPROC);
1199 DECLARE_GLFUNC_PTR(BufferDataARB, PFNGLBUFFERDATAARBPROC);
1200 DECLARE_GLFUNC_PTR(MapBufferARB, PFNGLMAPBUFFERARBPROC);
1201 DECLARE_GLFUNC_PTR(UnmapBufferARB, PFNGLUNMAPBUFFERARBPROC);
1202 DECLARE_GLFUNC_PTR(DeleteBuffersARB, PFNGLDELETEBUFFERSARBPROC);
1203 DECLARE_GLFUNC_PTR(GetBufferParameterivARB, PFNGLGETBUFFERPARAMETERIVARBPROC);
1204
1205 /* These are from GL_ARB_map_buffer_range, and are optional
1206 * unless we're given Use_Map_Buffer_Range. Note that they do *not*
1207 * have the standard "ARB" suffixes; this is because the extension
1208 * was introduced *after* a superset was standardized in OpenGL 3.0.
1209 * (The extension really only exists to allow the functionality on
1210 * devices that cannot implement a full OpenGL 3.0 driver.)
1211 */
1212 DECLARE_GLFUNC_PTR(FlushMappedBufferRange, PFNGLFLUSHMAPPEDBUFFERRANGEPROC);
1213 DECLARE_GLFUNC_PTR(MapBufferRange, PFNGLMAPBUFFERRANGEPROC);
1214
1215 /* This is from APPLE_flush_buffer_range, and is optional even if
1216 * we're given Use_Map_Buffer_Range. Test it before using it.
1217 */
1218 DECLARE_GLFUNC_PTR(BufferParameteriAPPLE, PFNGLBUFFERPARAMETERIAPPLEPROC);
1219
1220 /* Make sure we have all the function pointers we need. */
1221 if (GenBuffersARB == NULL ||
1222 BindBufferARB == NULL ||
1223 BufferDataARB == NULL ||
1224 MapBufferARB == NULL ||
1225 UnmapBufferARB == NULL ||
1226 DeleteBuffersARB == NULL ||
1227 GetBufferParameterivARB == NULL) {
1228 fprintf(stderr, "%s: missing basic MapBuffer functions\n", __FUNCTION__);
1229 return GL_FALSE;
1230 }
1231 if (usage == Use_Map_Buffer_Range) {
1232 if (FlushMappedBufferRange == NULL || MapBufferRange == NULL) {
1233 fprintf(stderr, "%s: missing MapBufferRange functions\n", __FUNCTION__);
1234 return GL_FALSE;
1235 }
1236 }
1237
1238 /* Create and define a buffer */
1239 (*GenBuffersARB)(1, &bufferID);
1240 (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, bufferID);
1241 (*BufferDataARB)(GL_ARRAY_BUFFER_ARB, BUFFER_DATA_SIZE, data,
1242 GL_DYNAMIC_DRAW_ARB);
1243 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1244
1245 /* If we're using MapBufferRange, and if the BufferParameteriAPPLE
1246 * function is present, use it before mapping. This particular
1247 * use is a no-op, intended just to exercise the entry point.
1248 */
1249 if (usage == Use_Map_Buffer_Range && BufferParameteriAPPLE != NULL) {
1250 (*BufferParameteriAPPLE)(GL_ARRAY_BUFFER_ARB,
1251 GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE);
1252 }
1253
1254 /* Map it, and make sure it's mapped. */
1255 switch(usage) {
1256 case Use_Map_Buffer:
1257 dataPtr = (float *) (*MapBufferARB)(
1258 GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1259 break;
1260 case Use_Map_Buffer_Range:
1261 dataPtr = (float *)(*MapBufferRange)(GL_ARRAY_BUFFER_ARB,
1262 4, 16, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
1263 break;
1264 }
1265 if (dataPtr == NULL) {
1266 fprintf(stderr, "%s: %s returned NULL\n", __FUNCTION__,
1267 usage == Use_Map_Buffer ? "MapBuffer" : "MapBufferRange");
1268 (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
1269 (*DeleteBuffersARB)(1, &bufferID);
1270 return GL_FALSE;
1271 }
1272 (*GetBufferParameterivARB)(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB,
1273 &bufferMapped);
1274 if (!bufferMapped) {
1275 fprintf(stderr, "%s: buffer should be mapped but isn't\n", __FUNCTION__);
1276 (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
1277 (*DeleteBuffersARB)(1, &bufferID);
1278 return GL_FALSE;
1279 }
1280 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1281
1282 /* Write something to it, just to make sure we don't segfault. */
1283 *dataPtr = 1.5;
1284
1285 /* Unmap to show we're finished with the buffer. Note that if we're
1286 * using MapBufferRange, we first have to flush the range we modified.
1287 */
1288 if (usage == Use_Map_Buffer_Range) {
1289 (*FlushMappedBufferRange)(GL_ARRAY_BUFFER_ARB, 4, 16);
1290 }
1291 if (!(*UnmapBufferARB)(GL_ARRAY_BUFFER_ARB)) {
1292 fprintf(stderr, "%s: UnmapBuffer failed\n", __FUNCTION__);
1293 (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
1294 (*DeleteBuffersARB)(1, &bufferID);
1295 return GL_FALSE;
1296 }
1297 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1298
1299 /* All done. */
1300 (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
1301 (*DeleteBuffersARB)(1, &bufferID);
1302 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1303 return GL_TRUE;
1304
1305 #undef BUFFER_DATA_SIZE
1306 }
1307
1308 /**************************************************************************
1309 * Exercises for occlusion query
1310 */
1311 static GLboolean
1312 exercise_occlusion_query(void)
1313 {
1314 GLuint queryObject;
1315 GLint queryReady;
1316 GLuint querySampleCount;
1317 GLint queryCurrent;
1318 GLint queryCounterBits;
1319
1320 /* Get the function pointers we need. These are from
1321 * GL_ARB_vertex_buffer_object and are required in all
1322 * cases.
1323 */
1324 DECLARE_GLFUNC_PTR(GenQueriesARB, PFNGLGENQUERIESARBPROC);
1325 DECLARE_GLFUNC_PTR(BeginQueryARB, PFNGLBEGINQUERYARBPROC);
1326 DECLARE_GLFUNC_PTR(GetQueryivARB, PFNGLGETQUERYIVARBPROC);
1327 DECLARE_GLFUNC_PTR(EndQueryARB, PFNGLENDQUERYARBPROC);
1328 DECLARE_GLFUNC_PTR(IsQueryARB, PFNGLISQUERYARBPROC);
1329 DECLARE_GLFUNC_PTR(GetQueryObjectivARB, PFNGLGETQUERYOBJECTIVARBPROC);
1330 DECLARE_GLFUNC_PTR(GetQueryObjectuivARB, PFNGLGETQUERYOBJECTUIVARBPROC);
1331 DECLARE_GLFUNC_PTR(DeleteQueriesARB, PFNGLDELETEQUERIESARBPROC);
1332
1333 /* Make sure we have all the function pointers we need. */
1334 if (GenQueriesARB == NULL ||
1335 BeginQueryARB == NULL ||
1336 GetQueryivARB == NULL ||
1337 EndQueryARB == NULL ||
1338 IsQueryARB == NULL ||
1339 GetQueryObjectivARB == NULL ||
1340 GetQueryObjectuivARB == NULL ||
1341 DeleteQueriesARB == NULL) {
1342 fprintf(stderr, "%s: don't have all the Query functions\n", __FUNCTION__);
1343 return GL_FALSE;
1344 }
1345
1346 /* Create a query object, and start a query. */
1347 (*GenQueriesARB)(1, &queryObject);
1348 (*BeginQueryARB)(GL_SAMPLES_PASSED_ARB, queryObject);
1349 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1350
1351 /* While we're in the query, check the functions that are supposed
1352 * to return which query we're in and how many bits of resolution
1353 * we get.
1354 */
1355 (*GetQueryivARB)(GL_SAMPLES_PASSED_ARB, GL_CURRENT_QUERY_ARB, &queryCurrent);
1356 if (queryCurrent != queryObject) {
1357 fprintf(stderr, "%s: current query 0x%x != set query 0x%x\n",
1358 __FUNCTION__, queryCurrent, queryObject);
1359 (*EndQueryARB)(GL_SAMPLES_PASSED_ARB);
1360 (*DeleteQueriesARB)(1, &queryObject);
1361 return GL_FALSE;
1362 }
1363 (*GetQueryivARB)(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB,
1364 &queryCounterBits);
1365 if (queryCounterBits < 1) {
1366 fprintf(stderr, "%s: query counter bits is too small (%d)\n",
1367 __FUNCTION__, queryCounterBits);
1368 (*EndQueryARB)(GL_SAMPLES_PASSED_ARB);
1369 (*DeleteQueriesARB)(1, &queryObject);
1370 return GL_FALSE;
1371 }
1372 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1373
1374 /* Finish up the query. Since we didn't draw anything, the result
1375 * should be 0 passed samples.
1376 */
1377 (*EndQueryARB)(GL_SAMPLES_PASSED_ARB);
1378 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1379
1380 /* Routine existence test */
1381 if (!(*IsQueryARB)(queryObject)) {
1382 fprintf(stderr, "%s: query object 0x%x fails existence test\n",
1383 __FUNCTION__, queryObject);
1384 (*DeleteQueriesARB)(1, &queryObject);
1385 return GL_FALSE;
1386 }
1387
1388 /* Loop until the query is ready, then get back the result. We use
1389 * the signed query for the boolean value of whether the result is
1390 * available, but the unsigned query to actually pull the result;
1391 * this is just to test both entrypoints, but in a real query you may
1392 * need the extra bit of resolution.
1393 */
1394 queryReady = GL_FALSE;
1395 do {
1396 (*GetQueryObjectivARB)(queryObject, GL_QUERY_RESULT_AVAILABLE_ARB,
1397 &queryReady);
1398 } while (!queryReady);
1399 (*GetQueryObjectuivARB)(queryObject, GL_QUERY_RESULT_ARB, &querySampleCount);
1400 (*DeleteQueriesARB)(1, &queryObject);
1401 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1402
1403 /* If sample count isn't 0, something's funny. */
1404 if (querySampleCount > 0) {
1405 fprintf(stderr, "%s: expected query result of 0, got %ud\n",
1406 __FUNCTION__, querySampleCount);
1407 return GL_FALSE;
1408 }
1409
1410 /* Here, all is well. */
1411 return GL_TRUE;
1412 }
1413
1414 /**************************************************************************
1415 * The following functions are used to check that the named OpenGL function
1416 * actually does what it's supposed to do.
1417 * The naming of these functions is significant. The getprocaddress.py script
1418 * scans this file and extracts these function names.
1419 */
1420
1421 static GLboolean
1422 test_WeightPointerARB(generic_func func)
1423 {
1424 /* Assume we have at least 2 vertex units (or this extension makes
1425 * no sense), and establish a set of 2-element vector weights.
1426 * We use floats that can be represented exactly in binary
1427 * floating point formats so we can compare correctly later.
1428 * We also make sure the 0th entry matches the default weights,
1429 * so we can restore the default easily.
1430 */
1431 #define USE_VERTEX_UNITS 2
1432 #define USE_WEIGHT_INDEX 3
1433 static GLfloat weights[] = {
1434 1.0, 0.0,
1435 0.875, 0.125,
1436 0.75, 0.25,
1437 0.625, 0.375,
1438 0.5, 0.5,
1439 0.375, 0.625,
1440 0.25, 0.75,
1441 0.125, 0.875,
1442 0.0, 1.0,
1443 };
1444 GLint numVertexUnits;
1445 GLfloat *currentWeights;
1446 int i;
1447 int errorCount = 0;
1448
1449 PFNGLWEIGHTPOINTERARBPROC WeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC) func;
1450
1451 /* Make sure we have at least two vertex units */
1452 glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &numVertexUnits);
1453 if (numVertexUnits < USE_VERTEX_UNITS) {
1454 fprintf(stderr, "%s: need %d vertex units, got %d\n",
1455 __FUNCTION__, USE_VERTEX_UNITS, numVertexUnits);
1456 return GL_FALSE;
1457 }
1458
1459 /* Make sure we allocate enough room to query all the current weights */
1460 currentWeights = (GLfloat *)malloc(numVertexUnits * sizeof(GLfloat));
1461 if (currentWeights == NULL) {
1462 fprintf(stderr, "%s: couldn't allocate room for %d floats\n",
1463 __FUNCTION__, numVertexUnits);
1464 return GL_FALSE;
1465 }
1466
1467 /* Set up the pointer, enable the state, and try to send down a
1468 * weight vector (we'll arbitrarily send index 2).
1469 */
1470 (*WeightPointerARB)(USE_VERTEX_UNITS, GL_FLOAT, 0, weights);
1471 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
1472 glArrayElement(USE_WEIGHT_INDEX);
1473 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1474
1475 /* Verify that it changed the current state. */
1476 glGetFloatv(GL_CURRENT_WEIGHT_ARB, currentWeights);
1477 for (i = 0; i < numVertexUnits; i++) {
1478 if (i < USE_VERTEX_UNITS) {
1479 /* This is one of the units we explicitly set. */
1480 if (currentWeights[i] != weights[USE_VERTEX_UNITS*USE_WEIGHT_INDEX + i]) {
1481 fprintf(stderr, "%s: current weight at index %d is %f, should be %f\n",
1482 __FUNCTION__, i, currentWeights[i],
1483 weights[USE_VERTEX_UNITS*USE_WEIGHT_INDEX + i]);
1484 errorCount++;
1485 }
1486 }
1487 else {
1488 /* All other weights should be 0. */
1489 if (currentWeights[i] != 0.0) {
1490 fprintf(stderr, "%s: current weight at index %d is %f, should be %f\n",
1491 __FUNCTION__, i, 0.0,
1492 weights[USE_VERTEX_UNITS*USE_WEIGHT_INDEX + i]);
1493 errorCount++;
1494 }
1495 }
1496 }
1497 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1498
1499 /* Restore the old state. We know the default set of weights is in
1500 * index 0.
1501 */
1502 glArrayElement(0);
1503 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
1504 (*WeightPointerARB)(0, GL_FLOAT, 0, NULL);
1505 free(currentWeights);
1506 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1507
1508 /* We're fine if we didn't get any mismatches. */
1509 if (errorCount == 0) {
1510 return GL_TRUE;
1511 }
1512 else {
1513 return GL_FALSE;
1514 }
1515 }
1516
1517 /* Wrappers on the exercise_occlusion_query function */
1518 static GLboolean
1519 test_GenQueriesARB(generic_func func)
1520 {
1521 (void) func;
1522 return exercise_occlusion_query();
1523 }
1524 static GLboolean
1525 test_BeginQueryARB(generic_func func)
1526 {
1527 (void) func;
1528 return exercise_occlusion_query();
1529 }
1530 static GLboolean
1531 test_GetQueryivARB(generic_func func)
1532 {
1533 (void) func;
1534 return exercise_occlusion_query();
1535 }
1536 static GLboolean
1537 test_EndQueryARB(generic_func func)
1538 {
1539 (void) func;
1540 return exercise_occlusion_query();
1541 }
1542 static GLboolean
1543 test_IsQueryARB(generic_func func)
1544 {
1545 (void) func;
1546 return exercise_occlusion_query();
1547 }
1548 static GLboolean
1549 test_GetQueryObjectivARB(generic_func func)
1550 {
1551 (void) func;
1552 return exercise_occlusion_query();
1553 }
1554 static GLboolean
1555 test_GetQueryObjectuivARB(generic_func func)
1556 {
1557 (void) func;
1558 return exercise_occlusion_query();
1559 }
1560 static GLboolean
1561 test_DeleteQueriesARB(generic_func func)
1562 {
1563 (void) func;
1564 return exercise_occlusion_query();
1565 }
1566
1567 /* Wrappers on the exercise_buffer_objects() function */
1568 static GLboolean
1569 test_GenBuffersARB(generic_func func)
1570 {
1571 (void) func;
1572 return exercise_buffer_objects(Use_Map_Buffer);
1573 }
1574 static GLboolean
1575 test_BindBufferARB(generic_func func)
1576 {
1577 (void) func;
1578 return exercise_buffer_objects(Use_Map_Buffer);
1579 }
1580 static GLboolean
1581 test_BufferDataARB(generic_func func)
1582 {
1583 (void) func;
1584 return exercise_buffer_objects(Use_Map_Buffer);
1585 }
1586 static GLboolean
1587 test_MapBufferARB(generic_func func)
1588 {
1589 (void) func;
1590 return exercise_buffer_objects(Use_Map_Buffer);
1591 }
1592 static GLboolean
1593 test_UnmapBufferARB(generic_func func)
1594 {
1595 (void) func;
1596 return exercise_buffer_objects(Use_Map_Buffer);
1597 }
1598 static GLboolean
1599 test_DeleteBuffersARB(generic_func func)
1600 {
1601 (void) func;
1602 return exercise_buffer_objects(Use_Map_Buffer);
1603 }
1604 static GLboolean
1605 test_GetBufferParameterivARB(generic_func func)
1606 {
1607 (void) func;
1608 return exercise_buffer_objects(Use_Map_Buffer);
1609 }
1610 static GLboolean
1611 test_FlushMappedBufferRange(generic_func func)
1612 {
1613 (void) func;
1614 return exercise_buffer_objects(Use_Map_Buffer_Range);
1615 }
1616 static GLboolean
1617 test_MapBufferRange(generic_func func)
1618 {
1619 (void) func;
1620 return exercise_buffer_objects(Use_Map_Buffer_Range);
1621 }
1622 static GLboolean
1623 test_BufferParameteriAPPLE(generic_func func)
1624 {
1625 (void) func;
1626 return exercise_buffer_objects(Use_Map_Buffer_Range);
1627 }
1628
1629 /* Wrappers on the exercise_framebuffer() function */
1630 static GLboolean
1631 test_BindFramebufferEXT(generic_func func)
1632 {
1633 (void) func;
1634 return exercise_framebuffer();
1635 }
1636 static GLboolean
1637 test_BindRenderbufferEXT(generic_func func)
1638 {
1639 (void) func;
1640 return exercise_framebuffer();
1641 }
1642 static GLboolean
1643 test_CheckFramebufferStatusEXT(generic_func func)
1644 {
1645 (void) func;
1646 return exercise_framebuffer();
1647 }
1648 static GLboolean
1649 test_DeleteFramebuffersEXT(generic_func func)
1650 {
1651 (void) func;
1652 return exercise_framebuffer();
1653 }
1654 static GLboolean
1655 test_DeleteRenderbuffersEXT(generic_func func)
1656 {
1657 (void) func;
1658 return exercise_framebuffer();
1659 }
1660 static GLboolean
1661 test_FramebufferRenderbufferEXT(generic_func func)
1662 {
1663 (void) func;
1664 return exercise_framebuffer();
1665 }
1666 static GLboolean
1667 test_GenFramebuffersEXT(generic_func func)
1668 {
1669 (void) func;
1670 return exercise_framebuffer();
1671 }
1672 static GLboolean
1673 test_GenRenderbuffersEXT(generic_func func)
1674 {
1675 (void) func;
1676 return exercise_framebuffer();
1677 }
1678 static GLboolean
1679 test_IsFramebufferEXT(generic_func func)
1680 {
1681 (void) func;
1682 return exercise_framebuffer();
1683 }
1684 static GLboolean
1685 test_IsRenderbufferEXT(generic_func func)
1686 {
1687 (void) func;
1688 return exercise_framebuffer();
1689 }
1690 static GLboolean
1691 test_RenderbufferStorageEXT(generic_func func)
1692 {
1693 (void) func;
1694 return exercise_framebuffer();
1695 }
1696 static GLboolean
1697 test_BlitFramebufferEXT(generic_func func)
1698 {
1699 (void) func;
1700 return exercise_framebuffer();
1701 }
1702
1703 /* These are wrappers on the exercise_CompressedTextures function.
1704 * Unfortunately, we cannot test the 1D counterparts, because the
1705 * texture compressions available all support 2D and higher only.
1706 */
1707 static GLboolean
1708 test_CompressedTexImage2DARB(generic_func func)
1709 {
1710 (void) func;
1711 return exercise_CompressedTextures(GL_TEXTURE_2D);
1712 }
1713 static GLboolean
1714 test_CompressedTexSubImage2DARB(generic_func func)
1715 {
1716 (void) func;
1717 return exercise_CompressedTextures(GL_TEXTURE_2D);
1718 }
1719 static GLboolean
1720 test_CompressedTexImage3DARB(generic_func func)
1721 {
1722 (void) func;
1723 return exercise_CompressedTextures(GL_TEXTURE_3D);
1724 }
1725 static GLboolean
1726 test_CompressedTexSubImage3DARB(generic_func func)
1727 {
1728 (void) func;
1729 return exercise_CompressedTextures(GL_TEXTURE_3D);
1730 }
1731 static GLboolean
1732 test_GetCompressedTexImageARB(generic_func func)
1733 {
1734 (void) func;
1735 return exercise_CompressedTextures(GL_TEXTURE_3D);
1736 }
1737
1738 /* Wrappers on exercise_fences(). */
1739 static GLboolean
1740 test_DeleteFencesNV(generic_func func)
1741 {
1742 (void) func;
1743 return exercise_fences();
1744 }
1745 static GLboolean
1746 test_GenFencesNV(generic_func func)
1747 {
1748 (void) func;
1749 return exercise_fences();
1750 }
1751 static GLboolean
1752 test_SetFenceNV(generic_func func)
1753 {
1754 (void) func;
1755 return exercise_fences();
1756 }
1757 static GLboolean
1758 test_TestFenceNV(generic_func func)
1759 {
1760 (void) func;
1761 return exercise_fences();
1762 }
1763 static GLboolean
1764 test_FinishFenceNV(generic_func func)
1765 {
1766 (void) func;
1767 return exercise_fences();
1768 }
1769 static GLboolean
1770 test_GetFenceivNV(generic_func func)
1771 {
1772 (void) func;
1773 return exercise_fences();
1774 }
1775 static GLboolean
1776 test_IsFenceNV(generic_func func)
1777 {
1778 (void) func;
1779 return exercise_fences();
1780 }
1781
1782 /* A bunch of glUniform*() tests */
1783 static GLboolean
1784 test_Uniform1iv(generic_func func)
1785 {
1786 PFNGLUNIFORM1IVARBPROC Uniform1ivARB = (PFNGLUNIFORM1IVARBPROC) func;
1787 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
1788
1789 /* This is a trivial fragment shader that sets the color of the
1790 * fragment to the uniform value passed in.
1791 */
1792 static const char *fragmentShaderText =
1793 "uniform int uniformColor;"
1794 "void main() {gl_FragColor.r = uniformColor;}";
1795 static const char *uniformName = "uniformColor";
1796
1797 GLhandleARB program;
1798 GLint uniformLocation;
1799 const GLint uniform[1] = {1};
1800 GLint queriedUniform[1];
1801
1802 if (GetUniformivARB == NULL) {
1803 return GL_FALSE;
1804 }
1805
1806 /* Call a helper function to compile up the shader and give
1807 * us back the validated program and uniform location.
1808 * If it fails, something's wrong and we can't continue.
1809 */
1810 if (!exercise_uniform_start(fragmentShaderText, uniformName,
1811 &program, &uniformLocation)) {
1812 return GL_FALSE;
1813 }
1814
1815 /* Set the value of the program uniform. Note that you must
1816 * use a compatible type. Our uniform above is an integer
1817 * so we must set it using integer versions
1818 * of the Uniform* functions. The "1" means we're setting
1819 * one vector's worth of information.
1820 */
1821 (*Uniform1ivARB)(uniformLocation, 1, uniform);
1822 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1823
1824 /* Query it back */
1825 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
1826 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1827
1828 /* Clean up before we check to see whether it came back unscathed */
1829 exercise_uniform_end(program);
1830
1831 /* Now check to see whether the uniform came back as expected. This
1832 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
1833 */
1834 return compare_ints(__FUNCTION__, 1, uniform, 1, queriedUniform);
1835 }
1836
1837 static GLboolean
1838 test_Uniform1i(generic_func func)
1839 {
1840 PFNGLUNIFORM1IARBPROC Uniform1iARB = (PFNGLUNIFORM1IARBPROC) func;
1841 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
1842
1843 /* This is a trivial fragment shader that sets the color of the
1844 * fragment to the uniform value passed in.
1845 */
1846 static const char *fragmentShaderText =
1847 "uniform int uniformColor;"
1848 "void main() {gl_FragColor.r = uniformColor;}";
1849 static const char *uniformName = "uniformColor";
1850
1851 GLhandleARB program;
1852 GLint uniformLocation;
1853 const GLint uniform[1] = {1};
1854 GLint queriedUniform[4];
1855
1856 if (GetUniformivARB == NULL) {
1857 return GL_FALSE;
1858 }
1859
1860 /* Call a helper function to compile up the shader and give
1861 * us back the validated program and uniform location.
1862 * If it fails, something's wrong and we can't continue.
1863 */
1864 if (!exercise_uniform_start(fragmentShaderText, uniformName,
1865 &program, &uniformLocation)) {
1866 return GL_FALSE;
1867 }
1868
1869 /* Set the value of the program uniform. Note that you must
1870 * use a compatible type. Our uniform above is an integer
1871 * so we must set it using integer versions
1872 * of the Uniform* functions.
1873 */
1874 (*Uniform1iARB)(uniformLocation, uniform[0]);
1875 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1876
1877 /* Query it back */
1878 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
1879 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1880
1881 /* Clean up before we check to see whether it came back unscathed */
1882 exercise_uniform_end(program);
1883
1884 /* Now check to see whether the uniform came back as expected. This
1885 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
1886 */
1887 return compare_ints(__FUNCTION__, 1, uniform, 1, queriedUniform);
1888 }
1889
1890 static GLboolean
1891 test_Uniform1fv(generic_func func)
1892 {
1893 PFNGLUNIFORM1FVARBPROC Uniform1fvARB = (PFNGLUNIFORM1FVARBPROC) func;
1894 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
1895
1896 /* This is a trivial fragment shader that sets the color of the
1897 * fragment to the uniform value passed in.
1898 */
1899 static const char *fragmentShaderText =
1900 "uniform float uniformColor;"
1901 "void main() {gl_FragColor.r = uniformColor;}";
1902 static const char *uniformName = "uniformColor";
1903
1904 GLhandleARB program;
1905 GLint uniformLocation;
1906 const GLfloat uniform[1] = {1.1};
1907 GLfloat queriedUniform[1];
1908
1909 if (GetUniformfvARB == NULL) {
1910 return GL_FALSE;
1911 }
1912
1913 /* Call a helper function to compile up the shader and give
1914 * us back the validated program and uniform location.
1915 * If it fails, something's wrong and we can't continue.
1916 */
1917 if (!exercise_uniform_start(fragmentShaderText, uniformName,
1918 &program, &uniformLocation)) {
1919 return GL_FALSE;
1920 }
1921
1922 /* Set the value of the program uniform. Note that you must
1923 * use a compatible type. Our uniform above is a float
1924 * so we must set it using float versions
1925 * of the Uniform* functions. The "1" means we're setting
1926 * one vector's worth of information.
1927 */
1928 (*Uniform1fvARB)(uniformLocation, 1, uniform);
1929 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1930
1931 /* Query it back */
1932 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
1933 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1934
1935 /* Clean up before we check to see whether it came back unscathed */
1936 exercise_uniform_end(program);
1937
1938 /* Now check to see whether the uniform came back as expected. This
1939 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
1940 */
1941 return compare_floats(__FUNCTION__, 1, uniform, 1, queriedUniform);
1942 }
1943
1944 static GLboolean
1945 test_Uniform1f(generic_func func)
1946 {
1947 PFNGLUNIFORM1FARBPROC Uniform1fARB = (PFNGLUNIFORM1FARBPROC) func;
1948 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
1949
1950 /* This is a trivial fragment shader that sets the color of the
1951 * fragment to the uniform value passed in.
1952 */
1953 static const char *fragmentShaderText =
1954 "uniform float uniformColor;"
1955 "void main() {gl_FragColor.r = uniformColor;}";
1956 static const char *uniformName = "uniformColor";
1957
1958 GLhandleARB program;
1959 GLint uniformLocation;
1960 const GLfloat uniform[1] = {1.1};
1961 GLfloat queriedUniform[1];
1962
1963 if (GetUniformfvARB == NULL) {
1964 return GL_FALSE;
1965 }
1966
1967 /* Call a helper function to compile up the shader and give
1968 * us back the validated program and uniform location.
1969 * If it fails, something's wrong and we can't continue.
1970 */
1971 if (!exercise_uniform_start(fragmentShaderText, uniformName,
1972 &program, &uniformLocation)) {
1973 return GL_FALSE;
1974 }
1975
1976 /* Set the value of the program uniform. Note that you must
1977 * use a compatible type. Our uniform above is a float
1978 * so we must set it using float versions
1979 * of the Uniform* functions.
1980 */
1981 (*Uniform1fARB)(uniformLocation, uniform[0]);
1982 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1983
1984 /* Query it back */
1985 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
1986 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
1987
1988 /* Clean up before we check to see whether it came back unscathed */
1989 exercise_uniform_end(program);
1990
1991 /* Now check to see whether the uniform came back as expected. This
1992 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
1993 */
1994 return compare_floats(__FUNCTION__, 1, uniform, 1, queriedUniform);
1995 }
1996
1997 static GLboolean
1998 test_Uniform2iv(generic_func func)
1999 {
2000 PFNGLUNIFORM2IVARBPROC Uniform2ivARB = (PFNGLUNIFORM2IVARBPROC) func;
2001 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
2002
2003 /* This is a trivial fragment shader that sets the color of the
2004 * fragment to the uniform value passed in.
2005 */
2006 static const char *fragmentShaderText =
2007 "uniform ivec2 uniformColor;"
2008 "void main() {gl_FragColor.rg = uniformColor;}";
2009 static const char *uniformName = "uniformColor";
2010
2011 GLhandleARB program;
2012 GLint uniformLocation;
2013 const GLint uniform[2] = {1,2};
2014 GLint queriedUniform[2];
2015
2016 if (GetUniformivARB == NULL) {
2017 return GL_FALSE;
2018 }
2019
2020 /* Call a helper function to compile up the shader and give
2021 * us back the validated program and uniform location.
2022 * If it fails, something's wrong and we can't continue.
2023 */
2024 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2025 &program, &uniformLocation)) {
2026 return GL_FALSE;
2027 }
2028
2029 /* Set the value of the program uniform. Note that you must
2030 * use a compatible type. Our uniform above is an integer
2031 * vector 2 (ivec2), so we must set it using integer versions
2032 * of the Uniform* functions. The "1" means we're setting
2033 * one vector's worth of information.
2034 */
2035 (*Uniform2ivARB)(uniformLocation, 1, uniform);
2036 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2037
2038 /* Query it back */
2039 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
2040 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2041
2042 /* Clean up before we check to see whether it came back unscathed */
2043 exercise_uniform_end(program);
2044
2045 /* Now check to see whether the uniform came back as expected. This
2046 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2047 */
2048 return compare_ints(__FUNCTION__, 2, uniform, 2, queriedUniform);
2049 }
2050
2051 static GLboolean
2052 test_Uniform2i(generic_func func)
2053 {
2054 PFNGLUNIFORM2IARBPROC Uniform2iARB = (PFNGLUNIFORM2IARBPROC) func;
2055 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
2056
2057 /* This is a trivial fragment shader that sets the color of the
2058 * fragment to the uniform value passed in.
2059 */
2060 static const char *fragmentShaderText =
2061 "uniform ivec2 uniformColor;"
2062 "void main() {gl_FragColor.rg = uniformColor;}";
2063 static const char *uniformName = "uniformColor";
2064
2065 GLhandleARB program;
2066 GLint uniformLocation;
2067 const GLint uniform[2] = {1,2};
2068 GLint queriedUniform[4];
2069
2070 if (GetUniformivARB == NULL) {
2071 return GL_FALSE;
2072 }
2073
2074 /* Call a helper function to compile up the shader and give
2075 * us back the validated program and uniform location.
2076 * If it fails, something's wrong and we can't continue.
2077 */
2078 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2079 &program, &uniformLocation)) {
2080 return GL_FALSE;
2081 }
2082
2083 /* Set the value of the program uniform. Note that you must
2084 * use a compatible type. Our uniform above is an integer
2085 * vector 2 (ivec2), so we must set it using integer versions
2086 * of the Uniform* functions.
2087 */
2088 (*Uniform2iARB)(uniformLocation, uniform[0], uniform[1]);
2089 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2090
2091 /* Query it back */
2092 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
2093 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2094
2095 /* Clean up before we check to see whether it came back unscathed */
2096 exercise_uniform_end(program);
2097
2098 /* Now check to see whether the uniform came back as expected. This
2099 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2100 */
2101 return compare_ints(__FUNCTION__, 2, uniform, 2, queriedUniform);
2102 }
2103
2104 static GLboolean
2105 test_Uniform2fv(generic_func func)
2106 {
2107 PFNGLUNIFORM2FVARBPROC Uniform2fvARB = (PFNGLUNIFORM2FVARBPROC) func;
2108 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
2109
2110 /* This is a trivial fragment shader that sets the color of the
2111 * fragment to the uniform value passed in.
2112 */
2113 static const char *fragmentShaderText =
2114 "uniform vec2 uniformColor;"
2115 "void main() {gl_FragColor.rg = uniformColor;}";
2116 static const char *uniformName = "uniformColor";
2117
2118 GLhandleARB program;
2119 GLint uniformLocation;
2120 const GLfloat uniform[2] = {1.1,2.2};
2121 GLfloat queriedUniform[2];
2122
2123 if (GetUniformfvARB == NULL) {
2124 return GL_FALSE;
2125 }
2126
2127 /* Call a helper function to compile up the shader and give
2128 * us back the validated program and uniform location.
2129 * If it fails, something's wrong and we can't continue.
2130 */
2131 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2132 &program, &uniformLocation)) {
2133 return GL_FALSE;
2134 }
2135
2136 /* Set the value of the program uniform. Note that you must
2137 * use a compatible type. Our uniform above is a float
2138 * vector 2 (vec2), so we must set it using float versions
2139 * of the Uniform* functions. The "1" means we're setting
2140 * one vector's worth of information.
2141 */
2142 (*Uniform2fvARB)(uniformLocation, 1, uniform);
2143 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2144
2145 /* Query it back */
2146 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
2147 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2148
2149 /* Clean up before we check to see whether it came back unscathed */
2150 exercise_uniform_end(program);
2151
2152 /* Now check to see whether the uniform came back as expected. This
2153 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2154 */
2155 return compare_floats(__FUNCTION__, 2, uniform, 2, queriedUniform);
2156 }
2157
2158 static GLboolean
2159 test_Uniform2f(generic_func func)
2160 {
2161 PFNGLUNIFORM2FARBPROC Uniform2fARB = (PFNGLUNIFORM2FARBPROC) func;
2162 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
2163
2164 /* This is a trivial fragment shader that sets the color of the
2165 * fragment to the uniform value passed in.
2166 */
2167 static const char *fragmentShaderText =
2168 "uniform vec2 uniformColor;"
2169 "void main() {gl_FragColor.rg = uniformColor;}";
2170 static const char *uniformName = "uniformColor";
2171
2172 GLhandleARB program;
2173 GLint uniformLocation;
2174 const GLfloat uniform[2] = {1.1,2.2};
2175 GLfloat queriedUniform[2];
2176
2177 if (GetUniformfvARB == NULL) {
2178 return GL_FALSE;
2179 }
2180
2181 /* Call a helper function to compile up the shader and give
2182 * us back the validated program and uniform location.
2183 * If it fails, something's wrong and we can't continue.
2184 */
2185 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2186 &program, &uniformLocation)) {
2187 return GL_FALSE;
2188 }
2189
2190 /* Set the value of the program uniform. Note that you must
2191 * use a compatible type. Our uniform above is a float
2192 * vector 2 (vec2), so we must set it using float versions
2193 * of the Uniform* functions.
2194 */
2195 (*Uniform2fARB)(uniformLocation, uniform[0], uniform[1]);
2196 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2197
2198 /* Query it back */
2199 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
2200 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2201
2202 /* Clean up before we check to see whether it came back unscathed */
2203 exercise_uniform_end(program);
2204
2205 /* Now check to see whether the uniform came back as expected. This
2206 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2207 */
2208 return compare_floats(__FUNCTION__, 2, uniform, 2, queriedUniform);
2209 }
2210
2211 static GLboolean
2212 test_Uniform3iv(generic_func func)
2213 {
2214 PFNGLUNIFORM3IVARBPROC Uniform3ivARB = (PFNGLUNIFORM3IVARBPROC) func;
2215 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
2216
2217 /* This is a trivial fragment shader that sets the color of the
2218 * fragment to the uniform value passed in.
2219 */
2220 static const char *fragmentShaderText =
2221 "uniform ivec3 uniformColor;"
2222 "void main() {gl_FragColor.rgb = uniformColor;}";
2223 static const char *uniformName = "uniformColor";
2224
2225 GLhandleARB program;
2226 GLint uniformLocation;
2227 const GLint uniform[3] = {1,2,3};
2228 GLint queriedUniform[3];
2229
2230 if (GetUniformivARB == NULL) {
2231 return GL_FALSE;
2232 }
2233
2234 /* Call a helper function to compile up the shader and give
2235 * us back the validated program and uniform location.
2236 * If it fails, something's wrong and we can't continue.
2237 */
2238 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2239 &program, &uniformLocation)) {
2240 return GL_FALSE;
2241 }
2242
2243 /* Set the value of the program uniform. Note that you must
2244 * use a compatible type. Our uniform above is an integer
2245 * vector 3 (ivec3), so we must set it using integer versions
2246 * of the Uniform* functions. The "1" means we're setting
2247 * one vector's worth of information.
2248 */
2249 (*Uniform3ivARB)(uniformLocation, 1, uniform);
2250 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2251
2252 /* Query it back */
2253 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
2254 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2255
2256 /* Clean up before we check to see whether it came back unscathed */
2257 exercise_uniform_end(program);
2258
2259 /* Now check to see whether the uniform came back as expected. This
2260 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2261 */
2262 return compare_ints(__FUNCTION__, 3, uniform, 3, queriedUniform);
2263 }
2264
2265 static GLboolean
2266 test_Uniform3i(generic_func func)
2267 {
2268 PFNGLUNIFORM3IARBPROC Uniform3iARB = (PFNGLUNIFORM3IARBPROC) func;
2269 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
2270
2271 /* This is a trivial fragment shader that sets the color of the
2272 * fragment to the uniform value passed in.
2273 */
2274 static const char *fragmentShaderText =
2275 "uniform ivec3 uniformColor;"
2276 "void main() {gl_FragColor.rgb = uniformColor;}";
2277 static const char *uniformName = "uniformColor";
2278
2279 GLhandleARB program;
2280 GLint uniformLocation;
2281 const GLint uniform[3] = {1,2,3};
2282 GLint queriedUniform[4];
2283
2284 if (GetUniformivARB == NULL) {
2285 return GL_FALSE;
2286 }
2287
2288 /* Call a helper function to compile up the shader and give
2289 * us back the validated program and uniform location.
2290 * If it fails, something's wrong and we can't continue.
2291 */
2292 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2293 &program, &uniformLocation)) {
2294 return GL_FALSE;
2295 }
2296
2297 /* Set the value of the program uniform. Note that you must
2298 * use a compatible type. Our uniform above is an integer
2299 * vector 3 (ivec3), so we must set it using integer versions
2300 * of the Uniform* functions.
2301 */
2302 (*Uniform3iARB)(uniformLocation, uniform[0], uniform[1], uniform[2]);
2303 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2304
2305 /* Query it back */
2306 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
2307 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2308
2309 /* Clean up before we check to see whether it came back unscathed */
2310 exercise_uniform_end(program);
2311
2312 /* Now check to see whether the uniform came back as expected. This
2313 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2314 */
2315 return compare_ints(__FUNCTION__, 3, uniform, 3, queriedUniform);
2316 }
2317
2318 static GLboolean
2319 test_Uniform3fv(generic_func func)
2320 {
2321 PFNGLUNIFORM3FVARBPROC Uniform3fvARB = (PFNGLUNIFORM3FVARBPROC) func;
2322 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
2323
2324 /* This is a trivial fragment shader that sets the color of the
2325 * fragment to the uniform value passed in.
2326 */
2327 static const char *fragmentShaderText =
2328 "uniform vec3 uniformColor;"
2329 "void main() {gl_FragColor.rgb = uniformColor;}";
2330 static const char *uniformName = "uniformColor";
2331
2332 GLhandleARB program;
2333 GLint uniformLocation;
2334 const GLfloat uniform[3] = {1.1,2.2,3.3};
2335 GLfloat queriedUniform[3];
2336
2337 if (GetUniformfvARB == NULL) {
2338 return GL_FALSE;
2339 }
2340
2341 /* Call a helper function to compile up the shader and give
2342 * us back the validated program and uniform location.
2343 * If it fails, something's wrong and we can't continue.
2344 */
2345 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2346 &program, &uniformLocation)) {
2347 return GL_FALSE;
2348 }
2349
2350 /* Set the value of the program uniform. Note that you must
2351 * use a compatible type. Our uniform above is a float
2352 * vector 3 (vec3), so we must set it using float versions
2353 * of the Uniform* functions. The "1" means we're setting
2354 * one vector's worth of information.
2355 */
2356 (*Uniform3fvARB)(uniformLocation, 1, uniform);
2357 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2358
2359 /* Query it back */
2360 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
2361 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2362
2363 /* Clean up before we check to see whether it came back unscathed */
2364 exercise_uniform_end(program);
2365
2366 /* Now check to see whether the uniform came back as expected. This
2367 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2368 */
2369 return compare_floats(__FUNCTION__, 3, uniform, 3, queriedUniform);
2370 }
2371
2372 static GLboolean
2373 test_Uniform3f(generic_func func)
2374 {
2375 PFNGLUNIFORM3FARBPROC Uniform3fARB = (PFNGLUNIFORM3FARBPROC) func;
2376 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
2377
2378 /* This is a trivial fragment shader that sets the color of the
2379 * fragment to the uniform value passed in.
2380 */
2381 static const char *fragmentShaderText =
2382 "uniform vec3 uniformColor;"
2383 "void main() {gl_FragColor.rgb = uniformColor;}";
2384 static const char *uniformName = "uniformColor";
2385
2386 GLhandleARB program;
2387 GLint uniformLocation;
2388 const GLfloat uniform[3] = {1.1,2.2,3.3};
2389 GLfloat queriedUniform[3];
2390
2391 if (GetUniformfvARB == NULL) {
2392 return GL_FALSE;
2393 }
2394
2395 /* Call a helper function to compile up the shader and give
2396 * us back the validated program and uniform location.
2397 * If it fails, something's wrong and we can't continue.
2398 */
2399 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2400 &program, &uniformLocation)) {
2401 return GL_FALSE;
2402 }
2403
2404 /* Set the value of the program uniform. Note that you must
2405 * use a compatible type. Our uniform above is a float
2406 * vector 3 (vec3), so we must set it using float versions
2407 * of the Uniform* functions.
2408 */
2409 (*Uniform3fARB)(uniformLocation, uniform[0], uniform[1], uniform[2]);
2410 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2411
2412 /* Query it back */
2413 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
2414 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2415
2416 /* Clean up before we check to see whether it came back unscathed */
2417 exercise_uniform_end(program);
2418
2419 /* Now check to see whether the uniform came back as expected. This
2420 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2421 */
2422 return compare_floats(__FUNCTION__, 3, uniform, 3, queriedUniform);
2423 }
2424
2425 static GLboolean
2426 test_Uniform4iv(generic_func func)
2427 {
2428 PFNGLUNIFORM4IVARBPROC Uniform4ivARB = (PFNGLUNIFORM4IVARBPROC) func;
2429 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
2430
2431 /* This is a trivial fragment shader that sets the color of the
2432 * fragment to the uniform value passed in.
2433 */
2434 static const char *fragmentShaderText =
2435 "uniform ivec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2436 static const char *uniformName = "uniformColor";
2437
2438 GLhandleARB program;
2439 GLint uniformLocation;
2440 const GLint uniform[4] = {1,2,3,4};
2441 GLint queriedUniform[4];
2442
2443 if (GetUniformivARB == NULL) {
2444 return GL_FALSE;
2445 }
2446
2447 /* Call a helper function to compile up the shader and give
2448 * us back the validated program and uniform location.
2449 * If it fails, something's wrong and we can't continue.
2450 */
2451 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2452 &program, &uniformLocation)) {
2453 return GL_FALSE;
2454 }
2455
2456 /* Set the value of the program uniform. Note that you must
2457 * use a compatible type. Our uniform above is an integer
2458 * vector (ivec4), so we must set it using integer versions
2459 * of the Uniform* functions. The "1" means we're setting
2460 * one vector's worth of information.
2461 */
2462 (*Uniform4ivARB)(uniformLocation, 1, uniform);
2463 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2464
2465 /* Query it back */
2466 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
2467 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2468
2469 /* Clean up before we check to see whether it came back unscathed */
2470 exercise_uniform_end(program);
2471
2472 /* Now check to see whether the uniform came back as expected. This
2473 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2474 */
2475 return compare_ints(__FUNCTION__, 4, uniform, 4, queriedUniform);
2476 }
2477
2478 static GLboolean
2479 test_Uniform4i(generic_func func)
2480 {
2481 PFNGLUNIFORM4IARBPROC Uniform4iARB = (PFNGLUNIFORM4IARBPROC) func;
2482 DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
2483
2484 /* This is a trivial fragment shader that sets the color of the
2485 * fragment to the uniform value passed in.
2486 */
2487 static const char *fragmentShaderText =
2488 "uniform ivec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2489 static const char *uniformName = "uniformColor";
2490
2491 GLhandleARB program;
2492 GLint uniformLocation;
2493 const GLint uniform[4] = {1,2,3,4};
2494 GLint queriedUniform[4];
2495
2496 if (GetUniformivARB == NULL) {
2497 return GL_FALSE;
2498 }
2499
2500 /* Call a helper function to compile up the shader and give
2501 * us back the validated program and uniform location.
2502 * If it fails, something's wrong and we can't continue.
2503 */
2504 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2505 &program, &uniformLocation)) {
2506 return GL_FALSE;
2507 }
2508
2509 /* Set the value of the program uniform. Note that you must
2510 * use a compatible type. Our uniform above is an integer
2511 * vector (ivec4), so we must set it using integer versions
2512 * of the Uniform* functions.
2513 */
2514 (*Uniform4iARB)(uniformLocation, uniform[0], uniform[1], uniform[2],
2515 uniform[3]);
2516 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2517
2518 /* Query it back */
2519 (*GetUniformivARB)(program, uniformLocation, queriedUniform);
2520 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2521
2522 /* Clean up before we check to see whether it came back unscathed */
2523 exercise_uniform_end(program);
2524
2525 /* Now check to see whether the uniform came back as expected. This
2526 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2527 */
2528 return compare_ints(__FUNCTION__, 4, uniform, 4, queriedUniform);
2529 }
2530
2531 static GLboolean
2532 test_Uniform4fv(generic_func func)
2533 {
2534 PFNGLUNIFORM4FVARBPROC Uniform4fvARB = (PFNGLUNIFORM4FVARBPROC) func;
2535 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
2536
2537 /* This is a trivial fragment shader that sets the color of the
2538 * fragment to the uniform value passed in.
2539 */
2540 static const char *fragmentShaderText =
2541 "uniform vec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2542 static const char *uniformName = "uniformColor";
2543
2544 GLhandleARB program;
2545 GLint uniformLocation;
2546 const GLfloat uniform[4] = {1.1,2.2,3.3,4.4};
2547 GLfloat queriedUniform[4];
2548
2549 if (GetUniformfvARB == NULL) {
2550 return GL_FALSE;
2551 }
2552
2553 /* Call a helper function to compile up the shader and give
2554 * us back the validated program and uniform location.
2555 * If it fails, something's wrong and we can't continue.
2556 */
2557 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2558 &program, &uniformLocation)) {
2559 return GL_FALSE;
2560 }
2561
2562 /* Set the value of the program uniform. Note that you must
2563 * use a compatible type. Our uniform above is a float
2564 * vector (vec4), so we must set it using float versions
2565 * of the Uniform* functions. The "1" means we're setting
2566 * one vector's worth of information.
2567 */
2568 (*Uniform4fvARB)(uniformLocation, 1, uniform);
2569 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2570
2571 /* Query it back */
2572 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
2573 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2574
2575 /* Clean up before we check to see whether it came back unscathed */
2576 exercise_uniform_end(program);
2577
2578 /* Now check to see whether the uniform came back as expected. This
2579 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2580 */
2581 return compare_floats(__FUNCTION__, 4, uniform, 4, queriedUniform);
2582 }
2583
2584 static GLboolean
2585 test_Uniform4f(generic_func func)
2586 {
2587 PFNGLUNIFORM4FARBPROC Uniform4fARB = (PFNGLUNIFORM4FARBPROC) func;
2588 DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
2589
2590 /* This is a trivial fragment shader that sets the color of the
2591 * fragment to the uniform value passed in.
2592 */
2593 static const char *fragmentShaderText =
2594 "uniform vec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2595 static const char *uniformName = "uniformColor";
2596
2597 GLhandleARB program;
2598 GLint uniformLocation;
2599 const GLfloat uniform[4] = {1.1,2.2,3.3,4.4};
2600 GLfloat queriedUniform[4];
2601
2602 if (GetUniformfvARB == NULL) {
2603 return GL_FALSE;
2604 }
2605
2606 /* Call a helper function to compile up the shader and give
2607 * us back the validated program and uniform location.
2608 * If it fails, something's wrong and we can't continue.
2609 */
2610 if (!exercise_uniform_start(fragmentShaderText, uniformName,
2611 &program, &uniformLocation)) {
2612 return GL_FALSE;
2613 }
2614
2615 /* Set the value of the program uniform. Note that you must
2616 * use a compatible type. Our uniform above is an integer
2617 * vector (ivec4), so we must set it using integer versions
2618 * of the Uniform* functions.
2619 */
2620 (*Uniform4fARB)(uniformLocation, uniform[0], uniform[1], uniform[2],
2621 uniform[3]);
2622 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2623
2624 /* Query it back */
2625 (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
2626 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
2627
2628 /* Clean up before we check to see whether it came back unscathed */
2629 exercise_uniform_end(program);
2630
2631 /* Now check to see whether the uniform came back as expected. This
2632 * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
2633 */
2634 return compare_floats(__FUNCTION__, 4, uniform, 4, queriedUniform);
2635 }
2636
2637 static GLboolean
2638 test_ActiveTextureARB(generic_func func)
2639 {
2640 PFNGLACTIVETEXTUREARBPROC activeTexture = (PFNGLACTIVETEXTUREARBPROC) func;
2641 GLint t;
2642 GLboolean pass;
2643 (*activeTexture)(GL_TEXTURE1_ARB);
2644 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &t);
2645 pass = (t == GL_TEXTURE1_ARB);
2646 (*activeTexture)(GL_TEXTURE0_ARB); /* restore default */
2647 return pass;
2648 }
2649
2650
2651 static GLboolean
2652 test_SecondaryColor3fEXT(generic_func func)
2653 {
2654 PFNGLSECONDARYCOLOR3FEXTPROC secColor3f = (PFNGLSECONDARYCOLOR3FEXTPROC) func;
2655 GLfloat color[4];
2656 GLboolean pass;
2657 (*secColor3f)(1.0, 1.0, 0.0);
2658 glGetFloatv(GL_CURRENT_SECONDARY_COLOR_EXT, color);
2659 pass = (color[0] == 1.0 && color[1] == 1.0 && color[2] == 0.0);
2660 (*secColor3f)(0.0, 0.0, 0.0); /* restore default */
2661 return pass;
2662 }
2663
2664
2665 static GLboolean
2666 test_ActiveStencilFaceEXT(generic_func func)
2667 {
2668 PFNGLACTIVESTENCILFACEEXTPROC activeFace = (PFNGLACTIVESTENCILFACEEXTPROC) func;
2669 GLint face;
2670 GLboolean pass;
2671 (*activeFace)(GL_BACK);
2672 glGetIntegerv(GL_ACTIVE_STENCIL_FACE_EXT, &face);
2673 pass = (face == GL_BACK);
2674 (*activeFace)(GL_FRONT); /* restore default */
2675 return pass;
2676 }
2677
2678
2679 static GLboolean
2680 test_VertexAttrib1fvARB(generic_func func)
2681 {
2682 PFNGLVERTEXATTRIB1FVARBPROC vertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) func;
2683 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
2684
2685 const GLfloat v[1] = {25.0};
2686 const GLfloat def[1] = {0};
2687 GLfloat res[4];
2688 GLboolean pass;
2689 (*vertexAttrib1fvARB)(6, v);
2690 (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2691 pass = (res[0] == 25.0 && res[1] == 0.0 && res[2] == 0.0 && res[3] == 1.0);
2692 (*vertexAttrib1fvARB)(6, def);
2693 return pass;
2694 }
2695
2696 static GLboolean
2697 test_VertexAttrib1dvARB(generic_func func)
2698 {
2699 PFNGLVERTEXATTRIB1DVARBPROC vertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) func;
2700 PFNGLGETVERTEXATTRIBDVARBPROC getVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvARB");
2701
2702 const GLdouble v[1] = {25.0};
2703 const GLdouble def[1] = {0};
2704 GLdouble res[4];
2705 GLboolean pass;
2706 (*vertexAttrib1dvARB)(6, v);
2707 (*getVertexAttribdvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2708 pass = (res[0] == 25.0 && res[1] == 0.0 && res[2] == 0.0 && res[3] == 1.0);
2709 (*vertexAttrib1dvARB)(6, def);
2710 return pass;
2711 }
2712
2713 static GLboolean
2714 test_VertexAttrib1svARB(generic_func func)
2715 {
2716 PFNGLVERTEXATTRIB1SVARBPROC vertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) func;
2717 PFNGLGETVERTEXATTRIBIVARBPROC getVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivARB");
2718
2719 const GLshort v[1] = {25.0};
2720 const GLshort def[1] = {0};
2721 GLint res[4];
2722 GLboolean pass;
2723 (*vertexAttrib1svARB)(6, v);
2724 (*getVertexAttribivARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2725 pass = (res[0] == 25 && res[1] == 0 && res[2] == 0 && res[3] == 1);
2726 (*vertexAttrib1svARB)(6, def);
2727 return pass;
2728 }
2729
2730 static GLboolean
2731 test_VertexAttrib4NubvARB(generic_func func)
2732 {
2733 PFNGLVERTEXATTRIB4NUBVARBPROC vertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) func;
2734 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
2735
2736 const GLubyte v[4] = {255, 0, 255, 0};
2737 const GLubyte def[4] = {0, 0, 0, 255};
2738 GLfloat res[4];
2739 GLboolean pass;
2740 (*vertexAttrib4NubvARB)(6, v);
2741 (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2742 pass = (res[0] == 1.0 && res[1] == 0.0 && res[2] == 1.0 && res[3] == 0.0);
2743 (*vertexAttrib4NubvARB)(6, def);
2744 return pass;
2745 }
2746
2747
2748 static GLboolean
2749 test_VertexAttrib4NuivARB(generic_func func)
2750 {
2751 PFNGLVERTEXATTRIB4NUIVARBPROC vertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) func;
2752 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
2753
2754 const GLuint v[4] = {0xffffffff, 0, 0xffffffff, 0};
2755 const GLuint def[4] = {0, 0, 0, 0xffffffff};
2756 GLfloat res[4];
2757 GLboolean pass;
2758 (*vertexAttrib4NuivARB)(6, v);
2759 (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2760 pass = (EQUAL(res[0], 1.0) && EQUAL(res[1], 0.0) && EQUAL(res[2], 1.0) && EQUAL(res[3], 0.0));
2761 (*vertexAttrib4NuivARB)(6, def);
2762 return pass;
2763 }
2764
2765
2766 static GLboolean
2767 test_VertexAttrib4ivARB(generic_func func)
2768 {
2769 PFNGLVERTEXATTRIB4IVARBPROC vertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) func;
2770 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
2771
2772 const GLint v[4] = {1, 2, -3, 4};
2773 const GLint def[4] = {0, 0, 0, 1};
2774 GLfloat res[4];
2775 GLboolean pass;
2776 (*vertexAttrib4ivARB)(6, v);
2777 (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2778 pass = (EQUAL(res[0], 1.0) && EQUAL(res[1], 2.0) && EQUAL(res[2], -3.0) && EQUAL(res[3], 4.0));
2779 (*vertexAttrib4ivARB)(6, def);
2780 return pass;
2781 }
2782
2783
2784 static GLboolean
2785 test_VertexAttrib4NsvARB(generic_func func)
2786 {
2787 PFNGLVERTEXATTRIB4NSVARBPROC vertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) func;
2788 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
2789
2790 const GLshort v[4] = {0, 32767, 32767, 0};
2791 const GLshort def[4] = {0, 0, 0, 32767};
2792 GLfloat res[4];
2793 GLboolean pass;
2794 (*vertexAttrib4NsvARB)(6, v);
2795 (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2796 pass = (EQUAL(res[0], 0.0) && EQUAL(res[1], 1.0) && EQUAL(res[2], 1.0) && EQUAL(res[3], 0.0));
2797 (*vertexAttrib4NsvARB)(6, def);
2798 return pass;
2799 }
2800
2801 static GLboolean
2802 test_VertexAttrib4NusvARB(generic_func func)
2803 {
2804 PFNGLVERTEXATTRIB4NUSVARBPROC vertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) func;
2805 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvARB");
2806
2807 const GLushort v[4] = {0xffff, 0, 0xffff, 0};
2808 const GLushort def[4] = {0, 0, 0, 0xffff};
2809 GLfloat res[4];
2810 GLboolean pass;
2811 (*vertexAttrib4NusvARB)(6, v);
2812 (*getVertexAttribfvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
2813 pass = (EQUAL(res[0], 1.0) && EQUAL(res[1], 0.0) && EQUAL(res[2], 1.0) && EQUAL(res[3], 0.0));
2814 (*vertexAttrib4NusvARB)(6, def);
2815 return pass;
2816 }
2817
2818 static GLboolean
2819 test_VertexAttrib1sNV(generic_func func)
2820 {
2821 PFNGLVERTEXATTRIB1SNVPROC vertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC) func;
2822 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
2823
2824 const GLshort v[4] = {2, 0, 0, 1};
2825 const GLshort def[4] = {0, 0, 0, 1};
2826 GLint res[4];
2827 (*vertexAttrib1sNV)(6, v[0]);
2828 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
2829 (*vertexAttrib1sNV)(6, def[0]);
2830 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
2831 }
2832
2833 static GLboolean
2834 test_VertexAttrib1fNV(generic_func func)
2835 {
2836 PFNGLVERTEXATTRIB1FNVPROC vertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC) func;
2837 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
2838
2839 const GLfloat v[4] = {2.5, 0.0, 0.0, 1.0};
2840 const GLfloat def[4] = {0, 0, 0, 1};
2841 GLfloat res[4];
2842 (*vertexAttrib1fNV)(6, v[0]);
2843 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2844 (*vertexAttrib1fNV)(6, def[0]);
2845 return compare_floats(__FUNCTION__, 4, v, 4, res);
2846 }
2847
2848 static GLboolean
2849 test_VertexAttrib1dNV(generic_func func)
2850 {
2851 PFNGLVERTEXATTRIB1DNVPROC vertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC) func;
2852 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
2853
2854 const GLdouble v[4] = {2.5, 0.0, 0.0, 1.0};
2855 const GLdouble def[4] = {0, 0, 0, 1};
2856 GLdouble res[4];
2857 (*vertexAttrib1dNV)(6, v[0]);
2858 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2859 (*vertexAttrib1dNV)(6, def[0]);
2860 return compare_doubles(__FUNCTION__, 4, v, 4, res);
2861 }
2862
2863 static GLboolean
2864 test_VertexAttrib2sNV(generic_func func)
2865 {
2866 PFNGLVERTEXATTRIB2SNVPROC vertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC) func;
2867 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
2868
2869 const GLshort v[4] = {2, 4, 0, 1};
2870 const GLshort def[4] = {0, 0, 0, 1};
2871 GLint res[4];
2872 (*vertexAttrib2sNV)(6, v[0], v[1]);
2873 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
2874 (*vertexAttrib2sNV)(6, def[0], def[1]);
2875 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
2876 }
2877
2878 static GLboolean
2879 test_VertexAttrib2fNV(generic_func func)
2880 {
2881 PFNGLVERTEXATTRIB2FNVPROC vertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC) func;
2882 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
2883
2884 const GLfloat v[4] = {2.5, 4.25, 0.0, 1.0};
2885 const GLfloat def[4] = {0, 0, 0, 1};
2886 GLfloat res[4];
2887 (*vertexAttrib2fNV)(6, v[0], v[1]);
2888 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2889 (*vertexAttrib2fNV)(6, def[0], def[1]);
2890 return compare_floats(__FUNCTION__, 4, v, 4, res);
2891 }
2892
2893 static GLboolean
2894 test_VertexAttrib2dNV(generic_func func)
2895 {
2896 PFNGLVERTEXATTRIB2DNVPROC vertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC) func;
2897 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
2898
2899 const GLdouble v[4] = {2.5, 4.25, 0.0, 1.0};
2900 const GLdouble def[4] = {0, 0, 0, 1};
2901 GLdouble res[4];
2902 (*vertexAttrib2dNV)(6, v[0], v[1]);
2903 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2904 (*vertexAttrib2dNV)(6, def[0], def[1]);
2905 return compare_doubles(__FUNCTION__, 4, v, 4, res);
2906 }
2907
2908 static GLboolean
2909 test_VertexAttrib3sNV(generic_func func)
2910 {
2911 PFNGLVERTEXATTRIB3SNVPROC vertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC) func;
2912 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
2913
2914 const GLshort v[4] = {2, 4, 7, 1};
2915 const GLshort def[4] = {0, 0, 0, 1};
2916 GLint res[4];
2917 (*vertexAttrib3sNV)(6, v[0], v[1], v[2]);
2918 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
2919 (*vertexAttrib3sNV)(6, def[0], def[1], def[2]);
2920 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
2921 }
2922
2923 static GLboolean
2924 test_VertexAttrib3fNV(generic_func func)
2925 {
2926 PFNGLVERTEXATTRIB3FNVPROC vertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC) func;
2927 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
2928
2929 const GLfloat v[4] = {2.5, 4.25, 7.125, 1.0};
2930 const GLfloat def[4] = {0, 0, 0, 1};
2931 GLfloat res[4];
2932 (*vertexAttrib3fNV)(6, v[0], v[1], v[2]);
2933 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2934 (*vertexAttrib3fNV)(6, def[0], def[1], def[2]);
2935 return compare_floats(__FUNCTION__, 4, v, 4, res);
2936 }
2937
2938 static GLboolean
2939 test_VertexAttrib3dNV(generic_func func)
2940 {
2941 PFNGLVERTEXATTRIB3DNVPROC vertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC) func;
2942 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
2943
2944 const GLdouble v[4] = {2.5, 4.25, 7.125, 1.0};
2945 const GLdouble def[4] = {0, 0, 0, 1};
2946 GLdouble res[4];
2947 (*vertexAttrib3dNV)(6, v[0], v[1], v[2]);
2948 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2949 (*vertexAttrib3dNV)(6, def[0], def[1], def[2]);
2950 return compare_doubles(__FUNCTION__, 4, v, 4, res);
2951 }
2952
2953 static GLboolean
2954 test_VertexAttrib4sNV(generic_func func)
2955 {
2956 PFNGLVERTEXATTRIB4SNVPROC vertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC) func;
2957 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
2958
2959 const GLshort v[4] = {2, 4, 7, 5};
2960 const GLshort def[4] = {0, 0, 0, 1};
2961 GLint res[4];
2962 (*vertexAttrib4sNV)(6, v[0], v[1], v[2], v[3]);
2963 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
2964 (*vertexAttrib4sNV)(6, def[0], def[1], def[2], def[3]);
2965 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
2966 }
2967
2968 static GLboolean
2969 test_VertexAttrib4fNV(generic_func func)
2970 {
2971 PFNGLVERTEXATTRIB4FNVPROC vertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC) func;
2972 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
2973
2974 const GLfloat v[4] = {2.5, 4.25, 7.125, 5.0625};
2975 const GLfloat def[4] = {0, 0, 0, 1};
2976 GLfloat res[4];
2977 (*vertexAttrib4fNV)(6, v[0], v[1], v[2], v[3]);
2978 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2979 (*vertexAttrib4fNV)(6, def[0], def[1], def[2], def[3]);
2980 return compare_floats(__FUNCTION__, 4, v, 4, res);
2981 }
2982
2983 static GLboolean
2984 test_VertexAttrib4dNV(generic_func func)
2985 {
2986 PFNGLVERTEXATTRIB4DNVPROC vertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC) func;
2987 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
2988
2989 const GLdouble v[4] = {2.5, 4.25, 7.125, 5.0625};
2990 const GLdouble def[4] = {0, 0, 0, 1};
2991 GLdouble res[4];
2992 (*vertexAttrib4dNV)(6, v[0], v[1], v[2], v[3]);
2993 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
2994 (*vertexAttrib4dNV)(6, def[0], def[1], def[2], def[3]);
2995 return compare_doubles(__FUNCTION__, 4, v, 4, res);
2996 }
2997
2998 static GLboolean
2999 test_VertexAttrib4ubNV(generic_func func)
3000 {
3001 PFNGLVERTEXATTRIB4UBNVPROC vertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC) func;
3002 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3003
3004 const GLubyte v[4] = {255, 0, 255, 0};
3005 const GLubyte def[4] = {0, 0, 0, 255};
3006 GLfloat res[4];
3007 /* There's no byte-value query; so we use the float-value query.
3008 * Bytes are interpreted as steps between 0 and 1, so the
3009 * expected float values will be 0.0 for byte value 0 and 1.0 for
3010 * byte value 255.
3011 */
3012 GLfloat expectedResults[4] = {1.0, 0.0, 1.0, 0.0};
3013 (*vertexAttrib4ubNV)(6, v[0], v[1], v[2], v[3]);
3014 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3015 (*vertexAttrib4ubNV)(6, def[0], def[1], def[2], def[3]);
3016 return compare_floats(__FUNCTION__, 4, expectedResults, 4, res);
3017 }
3018
3019 static GLboolean
3020 test_VertexAttrib1fvNV(generic_func func)
3021 {
3022 PFNGLVERTEXATTRIB1FVNVPROC vertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC) func;
3023 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3024
3025 const GLfloat v[4] = {2.5, 0.0, 0.0, 1.0};
3026 const GLfloat def[4] = {0, 0, 0, 1};
3027 GLfloat res[4];
3028 (*vertexAttrib1fvNV)(6, v);
3029 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3030 (*vertexAttrib1fvNV)(6, def);
3031 return compare_floats(__FUNCTION__, 4, v, 4, res);
3032 }
3033
3034 static GLboolean
3035 test_VertexAttrib1dvNV(generic_func func)
3036 {
3037 PFNGLVERTEXATTRIB1DVNVPROC vertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC) func;
3038 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3039
3040 const GLdouble v[4] = {2.5, 0.0, 0.0, 1.0};
3041 const GLdouble def[4] = {0, 0, 0, 1};
3042 GLdouble res[4];
3043 (*vertexAttrib1dvNV)(6, v);
3044 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3045 (*vertexAttrib1dvNV)(6, def);
3046 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3047 }
3048
3049 static GLboolean
3050 test_VertexAttrib2svNV(generic_func func)
3051 {
3052 PFNGLVERTEXATTRIB2SVNVPROC vertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC) func;
3053 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
3054
3055 const GLshort v[4] = {2, 4, 0, 1};
3056 const GLshort def[4] = {0, 0, 0, 1};
3057 GLint res[4];
3058 (*vertexAttrib2svNV)(6, v);
3059 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
3060 (*vertexAttrib2svNV)(6, def);
3061 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
3062 }
3063
3064 static GLboolean
3065 test_VertexAttrib2fvNV(generic_func func)
3066 {
3067 PFNGLVERTEXATTRIB2FVNVPROC vertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC) func;
3068 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3069
3070 const GLfloat v[4] = {2.5, 4.25, 0.0, 1.0};
3071 const GLfloat def[4] = {0, 0, 0, 1};
3072 GLfloat res[4];
3073 (*vertexAttrib2fvNV)(6, v);
3074 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3075 (*vertexAttrib2fvNV)(6, def);
3076 return compare_floats(__FUNCTION__, 4, v, 4, res);
3077 }
3078
3079 static GLboolean
3080 test_VertexAttrib2dvNV(generic_func func)
3081 {
3082 PFNGLVERTEXATTRIB2DVNVPROC vertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC) func;
3083 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3084
3085 const GLdouble v[4] = {2.5, 4.25, 0.0, 1.0};
3086 const GLdouble def[4] = {0, 0, 0, 1};
3087 GLdouble res[4];
3088 (*vertexAttrib2dvNV)(6, v);
3089 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3090 (*vertexAttrib2dvNV)(6, def);
3091 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3092 }
3093
3094 static GLboolean
3095 test_VertexAttrib3svNV(generic_func func)
3096 {
3097 PFNGLVERTEXATTRIB3SVNVPROC vertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC) func;
3098 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
3099
3100 const GLshort v[4] = {2, 4, 7, 1};
3101 const GLshort def[4] = {0, 0, 0, 1};
3102 GLint res[4];
3103 (*vertexAttrib3svNV)(6, v);
3104 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
3105 (*vertexAttrib3svNV)(6, def);
3106 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
3107 }
3108
3109 static GLboolean
3110 test_VertexAttrib3fvNV(generic_func func)
3111 {
3112 PFNGLVERTEXATTRIB3FVNVPROC vertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC) func;
3113 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3114
3115 const GLfloat v[4] = {2.5, 4.25, 7.125, 1.0};
3116 const GLfloat def[4] = {0, 0, 0, 1};
3117 GLfloat res[4];
3118 (*vertexAttrib3fvNV)(6, v);
3119 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3120 (*vertexAttrib3fvNV)(6, def);
3121 return compare_floats(__FUNCTION__, 4, v, 4, res);
3122 }
3123
3124 static GLboolean
3125 test_VertexAttrib3dvNV(generic_func func)
3126 {
3127 PFNGLVERTEXATTRIB3DVNVPROC vertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC) func;
3128 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3129
3130 const GLdouble v[4] = {2.5, 4.25, 7.125, 1.0};
3131 const GLdouble def[4] = {0, 0, 0, 1};
3132 GLdouble res[4];
3133 (*vertexAttrib3dvNV)(6, v);
3134 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3135 (*vertexAttrib3dvNV)(6, def);
3136 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3137 }
3138
3139 static GLboolean
3140 test_VertexAttrib4svNV(generic_func func)
3141 {
3142 PFNGLVERTEXATTRIB4SVNVPROC vertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC) func;
3143 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
3144
3145 const GLshort v[4] = {2, 4, 7, 5};
3146 const GLshort def[4] = {0, 0, 0, 1};
3147 GLint res[4];
3148 (*vertexAttrib4svNV)(6, v);
3149 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
3150 (*vertexAttrib4svNV)(6, def);
3151 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
3152 }
3153
3154 static GLboolean
3155 test_VertexAttrib4fvNV(generic_func func)
3156 {
3157 PFNGLVERTEXATTRIB4FVNVPROC vertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC) func;
3158 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3159
3160 const GLfloat v[4] = {2.5, 4.25, 7.125, 5.0625};
3161 const GLfloat def[4] = {0, 0, 0, 1};
3162 GLfloat res[4];
3163 (*vertexAttrib4fvNV)(6, v);
3164 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3165 (*vertexAttrib4fvNV)(6, def);
3166 return compare_floats(__FUNCTION__, 4, v, 4, res);
3167 }
3168
3169 static GLboolean
3170 test_VertexAttrib4dvNV(generic_func func)
3171 {
3172 PFNGLVERTEXATTRIB4DVNVPROC vertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC) func;
3173 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3174
3175 const GLdouble v[4] = {2.5, 4.25, 7.125, 5.0625};
3176 const GLdouble def[4] = {0, 0, 0, 1};
3177 GLdouble res[4];
3178 (*vertexAttrib4dvNV)(6, v);
3179 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3180 (*vertexAttrib4dvNV)(6, def);
3181 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3182 }
3183
3184 static GLboolean
3185 test_VertexAttrib4ubvNV(generic_func func)
3186 {
3187 PFNGLVERTEXATTRIB4UBVNVPROC vertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC) func;
3188 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3189
3190 const GLubyte v[4] = {255, 0, 255, 0};
3191 const GLubyte def[4] = {0, 0, 0, 255};
3192 GLfloat res[4];
3193 /* There's no byte-value query; so we use the float-value query.
3194 * Bytes are interpreted as steps between 0 and 1, so the
3195 * expected float values will be 0.0 for byte value 0 and 1.0 for
3196 * byte value 255.
3197 */
3198 GLfloat expectedResults[4] = {1.0, 0.0, 1.0, 0.0};
3199 (*vertexAttrib4ubvNV)(6, v);
3200 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3201 (*vertexAttrib4ubvNV)(6, def);
3202 return compare_floats(__FUNCTION__, 4, expectedResults, 4, res);
3203 }
3204
3205 static GLboolean
3206 test_VertexAttribs1fvNV(generic_func func)
3207 {
3208 PFNGLVERTEXATTRIBS1FVNVPROC vertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC) func;
3209 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3210
3211 const GLfloat v[4] = {2.5, 0.0, 0.0, 1.0};
3212 const GLfloat def[4] = {0, 0, 0, 1};
3213 GLfloat res[4];
3214 (*vertexAttribs1fvNV)(6, 1, v);
3215 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3216 (*vertexAttribs1fvNV)(6, 1, def);
3217 return compare_floats(__FUNCTION__, 4, v, 4, res);
3218 }
3219
3220 static GLboolean
3221 test_VertexAttribs1dvNV(generic_func func)
3222 {
3223 PFNGLVERTEXATTRIBS1DVNVPROC vertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC) func;
3224 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3225
3226 const GLdouble v[4] = {2.5, 0.0, 0.0, 1.0};
3227 const GLdouble def[4] = {0, 0, 0, 1};
3228 GLdouble res[4];
3229 (*vertexAttribs1dvNV)(6, 1, v);
3230 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3231 (*vertexAttribs1dvNV)(6, 1, def);
3232 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3233 }
3234
3235 static GLboolean
3236 test_VertexAttribs2svNV(generic_func func)
3237 {
3238 PFNGLVERTEXATTRIBS2SVNVPROC vertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC) func;
3239 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
3240
3241 const GLshort v[4] = {2, 4, 0, 1};
3242 const GLshort def[4] = {0, 0, 0, 1};
3243 GLint res[4];
3244 (*vertexAttribs2svNV)(6, 1, v);
3245 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
3246 (*vertexAttribs2svNV)(6, 1, def);
3247 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
3248 }
3249
3250 static GLboolean
3251 test_VertexAttribs2fvNV(generic_func func)
3252 {
3253 PFNGLVERTEXATTRIBS2FVNVPROC vertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC) func;
3254 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3255
3256 const GLfloat v[4] = {2.5, 4.25, 0.0, 1.0};
3257 const GLfloat def[4] = {0, 0, 0, 1};
3258 GLfloat res[4];
3259 (*vertexAttribs2fvNV)(6, 1, v);
3260 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3261 (*vertexAttribs2fvNV)(6, 1, def);
3262 return compare_floats(__FUNCTION__, 4, v, 4, res);
3263 }
3264
3265 static GLboolean
3266 test_VertexAttribs2dvNV(generic_func func)
3267 {
3268 PFNGLVERTEXATTRIBS2DVNVPROC vertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC) func;
3269 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3270
3271 const GLdouble v[4] = {2.5, 4.25, 0.0, 1.0};
3272 const GLdouble def[4] = {0, 0, 0, 1};
3273 GLdouble res[4];
3274 (*vertexAttribs2dvNV)(6, 1, v);
3275 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3276 (*vertexAttribs2dvNV)(6, 1, def);
3277 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3278 }
3279
3280 static GLboolean
3281 test_VertexAttribs3svNV(generic_func func)
3282 {
3283 PFNGLVERTEXATTRIBS3SVNVPROC vertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC) func;
3284 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
3285
3286 const GLshort v[4] = {2, 4, 7, 1};
3287 const GLshort def[4] = {0, 0, 0, 1};
3288 GLint res[4];
3289 (*vertexAttribs3svNV)(6, 1, v);
3290 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
3291 (*vertexAttribs3svNV)(6, 1, def);
3292 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
3293 }
3294
3295 static GLboolean
3296 test_VertexAttribs3fvNV(generic_func func)
3297 {
3298 PFNGLVERTEXATTRIBS3FVNVPROC vertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC) func;
3299 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3300
3301 const GLfloat v[4] = {2.5, 4.25, 7.125, 1.0};
3302 const GLfloat def[4] = {0, 0, 0, 1};
3303 GLfloat res[4];
3304 (*vertexAttribs3fvNV)(6, 1, v);
3305 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3306 (*vertexAttribs3fvNV)(6, 1, def);
3307 return compare_floats(__FUNCTION__, 4, v, 4, res);
3308 }
3309
3310 static GLboolean
3311 test_VertexAttribs3dvNV(generic_func func)
3312 {
3313 PFNGLVERTEXATTRIBS3DVNVPROC vertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC) func;
3314 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3315
3316 const GLdouble v[4] = {2.5, 4.25, 7.125, 1.0};
3317 const GLdouble def[4] = {0, 0, 0, 1};
3318 GLdouble res[4];
3319 (*vertexAttribs3dvNV)(6, 1, v);
3320 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3321 (*vertexAttribs3dvNV)(6, 1, def);
3322 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3323 }
3324
3325 static GLboolean
3326 test_VertexAttribs4svNV(generic_func func)
3327 {
3328 PFNGLVERTEXATTRIBS4SVNVPROC vertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC) func;
3329 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
3330
3331 const GLshort v[4] = {2, 4, 7, 5};
3332 const GLshort def[4] = {0, 0, 0, 1};
3333 GLint res[4];
3334 (*vertexAttribs4svNV)(6, 1, v);
3335 (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
3336 (*vertexAttribs4svNV)(6, 1, def);
3337 return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
3338 }
3339
3340 static GLboolean
3341 test_VertexAttribs4fvNV(generic_func func)
3342 {
3343 PFNGLVERTEXATTRIBS4FVNVPROC vertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC) func;
3344 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3345
3346 const GLfloat v[4] = {2.5, 4.25, 7.125, 5.0625};
3347 const GLfloat def[4] = {0, 0, 0, 1};
3348 GLfloat res[4];
3349 (*vertexAttribs4fvNV)(6, 1, v);
3350 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3351 (*vertexAttribs4fvNV)(6, 1, def);
3352 return compare_floats(__FUNCTION__, 4, v, 4, res);
3353 }
3354
3355 static GLboolean
3356 test_VertexAttribs4dvNV(generic_func func)
3357 {
3358 PFNGLVERTEXATTRIBS4DVNVPROC vertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC) func;
3359 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
3360
3361 const GLdouble v[4] = {2.5, 4.25, 7.125, 5.0625};
3362 const GLdouble def[4] = {0, 0, 0, 1};
3363 GLdouble res[4];
3364 (*vertexAttribs4dvNV)(6, 1, v);
3365 (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3366 (*vertexAttribs4dvNV)(6, 1, def);
3367 return compare_doubles(__FUNCTION__, 4, v, 4, res);
3368 }
3369
3370 static GLboolean
3371 test_VertexAttribs4ubvNV(generic_func func)
3372 {
3373 PFNGLVERTEXATTRIBS4UBVNVPROC vertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC) func;
3374 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
3375
3376 const GLubyte v[4] = {255, 0, 255, 0};
3377 const GLubyte def[4] = {0, 0, 0, 255};
3378 GLfloat res[4];
3379 /* There's no byte-value query; so we use the float-value query.
3380 * Bytes are interpreted as steps between 0 and 1, so the
3381 * expected float values will be 0.0 for byte value 0 and 1.0 for
3382 * byte value 255.
3383 */
3384 GLfloat expectedResults[4] = {1.0, 0.0, 1.0, 0.0};
3385 (*vertexAttribs4ubvNV)(6, 1, v);
3386 (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
3387 (*vertexAttribs4ubvNV)(6, 1, def);
3388 return compare_floats(__FUNCTION__, 4, expectedResults, 4, res);
3389 }
3390
3391 static GLboolean
3392 test_StencilFuncSeparateATI(generic_func func)
3393 {
3394 #ifdef GL_ATI_separate_stencil
3395 PFNGLSTENCILFUNCSEPARATEATIPROC stencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC) func;
3396 GLint frontFunc, backFunc;
3397 GLint frontRef, backRef;
3398 GLint frontMask, backMask;
3399 (*stencilFuncSeparateATI)(GL_LESS, GL_GREATER, 2, 0xa);
3400 glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
3401 glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
3402 glGetIntegerv(GL_STENCIL_REF, &frontRef);
3403 glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
3404 glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontMask);
3405 glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backMask);
3406 if (frontFunc != GL_LESS ||
3407 backFunc != GL_GREATER ||
3408 frontRef != 2 ||
3409 backRef != 2 ||
3410 frontMask != 0xa ||
3411 backMask != 0xa)
3412 return GL_FALSE;
3413 #endif
3414 return GL_TRUE;
3415 }
3416
3417 static GLboolean
3418 test_StencilFuncSeparate(generic_func func)
3419 {
3420 #ifdef GL_VERSION_2_0
3421 PFNGLSTENCILFUNCSEPARATEPROC stencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) func;
3422 GLint frontFunc, backFunc;
3423 GLint frontRef, backRef;
3424 GLint frontMask, backMask;
3425 (*stencilFuncSeparate)(GL_BACK, GL_GREATER, 2, 0xa);
3426 glGetIntegerv(GL_STENCIL_FUNC, &frontFunc);
3427 glGetIntegerv(GL_STENCIL_BACK_FUNC, &backFunc);
3428 glGetIntegerv(GL_STENCIL_REF, &frontRef);
3429 glGetIntegerv(GL_STENCIL_BACK_REF, &backRef);
3430 glGetIntegerv(GL_STENCIL_VALUE_MASK, &frontMask);
3431 glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &backMask);
3432 if (frontFunc != GL_ALWAYS ||
3433 backFunc != GL_GREATER ||
3434 frontRef != 0 ||
3435 backRef != 2 ||
3436 frontMask == 0xa || /* might be 0xff or ~0 */
3437 backMask != 0xa)
3438 return GL_FALSE;
3439 #endif
3440 return GL_TRUE;
3441 }
3442
3443 static GLboolean
3444 test_StencilOpSeparate(generic_func func)
3445 {
3446 #ifdef GL_VERSION_2_0
3447 PFNGLSTENCILOPSEPARATEPROC stencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) func;
3448 GLint frontFail, backFail;
3449 GLint frontZFail, backZFail;
3450 GLint frontZPass, backZPass;
3451 (*stencilOpSeparate)(GL_BACK, GL_INCR, GL_DECR, GL_INVERT);
3452 glGetIntegerv(GL_STENCIL_FAIL, &frontFail);
3453 glGetIntegerv(GL_STENCIL_BACK_FAIL, &backFail);
3454 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &frontZFail);
3455 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &backZFail);
3456 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &frontZPass);
3457 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &backZPass);
3458 if (frontFail != GL_KEEP ||
3459 backFail != GL_INCR ||
3460 frontZFail != GL_KEEP ||
3461 backZFail != GL_DECR ||
3462 frontZPass != GL_KEEP ||
3463 backZPass != GL_INVERT)
3464 return GL_FALSE;
3465 #endif
3466 return GL_TRUE;
3467 }
3468
3469 static GLboolean
3470 test_StencilMaskSeparate(generic_func func)
3471 {
3472 #ifdef GL_VERSION_2_0
3473 PFNGLSTENCILMASKSEPARATEPROC stencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) func;
3474 GLint frontMask, backMask;
3475 (*stencilMaskSeparate)(GL_BACK, 0x1b);
3476 glGetIntegerv(GL_STENCIL_WRITEMASK, &frontMask);
3477 glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &backMask);
3478 if (frontMask == 0x1b ||
3479 backMask != 0x1b)
3480 return GL_FALSE;
3481 #endif
3482 return GL_TRUE;
3483 }
3484
3485
3486 /*
3487 * The following file is auto-generated with Python.
3488 */
3489 #include "getproclist.h"
3490
3491
3492
3493 static int
3494 extension_supported(const char *haystack, const char *needle)
3495 {
3496 const char *p = strstr(haystack, needle);
3497 if (p) {
3498 /* found string, make sure next char is space or zero */
3499 const int len = strlen(needle);
3500 if (p[len] == ' ' || p[len] == 0)
3501 return 1;
3502 else
3503 return 0;
3504 }
3505 else
3506 return 0;
3507 }
3508
3509
3510 /* Run all the known extension function tests, if the extension is supported.
3511 * Return a count of how many failed.
3512 */
3513 static int
3514 check_functions( const char *extensions )
3515 {
3516 struct name_test_pair *entry;
3517 int failures = 0, passes = 0, untested = 0;
3518 int totalFail = 0, totalPass = 0, totalUntested = 0, totalUnsupported = 0;
3519 int doTests = 0;
3520 const char *version = (const char *) glGetString(GL_VERSION);
3521
3522 /* The functions list will have "real" entries (consisting of
3523 * a GL function name and a pointer to an exercise function for
3524 * that GL function), and "group" entries (indicated as
3525 * such by having a "-" as the first character of the name).
3526 * "Group" names always start with the "-" character, and can
3527 * be numeric (e.g. "-1.0", "-2.1"), indicating that a particular
3528 * OpenGL version is required for the following functions; or can be
3529 * an extension name (e.g. "-GL_ARB_multitexture") that means
3530 * that the named extension is required for the following functions.
3531 */
3532 for (entry = functions; entry->name; entry++) {
3533 /* Check if this is a group indicator */
3534 if (entry->name[0] == '-') {
3535 /* A group indicator; check if it's an OpenGL version group */
3536 if (entry->name[1] == '1') {
3537 /* check GL version 1.x */
3538 if (version[0] == '1' &&
3539 version[1] == '.' &&
3540 version[2] >= entry->name[3])
3541 doTests = 1;
3542 else
3543 doTests = 0;
3544 }
3545 else if (entry->name[1] == '2') {
3546 if (version[0] == '2' &&
3547 version[1] == '.' &&
3548 version[2] >= entry->name[3])
3549 doTests = 1;
3550 else
3551 doTests = 0;
3552 }
3553 else {
3554 /* check if the named extension is available */
3555 doTests = extension_supported(extensions, entry->name+1);
3556 }
3557
3558 /* doTests is now set if we're starting an OpenGL version
3559 * group, and the running OpenGL version is at least the
3560 * version required; or if we're starting an OpenGL extension
3561 * group, and the extension is supported.
3562 */
3563 if (doTests)
3564 printf("Testing %s functions\n", entry->name + 1);
3565
3566 /* Each time we hit a title function, reset the function
3567 * counts.
3568 */
3569 failures = 0;
3570 passes = 0;
3571 untested = 0;
3572 }
3573 else if (doTests) {
3574 /* Here, we know we're trying to exercise a function for
3575 * a supported extension. See whether we have a test for
3576 * it, and try to run it.
3577 */
3578 generic_func funcPtr = (generic_func) glXGetProcAddressARB((const GLubyte *) entry->name);
3579 if (funcPtr) {
3580 if (entry->test) {
3581 GLboolean b;
3582 printf(" Validating %s:", entry->name);
3583 b = (*entry->test)(funcPtr);
3584 if (b) {
3585 printf(" Pass\n");
3586 passes++;
3587 totalPass++;
3588 }
3589 else {
3590 printf(" FAIL!!!\n");
3591 failures++;
3592 totalFail++;
3593 }
3594 }
3595 else {
3596 untested++;
3597 totalUntested++;
3598 }
3599 }
3600 else {
3601 printf(" glXGetProcAddress(%s) failed!\n", entry->name);
3602 failures++;
3603 totalFail++;
3604 }
3605 }
3606 else {
3607 /* Here, we have a function that belongs to a group that
3608 * is known to be unsupported.
3609 */
3610 totalUnsupported++;
3611 }
3612
3613 /* Make sure a poor test case doesn't leave any lingering
3614 * OpenGL errors.
3615 */
3616 CheckGLError(__LINE__, __FILE__, __FUNCTION__);
3617
3618 if (doTests && (!(entry+1)->name || (entry+1)->name[0] == '-')) {
3619 if (failures > 0) {
3620 printf(" %d failed.\n", failures);
3621 }
3622 if (passes > 0) {
3623 printf(" %d passed.\n", passes);
3624 }
3625 if (untested > 0) {
3626 printf(" %d untested.\n", untested);
3627 }
3628 }
3629 }
3630
3631 printf("-----------------------------\n");
3632 printf("Total: %d pass %d fail %d untested %d unsupported %d total\n",
3633 totalPass, totalFail, totalUntested, totalUnsupported,
3634 totalPass + totalFail + totalUntested + totalUnsupported);
3635
3636 return totalFail;
3637 }
3638
3639
3640 /* Return an error code */
3641 #define ERROR_NONE 0
3642 #define ERROR_NO_VISUAL 1
3643 #define ERROR_NO_CONTEXT 2
3644 #define ERROR_NO_MAKECURRENT 3
3645 #define ERROR_FAILED 4
3646
3647 static int
3648 print_screen_info(Display *dpy, int scrnum, Bool allowDirect)
3649 {
3650 Window win;
3651 int attribSingle[] = {
3652 GLX_RGBA,
3653 GLX_RED_SIZE, 1,
3654 GLX_GREEN_SIZE, 1,
3655 GLX_BLUE_SIZE, 1,
3656 GLX_STENCIL_SIZE, 1,
3657 None };
3658 int attribDouble[] = {
3659 GLX_RGBA,
3660 GLX_RED_SIZE, 1,
3661 GLX_GREEN_SIZE, 1,
3662 GLX_BLUE_SIZE, 1,
3663 GLX_STENCIL_SIZE, 1,
3664 GLX_DOUBLEBUFFER,
3665 None };
3666
3667 XSetWindowAttributes attr;
3668 unsigned long mask;
3669 Window root;
3670 GLXContext ctx;
3671 XVisualInfo *visinfo;
3672 int width = 100, height = 100;
3673 int failures;
3674
3675 root = RootWindow(dpy, scrnum);
3676
3677 visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
3678 if (!visinfo) {
3679 visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
3680 if (!visinfo) {
3681 fprintf(stderr, "Error: couldn't find RGB GLX visual\n");
3682 return ERROR_NO_VISUAL;
3683 }
3684 }
3685
3686 attr.background_pixel = 0;
3687 attr.border_pixel = 0;
3688 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
3689 attr.event_mask = StructureNotifyMask | ExposureMask;
3690 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
3691 win = XCreateWindow(dpy, root, 0, 0, width, height,
3692 0, visinfo->depth, InputOutput,
3693 visinfo->visual, mask, &attr);
3694
3695 ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
3696 if (!ctx) {
3697 fprintf(stderr, "Error: glXCreateContext failed\n");
3698 XDestroyWindow(dpy, win);
3699 return ERROR_NO_CONTEXT;
3700 }
3701
3702 if (!glXMakeCurrent(dpy, win, ctx)) {
3703 fprintf(stderr, "Error: glXMakeCurrent failed\n");
3704 glXDestroyContext(dpy, ctx);
3705 XDestroyWindow(dpy, win);
3706 return ERROR_NO_MAKECURRENT;
3707 }
3708
3709 failures = check_functions( (const char *) glGetString(GL_EXTENSIONS) );
3710 glXDestroyContext(dpy, ctx);
3711 XDestroyWindow(dpy, win);
3712
3713 return (failures == 0 ? ERROR_NONE : ERROR_FAILED);
3714 }
3715
3716 int
3717 main(int argc, char *argv[])
3718 {
3719 char *displayName = NULL;
3720 Display *dpy;
3721 int returnCode;
3722
3723 dpy = XOpenDisplay(displayName);
3724 if (!dpy) {
3725 fprintf(stderr, "Error: unable to open display %s\n", displayName);
3726 return -1;
3727 }
3728
3729 returnCode = print_screen_info(dpy, 0, GL_TRUE);
3730
3731 XCloseDisplay(dpy);
3732
3733 return returnCode;
3734 }