mesa: Rewrite the way uniforms are tracked and handled
[mesa.git] / src / mesa / main / uniforms.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
6 * Copyright © 2010 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file uniforms.c
28 * Functions related to GLSL uniform variables.
29 * \author Brian Paul
30 */
31
32 /**
33 * XXX things to do:
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
36 */
37
38 #include "main/glheader.h"
39 #include "main/context.h"
40 #include "main/dispatch.h"
41 #include "main/shaderapi.h"
42 #include "main/shaderobj.h"
43 #include "main/uniforms.h"
44 #include "ir_uniform.h"
45 #include "glsl_types.h"
46
47 /**
48 * Update the vertex/fragment program's TexturesUsed array.
49 *
50 * This needs to be called after glUniform(set sampler var) is called.
51 * A call to glUniform(samplerVar, value) causes a sampler to point to a
52 * particular texture unit. We know the sampler's texture target
53 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
54 * set by glUniform() calls.
55 *
56 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
57 * information to update the prog->TexturesUsed[] values.
58 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
59 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
60 * We'll use that info for state validation before rendering.
61 */
62 void
63 _mesa_update_shader_textures_used(struct gl_program *prog)
64 {
65 GLuint s;
66
67 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
68
69 for (s = 0; s < MAX_SAMPLERS; s++) {
70 if (prog->SamplersUsed & (1 << s)) {
71 GLuint unit = prog->SamplerUnits[s];
72 GLuint tgt = prog->SamplerTargets[s];
73 assert(unit < Elements(prog->TexturesUsed));
74 assert(tgt < NUM_TEXTURE_TARGETS);
75 prog->TexturesUsed[unit] |= (1 << tgt);
76 }
77 }
78 }
79
80 /**
81 * Connect a piece of driver storage with a part of a uniform
82 *
83 * \param uni The uniform with which the storage will be associated
84 * \param element_stride Byte-stride between array elements.
85 * \sa gl_uniform_driver_storage::element_stride.
86 * \param vector_stride Byte-stride between vectors (in a matrix).
87 * \sa gl_uniform_driver_storage::vector_stride.
88 * \param format Conversion from native format to driver format
89 * required by the driver.
90 * \param data Location to dump the data.
91 */
92 void
93 _mesa_uniform_attach_driver_storage(struct gl_uniform_storage *uni,
94 unsigned element_stride,
95 unsigned vector_stride,
96 enum gl_uniform_driver_format format,
97 void *data)
98 {
99 uni->driver_storage = (struct gl_uniform_driver_storage*)
100 realloc(uni->driver_storage,
101 sizeof(struct gl_uniform_driver_storage)
102 * (uni->num_driver_storage + 1));
103
104 uni->driver_storage[uni->num_driver_storage].element_stride = element_stride;
105 uni->driver_storage[uni->num_driver_storage].vector_stride = vector_stride;
106 uni->driver_storage[uni->num_driver_storage].format = (uint8_t) format;
107 uni->driver_storage[uni->num_driver_storage].data = data;
108
109 uni->num_driver_storage++;
110 }
111
112 /**
113 * Sever all connections with all pieces of driver storage for all uniforms
114 *
115 * \warning
116 * This function does \b not release any of the \c data pointers
117 * previously passed in to \c _mesa_uniform_attach_driver_stoarge.
118 */
119 void
120 _mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage *uni)
121 {
122 free(uni->driver_storage);
123 uni->driver_storage = NULL;
124 uni->num_driver_storage = 0;
125 }
126
127 void GLAPIENTRY
128 _mesa_Uniform1fARB(GLint location, GLfloat v0)
129 {
130 GET_CURRENT_CONTEXT(ctx);
131 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT);
132 }
133
134 void GLAPIENTRY
135 _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
136 {
137 GET_CURRENT_CONTEXT(ctx);
138 GLfloat v[2];
139 v[0] = v0;
140 v[1] = v1;
141 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
142 }
143
144 void GLAPIENTRY
145 _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
146 {
147 GET_CURRENT_CONTEXT(ctx);
148 GLfloat v[3];
149 v[0] = v0;
150 v[1] = v1;
151 v[2] = v2;
152 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
153 }
154
155 void GLAPIENTRY
156 _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
157 GLfloat v3)
158 {
159 GET_CURRENT_CONTEXT(ctx);
160 GLfloat v[4];
161 v[0] = v0;
162 v[1] = v1;
163 v[2] = v2;
164 v[3] = v3;
165 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
166 }
167
168 void GLAPIENTRY
169 _mesa_Uniform1iARB(GLint location, GLint v0)
170 {
171 GET_CURRENT_CONTEXT(ctx);
172 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT);
173 }
174
175 void GLAPIENTRY
176 _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
177 {
178 GET_CURRENT_CONTEXT(ctx);
179 GLint v[2];
180 v[0] = v0;
181 v[1] = v1;
182 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2);
183 }
184
185 void GLAPIENTRY
186 _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
187 {
188 GET_CURRENT_CONTEXT(ctx);
189 GLint v[3];
190 v[0] = v0;
191 v[1] = v1;
192 v[2] = v2;
193 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3);
194 }
195
196 void GLAPIENTRY
197 _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
198 {
199 GET_CURRENT_CONTEXT(ctx);
200 GLint v[4];
201 v[0] = v0;
202 v[1] = v1;
203 v[2] = v2;
204 v[3] = v3;
205 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4);
206 }
207
208 void GLAPIENTRY
209 _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
210 {
211 GET_CURRENT_CONTEXT(ctx);
212 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT);
213 }
214
215 void GLAPIENTRY
216 _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
217 {
218 GET_CURRENT_CONTEXT(ctx);
219 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2);
220 }
221
222 void GLAPIENTRY
223 _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
224 {
225 GET_CURRENT_CONTEXT(ctx);
226 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3);
227 }
228
229 void GLAPIENTRY
230 _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
231 {
232 GET_CURRENT_CONTEXT(ctx);
233 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4);
234 }
235
236 void GLAPIENTRY
237 _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
238 {
239 GET_CURRENT_CONTEXT(ctx);
240 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT);
241 }
242
243 void GLAPIENTRY
244 _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
245 {
246 GET_CURRENT_CONTEXT(ctx);
247 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2);
248 }
249
250 void GLAPIENTRY
251 _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
252 {
253 GET_CURRENT_CONTEXT(ctx);
254 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3);
255 }
256
257 void GLAPIENTRY
258 _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
259 {
260 GET_CURRENT_CONTEXT(ctx);
261 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
262 }
263
264
265 /** OpenGL 3.0 GLuint-valued functions **/
266 void GLAPIENTRY
267 _mesa_Uniform1ui(GLint location, GLuint v0)
268 {
269 GET_CURRENT_CONTEXT(ctx);
270 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
271 }
272
273 void GLAPIENTRY
274 _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
275 {
276 GET_CURRENT_CONTEXT(ctx);
277 GLuint v[2];
278 v[0] = v0;
279 v[1] = v1;
280 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
281 }
282
283 void GLAPIENTRY
284 _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
285 {
286 GET_CURRENT_CONTEXT(ctx);
287 GLuint v[3];
288 v[0] = v0;
289 v[1] = v1;
290 v[2] = v2;
291 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
292 }
293
294 void GLAPIENTRY
295 _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
296 {
297 GET_CURRENT_CONTEXT(ctx);
298 GLuint v[4];
299 v[0] = v0;
300 v[1] = v1;
301 v[2] = v2;
302 v[3] = v3;
303 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
304 }
305
306 void GLAPIENTRY
307 _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
308 {
309 GET_CURRENT_CONTEXT(ctx);
310 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT);
311 }
312
313 void GLAPIENTRY
314 _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
315 {
316 GET_CURRENT_CONTEXT(ctx);
317 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
318 }
319
320 void GLAPIENTRY
321 _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
322 {
323 GET_CURRENT_CONTEXT(ctx);
324 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
325 }
326
327 void GLAPIENTRY
328 _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
329 {
330 GET_CURRENT_CONTEXT(ctx);
331 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
332 }
333
334
335
336 void GLAPIENTRY
337 _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
338 const GLfloat * value)
339 {
340 GET_CURRENT_CONTEXT(ctx);
341 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
342 2, 2, location, count, transpose, value);
343 }
344
345 void GLAPIENTRY
346 _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
347 const GLfloat * value)
348 {
349 GET_CURRENT_CONTEXT(ctx);
350 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
351 3, 3, location, count, transpose, value);
352 }
353
354 void GLAPIENTRY
355 _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
356 const GLfloat * value)
357 {
358 GET_CURRENT_CONTEXT(ctx);
359 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
360 4, 4, location, count, transpose, value);
361 }
362
363
364 /**
365 * Non-square UniformMatrix are OpenGL 2.1
366 */
367 void GLAPIENTRY
368 _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
369 const GLfloat *value)
370 {
371 GET_CURRENT_CONTEXT(ctx);
372 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
373 2, 3, location, count, transpose, value);
374 }
375
376 void GLAPIENTRY
377 _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
378 const GLfloat *value)
379 {
380 GET_CURRENT_CONTEXT(ctx);
381 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
382 3, 2, location, count, transpose, value);
383 }
384
385 void GLAPIENTRY
386 _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
387 const GLfloat *value)
388 {
389 GET_CURRENT_CONTEXT(ctx);
390 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
391 2, 4, location, count, transpose, value);
392 }
393
394 void GLAPIENTRY
395 _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
396 const GLfloat *value)
397 {
398 GET_CURRENT_CONTEXT(ctx);
399 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
400 4, 2, location, count, transpose, value);
401 }
402
403 void GLAPIENTRY
404 _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
405 const GLfloat *value)
406 {
407 GET_CURRENT_CONTEXT(ctx);
408 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
409 3, 4, location, count, transpose, value);
410 }
411
412 void GLAPIENTRY
413 _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
414 const GLfloat *value)
415 {
416 GET_CURRENT_CONTEXT(ctx);
417 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
418 4, 3, location, count, transpose, value);
419 }
420
421
422 void GLAPIENTRY
423 _mesa_GetnUniformfvARB(GLhandleARB program, GLint location,
424 GLsizei bufSize, GLfloat *params)
425 {
426 GET_CURRENT_CONTEXT(ctx);
427 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_FLOAT, params);
428 }
429
430 void GLAPIENTRY
431 _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
432 {
433 _mesa_GetnUniformfvARB(program, location, INT_MAX, params);
434 }
435
436
437 void GLAPIENTRY
438 _mesa_GetnUniformivARB(GLhandleARB program, GLint location,
439 GLsizei bufSize, GLint *params)
440 {
441 GET_CURRENT_CONTEXT(ctx);
442 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_INT, params);
443 }
444
445 void GLAPIENTRY
446 _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
447 {
448 _mesa_GetnUniformivARB(program, location, INT_MAX, params);
449 }
450
451
452 /* GL3 */
453 void GLAPIENTRY
454 _mesa_GetnUniformuivARB(GLhandleARB program, GLint location,
455 GLsizei bufSize, GLuint *params)
456 {
457 GET_CURRENT_CONTEXT(ctx);
458 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_UINT, params);
459 }
460
461 void GLAPIENTRY
462 _mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
463 {
464 _mesa_GetnUniformuivARB(program, location, INT_MAX, params);
465 }
466
467
468 /* GL4 */
469 void GLAPIENTRY
470 _mesa_GetnUniformdvARB(GLhandleARB program, GLint location,
471 GLsizei bufSize, GLdouble *params)
472 {
473 GET_CURRENT_CONTEXT(ctx);
474
475 (void) program;
476 (void) location;
477 (void) bufSize;
478 (void) params;
479
480 /*
481 _mesa_get_uniform(ctx, program, location, bufSize, GL_DOUBLE, params);
482 */
483 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
484 "(GL_ARB_gpu_shader_fp64 not implemented)");
485 }
486
487 void GLAPIENTRY
488 _mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params)
489 {
490 _mesa_GetnUniformdvARB(program, location, INT_MAX, params);
491 }
492
493
494 GLint GLAPIENTRY
495 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
496 {
497 struct gl_shader_program *shProg;
498
499 GET_CURRENT_CONTEXT(ctx);
500
501 shProg = _mesa_lookup_shader_program_err(ctx, programObj,
502 "glGetUniformLocation");
503 if (!shProg)
504 return -1;
505
506 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
507 *
508 * "If program has not been successfully linked, the error
509 * INVALID_OPERATION is generated."
510 */
511 if (shProg->LinkStatus == GL_FALSE) {
512 _mesa_error(ctx, GL_INVALID_OPERATION,
513 "glGetUniformLocation(program not linked)");
514 return -1;
515 }
516
517 return _mesa_get_uniform_location(ctx, shProg, name);
518 }
519
520
521 /**
522 * Plug in shader uniform-related functions into API dispatch table.
523 */
524 void
525 _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
526 {
527 #if FEATURE_GL
528 SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
529 SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
530 SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
531 SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
532 SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
533 SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
534 SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
535 SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
536 SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
537 SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
538 SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
539 SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
540 SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
541 SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
542 SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
543 SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
544 SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
545 SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
546 SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
547
548 SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
549 SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
550 SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
551 SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
552
553 /* OpenGL 2.1 */
554 SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
555 SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
556 SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
557 SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
558 SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
559 SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
560
561 /* OpenGL 3.0 */
562 SET_Uniform1uiEXT(exec, _mesa_Uniform1ui);
563 SET_Uniform2uiEXT(exec, _mesa_Uniform2ui);
564 SET_Uniform3uiEXT(exec, _mesa_Uniform3ui);
565 SET_Uniform4uiEXT(exec, _mesa_Uniform4ui);
566 SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv);
567 SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv);
568 SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv);
569 SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv);
570 SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv);
571
572 /* GL_ARB_robustness */
573 SET_GetnUniformfvARB(exec, _mesa_GetnUniformfvARB);
574 SET_GetnUniformivARB(exec, _mesa_GetnUniformivARB);
575 SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB);
576 SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */
577
578 #endif /* FEATURE_GL */
579 }