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