2 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * Test that glXGetProcAddress works.
26 #define GLX_GLXEXT_PROTOTYPES
29 #include <X11/Xutil.h>
38 typedef void (*generic_func
)();
40 #define EQUAL(X, Y) (fabs((X) - (Y)) < 0.001)
43 * The following functions are used to check that the named OpenGL function
44 * actually does what it's supposed to do.
45 * The naming of these functions is signficant. The getprocaddress.py script
46 * scans this file and extracts these function names.
51 test_ActiveTextureARB(generic_func func
)
53 PFNGLACTIVETEXTUREARBPROC activeTexture
= (PFNGLACTIVETEXTUREARBPROC
) func
;
56 (*activeTexture
)(GL_TEXTURE1_ARB
);
57 glGetIntegerv(GL_ACTIVE_TEXTURE_ARB
, &t
);
58 pass
= (t
== GL_TEXTURE1_ARB
);
59 (*activeTexture
)(GL_TEXTURE0_ARB
); /* restore default */
65 test_SecondaryColor3fEXT(generic_func func
)
67 PFNGLSECONDARYCOLOR3FEXTPROC secColor3f
= (PFNGLSECONDARYCOLOR3FEXTPROC
) func
;
70 (*secColor3f
)(1.0, 1.0, 0.0);
71 glGetFloatv(GL_CURRENT_SECONDARY_COLOR_EXT
, color
);
72 pass
= (color
[0] == 1.0 && color
[1] == 1.0 && color
[2] == 0.0);
73 (*secColor3f
)(0.0, 0.0, 0.0); /* restore default */
79 test_ActiveStencilFaceEXT(generic_func func
)
81 PFNGLACTIVESTENCILFACEEXTPROC activeFace
= (PFNGLACTIVESTENCILFACEEXTPROC
) func
;
84 (*activeFace
)(GL_BACK
);
85 glGetIntegerv(GL_ACTIVE_STENCIL_FACE_EXT
, &face
);
86 pass
= (face
== GL_BACK
);
87 (*activeFace
)(GL_FRONT
); /* restore default */
93 test_VertexAttrib1fvARB(generic_func func
)
95 PFNGLVERTEXATTRIB1FVARBPROC vertexAttrib1fvARB
= (PFNGLVERTEXATTRIB1FVARBPROC
) func
;
96 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
98 const GLfloat v
[1] = {25.0};
99 const GLfloat def
[1] = {0};
102 (*vertexAttrib1fvARB
)(6, v
);
103 (*getVertexAttribfvARB
)(6, GL_CURRENT_VERTEX_ATTRIB_ARB
, res
);
104 pass
= (res
[0] == 25.0 && res
[1] == 0.0 && res
[2] == 0.0 && res
[3] == 1.0);
105 (*vertexAttrib1fvARB
)(6, def
);
110 test_VertexAttrib4NubvARB(generic_func func
)
112 PFNGLVERTEXATTRIB4NUBVARBPROC vertexAttrib4NubvARB
= (PFNGLVERTEXATTRIB4NUBVARBPROC
) func
;
113 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
115 const GLubyte v
[4] = {255, 0, 255, 0};
116 const GLubyte def
[4] = {0, 0, 0, 255};
119 (*vertexAttrib4NubvARB
)(6, v
);
120 (*getVertexAttribfvARB
)(6, GL_CURRENT_VERTEX_ATTRIB_ARB
, res
);
121 pass
= (res
[0] == 1.0 && res
[1] == 0.0 && res
[2] == 1.0 && res
[3] == 0.0);
122 (*vertexAttrib4NubvARB
)(6, def
);
128 test_VertexAttrib4NuivARB(generic_func func
)
130 PFNGLVERTEXATTRIB4NUIVARBPROC vertexAttrib4NuivARB
= (PFNGLVERTEXATTRIB4NUIVARBPROC
) func
;
131 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
133 const GLuint v
[4] = {0xffffffff, 0, 0xffffffff, 0};
134 const GLuint def
[4] = {0, 0, 0, 0xffffffff};
137 (*vertexAttrib4NuivARB
)(6, v
);
138 (*getVertexAttribfvARB
)(6, GL_CURRENT_VERTEX_ATTRIB_ARB
, res
);
139 pass
= (EQUAL(res
[0], 1.0) && EQUAL(res
[1], 0.0) && EQUAL(res
[2], 1.0) && EQUAL(res
[3], 0.0));
140 (*vertexAttrib4NuivARB
)(6, def
);
146 test_VertexAttrib4ivARB(generic_func func
)
148 PFNGLVERTEXATTRIB4IVARBPROC vertexAttrib4ivARB
= (PFNGLVERTEXATTRIB4IVARBPROC
) func
;
149 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
151 const GLint v
[4] = {1, 2, -3, 4};
152 const GLint def
[4] = {0, 0, 0, 1};
155 (*vertexAttrib4ivARB
)(6, v
);
156 (*getVertexAttribfvARB
)(6, GL_CURRENT_VERTEX_ATTRIB_ARB
, res
);
157 pass
= (EQUAL(res
[0], 1.0) && EQUAL(res
[1], 2.0) && EQUAL(res
[2], -3.0) && EQUAL(res
[3], 4.0));
158 (*vertexAttrib4ivARB
)(6, def
);
164 test_VertexAttrib4NsvARB(generic_func func
)
166 PFNGLVERTEXATTRIB4NSVARBPROC vertexAttrib4NsvARB
= (PFNGLVERTEXATTRIB4NSVARBPROC
) func
;
167 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
169 const GLshort v
[4] = {0, 32767, 32767, 0};
170 const GLshort def
[4] = {0, 0, 0, 32767};
173 (*vertexAttrib4NsvARB
)(6, v
);
174 (*getVertexAttribfvARB
)(6, GL_CURRENT_VERTEX_ATTRIB_ARB
, res
);
175 pass
= (EQUAL(res
[0], 0.0) && EQUAL(res
[1], 1.0) && EQUAL(res
[2], 1.0) && EQUAL(res
[3], 0.0));
176 (*vertexAttrib4NsvARB
)(6, def
);
182 test_VertexAttrib4NusvARB(generic_func func
)
184 PFNGLVERTEXATTRIB4NUSVARBPROC vertexAttrib4NusvARB
= (PFNGLVERTEXATTRIB4NUSVARBPROC
) func
;
185 PFNGLGETVERTEXATTRIBFVARBPROC getVertexAttribfvARB
= (PFNGLGETVERTEXATTRIBFVARBPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvARB");
187 const GLushort v
[4] = {0xffff, 0, 0xffff, 0};
188 const GLushort def
[4] = {0, 0, 0, 0xffff};
191 (*vertexAttrib4NusvARB
)(6, v
);
192 (*getVertexAttribfvARB
)(6, GL_CURRENT_VERTEX_ATTRIB_ARB
, res
);
193 pass
= (EQUAL(res
[0], 1.0) && EQUAL(res
[1], 0.0) && EQUAL(res
[2], 1.0) && EQUAL(res
[3], 0.0));
194 (*vertexAttrib4NusvARB
)(6, def
);
200 test_VertexAttrib4ubNV(generic_func func
)
202 PFNGLVERTEXATTRIB4UBNVPROC vertexAttrib4ubNV
= (PFNGLVERTEXATTRIB4UBNVPROC
) func
;
203 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
205 const GLubyte v
[4] = {255, 0, 255, 0};
206 const GLubyte def
[4] = {0, 0, 0, 255};
209 (*vertexAttrib4ubNV
)(6, v
[0], v
[1], v
[2], v
[3]);
210 (*getVertexAttribfvNV
)(6, GL_CURRENT_ATTRIB_NV
, res
);
211 pass
= (res
[0] == 1.0 && res
[1] == 0.0 && res
[2] == 1.0 && res
[3] == 0.0);
212 (*vertexAttrib4ubNV
)(6, def
[0], def
[1], def
[2], def
[3]);
218 test_VertexAttrib2sNV(generic_func func
)
220 PFNGLVERTEXATTRIB2SNVPROC vertexAttrib2sNV
= (PFNGLVERTEXATTRIB2SNVPROC
) func
;
221 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
223 const GLshort v
[2] = {2, -4,};
224 const GLshort def
[2] = {0, 0};
227 (*vertexAttrib2sNV
)(6, v
[0], v
[1]);
228 (*getVertexAttribfvNV
)(6, GL_CURRENT_ATTRIB_NV
, res
);
229 pass
= (EQUAL(res
[0], 2) && EQUAL(res
[1], -4) && EQUAL(res
[2], 0) && res
[3] == 1.0);
230 (*vertexAttrib2sNV
)(6, def
[0], def
[1]);
236 test_VertexAttrib3fNV(generic_func func
)
238 PFNGLVERTEXATTRIB3FNVPROC vertexAttrib3fNV
= (PFNGLVERTEXATTRIB3FNVPROC
) func
;
239 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
241 const GLfloat v
[3] = {0.2, 0.4, 0.8};
242 const GLfloat def
[3] = {0, 0, 0};
245 (*vertexAttrib3fNV
)(6, v
[0], v
[1], v
[2]);
246 (*getVertexAttribfvNV
)(6, GL_CURRENT_ATTRIB_NV
, res
);
247 pass
= (EQUAL(res
[0], 0.2) && EQUAL(res
[1], 0.4) && EQUAL(res
[2], 0.8) && res
[3] == 1.0);
248 (*vertexAttrib3fNV
)(6, def
[0], def
[1], def
[2]);
254 test_VertexAttrib4dvNV(generic_func func
)
256 PFNGLVERTEXATTRIB4DVNVPROC vertexAttrib4dvNV
= (PFNGLVERTEXATTRIB4DVNVPROC
) func
;
257 PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV
= (PFNGLGETVERTEXATTRIBFVNVPROC
) glXGetProcAddressARB((const GLubyte
*) "glGetVertexAttribfvNV");
259 const GLdouble v
[4] = {0.2, 0.4, 0.8, 1.2};
260 const GLdouble def
[4] = {0, 0, 0, 1};
263 (*vertexAttrib4dvNV
)(6, v
);
264 (*getVertexAttribfvNV
)(6, GL_CURRENT_ATTRIB_NV
, res
);
265 pass
= (EQUAL(res
[0], 0.2) && EQUAL(res
[1], 0.4) && EQUAL(res
[2], 0.8) && EQUAL(res
[3], 1.2));
266 (*vertexAttrib4dvNV
)(6, def
);
272 test_StencilFuncSeparate(generic_func func
)
274 #ifdef GL_VERSION_2_0
275 PFNGLSTENCILFUNCSEPARATEPROC stencilFuncSeparate
= (PFNGLSTENCILFUNCSEPARATEPROC
) func
;
276 GLint frontFunc
, backFunc
;
277 GLint frontRef
, backRef
;
278 GLint frontMask
, backMask
;
279 (*stencilFuncSeparate
)(GL_BACK
, GL_GREATER
, 2, 0xa);
280 glGetIntegerv(GL_STENCIL_FUNC
, &frontFunc
);
281 glGetIntegerv(GL_STENCIL_BACK_FUNC
, &backFunc
);
282 glGetIntegerv(GL_STENCIL_REF
, &frontRef
);
283 glGetIntegerv(GL_STENCIL_BACK_REF
, &backRef
);
284 glGetIntegerv(GL_STENCIL_VALUE_MASK
, &frontMask
);
285 glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK
, &backMask
);
286 if (frontFunc
!= GL_ALWAYS
||
287 backFunc
!= GL_GREATER
||
290 frontMask
== 0xa || /* might be 0xff or ~0 */
298 test_StencilOpSeparate(generic_func func
)
300 #ifdef GL_VERSION_2_0
301 PFNGLSTENCILOPSEPARATEPROC stencilOpSeparate
= (PFNGLSTENCILOPSEPARATEPROC
) func
;
302 GLint frontFail
, backFail
;
303 GLint frontZFail
, backZFail
;
304 GLint frontZPass
, backZPass
;
305 (*stencilOpSeparate
)(GL_BACK
, GL_INCR
, GL_DECR
, GL_INVERT
);
306 glGetIntegerv(GL_STENCIL_FAIL
, &frontFail
);
307 glGetIntegerv(GL_STENCIL_BACK_FAIL
, &backFail
);
308 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL
, &frontZFail
);
309 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL
, &backZFail
);
310 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS
, &frontZPass
);
311 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS
, &backZPass
);
312 if (frontFail
!= GL_KEEP
||
313 backFail
!= GL_INCR
||
314 frontZFail
!= GL_KEEP
||
315 backZFail
!= GL_DECR
||
316 frontZPass
!= GL_KEEP
||
317 backZPass
!= GL_INVERT
)
324 test_StencilMaskSeparate(generic_func func
)
326 #ifdef GL_VERSION_2_0
327 PFNGLSTENCILMASKSEPARATEPROC stencilMaskSeparate
= (PFNGLSTENCILMASKSEPARATEPROC
) func
;
328 GLint frontMask
, backMask
;
329 (*stencilMaskSeparate
)(GL_BACK
, 0x1b);
330 glGetIntegerv(GL_STENCIL_WRITEMASK
, &frontMask
);
331 glGetIntegerv(GL_STENCIL_BACK_WRITEMASK
, &backMask
);
332 if (frontMask
== 0x1b ||
341 * The following file is auto-generated with Python.
343 #include "getproclist.h"
348 extension_supported(const char *haystack
, const char *needle
)
350 const char *p
= strstr(haystack
, needle
);
352 /* found string, make sure next char is space or zero */
353 const int len
= strlen(needle
);
354 if (p
[len
] == ' ' || p
[len
] == 0)
365 check_functions( const char *extensions
)
367 struct name_test_pair
*entry
;
368 int failures
= 0, passes
= 0;
369 int totalFail
= 0, totalPass
= 0;
372 for (entry
= functions
; entry
->name
; entry
++) {
373 if (entry
->name
[0] == '-') {
374 const char *version
= (const char *) glGetString(GL_VERSION
);
375 if (entry
->name
[1] == '1') {
376 /* check GL version 1.x */
377 if (version
[0] == '1' &&
379 version
[2] >= entry
->name
[3])
384 else if (entry
->name
[1] == '2') {
385 if (version
[0] == '2' &&
387 version
[2] >= entry
->name
[3])
393 /* check if the named extension is available */
394 doTests
= extension_supported(extensions
, entry
->name
+1);
397 printf("Testing %s functions\n", entry
->name
+ 1);
398 totalFail
+= failures
;
404 generic_func funcPtr
= (generic_func
) glXGetProcAddressARB((const GLubyte
*) entry
->name
);
408 printf(" Validating %s:", entry
->name
);
409 b
= (*entry
->test
)(funcPtr
);
415 printf(" FAIL!!!\n");
424 printf(" glXGetProcAddress(%s) failed!\n", entry
->name
);
429 if (doTests
&& (!(entry
+1)->name
|| (entry
+1)->name
[0] == '-')) {
431 printf(" %d failed.\n", failures
);
434 printf(" %d passed.\n", passes
);
438 totalFail
+= failures
;
441 printf("-----------------------------\n");
442 printf("Total: %d pass %d fail\n", totalPass
, totalFail
);
448 print_screen_info(Display
*dpy
, int scrnum
, Bool allowDirect
)
451 int attribSingle
[] = {
458 int attribDouble
[] = {
467 XSetWindowAttributes attr
;
471 XVisualInfo
*visinfo
;
472 int width
= 100, height
= 100;
474 root
= RootWindow(dpy
, scrnum
);
476 visinfo
= glXChooseVisual(dpy
, scrnum
, attribSingle
);
478 visinfo
= glXChooseVisual(dpy
, scrnum
, attribDouble
);
480 fprintf(stderr
, "Error: couldn't find RGB GLX visual\n");
485 attr
.background_pixel
= 0;
486 attr
.border_pixel
= 0;
487 attr
.colormap
= XCreateColormap(dpy
, root
, visinfo
->visual
, AllocNone
);
488 attr
.event_mask
= StructureNotifyMask
| ExposureMask
;
489 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
;
490 win
= XCreateWindow(dpy
, root
, 0, 0, width
, height
,
491 0, visinfo
->depth
, InputOutput
,
492 visinfo
->visual
, mask
, &attr
);
494 ctx
= glXCreateContext( dpy
, visinfo
, NULL
, allowDirect
);
496 fprintf(stderr
, "Error: glXCreateContext failed\n");
497 XDestroyWindow(dpy
, win
);
501 if (glXMakeCurrent(dpy
, win
, ctx
)) {
502 check_functions( (const char *) glGetString(GL_EXTENSIONS
) );
505 fprintf(stderr
, "Error: glXMakeCurrent failed\n");
508 glXDestroyContext(dpy
, ctx
);
509 XDestroyWindow(dpy
, win
);
514 main(int argc
, char *argv
[])
516 char *displayName
= NULL
;
519 dpy
= XOpenDisplay(displayName
);
521 fprintf(stderr
, "Error: unable to open display %s\n", displayName
);
525 print_screen_info(dpy
, 0, GL_TRUE
);