2 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
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.
23 * Test that glXGetProcAddress works.
26 #define GLX_GLXEXT_PROTOTYPES
29 #include <X11/Xutil.h>
38 typedef void (*generic_func
)();
40 #define EQUAL(X, Y) (fabs((X) - (Y)) < 0.001)
42 /* This macro simplifies the task of querying an extension function
43 * pointer and checking to see whether it resolved.
45 #define DECLARE_GLFUNC_PTR(name,type) \
46 type name = (type) glXGetProcAddressARB((const GLubyte *) "gl" #name)
48 /********************************************************************
49 * Generic helper functions used by the test functions.
52 static void CheckGLError(int line
, const char *file
, const char *function
)
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",
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":
68 line
, file
, function
);
69 errorCode
= glGetError();
75 compare_bytes(const char *errorLabel
, GLuint expectedSize
,
76 const GLubyte
*expectedData
, GLuint actualSize
, const GLubyte
*actualData
)
80 if (expectedSize
== actualSize
&&
81 memcmp(expectedData
, actualData
, actualSize
) == 0) {
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
++) {
107 fprintf(stderr
, " %s: size %d: {", label
, size
);
108 for (j
= 0; j
< size
; j
++) {
109 fprintf(stderr
, "%s0x%02x", j
> 0 ? ", " : "", ptr
[j
]);
111 fprintf(stderr
, "}\n");
114 /* We fail if the data is unexpected. */
120 compare_ints(const char *errorLabel
, GLuint expectedSize
,
121 const GLint
*expectedData
, GLuint actualSize
, const GLint
*actualData
)
125 if (expectedSize
== actualSize
&&
126 memcmp(expectedData
, actualData
, actualSize
*sizeof(*expectedData
)) == 0) {
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
++) {
152 fprintf(stderr
, " %s: size %d: {", label
, size
);
153 for (j
= 0; j
< size
; j
++) {
154 fprintf(stderr
, "%s%d", j
> 0 ? ", " : "", ptr
[j
]);
156 fprintf(stderr
, "}\n");
159 /* We fail if the data is unexpected. */
163 #define MAX_CONVERTED_VALUES 4
165 compare_shorts_to_ints(const char *errorLabel
, GLuint expectedSize
,
166 const GLshort
*expectedData
, GLuint actualSize
, const GLint
*actualData
)
169 GLint convertedValues
[MAX_CONVERTED_VALUES
];
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
);
177 for (i
= 0; i
< expectedSize
; i
++) {
178 convertedValues
[i
] = (GLint
) expectedData
[i
];
181 return compare_ints(errorLabel
, expectedSize
, convertedValues
,
182 actualSize
, actualData
);
186 compare_floats(const char *errorLabel
, GLuint expectedSize
,
187 const GLfloat
*expectedData
, GLuint actualSize
, const GLfloat
*actualData
)
191 if (expectedSize
== actualSize
&&
192 memcmp(expectedData
, actualData
, actualSize
*sizeof(*expectedData
)) == 0) {
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
++) {
218 fprintf(stderr
, " %s: size %d: {", label
, size
);
219 for (j
= 0; j
< size
; j
++) {
220 fprintf(stderr
, "%s%f", j
> 0 ? ", " : "", ptr
[j
]);
222 fprintf(stderr
, "}\n");
225 /* We fail if the data is unexpected. */
230 compare_doubles(const char *errorLabel
, GLuint expectedSize
,
231 const GLdouble
*expectedData
, GLuint actualSize
, const GLdouble
*actualData
)
235 if (expectedSize
== actualSize
||
236 memcmp(expectedData
, actualData
, actualSize
*sizeof(*expectedData
)) == 0) {
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
++) {
262 fprintf(stderr
, " %s: size %d: {", label
, size
);
263 for (j
= 0; j
< size
; j
++) {
264 fprintf(stderr
, "%s%f", j
> 0 ? ", " : "", ptr
[j
]);
266 fprintf(stderr
, "}\n");
269 /* We fail if the data is unexpected. */
273 /********************************************************************
274 * Functions to assist with GL_ARB_texture_compressiong testing
278 check_texture_format_supported(GLenum format
)
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",
292 memset(formats
, 0, numFormats
* sizeof(GLint
));
293 glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB
, formats
);
295 for (i
= 0; i
< numFormats
; i
++) {
296 if (formats
[i
] == format
) {
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" : \
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
]));
321 fprintf(stderr
, "\n");
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.
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
)
334 /* These are the data we query about the texture. */
336 GLenum compressedFormat
;
337 GLint compressedSize
;
338 GLubyte
*compressedData
;
340 /* We need this function pointer to operate. */
341 DECLARE_GLFUNC_PTR(GetCompressedTexImageARB
, PFNGLGETCOMPRESSEDTEXIMAGEARBPROC
);
342 if (GetCompressedTexImageARB
== NULL
) {
344 "%s: could not query GetCompressedTexImageARB function pointer\n",
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
)) {
354 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
355 /* Set up the base image, requesting that the GL library compress it. */
358 glTexImage1D(GL_TEXTURE_1D
, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
,
360 GL_RGBA
, GL_UNSIGNED_BYTE
, texture
);
363 glTexImage2D(GL_TEXTURE_2D
, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
,
365 GL_RGBA
, GL_UNSIGNED_BYTE
, texture
);
368 glTexImage3D(GL_TEXTURE_3D
, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
,
369 width
, height
, depth
, 0,
370 GL_RGBA
, GL_UNSIGNED_BYTE
, texture
);
373 fprintf(stderr
, "%s: unknown dimension 0x%04x.\n", message
, dimension
);
376 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
378 /* Make sure the texture is compressed, and pull it out if it is. */
379 glGetTexLevelParameteriv(dimension
, 0, GL_TEXTURE_COMPRESSED_ARB
,
382 fprintf(stderr
, "%s: could not compress GL_COMPRESSED_RGBA_S3TC_DXT3_EXT texture\n",
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
);
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
);
402 memset(compressedData
, 0, compressedSize
);
403 (*GetCompressedTexImageARB
)(dimension
, 0, compressedData
);
404 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
406 /* Compare it to the expected compressed data. The compare_bytes()
407 * call will print out diagnostics in the case of failure.
409 if (!compare_bytes(message
,
410 expectedCompressedSize
, expectedCompressedData
,
411 compressedSize
, compressedData
)) {
413 free(compressedData
);
417 /* All done. Free our allocated data and return success. */
418 free(compressedData
);
422 /* We'll use one function to exercise 1D, 2D, and 3D textures. */
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.
431 exercise_CompressedTextures(GLenum dimension
)
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.
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
,
450 GLubyte uncompressedTexture
[TEXTURE_WIDTH
*TEXTURE_HEIGHT
*TEXTURE_DEPTH
*4];
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] = {
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.
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
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
507 /* The similar calculations for the 4x4 subtexture are left
508 * as an exercise for the reader.
510 static GLubyte compressedSubTexture
[] = {
511 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
512 0x00, 0xf8, 0xe0, 0x07, 0x05, 0x05, 0x50, 0x50,
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
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.
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
542 /* These are the data we query about the texture. */
543 GLint queryIsCompressed
;
544 GLenum queryCompressedFormat
;
545 GLint queryCompressedSize
;
546 GLubyte queryCompressedData
[sizeof(compressedTexture
)];
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.
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
);
560 /* If the necessary functions are missing, we can't continue */
561 if (GetCompressedTexImageARB
== NULL
) {
562 fprintf(stderr
, "%s: GetCompressedTexImageARB function is missing\n",
568 if (CompressedTexImage1DARB
== NULL
|| CompressedTexSubImage1DARB
== NULL
) {
569 fprintf(stderr
, "%s: 1D compressed texture functions are missing\n",
575 if (CompressedTexImage2DARB
== NULL
|| CompressedTexSubImage2DARB
== NULL
) {
576 fprintf(stderr
, "%s: 2D compressed texture functions are missing\n",
582 if (CompressedTexImage3DARB
== NULL
|| CompressedTexSubImage3DARB
== NULL
) {
583 fprintf(stderr
, "%s: 3D compressed texture functions are missing\n",
589 fprintf(stderr
, "%s: unknown texture dimension 0x%04x passed.\n",
590 __FUNCTION__
, dimension
);
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
)) {
599 /* Something's wrong with texture compression. The function
600 * above will have printed an appropriate error.
605 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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
)) {
612 /* Something's wrong with texture compression. The function
613 * above will have printed an appropriate error.
618 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
620 /* Send the base compressed texture down to the hardware. */
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
);
630 (*CompressedTexImage2DARB
)(GL_TEXTURE_2D
, 0,
631 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
,
632 TEXTURE_WIDTH
, TEXTURE_HEIGHT
, 0,
633 sizeof(compressedTexture
), compressedTexture
);
637 (*CompressedTexImage1DARB
)(GL_TEXTURE_1D
, 0,
638 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
,
640 sizeof(compressedTexture
), compressedTexture
);
643 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
645 /* For grins, query it to make sure it is as expected. */
646 glGetTexLevelParameteriv(dimension
, 0, GL_TEXTURE_COMPRESSED_ARB
,
648 if (!queryIsCompressed
) {
649 fprintf(stderr
, "%s: compressed texture did not come back as compressed\n",
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
);
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
);
667 (*GetCompressedTexImageARB
)(dimension
, 0, queryCompressedData
);
669 "exercise_CompressedTextures:doublechecking compressed texture",
670 sizeof(compressedTexture
), compressedTexture
,
671 queryCompressedSize
, queryCompressedData
)) {
675 /* Now apply the texture subimage. The current implementation of
676 * S3TC requires that subimages be only applied to whole blocks.
678 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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
);
688 (*CompressedTexSubImage2DARB
)(GL_TEXTURE_2D
, 0,
690 SUBTEXTURE_WIDTH
, SUBTEXTURE_HEIGHT
,
691 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
,
692 sizeof(compressedSubTexture
), compressedSubTexture
);
695 (*CompressedTexSubImage2DARB
)(GL_TEXTURE_2D
, 0,
697 SUBTEXTURE_WIDTH
, SUBTEXTURE_HEIGHT
,
698 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
,
699 sizeof(compressedSubTexture
), compressedSubTexture
);
702 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
704 /* Query the compressed texture back now, and see that it
707 (*GetCompressedTexImageARB
)(dimension
, 0, queryCompressedData
);
708 if (!compare_bytes("exercise_CompressedTextures:combined texture",
709 sizeof(compressedCombinedTexture
), compressedCombinedTexture
,
710 queryCompressedSize
, queryCompressedData
)) {
713 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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.
720 glGetTexImage(dimension
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, uncompressedTexture
);
721 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
723 /* If we survived this far, we pass. */
727 /**************************************************************************
728 * Functions to assist with GL_EXT_framebuffer_object and
729 * GL_EXT_framebuffer_blit testing.
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" : \
745 exercise_framebuffer(void)
747 GLuint framebufferID
= 0;
748 GLuint renderbufferID
= 0;
750 /* Dimensions of the framebuffer and renderbuffers are arbitrary.
751 * Since they won't be shown on-screen, we can use whatever we want.
753 const GLint Width
= 100;
754 const GLint Height
= 100;
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).
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
);
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.
778 DECLARE_GLFUNC_PTR(BlitFramebufferEXT
, PFNGLBLITFRAMEBUFFEREXTPROC
);
780 /* We cannot test unless we have all the function pointers. */
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
794 fprintf(stderr
, "%s: could not locate all framebuffer functions\n",
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",
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
);
816 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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
);
828 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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.
834 (*GenRenderbuffersEXT
)(1, &renderbufferID
);
835 if (renderbufferID
== 0) {
836 fprintf(stderr
, "%s: could not generate a renderbuffer ID\n",
838 (*BindFramebufferEXT
)(GL_FRAMEBUFFER_EXT
, 0);
839 (*DeleteFramebuffersEXT
)(1, &framebufferID
);
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
);
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
);
865 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
867 /* Add the renderbuffer as a color attachment to the current
868 * framebuffer (which is our generated framebuffer).
870 (*FramebufferRenderbufferEXT
)(GL_FRAMEBUFFER_EXT
, GL_COLOR_ATTACHMENT1_EXT
,
871 GL_RENDERBUFFER_EXT
, renderbufferID
);
872 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
874 /* The renderbuffer will need some dimensions and storage space. */
875 (*RenderbufferStorageEXT
)(GL_RENDERBUFFER_EXT
, GL_RGB
, Width
, Height
);
876 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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.
882 glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT
);
883 glReadBuffer(GL_COLOR_ATTACHMENT1_EXT
);
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
);
891 (*BindRenderbufferEXT
)(GL_RENDERBUFFER_EXT
, 0);
892 (*DeleteRenderbuffersEXT
)(1, &renderbufferID
);
893 (*BindFramebufferEXT
)(GL_FRAMEBUFFER_EXT
, 0);
894 (*DeleteFramebuffersEXT
)(1, &framebufferID
);
898 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
900 /* Define the contents of the frame buffer */
901 glClearColor(0.5, 0.5, 0.5, 0.0);
902 glClear(GL_COLOR_BUFFER_BIT
);
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).
909 if (BlitFramebufferEXT
!= NULL
) {
910 (*BlitFramebufferEXT
)(5, 5, 10, 10, 90, 90, 95, 95,
911 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
913 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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.
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__
);
930 /**************************************************************************
931 * Functions to assist with GL_ARB_shader_objects testing.
935 print_info_log(const char *message
, GLhandleARB object
)
937 DECLARE_GLFUNC_PTR(GetObjectParameterivARB
, PFNGLGETOBJECTPARAMETERIVARBPROC
);
938 DECLARE_GLFUNC_PTR(GetInfoLogARB
, PFNGLGETINFOLOGARBPROC
);
939 int logLength
, queryLength
;
942 if (GetObjectParameterivARB
== NULL
) {
943 fprintf(stderr
, "%s: could not get GetObjectParameterivARB address\n",
947 if (GetInfoLogARB
== NULL
) {
948 fprintf(stderr
, "%s: could not get GetInfoLogARB address\n",
953 (*GetObjectParameterivARB
)(object
, GL_OBJECT_INFO_LOG_LENGTH_ARB
,
955 if (logLength
== 0) {
956 fprintf(stderr
, "%s: info log length is 0\n", message
);
959 log
= malloc(logLength
);
961 fprintf(stderr
, "%s: could not malloc %d bytes for info log\n",
965 (*GetInfoLogARB
)(object
, logLength
, &queryLength
, log
);
966 fprintf(stderr
, "%s: info log says '%s'\n",
973 exercise_uniform_start(const char *fragmentShaderText
, const char *uniformName
,
974 GLhandleARB
*returnProgram
, GLint
*returnUniformLocation
)
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
;
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
||
1006 /* Create the trivial fragment shader and program. For safety
1007 * we'll check to make sure they compile and link correctly.
1009 fs
= (*CreateShaderObjectARB
)(GL_FRAGMENT_SHADER_ARB
);
1010 (*ShaderSourceARB
)(fs
, 1, &fragmentShaderText
, NULL
);
1011 (*CompileShaderARB
)(fs
);
1012 (*GetObjectParameterivARB
)(fs
, GL_OBJECT_COMPILE_STATUS_ARB
,
1014 if (!shaderCompiled
) {
1015 print_info_log("shader did not compile", fs
);
1016 (*DeleteObjectARB
)(fs
);
1017 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1020 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1022 program
= (*CreateProgramObjectARB
)();
1023 (*AttachObjectARB
)(program
, fs
);
1024 (*LinkProgramARB
)(program
);
1025 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1027 /* Make sure we're going to run successfully */
1028 (*ValidateProgramARB
)(program
);
1029 (*GetObjectParameterivARB
)(program
, GL_OBJECT_VALIDATE_STATUS_ARB
,
1031 if (!programValidated
) {;
1032 print_info_log("program did not validate", program
);
1033 (*DeleteObjectARB
)(program
);
1034 (*DeleteObjectARB
)(fs
);
1035 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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.
1042 (*UseProgramObjectARB
)(program
);
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.
1047 (*DeleteObjectARB
)(fs
);
1049 /* Find the location index of the uniform variable we declared;
1050 * the caller will ned that to set the value.
1052 uniformLocation
= (*GetUniformLocationARB
)(program
, uniformName
);
1053 if (uniformLocation
== -1) {
1054 fprintf(stderr
, "%s: could not determine uniform location\n",
1056 (*DeleteObjectARB
)(program
);
1057 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1061 /* All done with what we're supposed to do - return the program
1062 * handle and the uniform location to the caller.
1064 *returnProgram
= program
;
1065 *returnUniformLocation
= uniformLocation
;
1070 exercise_uniform_end(GLhandleARB program
)
1072 DECLARE_GLFUNC_PTR(UseProgramObjectARB
, PFNGLUSEPROGRAMOBJECTARBPROC
);
1073 DECLARE_GLFUNC_PTR(DeleteObjectARB
, PFNGLDELETEOBJECTARBPROC
);
1074 if (UseProgramObjectARB
== NULL
|| DeleteObjectARB
== NULL
) {
1078 /* Turn off our program by setting the special value 0, and
1079 * then delete the program object.
1081 (*UseProgramObjectARB
)(0);
1082 (*DeleteObjectARB
)(program
);
1083 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1086 /**************************************************************************
1087 * Exercises for fences
1090 exercise_fences(void)
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
);
1100 GLint fenceStatus
, fenceCondition
;
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",
1116 /* Create and set a simple fence. */
1117 (*GenFencesNV
)(1, &fence
);
1118 (*SetFenceNV
)(fence
, GL_ALL_COMPLETED_NV
);
1119 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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
);
1127 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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
);
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
);
1144 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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();
1150 (*SetFenceNV
)(fence
, GL_ALL_COMPLETED_NV
);
1153 while (!(*TestFenceNV
)(fence
)) {
1160 fprintf(stderr
, "%s: fence never returned true\n", __FUNCTION__
);
1161 (*DeleteFencesNV
)(1, &fence
);
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",
1169 (*DeleteFencesNV
)(1, &fence
);
1172 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1174 /* All done. Delete the fence and return. */
1175 (*DeleteFencesNV
)(1, &fence
);
1176 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1180 /**************************************************************************
1181 * Exercises for buffer objects
1183 enum Map_Buffer_Usage
{ Use_Map_Buffer
, Use_Map_Buffer_Range
};
1185 exercise_buffer_objects(enum Map_Buffer_Usage usage
)
1187 #define BUFFER_DATA_SIZE 1024
1190 static GLubyte data
[BUFFER_DATA_SIZE
] = {0};
1191 float *dataPtr
= NULL
;
1193 /* Get the function pointers we need. These are from
1194 * GL_ARB_vertex_buffer_object and are required in all
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
);
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.)
1212 DECLARE_GLFUNC_PTR(FlushMappedBufferRange
, PFNGLFLUSHMAPPEDBUFFERRANGEPROC
);
1213 DECLARE_GLFUNC_PTR(MapBufferRange
, PFNGLMAPBUFFERRANGEPROC
);
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.
1218 DECLARE_GLFUNC_PTR(BufferParameteriAPPLE
, PFNGLBUFFERPARAMETERIAPPLEPROC
);
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__
);
1231 if (usage
== Use_Map_Buffer_Range
) {
1232 if (FlushMappedBufferRange
== NULL
|| MapBufferRange
== NULL
) {
1233 fprintf(stderr
, "%s: missing MapBufferRange functions\n", __FUNCTION__
);
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__
);
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.
1249 if (usage
== Use_Map_Buffer_Range
&& BufferParameteriAPPLE
!= NULL
) {
1250 (*BufferParameteriAPPLE
)(GL_ARRAY_BUFFER_ARB
,
1251 GL_BUFFER_SERIALIZED_MODIFY_APPLE
, GL_TRUE
);
1254 /* Map it, and make sure it's mapped. */
1256 case Use_Map_Buffer
:
1257 dataPtr
= (float *) (*MapBufferARB
)(
1258 GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
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
);
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
);
1272 (*GetBufferParameterivARB
)(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
,
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
);
1280 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1282 /* Write something to it, just to make sure we don't segfault. */
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.
1288 if (usage
== Use_Map_Buffer_Range
) {
1289 (*FlushMappedBufferRange
)(GL_ARRAY_BUFFER_ARB
, 4, 16);
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
);
1297 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1300 (*BindBufferARB
)(GL_ARRAY_BUFFER_ARB
, 0);
1301 (*DeleteBuffersARB
)(1, &bufferID
);
1302 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1305 #undef BUFFER_DATA_SIZE
1308 /**************************************************************************
1309 * Exercises for occlusion query
1312 exercise_occlusion_query(void)
1316 GLuint querySampleCount
;
1318 GLint queryCounterBits
;
1320 /* Get the function pointers we need. These are from
1321 * GL_ARB_vertex_buffer_object and are required in all
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
);
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__
);
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__
);
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
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
);
1363 (*GetQueryivARB
)(GL_SAMPLES_PASSED_ARB
, GL_QUERY_COUNTER_BITS_ARB
,
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
);
1372 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1374 /* Finish up the query. Since we didn't draw anything, the result
1375 * should be 0 passed samples.
1377 (*EndQueryARB
)(GL_SAMPLES_PASSED_ARB
);
1378 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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
);
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.
1394 queryReady
= GL_FALSE
;
1396 (*GetQueryObjectivARB
)(queryObject
, GL_QUERY_RESULT_AVAILABLE_ARB
,
1398 } while (!queryReady
);
1399 (*GetQueryObjectuivARB
)(queryObject
, GL_QUERY_RESULT_ARB
, &querySampleCount
);
1400 (*DeleteQueriesARB
)(1, &queryObject
);
1401 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
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
);
1410 /* Here, all is well. */
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.
1422 test_WeightPointerARB(generic_func func
)
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.
1431 #define USE_VERTEX_UNITS 2
1432 #define USE_WEIGHT_INDEX 3
1433 static GLfloat weights
[] = {
1444 GLint numVertexUnits
;
1445 GLfloat
*currentWeights
;
1449 PFNGLWEIGHTPOINTERARBPROC WeightPointerARB
= (PFNGLWEIGHTPOINTERARBPROC
) func
;
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
);
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
);
1467 /* Set up the pointer, enable the state, and try to send down a
1468 * weight vector (we'll arbitrarily send index 2).
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__
);
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
]);
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
]);
1497 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1499 /* Restore the old state. We know the default set of weights is in
1503 glDisableClientState(GL_WEIGHT_ARRAY_ARB
);
1504 (*WeightPointerARB
)(0, GL_FLOAT
, 0, NULL
);
1505 free(currentWeights
);
1506 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1508 /* We're fine if we didn't get any mismatches. */
1509 if (errorCount
== 0) {
1517 /* Wrappers on the exercise_occlusion_query function */
1519 test_GenQueriesARB(generic_func func
)
1522 return exercise_occlusion_query();
1525 test_BeginQueryARB(generic_func func
)
1528 return exercise_occlusion_query();
1531 test_GetQueryivARB(generic_func func
)
1534 return exercise_occlusion_query();
1537 test_EndQueryARB(generic_func func
)
1540 return exercise_occlusion_query();
1543 test_IsQueryARB(generic_func func
)
1546 return exercise_occlusion_query();
1549 test_GetQueryObjectivARB(generic_func func
)
1552 return exercise_occlusion_query();
1555 test_GetQueryObjectuivARB(generic_func func
)
1558 return exercise_occlusion_query();
1561 test_DeleteQueriesARB(generic_func func
)
1564 return exercise_occlusion_query();
1567 /* Wrappers on the exercise_buffer_objects() function */
1569 test_GenBuffersARB(generic_func func
)
1572 return exercise_buffer_objects(Use_Map_Buffer
);
1575 test_BindBufferARB(generic_func func
)
1578 return exercise_buffer_objects(Use_Map_Buffer
);
1581 test_BufferDataARB(generic_func func
)
1584 return exercise_buffer_objects(Use_Map_Buffer
);
1587 test_MapBufferARB(generic_func func
)
1590 return exercise_buffer_objects(Use_Map_Buffer
);
1593 test_UnmapBufferARB(generic_func func
)
1596 return exercise_buffer_objects(Use_Map_Buffer
);
1599 test_DeleteBuffersARB(generic_func func
)
1602 return exercise_buffer_objects(Use_Map_Buffer
);
1605 test_GetBufferParameterivARB(generic_func func
)
1608 return exercise_buffer_objects(Use_Map_Buffer
);
1611 test_FlushMappedBufferRange(generic_func func
)
1614 return exercise_buffer_objects(Use_Map_Buffer_Range
);
1617 test_MapBufferRange(generic_func func
)
1620 return exercise_buffer_objects(Use_Map_Buffer_Range
);
1623 test_BufferParameteriAPPLE(generic_func func
)
1626 return exercise_buffer_objects(Use_Map_Buffer_Range
);
1629 /* Wrappers on the exercise_framebuffer() function */
1631 test_BindFramebufferEXT(generic_func func
)
1634 return exercise_framebuffer();
1637 test_BindRenderbufferEXT(generic_func func
)
1640 return exercise_framebuffer();
1643 test_CheckFramebufferStatusEXT(generic_func func
)
1646 return exercise_framebuffer();
1649 test_DeleteFramebuffersEXT(generic_func func
)
1652 return exercise_framebuffer();
1655 test_DeleteRenderbuffersEXT(generic_func func
)
1658 return exercise_framebuffer();
1661 test_FramebufferRenderbufferEXT(generic_func func
)
1664 return exercise_framebuffer();
1667 test_GenFramebuffersEXT(generic_func func
)
1670 return exercise_framebuffer();
1673 test_GenRenderbuffersEXT(generic_func func
)
1676 return exercise_framebuffer();
1679 test_IsFramebufferEXT(generic_func func
)
1682 return exercise_framebuffer();
1685 test_IsRenderbufferEXT(generic_func func
)
1688 return exercise_framebuffer();
1691 test_RenderbufferStorageEXT(generic_func func
)
1694 return exercise_framebuffer();
1697 test_BlitFramebufferEXT(generic_func func
)
1700 return exercise_framebuffer();
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.
1708 test_CompressedTexImage2DARB(generic_func func
)
1711 return exercise_CompressedTextures(GL_TEXTURE_2D
);
1714 test_CompressedTexSubImage2DARB(generic_func func
)
1717 return exercise_CompressedTextures(GL_TEXTURE_2D
);
1720 test_CompressedTexImage3DARB(generic_func func
)
1723 return exercise_CompressedTextures(GL_TEXTURE_3D
);
1726 test_CompressedTexSubImage3DARB(generic_func func
)
1729 return exercise_CompressedTextures(GL_TEXTURE_3D
);
1732 test_GetCompressedTexImageARB(generic_func func
)
1735 return exercise_CompressedTextures(GL_TEXTURE_3D
);
1738 /* Wrappers on exercise_fences(). */
1740 test_DeleteFencesNV(generic_func func
)
1743 return exercise_fences();
1746 test_GenFencesNV(generic_func func
)
1749 return exercise_fences();
1752 test_SetFenceNV(generic_func func
)
1755 return exercise_fences();
1758 test_TestFenceNV(generic_func func
)
1761 return exercise_fences();
1764 test_FinishFenceNV(generic_func func
)
1767 return exercise_fences();
1770 test_GetFenceivNV(generic_func func
)
1773 return exercise_fences();
1776 test_IsFenceNV(generic_func func
)
1779 return exercise_fences();
1782 /* A bunch of glUniform*() tests */
1784 test_Uniform1iv(generic_func func
)
1786 PFNGLUNIFORM1IVARBPROC Uniform1ivARB
= (PFNGLUNIFORM1IVARBPROC
) func
;
1787 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
1789 /* This is a trivial fragment shader that sets the color of the
1790 * fragment to the uniform value passed in.
1792 static const char *fragmentShaderText
=
1793 "uniform int uniformColor;"
1794 "void main() {gl_FragColor.r = uniformColor;}";
1795 static const char *uniformName
= "uniformColor";
1797 GLhandleARB program
;
1798 GLint uniformLocation
;
1799 const GLint uniform
[1] = {1};
1800 GLint queriedUniform
[1];
1802 if (GetUniformivARB
== NULL
) {
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.
1810 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
1811 &program
, &uniformLocation
)) {
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.
1821 (*Uniform1ivARB
)(uniformLocation
, 1, uniform
);
1822 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1825 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
1826 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1828 /* Clean up before we check to see whether it came back unscathed */
1829 exercise_uniform_end(program
);
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.
1834 return compare_ints(__FUNCTION__
, 1, uniform
, 1, queriedUniform
);
1838 test_Uniform1i(generic_func func
)
1840 PFNGLUNIFORM1IARBPROC Uniform1iARB
= (PFNGLUNIFORM1IARBPROC
) func
;
1841 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
1843 /* This is a trivial fragment shader that sets the color of the
1844 * fragment to the uniform value passed in.
1846 static const char *fragmentShaderText
=
1847 "uniform int uniformColor;"
1848 "void main() {gl_FragColor.r = uniformColor;}";
1849 static const char *uniformName
= "uniformColor";
1851 GLhandleARB program
;
1852 GLint uniformLocation
;
1853 const GLint uniform
[1] = {1};
1854 GLint queriedUniform
[4];
1856 if (GetUniformivARB
== NULL
) {
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.
1864 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
1865 &program
, &uniformLocation
)) {
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.
1874 (*Uniform1iARB
)(uniformLocation
, uniform
[0]);
1875 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1878 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
1879 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1881 /* Clean up before we check to see whether it came back unscathed */
1882 exercise_uniform_end(program
);
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.
1887 return compare_ints(__FUNCTION__
, 1, uniform
, 1, queriedUniform
);
1891 test_Uniform1fv(generic_func func
)
1893 PFNGLUNIFORM1FVARBPROC Uniform1fvARB
= (PFNGLUNIFORM1FVARBPROC
) func
;
1894 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
1896 /* This is a trivial fragment shader that sets the color of the
1897 * fragment to the uniform value passed in.
1899 static const char *fragmentShaderText
=
1900 "uniform float uniformColor;"
1901 "void main() {gl_FragColor.r = uniformColor;}";
1902 static const char *uniformName
= "uniformColor";
1904 GLhandleARB program
;
1905 GLint uniformLocation
;
1906 const GLfloat uniform
[1] = {1.1};
1907 GLfloat queriedUniform
[1];
1909 if (GetUniformfvARB
== NULL
) {
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.
1917 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
1918 &program
, &uniformLocation
)) {
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.
1928 (*Uniform1fvARB
)(uniformLocation
, 1, uniform
);
1929 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1932 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
1933 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1935 /* Clean up before we check to see whether it came back unscathed */
1936 exercise_uniform_end(program
);
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.
1941 return compare_floats(__FUNCTION__
, 1, uniform
, 1, queriedUniform
);
1945 test_Uniform1f(generic_func func
)
1947 PFNGLUNIFORM1FARBPROC Uniform1fARB
= (PFNGLUNIFORM1FARBPROC
) func
;
1948 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
1950 /* This is a trivial fragment shader that sets the color of the
1951 * fragment to the uniform value passed in.
1953 static const char *fragmentShaderText
=
1954 "uniform float uniformColor;"
1955 "void main() {gl_FragColor.r = uniformColor;}";
1956 static const char *uniformName
= "uniformColor";
1958 GLhandleARB program
;
1959 GLint uniformLocation
;
1960 const GLfloat uniform
[1] = {1.1};
1961 GLfloat queriedUniform
[1];
1963 if (GetUniformfvARB
== NULL
) {
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.
1971 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
1972 &program
, &uniformLocation
)) {
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.
1981 (*Uniform1fARB
)(uniformLocation
, uniform
[0]);
1982 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1985 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
1986 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
1988 /* Clean up before we check to see whether it came back unscathed */
1989 exercise_uniform_end(program
);
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.
1994 return compare_floats(__FUNCTION__
, 1, uniform
, 1, queriedUniform
);
1998 test_Uniform2iv(generic_func func
)
2000 PFNGLUNIFORM2IVARBPROC Uniform2ivARB
= (PFNGLUNIFORM2IVARBPROC
) func
;
2001 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
2003 /* This is a trivial fragment shader that sets the color of the
2004 * fragment to the uniform value passed in.
2006 static const char *fragmentShaderText
=
2007 "uniform ivec2 uniformColor;"
2008 "void main() {gl_FragColor.rg = uniformColor;}";
2009 static const char *uniformName
= "uniformColor";
2011 GLhandleARB program
;
2012 GLint uniformLocation
;
2013 const GLint uniform
[2] = {1,2};
2014 GLint queriedUniform
[2];
2016 if (GetUniformivARB
== NULL
) {
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.
2024 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2025 &program
, &uniformLocation
)) {
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.
2035 (*Uniform2ivARB
)(uniformLocation
, 1, uniform
);
2036 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2039 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
2040 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2042 /* Clean up before we check to see whether it came back unscathed */
2043 exercise_uniform_end(program
);
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.
2048 return compare_ints(__FUNCTION__
, 2, uniform
, 2, queriedUniform
);
2052 test_Uniform2i(generic_func func
)
2054 PFNGLUNIFORM2IARBPROC Uniform2iARB
= (PFNGLUNIFORM2IARBPROC
) func
;
2055 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
2057 /* This is a trivial fragment shader that sets the color of the
2058 * fragment to the uniform value passed in.
2060 static const char *fragmentShaderText
=
2061 "uniform ivec2 uniformColor;"
2062 "void main() {gl_FragColor.rg = uniformColor;}";
2063 static const char *uniformName
= "uniformColor";
2065 GLhandleARB program
;
2066 GLint uniformLocation
;
2067 const GLint uniform
[2] = {1,2};
2068 GLint queriedUniform
[4];
2070 if (GetUniformivARB
== NULL
) {
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.
2078 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2079 &program
, &uniformLocation
)) {
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.
2088 (*Uniform2iARB
)(uniformLocation
, uniform
[0], uniform
[1]);
2089 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2092 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
2093 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2095 /* Clean up before we check to see whether it came back unscathed */
2096 exercise_uniform_end(program
);
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.
2101 return compare_ints(__FUNCTION__
, 2, uniform
, 2, queriedUniform
);
2105 test_Uniform2fv(generic_func func
)
2107 PFNGLUNIFORM2FVARBPROC Uniform2fvARB
= (PFNGLUNIFORM2FVARBPROC
) func
;
2108 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
2110 /* This is a trivial fragment shader that sets the color of the
2111 * fragment to the uniform value passed in.
2113 static const char *fragmentShaderText
=
2114 "uniform vec2 uniformColor;"
2115 "void main() {gl_FragColor.rg = uniformColor;}";
2116 static const char *uniformName
= "uniformColor";
2118 GLhandleARB program
;
2119 GLint uniformLocation
;
2120 const GLfloat uniform
[2] = {1.1,2.2};
2121 GLfloat queriedUniform
[2];
2123 if (GetUniformfvARB
== NULL
) {
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.
2131 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2132 &program
, &uniformLocation
)) {
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.
2142 (*Uniform2fvARB
)(uniformLocation
, 1, uniform
);
2143 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2146 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
2147 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2149 /* Clean up before we check to see whether it came back unscathed */
2150 exercise_uniform_end(program
);
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.
2155 return compare_floats(__FUNCTION__
, 2, uniform
, 2, queriedUniform
);
2159 test_Uniform2f(generic_func func
)
2161 PFNGLUNIFORM2FARBPROC Uniform2fARB
= (PFNGLUNIFORM2FARBPROC
) func
;
2162 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
2164 /* This is a trivial fragment shader that sets the color of the
2165 * fragment to the uniform value passed in.
2167 static const char *fragmentShaderText
=
2168 "uniform vec2 uniformColor;"
2169 "void main() {gl_FragColor.rg = uniformColor;}";
2170 static const char *uniformName
= "uniformColor";
2172 GLhandleARB program
;
2173 GLint uniformLocation
;
2174 const GLfloat uniform
[2] = {1.1,2.2};
2175 GLfloat queriedUniform
[2];
2177 if (GetUniformfvARB
== NULL
) {
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.
2185 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2186 &program
, &uniformLocation
)) {
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.
2195 (*Uniform2fARB
)(uniformLocation
, uniform
[0], uniform
[1]);
2196 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2199 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
2200 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2202 /* Clean up before we check to see whether it came back unscathed */
2203 exercise_uniform_end(program
);
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.
2208 return compare_floats(__FUNCTION__
, 2, uniform
, 2, queriedUniform
);
2212 test_Uniform3iv(generic_func func
)
2214 PFNGLUNIFORM3IVARBPROC Uniform3ivARB
= (PFNGLUNIFORM3IVARBPROC
) func
;
2215 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
2217 /* This is a trivial fragment shader that sets the color of the
2218 * fragment to the uniform value passed in.
2220 static const char *fragmentShaderText
=
2221 "uniform ivec3 uniformColor;"
2222 "void main() {gl_FragColor.rgb = uniformColor;}";
2223 static const char *uniformName
= "uniformColor";
2225 GLhandleARB program
;
2226 GLint uniformLocation
;
2227 const GLint uniform
[3] = {1,2,3};
2228 GLint queriedUniform
[3];
2230 if (GetUniformivARB
== NULL
) {
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.
2238 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2239 &program
, &uniformLocation
)) {
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.
2249 (*Uniform3ivARB
)(uniformLocation
, 1, uniform
);
2250 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2253 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
2254 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2256 /* Clean up before we check to see whether it came back unscathed */
2257 exercise_uniform_end(program
);
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.
2262 return compare_ints(__FUNCTION__
, 3, uniform
, 3, queriedUniform
);
2266 test_Uniform3i(generic_func func
)
2268 PFNGLUNIFORM3IARBPROC Uniform3iARB
= (PFNGLUNIFORM3IARBPROC
) func
;
2269 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
2271 /* This is a trivial fragment shader that sets the color of the
2272 * fragment to the uniform value passed in.
2274 static const char *fragmentShaderText
=
2275 "uniform ivec3 uniformColor;"
2276 "void main() {gl_FragColor.rgb = uniformColor;}";
2277 static const char *uniformName
= "uniformColor";
2279 GLhandleARB program
;
2280 GLint uniformLocation
;
2281 const GLint uniform
[3] = {1,2,3};
2282 GLint queriedUniform
[4];
2284 if (GetUniformivARB
== NULL
) {
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.
2292 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2293 &program
, &uniformLocation
)) {
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.
2302 (*Uniform3iARB
)(uniformLocation
, uniform
[0], uniform
[1], uniform
[2]);
2303 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2306 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
2307 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2309 /* Clean up before we check to see whether it came back unscathed */
2310 exercise_uniform_end(program
);
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.
2315 return compare_ints(__FUNCTION__
, 3, uniform
, 3, queriedUniform
);
2319 test_Uniform3fv(generic_func func
)
2321 PFNGLUNIFORM3FVARBPROC Uniform3fvARB
= (PFNGLUNIFORM3FVARBPROC
) func
;
2322 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
2324 /* This is a trivial fragment shader that sets the color of the
2325 * fragment to the uniform value passed in.
2327 static const char *fragmentShaderText
=
2328 "uniform vec3 uniformColor;"
2329 "void main() {gl_FragColor.rgb = uniformColor;}";
2330 static const char *uniformName
= "uniformColor";
2332 GLhandleARB program
;
2333 GLint uniformLocation
;
2334 const GLfloat uniform
[3] = {1.1,2.2,3.3};
2335 GLfloat queriedUniform
[3];
2337 if (GetUniformfvARB
== NULL
) {
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.
2345 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2346 &program
, &uniformLocation
)) {
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.
2356 (*Uniform3fvARB
)(uniformLocation
, 1, uniform
);
2357 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2360 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
2361 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2363 /* Clean up before we check to see whether it came back unscathed */
2364 exercise_uniform_end(program
);
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.
2369 return compare_floats(__FUNCTION__
, 3, uniform
, 3, queriedUniform
);
2373 test_Uniform3f(generic_func func
)
2375 PFNGLUNIFORM3FARBPROC Uniform3fARB
= (PFNGLUNIFORM3FARBPROC
) func
;
2376 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
2378 /* This is a trivial fragment shader that sets the color of the
2379 * fragment to the uniform value passed in.
2381 static const char *fragmentShaderText
=
2382 "uniform vec3 uniformColor;"
2383 "void main() {gl_FragColor.rgb = uniformColor;}";
2384 static const char *uniformName
= "uniformColor";
2386 GLhandleARB program
;
2387 GLint uniformLocation
;
2388 const GLfloat uniform
[3] = {1.1,2.2,3.3};
2389 GLfloat queriedUniform
[3];
2391 if (GetUniformfvARB
== NULL
) {
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.
2399 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2400 &program
, &uniformLocation
)) {
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.
2409 (*Uniform3fARB
)(uniformLocation
, uniform
[0], uniform
[1], uniform
[2]);
2410 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2413 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
2414 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2416 /* Clean up before we check to see whether it came back unscathed */
2417 exercise_uniform_end(program
);
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.
2422 return compare_floats(__FUNCTION__
, 3, uniform
, 3, queriedUniform
);
2426 test_Uniform4iv(generic_func func
)
2428 PFNGLUNIFORM4IVARBPROC Uniform4ivARB
= (PFNGLUNIFORM4IVARBPROC
) func
;
2429 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
2431 /* This is a trivial fragment shader that sets the color of the
2432 * fragment to the uniform value passed in.
2434 static const char *fragmentShaderText
=
2435 "uniform ivec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2436 static const char *uniformName
= "uniformColor";
2438 GLhandleARB program
;
2439 GLint uniformLocation
;
2440 const GLint uniform
[4] = {1,2,3,4};
2441 GLint queriedUniform
[4];
2443 if (GetUniformivARB
== NULL
) {
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.
2451 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2452 &program
, &uniformLocation
)) {
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.
2462 (*Uniform4ivARB
)(uniformLocation
, 1, uniform
);
2463 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2466 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
2467 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2469 /* Clean up before we check to see whether it came back unscathed */
2470 exercise_uniform_end(program
);
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.
2475 return compare_ints(__FUNCTION__
, 4, uniform
, 4, queriedUniform
);
2479 test_Uniform4i(generic_func func
)
2481 PFNGLUNIFORM4IARBPROC Uniform4iARB
= (PFNGLUNIFORM4IARBPROC
) func
;
2482 DECLARE_GLFUNC_PTR(GetUniformivARB
, PFNGLGETUNIFORMIVARBPROC
);
2484 /* This is a trivial fragment shader that sets the color of the
2485 * fragment to the uniform value passed in.
2487 static const char *fragmentShaderText
=
2488 "uniform ivec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2489 static const char *uniformName
= "uniformColor";
2491 GLhandleARB program
;
2492 GLint uniformLocation
;
2493 const GLint uniform
[4] = {1,2,3,4};
2494 GLint queriedUniform
[4];
2496 if (GetUniformivARB
== NULL
) {
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.
2504 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2505 &program
, &uniformLocation
)) {
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.
2514 (*Uniform4iARB
)(uniformLocation
, uniform
[0], uniform
[1], uniform
[2],
2516 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2519 (*GetUniformivARB
)(program
, uniformLocation
, queriedUniform
);
2520 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2522 /* Clean up before we check to see whether it came back unscathed */
2523 exercise_uniform_end(program
);
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.
2528 return compare_ints(__FUNCTION__
, 4, uniform
, 4, queriedUniform
);
2532 test_Uniform4fv(generic_func func
)
2534 PFNGLUNIFORM4FVARBPROC Uniform4fvARB
= (PFNGLUNIFORM4FVARBPROC
) func
;
2535 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
2537 /* This is a trivial fragment shader that sets the color of the
2538 * fragment to the uniform value passed in.
2540 static const char *fragmentShaderText
=
2541 "uniform vec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2542 static const char *uniformName
= "uniformColor";
2544 GLhandleARB program
;
2545 GLint uniformLocation
;
2546 const GLfloat uniform
[4] = {1.1,2.2,3.3,4.4};
2547 GLfloat queriedUniform
[4];
2549 if (GetUniformfvARB
== NULL
) {
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.
2557 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2558 &program
, &uniformLocation
)) {
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.
2568 (*Uniform4fvARB
)(uniformLocation
, 1, uniform
);
2569 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2572 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
2573 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2575 /* Clean up before we check to see whether it came back unscathed */
2576 exercise_uniform_end(program
);
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.
2581 return compare_floats(__FUNCTION__
, 4, uniform
, 4, queriedUniform
);
2585 test_Uniform4f(generic_func func
)
2587 PFNGLUNIFORM4FARBPROC Uniform4fARB
= (PFNGLUNIFORM4FARBPROC
) func
;
2588 DECLARE_GLFUNC_PTR(GetUniformfvARB
, PFNGLGETUNIFORMFVARBPROC
);
2590 /* This is a trivial fragment shader that sets the color of the
2591 * fragment to the uniform value passed in.
2593 static const char *fragmentShaderText
=
2594 "uniform vec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
2595 static const char *uniformName
= "uniformColor";
2597 GLhandleARB program
;
2598 GLint uniformLocation
;
2599 const GLfloat uniform
[4] = {1.1,2.2,3.3,4.4};
2600 GLfloat queriedUniform
[4];
2602 if (GetUniformfvARB
== NULL
) {
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.
2610 if (!exercise_uniform_start(fragmentShaderText
, uniformName
,
2611 &program
, &uniformLocation
)) {
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.
2620 (*Uniform4fARB
)(uniformLocation
, uniform
[0], uniform
[1], uniform
[2],
2622 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2625 (*GetUniformfvARB
)(program
, uniformLocation
, queriedUniform
);
2626 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
2628 /* Clean up before we check to see whether it came back unscathed */
2629 exercise_uniform_end(program
);
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.
2634 return compare_floats(__FUNCTION__
, 4, uniform
, 4, queriedUniform
);
2638 test_ActiveTextureARB(generic_func func
)
2640 PFNGLACTIVETEXTUREARBPROC activeTexture
= (PFNGLACTIVETEXTUREARBPROC
) func
;
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 */
2652 test_SecondaryColor3fEXT(generic_func func
)
2654 PFNGLSECONDARYCOLOR3FEXTPROC secColor3f
= (PFNGLSECONDARYCOLOR3FEXTPROC
) func
;
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 */
2666 test_ActiveStencilFaceEXT(generic_func func
)
2668 PFNGLACTIVESTENCILFACEEXTPROC activeFace
= (PFNGLACTIVESTENCILFACEEXTPROC
) func
;
2671 (*activeFace
)(GL_BACK
);
2672 glGetIntegerv(GL_ACTIVE_STENCIL_FACE_EXT
, &face
);
2673 pass
= (face
== GL_BACK
);
2674 (*activeFace
)(GL_FRONT
); /* restore default */
2680 test_VertexAttrib1fvARB(generic_func func
)
2682 PFNGLVERTEXATTRIB1FVARBPROC vertexAttrib1fvARB
= (PFNGLVERTEXATTRIB1FVARBPROC
) func
;
2683 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
2685 const GLfloat v
[1] = {25.0};
2686 const GLfloat def
[1] = {0};
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
);
2697 test_VertexAttrib1dvARB(generic_func func
)
2699 PFNGLVERTEXATTRIB1DVARBPROC vertexAttrib1dvARB
= (PFNGLVERTEXATTRIB1DVARBPROC
) func
;
2700 PFNGLGETVERTEXATTRIBDVARBPROC getVertexAttribdvARB
= (PFNGLGETVERTEXATTRIBDVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvARB");
2702 const GLdouble v
[1] = {25.0};
2703 const GLdouble def
[1] = {0};
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
);
2714 test_VertexAttrib1svARB(generic_func func
)
2716 PFNGLVERTEXATTRIB1SVARBPROC vertexAttrib1svARB
= (PFNGLVERTEXATTRIB1SVARBPROC
) func
;
2717 PFNGLGETVERTEXATTRIBIVARBPROC getVertexAttribivARB
= (PFNGLGETVERTEXATTRIBIVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivARB");
2719 const GLshort v
[1] = {25.0};
2720 const GLshort def
[1] = {0};
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
);
2731 test_VertexAttrib4NubvARB(generic_func func
)
2733 PFNGLVERTEXATTRIB4NUBVARBPROC vertexAttrib4NubvARB
= (PFNGLVERTEXATTRIB4NUBVARBPROC
) func
;
2734 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
2736 const GLubyte v
[4] = {255, 0, 255, 0};
2737 const GLubyte def
[4] = {0, 0, 0, 255};
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
);
2749 test_VertexAttrib4NuivARB(generic_func func
)
2751 PFNGLVERTEXATTRIB4NUIVARBPROC vertexAttrib4NuivARB
= (PFNGLVERTEXATTRIB4NUIVARBPROC
) func
;
2752 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
2754 const GLuint v
[4] = {0xffffffff, 0, 0xffffffff, 0};
2755 const GLuint def
[4] = {0, 0, 0, 0xffffffff};
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
);
2767 test_VertexAttrib4ivARB(generic_func func
)
2769 PFNGLVERTEXATTRIB4IVARBPROC vertexAttrib4ivARB
= (PFNGLVERTEXATTRIB4IVARBPROC
) func
;
2770 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
2772 const GLint v
[4] = {1, 2, -3, 4};
2773 const GLint def
[4] = {0, 0, 0, 1};
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
);
2785 test_VertexAttrib4NsvARB(generic_func func
)
2787 PFNGLVERTEXATTRIB4NSVARBPROC vertexAttrib4NsvARB
= (PFNGLVERTEXATTRIB4NSVARBPROC
) func
;
2788 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
2790 const GLshort v
[4] = {0, 32767, 32767, 0};
2791 const GLshort def
[4] = {0, 0, 0, 32767};
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
);
2802 test_VertexAttrib4NusvARB(generic_func func
)
2804 PFNGLVERTEXATTRIB4NUSVARBPROC vertexAttrib4NusvARB
= (PFNGLVERTEXATTRIB4NUSVARBPROC
) func
;
2805 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
2807 const GLushort v
[4] = {0xffff, 0, 0xffff, 0};
2808 const GLushort def
[4] = {0, 0, 0, 0xffff};
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
);
2819 test_VertexAttrib1sNV(generic_func func
)
2821 PFNGLVERTEXATTRIB1SNVPROC vertexAttrib1sNV
= (PFNGLVERTEXATTRIB1SNVPROC
) func
;
2822 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
2824 const GLshort v
[4] = {2, 0, 0, 1};
2825 const GLshort def
[4] = {0, 0, 0, 1};
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
);
2834 test_VertexAttrib1fNV(generic_func func
)
2836 PFNGLVERTEXATTRIB1FNVPROC vertexAttrib1fNV
= (PFNGLVERTEXATTRIB1FNVPROC
) func
;
2837 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
2839 const GLfloat v
[4] = {2.5, 0.0, 0.0, 1.0};
2840 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
2849 test_VertexAttrib1dNV(generic_func func
)
2851 PFNGLVERTEXATTRIB1DNVPROC vertexAttrib1dNV
= (PFNGLVERTEXATTRIB1DNVPROC
) func
;
2852 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
2854 const GLdouble v
[4] = {2.5, 0.0, 0.0, 1.0};
2855 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
2864 test_VertexAttrib2sNV(generic_func func
)
2866 PFNGLVERTEXATTRIB2SNVPROC vertexAttrib2sNV
= (PFNGLVERTEXATTRIB2SNVPROC
) func
;
2867 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
2869 const GLshort v
[4] = {2, 4, 0, 1};
2870 const GLshort def
[4] = {0, 0, 0, 1};
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
);
2879 test_VertexAttrib2fNV(generic_func func
)
2881 PFNGLVERTEXATTRIB2FNVPROC vertexAttrib2fNV
= (PFNGLVERTEXATTRIB2FNVPROC
) func
;
2882 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
2884 const GLfloat v
[4] = {2.5, 4.25, 0.0, 1.0};
2885 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
2894 test_VertexAttrib2dNV(generic_func func
)
2896 PFNGLVERTEXATTRIB2DNVPROC vertexAttrib2dNV
= (PFNGLVERTEXATTRIB2DNVPROC
) func
;
2897 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
2899 const GLdouble v
[4] = {2.5, 4.25, 0.0, 1.0};
2900 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
2909 test_VertexAttrib3sNV(generic_func func
)
2911 PFNGLVERTEXATTRIB3SNVPROC vertexAttrib3sNV
= (PFNGLVERTEXATTRIB3SNVPROC
) func
;
2912 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
2914 const GLshort v
[4] = {2, 4, 7, 1};
2915 const GLshort def
[4] = {0, 0, 0, 1};
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
);
2924 test_VertexAttrib3fNV(generic_func func
)
2926 PFNGLVERTEXATTRIB3FNVPROC vertexAttrib3fNV
= (PFNGLVERTEXATTRIB3FNVPROC
) func
;
2927 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
2929 const GLfloat v
[4] = {2.5, 4.25, 7.125, 1.0};
2930 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
2939 test_VertexAttrib3dNV(generic_func func
)
2941 PFNGLVERTEXATTRIB3DNVPROC vertexAttrib3dNV
= (PFNGLVERTEXATTRIB3DNVPROC
) func
;
2942 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
2944 const GLdouble v
[4] = {2.5, 4.25, 7.125, 1.0};
2945 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
2954 test_VertexAttrib4sNV(generic_func func
)
2956 PFNGLVERTEXATTRIB4SNVPROC vertexAttrib4sNV
= (PFNGLVERTEXATTRIB4SNVPROC
) func
;
2957 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
2959 const GLshort v
[4] = {2, 4, 7, 5};
2960 const GLshort def
[4] = {0, 0, 0, 1};
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
);
2969 test_VertexAttrib4fNV(generic_func func
)
2971 PFNGLVERTEXATTRIB4FNVPROC vertexAttrib4fNV
= (PFNGLVERTEXATTRIB4FNVPROC
) func
;
2972 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
2974 const GLfloat v
[4] = {2.5, 4.25, 7.125, 5.0625};
2975 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
2984 test_VertexAttrib4dNV(generic_func func
)
2986 PFNGLVERTEXATTRIB4DNVPROC vertexAttrib4dNV
= (PFNGLVERTEXATTRIB4DNVPROC
) func
;
2987 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
2989 const GLdouble v
[4] = {2.5, 4.25, 7.125, 5.0625};
2990 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
2999 test_VertexAttrib4ubNV(generic_func func
)
3001 PFNGLVERTEXATTRIB4UBNVPROC vertexAttrib4ubNV
= (PFNGLVERTEXATTRIB4UBNVPROC
) func
;
3002 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3004 const GLubyte v
[4] = {255, 0, 255, 0};
3005 const GLubyte def
[4] = {0, 0, 0, 255};
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
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
);
3020 test_VertexAttrib1fvNV(generic_func func
)
3022 PFNGLVERTEXATTRIB1FVNVPROC vertexAttrib1fvNV
= (PFNGLVERTEXATTRIB1FVNVPROC
) func
;
3023 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3025 const GLfloat v
[4] = {2.5, 0.0, 0.0, 1.0};
3026 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3035 test_VertexAttrib1dvNV(generic_func func
)
3037 PFNGLVERTEXATTRIB1DVNVPROC vertexAttrib1dvNV
= (PFNGLVERTEXATTRIB1DVNVPROC
) func
;
3038 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3040 const GLdouble v
[4] = {2.5, 0.0, 0.0, 1.0};
3041 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3050 test_VertexAttrib2svNV(generic_func func
)
3052 PFNGLVERTEXATTRIB2SVNVPROC vertexAttrib2svNV
= (PFNGLVERTEXATTRIB2SVNVPROC
) func
;
3053 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
3055 const GLshort v
[4] = {2, 4, 0, 1};
3056 const GLshort def
[4] = {0, 0, 0, 1};
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
);
3065 test_VertexAttrib2fvNV(generic_func func
)
3067 PFNGLVERTEXATTRIB2FVNVPROC vertexAttrib2fvNV
= (PFNGLVERTEXATTRIB2FVNVPROC
) func
;
3068 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3070 const GLfloat v
[4] = {2.5, 4.25, 0.0, 1.0};
3071 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3080 test_VertexAttrib2dvNV(generic_func func
)
3082 PFNGLVERTEXATTRIB2DVNVPROC vertexAttrib2dvNV
= (PFNGLVERTEXATTRIB2DVNVPROC
) func
;
3083 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3085 const GLdouble v
[4] = {2.5, 4.25, 0.0, 1.0};
3086 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3095 test_VertexAttrib3svNV(generic_func func
)
3097 PFNGLVERTEXATTRIB3SVNVPROC vertexAttrib3svNV
= (PFNGLVERTEXATTRIB3SVNVPROC
) func
;
3098 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
3100 const GLshort v
[4] = {2, 4, 7, 1};
3101 const GLshort def
[4] = {0, 0, 0, 1};
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
);
3110 test_VertexAttrib3fvNV(generic_func func
)
3112 PFNGLVERTEXATTRIB3FVNVPROC vertexAttrib3fvNV
= (PFNGLVERTEXATTRIB3FVNVPROC
) func
;
3113 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3115 const GLfloat v
[4] = {2.5, 4.25, 7.125, 1.0};
3116 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3125 test_VertexAttrib3dvNV(generic_func func
)
3127 PFNGLVERTEXATTRIB3DVNVPROC vertexAttrib3dvNV
= (PFNGLVERTEXATTRIB3DVNVPROC
) func
;
3128 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3130 const GLdouble v
[4] = {2.5, 4.25, 7.125, 1.0};
3131 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3140 test_VertexAttrib4svNV(generic_func func
)
3142 PFNGLVERTEXATTRIB4SVNVPROC vertexAttrib4svNV
= (PFNGLVERTEXATTRIB4SVNVPROC
) func
;
3143 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
3145 const GLshort v
[4] = {2, 4, 7, 5};
3146 const GLshort def
[4] = {0, 0, 0, 1};
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
);
3155 test_VertexAttrib4fvNV(generic_func func
)
3157 PFNGLVERTEXATTRIB4FVNVPROC vertexAttrib4fvNV
= (PFNGLVERTEXATTRIB4FVNVPROC
) func
;
3158 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3160 const GLfloat v
[4] = {2.5, 4.25, 7.125, 5.0625};
3161 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3170 test_VertexAttrib4dvNV(generic_func func
)
3172 PFNGLVERTEXATTRIB4DVNVPROC vertexAttrib4dvNV
= (PFNGLVERTEXATTRIB4DVNVPROC
) func
;
3173 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3175 const GLdouble v
[4] = {2.5, 4.25, 7.125, 5.0625};
3176 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3185 test_VertexAttrib4ubvNV(generic_func func
)
3187 PFNGLVERTEXATTRIB4UBVNVPROC vertexAttrib4ubvNV
= (PFNGLVERTEXATTRIB4UBVNVPROC
) func
;
3188 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3190 const GLubyte v
[4] = {255, 0, 255, 0};
3191 const GLubyte def
[4] = {0, 0, 0, 255};
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
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
);
3206 test_VertexAttribs1fvNV(generic_func func
)
3208 PFNGLVERTEXATTRIBS1FVNVPROC vertexAttribs1fvNV
= (PFNGLVERTEXATTRIBS1FVNVPROC
) func
;
3209 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3211 const GLfloat v
[4] = {2.5, 0.0, 0.0, 1.0};
3212 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3221 test_VertexAttribs1dvNV(generic_func func
)
3223 PFNGLVERTEXATTRIBS1DVNVPROC vertexAttribs1dvNV
= (PFNGLVERTEXATTRIBS1DVNVPROC
) func
;
3224 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3226 const GLdouble v
[4] = {2.5, 0.0, 0.0, 1.0};
3227 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3236 test_VertexAttribs2svNV(generic_func func
)
3238 PFNGLVERTEXATTRIBS2SVNVPROC vertexAttribs2svNV
= (PFNGLVERTEXATTRIBS2SVNVPROC
) func
;
3239 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
3241 const GLshort v
[4] = {2, 4, 0, 1};
3242 const GLshort def
[4] = {0, 0, 0, 1};
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
);
3251 test_VertexAttribs2fvNV(generic_func func
)
3253 PFNGLVERTEXATTRIBS2FVNVPROC vertexAttribs2fvNV
= (PFNGLVERTEXATTRIBS2FVNVPROC
) func
;
3254 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3256 const GLfloat v
[4] = {2.5, 4.25, 0.0, 1.0};
3257 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3266 test_VertexAttribs2dvNV(generic_func func
)
3268 PFNGLVERTEXATTRIBS2DVNVPROC vertexAttribs2dvNV
= (PFNGLVERTEXATTRIBS2DVNVPROC
) func
;
3269 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3271 const GLdouble v
[4] = {2.5, 4.25, 0.0, 1.0};
3272 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3281 test_VertexAttribs3svNV(generic_func func
)
3283 PFNGLVERTEXATTRIBS3SVNVPROC vertexAttribs3svNV
= (PFNGLVERTEXATTRIBS3SVNVPROC
) func
;
3284 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
3286 const GLshort v
[4] = {2, 4, 7, 1};
3287 const GLshort def
[4] = {0, 0, 0, 1};
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
);
3296 test_VertexAttribs3fvNV(generic_func func
)
3298 PFNGLVERTEXATTRIBS3FVNVPROC vertexAttribs3fvNV
= (PFNGLVERTEXATTRIBS3FVNVPROC
) func
;
3299 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3301 const GLfloat v
[4] = {2.5, 4.25, 7.125, 1.0};
3302 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3311 test_VertexAttribs3dvNV(generic_func func
)
3313 PFNGLVERTEXATTRIBS3DVNVPROC vertexAttribs3dvNV
= (PFNGLVERTEXATTRIBS3DVNVPROC
) func
;
3314 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3316 const GLdouble v
[4] = {2.5, 4.25, 7.125, 1.0};
3317 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3326 test_VertexAttribs4svNV(generic_func func
)
3328 PFNGLVERTEXATTRIBS4SVNVPROC vertexAttribs4svNV
= (PFNGLVERTEXATTRIBS4SVNVPROC
) func
;
3329 PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV
= (PFNGLGETVERTEXATTRIBIVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribivNV");
3331 const GLshort v
[4] = {2, 4, 7, 5};
3332 const GLshort def
[4] = {0, 0, 0, 1};
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
);
3341 test_VertexAttribs4fvNV(generic_func func
)
3343 PFNGLVERTEXATTRIBS4FVNVPROC vertexAttribs4fvNV
= (PFNGLVERTEXATTRIBS4FVNVPROC
) func
;
3344 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3346 const GLfloat v
[4] = {2.5, 4.25, 7.125, 5.0625};
3347 const GLfloat def
[4] = {0, 0, 0, 1};
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
);
3356 test_VertexAttribs4dvNV(generic_func func
)
3358 PFNGLVERTEXATTRIBS4DVNVPROC vertexAttribs4dvNV
= (PFNGLVERTEXATTRIBS4DVNVPROC
) func
;
3359 PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV
= (PFNGLGETVERTEXATTRIBDVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribdvNV");
3361 const GLdouble v
[4] = {2.5, 4.25, 7.125, 5.0625};
3362 const GLdouble def
[4] = {0, 0, 0, 1};
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
);
3371 test_VertexAttribs4ubvNV(generic_func func
)
3373 PFNGLVERTEXATTRIBS4UBVNVPROC vertexAttribs4ubvNV
= (PFNGLVERTEXATTRIBS4UBVNVPROC
) func
;
3374 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
3376 const GLubyte v
[4] = {255, 0, 255, 0};
3377 const GLubyte def
[4] = {0, 0, 0, 255};
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
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
);
3392 test_StencilFuncSeparateATI(generic_func func
)
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
||
3418 test_StencilFuncSeparate(generic_func func
)
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
||
3436 frontMask
== 0xa || /* might be 0xff or ~0 */
3444 test_StencilOpSeparate(generic_func func
)
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
)
3470 test_StencilMaskSeparate(generic_func func
)
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 ||
3487 * The following file is auto-generated with Python.
3489 #include "getproclist.h"
3494 extension_supported(const char *haystack
, const char *needle
)
3496 const char *p
= strstr(haystack
, needle
);
3498 /* found string, make sure next char is space or zero */
3499 const int len
= strlen(needle
);
3500 if (p
[len
] == ' ' || p
[len
] == 0)
3510 /* Run all the known extension function tests, if the extension is supported.
3511 * Return a count of how many failed.
3514 check_functions( const char *extensions
)
3516 struct name_test_pair
*entry
;
3517 int failures
= 0, passes
= 0, untested
= 0;
3518 int totalFail
= 0, totalPass
= 0, totalUntested
= 0, totalUnsupported
= 0;
3520 const char *version
= (const char *) glGetString(GL_VERSION
);
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.
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])
3545 else if (entry
->name
[1] == '2') {
3546 if (version
[0] == '2' &&
3547 version
[1] == '.' &&
3548 version
[2] >= entry
->name
[3])
3554 /* check if the named extension is available */
3555 doTests
= extension_supported(extensions
, entry
->name
+1);
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.
3564 printf("Testing %s functions\n", entry
->name
+ 1);
3566 /* Each time we hit a title function, reset the function
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.
3578 generic_func funcPtr
= (generic_func
) glXGetProcAddressARB((const GLubyte
*) entry
->name
);
3582 printf(" Validating %s:", entry
->name
);
3583 b
= (*entry
->test
)(funcPtr
);
3590 printf(" FAIL!!!\n");
3601 printf(" glXGetProcAddress(%s) failed!\n", entry
->name
);
3607 /* Here, we have a function that belongs to a group that
3608 * is known to be unsupported.
3613 /* Make sure a poor test case doesn't leave any lingering
3616 CheckGLError(__LINE__
, __FILE__
, __FUNCTION__
);
3618 if (doTests
&& (!(entry
+1)->name
|| (entry
+1)->name
[0] == '-')) {
3620 printf(" %d failed.\n", failures
);
3623 printf(" %d passed.\n", passes
);
3626 printf(" %d untested.\n", untested
);
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
);
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
3648 print_screen_info(Display
*dpy
, int scrnum
, Bool allowDirect
)
3651 int attribSingle
[] = {
3656 GLX_STENCIL_SIZE
, 1,
3658 int attribDouble
[] = {
3663 GLX_STENCIL_SIZE
, 1,
3667 XSetWindowAttributes attr
;
3671 XVisualInfo
*visinfo
;
3672 int width
= 100, height
= 100;
3675 root
= RootWindow(dpy
, scrnum
);
3677 visinfo
= glXChooseVisual(dpy
, scrnum
, attribSingle
);
3679 visinfo
= glXChooseVisual(dpy
, scrnum
, attribDouble
);
3681 fprintf(stderr
, "Error: couldn't find RGB GLX visual\n");
3682 return ERROR_NO_VISUAL
;
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
);
3695 ctx
= glXCreateContext( dpy
, visinfo
, NULL
, allowDirect
);
3697 fprintf(stderr
, "Error: glXCreateContext failed\n");
3698 XDestroyWindow(dpy
, win
);
3699 return ERROR_NO_CONTEXT
;
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
;
3709 failures
= check_functions( (const char *) glGetString(GL_EXTENSIONS
) );
3710 glXDestroyContext(dpy
, ctx
);
3711 XDestroyWindow(dpy
, win
);
3713 return (failures
== 0 ? ERROR_NONE
: ERROR_FAILED
);
3717 main(int argc
, char *argv
[])
3719 char *displayName
= NULL
;
3723 dpy
= XOpenDisplay(displayName
);
3725 fprintf(stderr
, "Error: unable to open display %s\n", displayName
);
3729 returnCode
= print_screen_info(dpy
, 0, GL_TRUE
);