uniforms.c revision acfbdfcbc8263cc0ace3468457a209dd80da017e
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 */
62void
63_mesa_update_shader_textures_used(struct gl_shader_program *shProg,
64				  struct gl_program *prog)
65{
66   GLuint s;
67
68   memcpy(prog->SamplerUnits, shProg->SamplerUnits, sizeof(prog->SamplerUnits));
69   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
70
71   for (s = 0; s < MAX_SAMPLERS; s++) {
72      if (prog->SamplersUsed & (1 << s)) {
73         GLuint unit = shProg->SamplerUnits[s];
74         GLuint tgt = shProg->SamplerTargets[s];
75         assert(unit < Elements(prog->TexturesUsed));
76         assert(tgt < NUM_TEXTURE_TARGETS);
77         prog->TexturesUsed[unit] |= (1 << tgt);
78      }
79   }
80}
81
82/**
83 * Connect a piece of driver storage with a part of a uniform
84 *
85 * \param uni            The uniform with which the storage will be associated
86 * \param element_stride Byte-stride between array elements.
87 *                       \sa gl_uniform_driver_storage::element_stride.
88 * \param vector_stride  Byte-stride between vectors (in a matrix).
89 *                       \sa gl_uniform_driver_storage::vector_stride.
90 * \param format         Conversion from native format to driver format
91 *                       required by the driver.
92 * \param data           Location to dump the data.
93 */
94void
95_mesa_uniform_attach_driver_storage(struct gl_uniform_storage *uni,
96				    unsigned element_stride,
97				    unsigned vector_stride,
98				    enum gl_uniform_driver_format format,
99				    void *data)
100{
101   uni->driver_storage = (struct gl_uniform_driver_storage*)
102      realloc(uni->driver_storage,
103	      sizeof(struct gl_uniform_driver_storage)
104	      * (uni->num_driver_storage + 1));
105
106   uni->driver_storage[uni->num_driver_storage].element_stride = element_stride;
107   uni->driver_storage[uni->num_driver_storage].vector_stride = vector_stride;
108   uni->driver_storage[uni->num_driver_storage].format = (uint8_t) format;
109   uni->driver_storage[uni->num_driver_storage].data = data;
110
111   uni->num_driver_storage++;
112}
113
114/**
115 * Sever all connections with all pieces of driver storage for all uniforms
116 *
117 * \warning
118 * This function does \b not release any of the \c data pointers
119 * previously passed in to \c _mesa_uniform_attach_driver_stoarge.
120 */
121void
122_mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage *uni)
123{
124   free(uni->driver_storage);
125   uni->driver_storage = NULL;
126   uni->num_driver_storage = 0;
127}
128
129void GLAPIENTRY
130_mesa_Uniform1fARB(GLint location, GLfloat v0)
131{
132   GET_CURRENT_CONTEXT(ctx);
133   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT);
134}
135
136void GLAPIENTRY
137_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
138{
139   GET_CURRENT_CONTEXT(ctx);
140   GLfloat v[2];
141   v[0] = v0;
142   v[1] = v1;
143   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
144}
145
146void GLAPIENTRY
147_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
148{
149   GET_CURRENT_CONTEXT(ctx);
150   GLfloat v[3];
151   v[0] = v0;
152   v[1] = v1;
153   v[2] = v2;
154   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
155}
156
157void GLAPIENTRY
158_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
159                   GLfloat v3)
160{
161   GET_CURRENT_CONTEXT(ctx);
162   GLfloat v[4];
163   v[0] = v0;
164   v[1] = v1;
165   v[2] = v2;
166   v[3] = v3;
167   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
168}
169
170void GLAPIENTRY
171_mesa_Uniform1iARB(GLint location, GLint v0)
172{
173   GET_CURRENT_CONTEXT(ctx);
174   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT);
175}
176
177void GLAPIENTRY
178_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
179{
180   GET_CURRENT_CONTEXT(ctx);
181   GLint v[2];
182   v[0] = v0;
183   v[1] = v1;
184   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2);
185}
186
187void GLAPIENTRY
188_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
189{
190   GET_CURRENT_CONTEXT(ctx);
191   GLint v[3];
192   v[0] = v0;
193   v[1] = v1;
194   v[2] = v2;
195   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3);
196}
197
198void GLAPIENTRY
199_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
200{
201   GET_CURRENT_CONTEXT(ctx);
202   GLint v[4];
203   v[0] = v0;
204   v[1] = v1;
205   v[2] = v2;
206   v[3] = v3;
207   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4);
208}
209
210void GLAPIENTRY
211_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
212{
213   GET_CURRENT_CONTEXT(ctx);
214   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT);
215}
216
217void GLAPIENTRY
218_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
219{
220   GET_CURRENT_CONTEXT(ctx);
221   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2);
222}
223
224void GLAPIENTRY
225_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
226{
227   GET_CURRENT_CONTEXT(ctx);
228   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3);
229}
230
231void GLAPIENTRY
232_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
233{
234   GET_CURRENT_CONTEXT(ctx);
235   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4);
236}
237
238void GLAPIENTRY
239_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
240{
241   GET_CURRENT_CONTEXT(ctx);
242   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT);
243}
244
245void GLAPIENTRY
246_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
247{
248   GET_CURRENT_CONTEXT(ctx);
249   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2);
250}
251
252void GLAPIENTRY
253_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
254{
255   GET_CURRENT_CONTEXT(ctx);
256   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3);
257}
258
259void GLAPIENTRY
260_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
261{
262   GET_CURRENT_CONTEXT(ctx);
263   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
264}
265
266
267/** OpenGL 3.0 GLuint-valued functions **/
268void GLAPIENTRY
269_mesa_Uniform1ui(GLint location, GLuint v0)
270{
271   GET_CURRENT_CONTEXT(ctx);
272   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
273}
274
275void GLAPIENTRY
276_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
277{
278   GET_CURRENT_CONTEXT(ctx);
279   GLuint v[2];
280   v[0] = v0;
281   v[1] = v1;
282   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
283}
284
285void GLAPIENTRY
286_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
287{
288   GET_CURRENT_CONTEXT(ctx);
289   GLuint v[3];
290   v[0] = v0;
291   v[1] = v1;
292   v[2] = v2;
293   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
294}
295
296void GLAPIENTRY
297_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
298{
299   GET_CURRENT_CONTEXT(ctx);
300   GLuint v[4];
301   v[0] = v0;
302   v[1] = v1;
303   v[2] = v2;
304   v[3] = v3;
305   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
306}
307
308void GLAPIENTRY
309_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
310{
311   GET_CURRENT_CONTEXT(ctx);
312   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT);
313}
314
315void GLAPIENTRY
316_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
317{
318   GET_CURRENT_CONTEXT(ctx);
319   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
320}
321
322void GLAPIENTRY
323_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
324{
325   GET_CURRENT_CONTEXT(ctx);
326   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
327}
328
329void GLAPIENTRY
330_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
331{
332   GET_CURRENT_CONTEXT(ctx);
333   _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
334}
335
336
337
338void GLAPIENTRY
339_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
340                          const GLfloat * value)
341{
342   GET_CURRENT_CONTEXT(ctx);
343   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
344			2, 2, location, count, transpose, value);
345}
346
347void GLAPIENTRY
348_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
349                          const GLfloat * value)
350{
351   GET_CURRENT_CONTEXT(ctx);
352   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
353			3, 3, location, count, transpose, value);
354}
355
356void GLAPIENTRY
357_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
358                          const GLfloat * value)
359{
360   GET_CURRENT_CONTEXT(ctx);
361   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
362			4, 4, location, count, transpose, value);
363}
364
365
366/**
367 * Non-square UniformMatrix are OpenGL 2.1
368 */
369void GLAPIENTRY
370_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
371                         const GLfloat *value)
372{
373   GET_CURRENT_CONTEXT(ctx);
374   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
375			2, 3, location, count, transpose, value);
376}
377
378void GLAPIENTRY
379_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
380                         const GLfloat *value)
381{
382   GET_CURRENT_CONTEXT(ctx);
383   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
384			3, 2, location, count, transpose, value);
385}
386
387void GLAPIENTRY
388_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
389                         const GLfloat *value)
390{
391   GET_CURRENT_CONTEXT(ctx);
392   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
393			2, 4, location, count, transpose, value);
394}
395
396void GLAPIENTRY
397_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
398                         const GLfloat *value)
399{
400   GET_CURRENT_CONTEXT(ctx);
401   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
402			4, 2, location, count, transpose, value);
403}
404
405void GLAPIENTRY
406_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
407                         const GLfloat *value)
408{
409   GET_CURRENT_CONTEXT(ctx);
410   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
411			3, 4, location, count, transpose, value);
412}
413
414void GLAPIENTRY
415_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
416                         const GLfloat *value)
417{
418   GET_CURRENT_CONTEXT(ctx);
419   _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
420			4, 3, location, count, transpose, value);
421}
422
423
424void GLAPIENTRY
425_mesa_GetnUniformfvARB(GLhandleARB program, GLint location,
426                       GLsizei bufSize, GLfloat *params)
427{
428   GET_CURRENT_CONTEXT(ctx);
429   _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_FLOAT, params);
430}
431
432void GLAPIENTRY
433_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
434{
435   _mesa_GetnUniformfvARB(program, location, INT_MAX, params);
436}
437
438
439void GLAPIENTRY
440_mesa_GetnUniformivARB(GLhandleARB program, GLint location,
441                       GLsizei bufSize, GLint *params)
442{
443   GET_CURRENT_CONTEXT(ctx);
444   _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_INT, params);
445}
446
447void GLAPIENTRY
448_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
449{
450   _mesa_GetnUniformivARB(program, location, INT_MAX, params);
451}
452
453
454/* GL3 */
455void GLAPIENTRY
456_mesa_GetnUniformuivARB(GLhandleARB program, GLint location,
457                        GLsizei bufSize, GLuint *params)
458{
459   GET_CURRENT_CONTEXT(ctx);
460   _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_UINT, params);
461}
462
463void GLAPIENTRY
464_mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
465{
466   _mesa_GetnUniformuivARB(program, location, INT_MAX, params);
467}
468
469
470/* GL4 */
471void GLAPIENTRY
472_mesa_GetnUniformdvARB(GLhandleARB program, GLint location,
473                        GLsizei bufSize, GLdouble *params)
474{
475   GET_CURRENT_CONTEXT(ctx);
476
477   (void) program;
478   (void) location;
479   (void) bufSize;
480   (void) params;
481
482   /*
483   _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
484   */
485   _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
486               "(GL_ARB_gpu_shader_fp64 not implemented)");
487}
488
489void GLAPIENTRY
490_mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params)
491{
492   _mesa_GetnUniformdvARB(program, location, INT_MAX, params);
493}
494
495
496GLint GLAPIENTRY
497_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
498{
499   struct gl_shader_program *shProg;
500   GLuint index, offset;
501
502   GET_CURRENT_CONTEXT(ctx);
503
504   shProg = _mesa_lookup_shader_program_err(ctx, programObj,
505					    "glGetUniformLocation");
506   if (!shProg)
507      return -1;
508
509   /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
510    *
511    *     "If program has not been successfully linked, the error
512    *     INVALID_OPERATION is generated."
513    */
514   if (shProg->LinkStatus == GL_FALSE) {
515      _mesa_error(ctx, GL_INVALID_OPERATION,
516		  "glGetUniformLocation(program not linked)");
517      return -1;
518   }
519
520   index = _mesa_get_uniform_location(ctx, shProg, name, &offset);
521   if (index == GL_INVALID_INDEX)
522      return -1;
523
524   return _mesa_uniform_merge_location_offset(index, offset);
525}
526
527static void GLAPIENTRY
528_mesa_GetUniformIndices(GLuint program,
529			GLsizei uniformCount,
530			const GLchar * const *uniformNames,
531			GLuint *uniformIndices)
532{
533   GET_CURRENT_CONTEXT(ctx);
534   GLsizei i;
535   struct gl_shader_program *shProg;
536
537   if (!ctx->Extensions.ARB_uniform_buffer_object) {
538      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformIndices");
539      return;
540   }
541
542   shProg = _mesa_lookup_shader_program_err(ctx, program,
543					    "glGetUniformIndices");
544   if (!shProg)
545      return;
546
547   if (uniformCount < 0) {
548      _mesa_error(ctx, GL_INVALID_VALUE,
549		  "glGetUniformIndices(uniformCount < 0)");
550      return;
551   }
552
553   for (i = 0; i < uniformCount; i++) {
554      unsigned offset;
555      uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg,
556						     uniformNames[i], &offset);
557   }
558}
559
560/**
561 * Plug in shader uniform-related functions into API dispatch table.
562 */
563void
564_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
565{
566#if FEATURE_GL
567   SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
568   SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
569   SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
570   SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
571   SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
572   SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
573   SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
574   SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
575   SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
576   SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
577   SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
578   SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
579   SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
580   SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
581   SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
582   SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
583   SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
584   SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
585   SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
586
587   SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
588   SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
589   SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
590   SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
591
592   /* OpenGL 2.1 */
593   SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
594   SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
595   SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
596   SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
597   SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
598   SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
599
600   /* OpenGL 3.0 */
601   SET_Uniform1uiEXT(exec, _mesa_Uniform1ui);
602   SET_Uniform2uiEXT(exec, _mesa_Uniform2ui);
603   SET_Uniform3uiEXT(exec, _mesa_Uniform3ui);
604   SET_Uniform4uiEXT(exec, _mesa_Uniform4ui);
605   SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv);
606   SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv);
607   SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv);
608   SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv);
609   SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv);
610
611   /* GL_ARB_robustness */
612   SET_GetnUniformfvARB(exec, _mesa_GetnUniformfvARB);
613   SET_GetnUniformivARB(exec, _mesa_GetnUniformivARB);
614   SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB);
615   SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */
616
617   /* GL_ARB_uniform_buffer_object / GL 3.1 */
618   SET_GetUniformIndices(exec, _mesa_GetUniformIndices);
619
620#endif /* FEATURE_GL */
621}
622