Split dispatch sanity's validate_function test into two
[mesa.git] / src / mesa / main / tests / dispatch_sanity.cpp
1 /*
2 * Copyright © 2012 Intel Corporation
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 (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 /**
25 * \name dispatch_sanity.cpp
26 *
27 * Verify that only set of functions that should be available in a particular
28 * API are available in that API.
29 *
30 * The list of expected functions originally came from the functions set by
31 * api_exec_es2.c. This file no longer exists in Mesa (but api_exec_es1.c was
32 * still generated at the time this test was written). It was the generated
33 * file that configured the dispatch table for ES2 contexts. This test
34 * verifies that all of the functions set by the old api_exec_es2.c (with the
35 * recent addition of VAO functions) are set in the dispatch table and
36 * everything else is a NOP.
37 *
38 * When adding extensions that add new functions, this test will need to be
39 * modified to expect dispatch functions for the new extension functions.
40 */
41
42 extern "C" {
43 #include "main/mfeatures.h"
44 }
45
46 #include <gtest/gtest.h>
47
48 extern "C" {
49 #include "GL/gl.h"
50 #include "GL/glext.h"
51 #include "main/compiler.h"
52 #include "main/api_exec.h"
53 #include "main/context.h"
54 #include "main/remap.h"
55 #include "glapi/glapi.h"
56 #include "drivers/common/driverfuncs.h"
57
58 #include "swrast/swrast.h"
59 #include "vbo/vbo.h"
60 #include "tnl/tnl.h"
61 #include "swrast_setup/swrast_setup.h"
62
63 #ifndef GLAPIENTRYP
64 #define GLAPIENTRYP GL_APIENTRYP
65 #endif
66
67 #include "main/dispatch.h"
68 }
69
70 struct function {
71 const char *name;
72 int offset;
73 };
74
75 extern const struct function gles2_functions_possible[];
76
77 #if FEATURE_ES1
78 extern "C" _glapi_table *_mesa_create_exec_table_es1(void);
79 extern const struct function gles11_functions_possible[];
80 #endif /* FEATURE_ES1 */
81
82 class DispatchSanity_test : public ::testing::Test {
83 public:
84 virtual void SetUp();
85
86 struct gl_config visual;
87 struct dd_function_table driver_functions;
88 struct gl_context share_list;
89 struct gl_context ctx;
90 };
91
92 void
93 DispatchSanity_test::SetUp()
94 {
95 memset(&visual, 0, sizeof(visual));
96 memset(&driver_functions, 0, sizeof(driver_functions));
97 memset(&share_list, 0, sizeof(share_list));
98 memset(&ctx, 0, sizeof(ctx));
99
100 _mesa_init_driver_functions(&driver_functions);
101 }
102
103 static const char *
104 offset_to_proc_name_safe(unsigned offset)
105 {
106 const char *name = _glapi_get_proc_name(offset);
107 return name ? name : "???";
108 }
109
110 /* Scan through the dispatch table and check that all the functions in
111 * _glapi_proc *table exist. When found, set their pointers in the table
112 * to _mesa_generic_nop. */
113 static void
114 validate_functions(_glapi_proc *table, const struct function *function_table)
115 {
116 for (unsigned i = 0; function_table[i].name != NULL; i++) {
117 const int offset = (function_table[i].offset != -1)
118 ? function_table[i].offset
119 : _glapi_get_proc_offset(function_table[i].name);
120
121 ASSERT_NE(-1, offset)
122 << "Function: " << function_table[i].name;
123 ASSERT_EQ(offset,
124 _glapi_get_proc_offset(function_table[i].name))
125 << "Function: " << function_table[i].name;
126 EXPECT_NE((_glapi_proc) _mesa_generic_nop, table[offset])
127 << "Function: " << function_table[i].name
128 << " at offset " << offset;
129
130 table[offset] = (_glapi_proc) _mesa_generic_nop;
131 }
132 }
133
134 /* Scan through the table and ensure that there is nothing except
135 * _mesa_generic_nop (as set by validate_functions(). */
136 static void
137 validate_nops(const _glapi_proc *table)
138 {
139 const unsigned size = _glapi_get_dispatch_table_size();
140 for (unsigned i = 0; i < size; i++) {
141 EXPECT_EQ((_glapi_proc) _mesa_generic_nop, table[i])
142 << "i = " << i << " (" << offset_to_proc_name_safe(i) << ")";
143 }
144 }
145
146 #if FEATURE_ES1
147 TEST_F(DispatchSanity_test, GLES11)
148 {
149 _glapi_proc *exec = (_glapi_proc *) _mesa_create_exec_table_es1();
150 validate_functions(exec, gles11_functions_possible);
151 validate_nops(exec);
152 }
153 #endif /* FEATURE_ES1 */
154
155 TEST_F(DispatchSanity_test, GLES2)
156 {
157 ctx.Version = 20;
158 _mesa_initialize_context(&ctx,
159 API_OPENGLES2, //api,
160 &visual,
161 NULL, //&share_list,
162 &driver_functions);
163
164 _swrast_CreateContext(&ctx);
165 _vbo_CreateContext(&ctx);
166 _tnl_CreateContext(&ctx);
167 _swsetup_CreateContext(&ctx);
168
169 validate_functions((_glapi_proc *) ctx.Exec, gles2_functions_possible);
170 validate_nops((_glapi_proc *) ctx.Exec);
171 }
172
173 #if FEATURE_ES1
174 const struct function gles11_functions_possible[] = {
175 { "glActiveTexture", _gloffset_ActiveTextureARB },
176 { "glAlphaFunc", _gloffset_AlphaFunc },
177 { "glAlphaFuncx", -1 },
178 { "glBindBuffer", -1 },
179 { "glBindFramebufferOES", -1 },
180 { "glBindRenderbufferOES", -1 },
181 { "glBindTexture", _gloffset_BindTexture },
182 { "glBlendEquationOES", _gloffset_BlendEquation },
183 { "glBlendEquationSeparateOES", -1 },
184 { "glBlendFunc", _gloffset_BlendFunc },
185 { "glBlendFuncSeparateOES", -1 },
186 { "glBufferData", -1 },
187 { "glBufferSubData", -1 },
188 { "glCheckFramebufferStatusOES", -1 },
189 { "glClear", _gloffset_Clear },
190 { "glClearColor", _gloffset_ClearColor },
191 { "glClearColorx", -1 },
192 { "glClearDepthf", -1 },
193 { "glClearDepthx", -1 },
194 { "glClearStencil", _gloffset_ClearStencil },
195 { "glClientActiveTexture", _gloffset_ClientActiveTextureARB },
196 { "glClipPlanef", -1 },
197 { "glClipPlanex", -1 },
198 { "glColor4f", _gloffset_Color4f },
199 { "glColor4ub", _gloffset_Color4ub },
200 { "glColor4x", -1 },
201 { "glColorMask", _gloffset_ColorMask },
202 { "glColorPointer", _gloffset_ColorPointer },
203 { "glCompressedTexImage2D", -1 },
204 { "glCompressedTexSubImage2D", -1 },
205 { "glCopyTexImage2D", _gloffset_CopyTexImage2D },
206 { "glCopyTexSubImage2D", _gloffset_CopyTexSubImage2D },
207 { "glCullFace", _gloffset_CullFace },
208 { "glDeleteBuffers", -1 },
209 { "glDeleteFramebuffersOES", -1 },
210 { "glDeleteRenderbuffersOES", -1 },
211 { "glDeleteTextures", _gloffset_DeleteTextures },
212 { "glDepthFunc", _gloffset_DepthFunc },
213 { "glDepthMask", _gloffset_DepthMask },
214 { "glDepthRangef", -1 },
215 { "glDepthRangex", -1 },
216 { "glDisable", _gloffset_Disable },
217 { "glDisableClientState", _gloffset_DisableClientState },
218 { "glDrawArrays", _gloffset_DrawArrays },
219 { "glDrawElements", _gloffset_DrawElements },
220 { "glDrawTexfOES", -1 },
221 { "glDrawTexfvOES", -1 },
222 { "glDrawTexiOES", -1 },
223 { "glDrawTexivOES", -1 },
224 { "glDrawTexsOES", -1 },
225 { "glDrawTexsvOES", -1 },
226 { "glDrawTexxOES", -1 },
227 { "glDrawTexxvOES", -1 },
228 { "glEGLImageTargetRenderbufferStorageOES", -1 },
229 { "glEGLImageTargetTexture2DOES", -1 },
230 { "glEnable", _gloffset_Enable },
231 { "glEnableClientState", _gloffset_EnableClientState },
232 { "glFinish", _gloffset_Finish },
233 { "glFlush", _gloffset_Flush },
234 { "glFogf", _gloffset_Fogf },
235 { "glFogfv", _gloffset_Fogfv },
236 { "glFogx", -1 },
237 { "glFogxv", -1 },
238 { "glFramebufferRenderbufferOES", -1 },
239 { "glFramebufferTexture2DOES", -1 },
240 { "glFrontFace", _gloffset_FrontFace },
241 { "glFrustumf", -1 },
242 { "glFrustumx", -1 },
243 { "glGenBuffers", -1 },
244 { "glGenFramebuffersOES", -1 },
245 { "glGenRenderbuffersOES", -1 },
246 { "glGenTextures", _gloffset_GenTextures },
247 { "glGenerateMipmapOES", -1 },
248 { "glGetBooleanv", _gloffset_GetBooleanv },
249 { "glGetBufferParameteriv", -1 },
250 { "glGetBufferPointervOES", -1 },
251 { "glGetClipPlanef", -1 },
252 { "glGetClipPlanex", -1 },
253 { "glGetError", _gloffset_GetError },
254 { "glGetFixedv", -1 },
255 { "glGetFloatv", _gloffset_GetFloatv },
256 { "glGetFramebufferAttachmentParameterivOES", -1 },
257 { "glGetIntegerv", _gloffset_GetIntegerv },
258 { "glGetLightfv", _gloffset_GetLightfv },
259 { "glGetLightxv", -1 },
260 { "glGetMaterialfv", _gloffset_GetMaterialfv },
261 { "glGetMaterialxv", -1 },
262 { "glGetPointerv", _gloffset_GetPointerv },
263 { "glGetRenderbufferParameterivOES", -1 },
264 { "glGetString", _gloffset_GetString },
265 { "glGetTexEnvfv", _gloffset_GetTexEnvfv },
266 { "glGetTexEnviv", _gloffset_GetTexEnviv },
267 { "glGetTexEnvxv", -1 },
268 { "glGetTexGenfvOES", _gloffset_GetTexGenfv },
269 { "glGetTexGenivOES", _gloffset_GetTexGeniv },
270 { "glGetTexGenxvOES", -1 },
271 { "glGetTexParameterfv", _gloffset_GetTexParameterfv },
272 { "glGetTexParameteriv", _gloffset_GetTexParameteriv },
273 { "glGetTexParameterxv", -1 },
274 { "glHint", _gloffset_Hint },
275 { "glIsBuffer", -1 },
276 { "glIsEnabled", _gloffset_IsEnabled },
277 { "glIsFramebufferOES", -1 },
278 { "glIsRenderbufferOES", -1 },
279 { "glIsTexture", _gloffset_IsTexture },
280 { "glLightModelf", _gloffset_LightModelf },
281 { "glLightModelfv", _gloffset_LightModelfv },
282 { "glLightModelx", -1 },
283 { "glLightModelxv", -1 },
284 { "glLightf", _gloffset_Lightf },
285 { "glLightfv", _gloffset_Lightfv },
286 { "glLightx", -1 },
287 { "glLightxv", -1 },
288 { "glLineWidth", _gloffset_LineWidth },
289 { "glLineWidthx", -1 },
290 { "glLoadIdentity", _gloffset_LoadIdentity },
291 { "glLoadMatrixf", _gloffset_LoadMatrixf },
292 { "glLoadMatrixx", -1 },
293 { "glLogicOp", _gloffset_LogicOp },
294 { "glMapBufferOES", -1 },
295 { "glMaterialf", _gloffset_Materialf },
296 { "glMaterialfv", _gloffset_Materialfv },
297 { "glMaterialx", -1 },
298 { "glMaterialxv", -1 },
299 { "glMatrixMode", _gloffset_MatrixMode },
300 { "glMultMatrixf", _gloffset_MultMatrixf },
301 { "glMultMatrixx", -1 },
302 { "glMultiDrawArraysEXT", -1 },
303 { "glMultiDrawElementsEXT", -1 },
304 { "glMultiTexCoord4f", _gloffset_MultiTexCoord4fARB },
305 { "glMultiTexCoord4x", -1 },
306 { "glNormal3f", _gloffset_Normal3f },
307 { "glNormal3x", -1 },
308 { "glNormalPointer", _gloffset_NormalPointer },
309 { "glOrthof", -1 },
310 { "glOrthox", -1 },
311 { "glPixelStorei", _gloffset_PixelStorei },
312 { "glPointParameterf", -1 },
313 { "glPointParameterfv", -1 },
314 { "glPointParameterx", -1 },
315 { "glPointParameterxv", -1 },
316 { "glPointSize", _gloffset_PointSize },
317 { "glPointSizePointerOES", -1 },
318 { "glPointSizex", -1 },
319 { "glPolygonOffset", _gloffset_PolygonOffset },
320 { "glPolygonOffsetx", -1 },
321 { "glPopMatrix", _gloffset_PopMatrix },
322 { "glPushMatrix", _gloffset_PushMatrix },
323 { "glQueryMatrixxOES", -1 },
324 { "glReadPixels", _gloffset_ReadPixels },
325 { "glRenderbufferStorageOES", -1 },
326 { "glRotatef", _gloffset_Rotatef },
327 { "glRotatex", -1 },
328 { "glSampleCoverage", -1 },
329 { "glSampleCoveragex", -1 },
330 { "glScalef", _gloffset_Scalef },
331 { "glScalex", -1 },
332 { "glScissor", _gloffset_Scissor },
333 { "glShadeModel", _gloffset_ShadeModel },
334 { "glStencilFunc", _gloffset_StencilFunc },
335 { "glStencilMask", _gloffset_StencilMask },
336 { "glStencilOp", _gloffset_StencilOp },
337 { "glTexCoordPointer", _gloffset_TexCoordPointer },
338 { "glTexEnvf", _gloffset_TexEnvf },
339 { "glTexEnvfv", _gloffset_TexEnvfv },
340 { "glTexEnvi", _gloffset_TexEnvi },
341 { "glTexEnviv", _gloffset_TexEnviv },
342 { "glTexEnvx", -1 },
343 { "glTexEnvxv", -1 },
344 { "glTexGenfOES", _gloffset_TexGenf },
345 { "glTexGenfvOES", _gloffset_TexGenfv },
346 { "glTexGeniOES", _gloffset_TexGeni },
347 { "glTexGenivOES", _gloffset_TexGeniv },
348 { "glTexGenxOES", -1 },
349 { "glTexGenxvOES", -1 },
350 { "glTexImage2D", _gloffset_TexImage2D },
351 { "glTexParameterf", _gloffset_TexParameterf },
352 { "glTexParameterfv", _gloffset_TexParameterfv },
353 { "glTexParameteri", _gloffset_TexParameteri },
354 { "glTexParameteriv", _gloffset_TexParameteriv },
355 { "glTexParameterx", -1 },
356 { "glTexParameterxv", -1 },
357 { "glTexSubImage2D", _gloffset_TexSubImage2D },
358 { "glTranslatef", _gloffset_Translatef },
359 { "glTranslatex", -1 },
360 { "glUnmapBufferOES", -1 },
361 { "glVertexPointer", _gloffset_VertexPointer },
362 { "glViewport", _gloffset_Viewport },
363 { NULL, -1 }
364 };
365 #endif /* FEATURE_ES1 */
366
367 const struct function gles2_functions_possible[] = {
368 { "glActiveTexture", _gloffset_ActiveTextureARB },
369 { "glAttachShader", -1 },
370 { "glBindAttribLocation", -1 },
371 { "glBindBuffer", -1 },
372 { "glBindFramebuffer", -1 },
373 { "glBindRenderbuffer", -1 },
374 { "glBindTexture", _gloffset_BindTexture },
375 { "glBindVertexArrayOES", -1 },
376 { "glBlendColor", _gloffset_BlendColor },
377 { "glBlendEquation", _gloffset_BlendEquation },
378 { "glBlendEquationSeparate", -1 },
379 { "glBlendFunc", _gloffset_BlendFunc },
380 { "glBlendFuncSeparate", -1 },
381 { "glBufferData", -1 },
382 { "glBufferSubData", -1 },
383 { "glCheckFramebufferStatus", -1 },
384 { "glClear", _gloffset_Clear },
385 { "glClearColor", _gloffset_ClearColor },
386 { "glClearDepthf", -1 },
387 { "glClearStencil", _gloffset_ClearStencil },
388 { "glColorMask", _gloffset_ColorMask },
389 { "glCompileShader", -1 },
390 { "glCompressedTexImage2D", -1 },
391 { "glCompressedTexImage3DOES", -1 },
392 { "glCompressedTexSubImage2D", -1 },
393 { "glCompressedTexSubImage3DOES", -1 },
394 { "glCopyTexImage2D", _gloffset_CopyTexImage2D },
395 { "glCopyTexSubImage2D", _gloffset_CopyTexSubImage2D },
396 { "glCopyTexSubImage3DOES", _gloffset_CopyTexSubImage3D },
397 { "glCreateProgram", -1 },
398 { "glCreateShader", -1 },
399 { "glCullFace", _gloffset_CullFace },
400 { "glDeleteBuffers", -1 },
401 { "glDeleteFramebuffers", -1 },
402 { "glDeleteProgram", -1 },
403 { "glDeleteRenderbuffers", -1 },
404 { "glDeleteShader", -1 },
405 { "glDeleteTextures", _gloffset_DeleteTextures },
406 { "glDeleteVertexArraysOES", -1 },
407 { "glDepthFunc", _gloffset_DepthFunc },
408 { "glDepthMask", _gloffset_DepthMask },
409 { "glDepthRangef", -1 },
410 { "glDetachShader", -1 },
411 { "glDisable", _gloffset_Disable },
412 { "glDisableVertexAttribArray", -1 },
413 { "glDrawArrays", _gloffset_DrawArrays },
414 { "glDrawBuffersNV", -1 },
415 { "glDrawElements", _gloffset_DrawElements },
416 { "glEGLImageTargetRenderbufferStorageOES", -1 },
417 { "glEGLImageTargetTexture2DOES", -1 },
418 { "glEnable", _gloffset_Enable },
419 { "glEnableVertexAttribArray", -1 },
420 { "glFinish", _gloffset_Finish },
421 { "glFlush", _gloffset_Flush },
422 { "glFlushMappedBufferRangeEXT", -1 },
423 { "glFramebufferRenderbuffer", -1 },
424 { "glFramebufferTexture2D", -1 },
425 { "glFramebufferTexture3DOES", -1 },
426 { "glFrontFace", _gloffset_FrontFace },
427 { "glGenBuffers", -1 },
428 { "glGenFramebuffers", -1 },
429 { "glGenRenderbuffers", -1 },
430 { "glGenTextures", _gloffset_GenTextures },
431 { "glGenVertexArraysOES", -1 },
432 { "glGenerateMipmap", -1 },
433 { "glGetActiveAttrib", -1 },
434 { "glGetActiveUniform", -1 },
435 { "glGetAttachedShaders", -1 },
436 { "glGetAttribLocation", -1 },
437 { "glGetBooleanv", _gloffset_GetBooleanv },
438 { "glGetBufferParameteriv", -1 },
439 { "glGetBufferPointervOES", -1 },
440 { "glGetError", _gloffset_GetError },
441 { "glGetFloatv", _gloffset_GetFloatv },
442 { "glGetFramebufferAttachmentParameteriv", -1 },
443 { "glGetIntegerv", _gloffset_GetIntegerv },
444 { "glGetProgramInfoLog", -1 },
445 { "glGetProgramiv", -1 },
446 { "glGetRenderbufferParameteriv", -1 },
447 { "glGetShaderInfoLog", -1 },
448 { "glGetShaderPrecisionFormat", -1 },
449 { "glGetShaderSource", -1 },
450 { "glGetShaderiv", -1 },
451 { "glGetString", _gloffset_GetString },
452 { "glGetTexParameterfv", _gloffset_GetTexParameterfv },
453 { "glGetTexParameteriv", _gloffset_GetTexParameteriv },
454 { "glGetUniformLocation", -1 },
455 { "glGetUniformfv", -1 },
456 { "glGetUniformiv", -1 },
457 { "glGetVertexAttribPointerv", -1 },
458 { "glGetVertexAttribfv", -1 },
459 { "glGetVertexAttribiv", -1 },
460 { "glHint", _gloffset_Hint },
461 { "glIsBuffer", -1 },
462 { "glIsEnabled", _gloffset_IsEnabled },
463 { "glIsFramebuffer", -1 },
464 { "glIsProgram", -1 },
465 { "glIsRenderbuffer", -1 },
466 { "glIsShader", -1 },
467 { "glIsTexture", _gloffset_IsTexture },
468 { "glIsVertexArrayOES", -1 },
469 { "glLineWidth", _gloffset_LineWidth },
470 { "glLinkProgram", -1 },
471 { "glMapBufferOES", -1 },
472 { "glMapBufferRangeEXT", -1 },
473 { "glMultiDrawArraysEXT", -1 },
474 { "glMultiDrawElementsEXT", -1 },
475 { "glPixelStorei", _gloffset_PixelStorei },
476 { "glPolygonOffset", _gloffset_PolygonOffset },
477 { "glReadBufferNV", _gloffset_ReadBuffer },
478 { "glReadPixels", _gloffset_ReadPixels },
479 { "glReleaseShaderCompiler", -1 },
480 { "glRenderbufferStorage", -1 },
481 { "glSampleCoverage", -1 },
482 { "glScissor", _gloffset_Scissor },
483 { "glShaderBinary", -1 },
484 { "glShaderSource", -1 },
485 { "glStencilFunc", _gloffset_StencilFunc },
486 { "glStencilFuncSeparate", -1 },
487 { "glStencilMask", _gloffset_StencilMask },
488 { "glStencilMaskSeparate", -1 },
489 { "glStencilOp", _gloffset_StencilOp },
490 { "glStencilOpSeparate", -1 },
491 { "glTexImage2D", _gloffset_TexImage2D },
492 { "glTexImage3DOES", _gloffset_TexImage3D },
493 { "glTexParameterf", _gloffset_TexParameterf },
494 { "glTexParameterfv", _gloffset_TexParameterfv },
495 { "glTexParameteri", _gloffset_TexParameteri },
496 { "glTexParameteriv", _gloffset_TexParameteriv },
497 { "glTexSubImage2D", _gloffset_TexSubImage2D },
498 { "glTexSubImage3DOES", _gloffset_TexSubImage3D },
499 { "glUniform1f", -1 },
500 { "glUniform1fv", -1 },
501 { "glUniform1i", -1 },
502 { "glUniform1iv", -1 },
503 { "glUniform2f", -1 },
504 { "glUniform2fv", -1 },
505 { "glUniform2i", -1 },
506 { "glUniform2iv", -1 },
507 { "glUniform3f", -1 },
508 { "glUniform3fv", -1 },
509 { "glUniform3i", -1 },
510 { "glUniform3iv", -1 },
511 { "glUniform4f", -1 },
512 { "glUniform4fv", -1 },
513 { "glUniform4i", -1 },
514 { "glUniform4iv", -1 },
515 { "glUniformMatrix2fv", -1 },
516 { "glUniformMatrix3fv", -1 },
517 { "glUniformMatrix4fv", -1 },
518 { "glUnmapBufferOES", -1 },
519 { "glUseProgram", -1 },
520 { "glValidateProgram", -1 },
521 { "glVertexAttrib1f", -1 },
522 { "glVertexAttrib1fv", -1 },
523 { "glVertexAttrib2f", -1 },
524 { "glVertexAttrib2fv", -1 },
525 { "glVertexAttrib3f", -1 },
526 { "glVertexAttrib3fv", -1 },
527 { "glVertexAttrib4f", -1 },
528 { "glVertexAttrib4fv", -1 },
529 { "glVertexAttribPointer", -1 },
530 { "glViewport", _gloffset_Viewport },
531 { NULL, -1 }
532 };