mesa: UseShaderProgramEXT and Uniform* shouldn't be allowed inside Begin/End
[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
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/dispatch.h"
42 #include "main/mfeatures.h"
43 #include "main/mtypes.h"
44 #include "main/shaderapi.h"
45 #include "main/shaderobj.h"
46 #include "main/uniforms.h"
47 #include "program/prog_parameter.h"
48 #include "program/prog_statevars.h"
49 #include "program/prog_uniform.h"
50 #include "program/prog_instruction.h"
51
52
53 static GLenum
54 base_uniform_type(GLenum type)
55 {
56 switch (type) {
57 #if 0 /* not needed, for now */
58 case GL_BOOL:
59 case GL_BOOL_VEC2:
60 case GL_BOOL_VEC3:
61 case GL_BOOL_VEC4:
62 return GL_BOOL;
63 #endif
64 case GL_FLOAT:
65 case GL_FLOAT_VEC2:
66 case GL_FLOAT_VEC3:
67 case GL_FLOAT_VEC4:
68 return GL_FLOAT;
69 case GL_UNSIGNED_INT:
70 case GL_UNSIGNED_INT_VEC2:
71 case GL_UNSIGNED_INT_VEC3:
72 case GL_UNSIGNED_INT_VEC4:
73 return GL_UNSIGNED_INT;
74 case GL_INT:
75 case GL_INT_VEC2:
76 case GL_INT_VEC3:
77 case GL_INT_VEC4:
78 return GL_INT;
79 default:
80 _mesa_problem(NULL, "Invalid type in base_uniform_type()");
81 return GL_FLOAT;
82 }
83 }
84
85
86 static GLboolean
87 is_boolean_type(GLenum type)
88 {
89 switch (type) {
90 case GL_BOOL:
91 case GL_BOOL_VEC2:
92 case GL_BOOL_VEC3:
93 case GL_BOOL_VEC4:
94 return GL_TRUE;
95 default:
96 return GL_FALSE;
97 }
98 }
99
100
101 static GLboolean
102 is_sampler_type(GLenum type)
103 {
104 switch (type) {
105 case GL_SAMPLER_1D:
106 case GL_SAMPLER_2D:
107 case GL_SAMPLER_3D:
108 case GL_SAMPLER_CUBE:
109 case GL_SAMPLER_1D_SHADOW:
110 case GL_SAMPLER_2D_SHADOW:
111 case GL_SAMPLER_2D_RECT_ARB:
112 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
113 case GL_SAMPLER_1D_ARRAY_EXT:
114 case GL_SAMPLER_2D_ARRAY_EXT:
115 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
116 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
117 return GL_TRUE;
118 default:
119 return GL_FALSE;
120 }
121 }
122
123
124 static struct gl_program_parameter *
125 get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
126 {
127 const struct gl_program *prog = NULL;
128 GLint progPos;
129
130 progPos = shProg->Uniforms->Uniforms[index].VertPos;
131 if (progPos >= 0) {
132 prog = &shProg->VertexProgram->Base;
133 }
134 else {
135 progPos = shProg->Uniforms->Uniforms[index].FragPos;
136 if (progPos >= 0) {
137 prog = &shProg->FragmentProgram->Base;
138 } else {
139 progPos = shProg->Uniforms->Uniforms[index].GeomPos;
140 if (progPos >= 0) {
141 prog = &shProg->GeometryProgram->Base;
142 }
143 }
144 }
145
146 if (!prog || progPos < 0)
147 return NULL; /* should never happen */
148
149 return &prog->Parameters->Parameters[progPos];
150 }
151
152
153 /**
154 * Called by glGetActiveUniform().
155 */
156 static void
157 _mesa_get_active_uniform(struct gl_context *ctx, GLuint program, GLuint index,
158 GLsizei maxLength, GLsizei *length, GLint *size,
159 GLenum *type, GLchar *nameOut)
160 {
161 const struct gl_shader_program *shProg;
162 const struct gl_program *prog = NULL;
163 const struct gl_program_parameter *param;
164 GLint progPos;
165
166 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
167 if (!shProg)
168 return;
169
170 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
171 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
172 return;
173 }
174
175 progPos = shProg->Uniforms->Uniforms[index].VertPos;
176 if (progPos >= 0) {
177 prog = &shProg->VertexProgram->Base;
178 }
179 else {
180 progPos = shProg->Uniforms->Uniforms[index].FragPos;
181 if (progPos >= 0) {
182 prog = &shProg->FragmentProgram->Base;
183 } else {
184 progPos = shProg->Uniforms->Uniforms[index].GeomPos;
185 if (progPos >= 0) {
186 prog = &shProg->GeometryProgram->Base;
187 }
188 }
189 }
190
191 if (!prog || progPos < 0)
192 return; /* should never happen */
193
194 ASSERT(progPos < prog->Parameters->NumParameters);
195 param = &prog->Parameters->Parameters[progPos];
196
197 if (nameOut) {
198 _mesa_copy_string(nameOut, maxLength, length, param->Name);
199 }
200
201 if (size) {
202 GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
203 if ((GLint) param->Size > typeSize) {
204 /* This is an array.
205 * Array elements are placed on vector[4] boundaries so they're
206 * a multiple of four floats. We round typeSize up to next multiple
207 * of four to get the right size below.
208 */
209 typeSize = (typeSize + 3) & ~3;
210 }
211 /* Note that the returned size is in units of the <type>, not bytes */
212 *size = param->Size / typeSize;
213 }
214
215 if (type) {
216 *type = param->DataType;
217 }
218 }
219
220
221 static unsigned
222 get_vector_elements(GLenum type)
223 {
224 switch (type) {
225 case GL_FLOAT:
226 case GL_INT:
227 case GL_BOOL:
228 case GL_UNSIGNED_INT:
229 default: /* Catch all the various sampler types. */
230 return 1;
231
232 case GL_FLOAT_VEC2:
233 case GL_INT_VEC2:
234 case GL_BOOL_VEC2:
235 case GL_UNSIGNED_INT_VEC2:
236 return 2;
237
238 case GL_FLOAT_VEC3:
239 case GL_INT_VEC3:
240 case GL_BOOL_VEC3:
241 case GL_UNSIGNED_INT_VEC3:
242 return 3;
243
244 case GL_FLOAT_VEC4:
245 case GL_INT_VEC4:
246 case GL_BOOL_VEC4:
247 case GL_UNSIGNED_INT_VEC4:
248 return 4;
249 }
250 }
251
252 static void
253 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
254 {
255 switch (type) {
256 case GL_FLOAT_MAT2:
257 *rows = *cols = 2;
258 break;
259 case GL_FLOAT_MAT2x3:
260 *rows = 3;
261 *cols = 2;
262 break;
263 case GL_FLOAT_MAT2x4:
264 *rows = 4;
265 *cols = 2;
266 break;
267 case GL_FLOAT_MAT3:
268 *rows = 3;
269 *cols = 3;
270 break;
271 case GL_FLOAT_MAT3x2:
272 *rows = 2;
273 *cols = 3;
274 break;
275 case GL_FLOAT_MAT3x4:
276 *rows = 4;
277 *cols = 3;
278 break;
279 case GL_FLOAT_MAT4:
280 *rows = 4;
281 *cols = 4;
282 break;
283 case GL_FLOAT_MAT4x2:
284 *rows = 2;
285 *cols = 4;
286 break;
287 case GL_FLOAT_MAT4x3:
288 *rows = 3;
289 *cols = 4;
290 break;
291 default:
292 *rows = *cols = 0;
293 }
294 }
295
296
297 /**
298 * Determine the number of rows and columns occupied by a uniform
299 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
300 * the number of rows = 1 and cols = number of elements in the vector.
301 */
302 static void
303 get_uniform_rows_cols(const struct gl_program_parameter *p,
304 GLint *rows, GLint *cols)
305 {
306 get_matrix_dims(p->DataType, rows, cols);
307 if (*rows == 0 && *cols == 0) {
308 /* not a matrix type, probably a float or vector */
309 *rows = 1;
310 *cols = get_vector_elements(p->DataType);
311 }
312 }
313
314
315 /**
316 * Helper for get_uniform[fi]v() functions.
317 * Given a shader program name and uniform location, return a pointer
318 * to the shader program and return the program parameter position.
319 */
320 static void
321 lookup_uniform_parameter(struct gl_context *ctx, GLuint program, GLint location,
322 struct gl_program **progOut, GLint *paramPosOut)
323 {
324 struct gl_shader_program *shProg
325 = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
326 struct gl_program *prog = NULL;
327 GLint progPos = -1;
328
329 /* if shProg is NULL, we'll have already recorded an error */
330
331 if (shProg) {
332 if (!shProg->Uniforms ||
333 location < 0 ||
334 location >= (GLint) shProg->Uniforms->NumUniforms) {
335 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
336 }
337 else {
338 /* OK, find the gl_program and program parameter location */
339 progPos = shProg->Uniforms->Uniforms[location].VertPos;
340 if (progPos >= 0) {
341 prog = &shProg->VertexProgram->Base;
342 }
343 else {
344 progPos = shProg->Uniforms->Uniforms[location].FragPos;
345 if (progPos >= 0) {
346 prog = &shProg->FragmentProgram->Base;
347 } else {
348 progPos = shProg->Uniforms->Uniforms[location].GeomPos;
349 if (progPos >= 0) {
350 prog = &shProg->GeometryProgram->Base;
351 }
352 }
353 }
354 }
355 }
356
357 *progOut = prog;
358 *paramPosOut = progPos;
359 }
360
361
362 /**
363 * GLGL uniform arrays and structs require special handling.
364 *
365 * The GL_ARB_shader_objects spec says that if you use
366 * glGetUniformLocation to get the location of an array, you CANNOT
367 * access other elements of the array by adding an offset to the
368 * returned location. For example, you must call
369 * glGetUniformLocation("foo[16]") if you want to set the 16th element
370 * of the array with glUniform().
371 *
372 * HOWEVER, some other OpenGL drivers allow accessing array elements
373 * by adding an offset to the returned array location. And some apps
374 * seem to depend on that behaviour.
375 *
376 * Mesa's gl_uniform_list doesn't directly support this since each
377 * entry in the list describes one uniform variable, not one uniform
378 * element. We could insert dummy entries in the list for each array
379 * element after [0] but that causes complications elsewhere.
380 *
381 * We solve this problem by encoding two values in the location that's
382 * returned by glGetUniformLocation():
383 * a) index into gl_uniform_list::Uniforms[] for the uniform
384 * b) an array/field offset (0 for simple types)
385 *
386 * These two values are encoded in the high and low halves of a GLint.
387 * By putting the uniform number in the high part and the offset in the
388 * low part, we can support the unofficial ability to index into arrays
389 * by adding offsets to the location value.
390 */
391 static void
392 merge_location_offset(GLint *location, GLint offset)
393 {
394 *location = (*location << 16) | offset;
395 }
396
397
398 /**
399 * Separate the uniform location and parameter offset. See above.
400 */
401 static void
402 split_location_offset(GLint *location, GLint *offset)
403 {
404 *offset = *location & 0xffff;
405 *location = *location >> 16;
406 }
407
408
409
410 /**
411 * Called via glGetUniformfv().
412 */
413 static void
414 _mesa_get_uniformfv(struct gl_context *ctx, GLuint program, GLint location,
415 GLsizei bufSize, GLfloat *params)
416 {
417 struct gl_program *prog;
418 GLint paramPos, offset;
419
420 split_location_offset(&location, &offset);
421
422 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
423
424 if (prog) {
425 const struct gl_program_parameter *p =
426 &prog->Parameters->Parameters[paramPos];
427 GLint rows, cols, i, j, k;
428 GLsizei numBytes;
429
430 get_uniform_rows_cols(p, &rows, &cols);
431
432 numBytes = rows * cols * sizeof *params;
433 if (bufSize < numBytes) {
434 _mesa_error( ctx, GL_INVALID_OPERATION,
435 "glGetnUniformfvARB(out of bounds: bufSize is %d,"
436 " but %d bytes are required)", bufSize, numBytes );
437 return;
438 }
439
440 k = 0;
441 for (i = 0; i < rows; i++) {
442 const int base = paramPos + offset + i;
443
444 for (j = 0; j < cols; j++ ) {
445 params[k++] = prog->Parameters->ParameterValues[base][j];
446 }
447 }
448 }
449 }
450
451
452 /**
453 * Called via glGetUniformiv().
454 * \sa _mesa_get_uniformfv, only difference is a cast.
455 */
456 static void
457 _mesa_get_uniformiv(struct gl_context *ctx, GLuint program, GLint location,
458 GLsizei bufSize, GLint *params)
459 {
460 struct gl_program *prog;
461 GLint paramPos, offset;
462
463 split_location_offset(&location, &offset);
464
465 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
466
467 if (prog) {
468 const struct gl_program_parameter *p =
469 &prog->Parameters->Parameters[paramPos];
470 GLint rows, cols, i, j, k;
471 GLsizei numBytes;
472
473 get_uniform_rows_cols(p, &rows, &cols);
474
475 numBytes = rows * cols * sizeof *params;
476 if (bufSize < numBytes) {
477 _mesa_error( ctx, GL_INVALID_OPERATION,
478 "glGetnUniformivARB(out of bounds: bufSize is %d,"
479 " but %d bytes are required)", bufSize, numBytes );
480 return;
481 }
482
483 k = 0;
484 for (i = 0; i < rows; i++) {
485 const int base = paramPos + offset + i;
486
487 for (j = 0; j < cols; j++ ) {
488 params[k++] = (GLint) prog->Parameters->ParameterValues[base][j];
489 }
490 }
491 }
492 }
493
494
495 /**
496 * Called via glGetUniformuiv().
497 * New in GL_EXT_gpu_shader4, OpenGL 3.0
498 * \sa _mesa_get_uniformfv, only difference is a cast.
499 */
500 static void
501 _mesa_get_uniformuiv(struct gl_context *ctx, GLuint program, GLint location,
502 GLsizei bufSize, GLuint *params)
503 {
504 struct gl_program *prog;
505 GLint paramPos, offset;
506
507 split_location_offset(&location, &offset);
508
509 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
510
511 if (prog) {
512 const struct gl_program_parameter *p =
513 &prog->Parameters->Parameters[paramPos];
514 GLint rows, cols, i, j, k;
515 GLsizei numBytes;
516
517 get_uniform_rows_cols(p, &rows, &cols);
518
519 numBytes = rows * cols * sizeof *params;
520 if (bufSize < numBytes) {
521 _mesa_error( ctx, GL_INVALID_OPERATION,
522 "glGetnUniformuivARB(out of bounds: bufSize is %d,"
523 " but %d bytes are required)", bufSize, numBytes );
524 return;
525 }
526
527 k = 0;
528 for (i = 0; i < rows; i++) {
529 const int base = paramPos + offset + i;
530
531 for (j = 0; j < cols; j++ ) {
532 params[k++] = (GLuint) prog->Parameters->ParameterValues[base][j];
533 }
534 }
535 }
536 }
537
538
539 /**
540 * Called via glGetUniformdv().
541 * New in GL_ARB_gpu_shader_fp64, OpenGL 4.0
542 */
543 static void
544 _mesa_get_uniformdv(struct gl_context *ctx, GLuint program, GLint location,
545 GLsizei bufSize, GLdouble *params)
546 {
547 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
548 "(GL_ARB_gpu_shader_fp64 not implemented)");
549 }
550
551
552 /**
553 * Called via glGetUniformLocation().
554 *
555 * The return value will encode two values, the uniform location and an
556 * offset (used for arrays, structs).
557 */
558 GLint
559 _mesa_get_uniform_location(struct gl_context *ctx, struct gl_shader_program *shProg,
560 const GLchar *name)
561 {
562 GLint offset = 0, location = -1;
563
564 if (shProg->LinkStatus == GL_FALSE) {
565 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
566 return -1;
567 }
568
569 /* XXX we should return -1 if the uniform was declared, but not
570 * actually used.
571 */
572
573 /* XXX we need to be able to parse uniform names for structs and arrays
574 * such as:
575 * mymatrix[1]
576 * mystruct.field1
577 */
578
579 {
580 /* handle 1-dimension arrays here... */
581 char *c = strchr(name, '[');
582 if (c) {
583 /* truncate name at [ */
584 const GLint len = c - name;
585 GLchar *newName = malloc(len + 1);
586 if (!newName)
587 return -1; /* out of mem */
588 memcpy(newName, name, len);
589 newName[len] = 0;
590
591 location = _mesa_lookup_uniform(shProg->Uniforms, newName);
592 if (location >= 0) {
593 const GLint element = atoi(c + 1);
594 if (element > 0) {
595 /* get type of the uniform array element */
596 struct gl_program_parameter *p;
597 p = get_uniform_parameter(shProg, location);
598 if (p) {
599 GLint rows, cols;
600 get_matrix_dims(p->DataType, &rows, &cols);
601 if (rows < 1)
602 rows = 1;
603 offset = element * rows;
604 }
605 }
606 }
607
608 free(newName);
609 }
610 }
611
612 if (location < 0) {
613 location = _mesa_lookup_uniform(shProg->Uniforms, name);
614 }
615
616 if (location >= 0) {
617 merge_location_offset(&location, offset);
618 }
619
620 return location;
621 }
622
623
624
625 /**
626 * Update the vertex/fragment program's TexturesUsed array.
627 *
628 * This needs to be called after glUniform(set sampler var) is called.
629 * A call to glUniform(samplerVar, value) causes a sampler to point to a
630 * particular texture unit. We know the sampler's texture target
631 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
632 * set by glUniform() calls.
633 *
634 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
635 * information to update the prog->TexturesUsed[] values.
636 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
637 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
638 * We'll use that info for state validation before rendering.
639 */
640 void
641 _mesa_update_shader_textures_used(struct gl_program *prog)
642 {
643 GLuint s;
644
645 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
646
647 for (s = 0; s < MAX_SAMPLERS; s++) {
648 if (prog->SamplersUsed & (1 << s)) {
649 GLuint unit = prog->SamplerUnits[s];
650 GLuint tgt = prog->SamplerTargets[s];
651 assert(unit < MAX_TEXTURE_IMAGE_UNITS);
652 assert(tgt < NUM_TEXTURE_TARGETS);
653 prog->TexturesUsed[unit] |= (1 << tgt);
654 }
655 }
656 }
657
658
659 /**
660 * Check if the type given by userType is allowed to set a uniform of the
661 * target type. Generally, equivalence is required, but setting Boolean
662 * uniforms can be done with glUniformiv or glUniformfv.
663 */
664 static GLboolean
665 compatible_types(GLenum userType, GLenum targetType)
666 {
667 if (userType == targetType)
668 return GL_TRUE;
669
670 if (targetType == GL_BOOL && (userType == GL_FLOAT ||
671 userType == GL_UNSIGNED_INT ||
672 userType == GL_INT))
673 return GL_TRUE;
674
675 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
676 userType == GL_UNSIGNED_INT_VEC2 ||
677 userType == GL_INT_VEC2))
678 return GL_TRUE;
679
680 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
681 userType == GL_UNSIGNED_INT_VEC3 ||
682 userType == GL_INT_VEC3))
683 return GL_TRUE;
684
685 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
686 userType == GL_UNSIGNED_INT_VEC4 ||
687 userType == GL_INT_VEC4))
688 return GL_TRUE;
689
690 if (is_sampler_type(targetType) && userType == GL_INT)
691 return GL_TRUE;
692
693 return GL_FALSE;
694 }
695
696
697 /**
698 * Set the value of a program's uniform variable.
699 * \param program the program whose uniform to update
700 * \param index the index of the program parameter for the uniform
701 * \param offset additional parameter slot offset (for arrays)
702 * \param type the incoming datatype of 'values'
703 * \param count the number of uniforms to set
704 * \param elems number of elements per uniform (1, 2, 3 or 4)
705 * \param values the new values, of datatype 'type'
706 */
707 static void
708 set_program_uniform(struct gl_context *ctx, struct gl_program *program,
709 GLint index, GLint offset,
710 GLenum type, GLsizei count, GLint elems,
711 const void *values)
712 {
713 const struct gl_program_parameter *param =
714 &program->Parameters->Parameters[index];
715
716 assert(offset >= 0);
717 assert(elems >= 1);
718 assert(elems <= 4);
719
720 if (!compatible_types(type, param->DataType)) {
721 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
722 return;
723 }
724
725 if (index + offset > (GLint) program->Parameters->Size) {
726 /* out of bounds! */
727 return;
728 }
729
730 if (param->Type == PROGRAM_SAMPLER) {
731 /* This controls which texture unit which is used by a sampler */
732 GLboolean changed = GL_FALSE;
733 GLint i;
734
735 /* this should have been caught by the compatible_types() check */
736 ASSERT(type == GL_INT);
737
738 /* loop over number of samplers to change */
739 for (i = 0; i < count; i++) {
740 GLuint sampler =
741 (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
742 GLuint texUnit = ((GLuint *) values)[i];
743
744 /* check that the sampler (tex unit index) is legal */
745 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
746 _mesa_error(ctx, GL_INVALID_VALUE,
747 "glUniform1(invalid sampler/tex unit index for '%s')",
748 param->Name);
749 return;
750 }
751
752 /* This maps a sampler to a texture unit: */
753 if (sampler < MAX_SAMPLERS) {
754 #if 0
755 printf("Set program %p sampler %d '%s' to unit %u\n",
756 program, sampler, param->Name, texUnit);
757 #endif
758 if (program->SamplerUnits[sampler] != texUnit) {
759 program->SamplerUnits[sampler] = texUnit;
760 changed = GL_TRUE;
761 }
762 }
763 }
764
765 if (changed) {
766 /* When a sampler's value changes it usually requires rewriting
767 * a GPU program's TEX instructions since there may not be a
768 * sampler->texture lookup table. We signal this with the
769 * ProgramStringNotify() callback.
770 */
771 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
772 _mesa_update_shader_textures_used(program);
773 /* Do we need to care about the return value here?
774 * This should not be the first time the driver was notified of
775 * this program.
776 */
777 (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
778 }
779 }
780 else {
781 /* ordinary uniform variable */
782 const GLboolean isUniformBool = is_boolean_type(param->DataType);
783 const GLenum basicType = base_uniform_type(type);
784 const GLint slots = (param->Size + 3) / 4;
785 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
786 GLsizei k, i;
787
788 if ((GLint) param->Size > typeSize) {
789 /* an array */
790 /* we'll ignore extra data below */
791 }
792 else {
793 /* non-array: count must be at most one; count == 0 is handled by the loop below */
794 if (count > 1) {
795 _mesa_error(ctx, GL_INVALID_OPERATION,
796 "glUniform(uniform '%s' is not an array)",
797 param->Name);
798 return;
799 }
800 }
801
802 /* loop over number of array elements */
803 for (k = 0; k < count; k++) {
804 GLfloat *uniformVal;
805
806 if (offset + k >= slots) {
807 /* Extra array data is ignored */
808 break;
809 }
810
811 /* uniformVal (the destination) is always float[4] */
812 uniformVal = program->Parameters->ParameterValues[index + offset + k];
813
814 if (basicType == GL_INT) {
815 /* convert user's ints to floats */
816 const GLint *iValues = ((const GLint *) values) + k * elems;
817 for (i = 0; i < elems; i++) {
818 uniformVal[i] = (GLfloat) iValues[i];
819 }
820 }
821 else if (basicType == GL_UNSIGNED_INT) {
822 /* convert user's uints to floats */
823 const GLuint *iValues = ((const GLuint *) values) + k * elems;
824 for (i = 0; i < elems; i++) {
825 uniformVal[i] = (GLfloat) iValues[i];
826 }
827 }
828 else {
829 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
830 assert(basicType == GL_FLOAT);
831 for (i = 0; i < elems; i++) {
832 uniformVal[i] = fValues[i];
833 }
834 }
835
836 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
837 if (isUniformBool) {
838 for (i = 0; i < elems; i++) {
839 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
840 }
841 }
842 }
843 }
844 }
845
846
847 /**
848 * Called via glUniform*() functions.
849 */
850 void
851 _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
852 GLint location, GLsizei count,
853 const GLvoid *values, GLenum type)
854 {
855 struct gl_uniform *uniform;
856 GLint elems, offset;
857
858 ASSERT_OUTSIDE_BEGIN_END(ctx);
859
860 if (!shProg || !shProg->LinkStatus) {
861 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
862 return;
863 }
864
865 if (location == -1)
866 return; /* The standard specifies this as a no-op */
867
868 if (location < -1) {
869 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
870 location);
871 return;
872 }
873
874 split_location_offset(&location, &offset);
875
876 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
877 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
878 return;
879 }
880
881 if (count < 0) {
882 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
883 return;
884 }
885
886 elems = _mesa_sizeof_glsl_type(type);
887
888 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
889
890 uniform = &shProg->Uniforms->Uniforms[location];
891
892 if (ctx->Shader.Flags & GLSL_UNIFORMS) {
893 const GLenum basicType = base_uniform_type(type);
894 GLint i;
895 printf("Mesa: set program %u uniform %s (loc %d) to: ",
896 shProg->Name, uniform->Name, location);
897 if (basicType == GL_INT) {
898 const GLint *v = (const GLint *) values;
899 for (i = 0; i < count * elems; i++) {
900 printf("%d ", v[i]);
901 }
902 }
903 else if (basicType == GL_UNSIGNED_INT) {
904 const GLuint *v = (const GLuint *) values;
905 for (i = 0; i < count * elems; i++) {
906 printf("%u ", v[i]);
907 }
908 }
909 else {
910 const GLfloat *v = (const GLfloat *) values;
911 assert(basicType == GL_FLOAT);
912 for (i = 0; i < count * elems; i++) {
913 printf("%g ", v[i]);
914 }
915 }
916 printf("\n");
917 }
918
919 /* A uniform var may be used by both a vertex shader and a fragment
920 * shader. We may need to update one or both shader's uniform here:
921 */
922 if (shProg->VertexProgram) {
923 /* convert uniform location to program parameter index */
924 GLint index = uniform->VertPos;
925 if (index >= 0) {
926 set_program_uniform(ctx, &shProg->VertexProgram->Base,
927 index, offset, type, count, elems, values);
928 }
929 }
930
931 if (shProg->FragmentProgram) {
932 /* convert uniform location to program parameter index */
933 GLint index = uniform->FragPos;
934 if (index >= 0) {
935 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
936 index, offset, type, count, elems, values);
937 }
938 }
939
940 if (shProg->GeometryProgram) {
941 /* convert uniform location to program parameter index */
942 GLint index = uniform->GeomPos;
943 if (index >= 0) {
944 set_program_uniform(ctx, &shProg->GeometryProgram->Base,
945 index, offset, type, count, elems, values);
946 }
947 }
948
949 uniform->Initialized = GL_TRUE;
950 }
951
952
953 /**
954 * Set a matrix-valued program parameter.
955 */
956 static void
957 set_program_uniform_matrix(struct gl_context *ctx, struct gl_program *program,
958 GLuint index, GLuint offset,
959 GLuint count, GLuint rows, GLuint cols,
960 GLboolean transpose, const GLfloat *values)
961 {
962 GLuint mat, row, col;
963 GLuint src = 0;
964 const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
965 const GLuint slots = (param->Size + 3) / 4;
966 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
967 GLint nr, nc;
968
969 /* check that the number of rows, columns is correct */
970 get_matrix_dims(param->DataType, &nr, &nc);
971 if (rows != nr || cols != nc) {
972 _mesa_error(ctx, GL_INVALID_OPERATION,
973 "glUniformMatrix(matrix size mismatch)");
974 return;
975 }
976
977 if ((GLint) param->Size <= typeSize) {
978 /* non-array: count must be at most one; count == 0 is handled by the loop below */
979 if (count > 1) {
980 _mesa_error(ctx, GL_INVALID_OPERATION,
981 "glUniformMatrix(uniform is not an array)");
982 return;
983 }
984 }
985
986 /*
987 * Note: the _columns_ of a matrix are stored in program registers, not
988 * the rows. So, the loops below look a little funny.
989 * XXX could optimize this a bit...
990 */
991
992 /* loop over matrices */
993 for (mat = 0; mat < count; mat++) {
994
995 /* each matrix: */
996 for (col = 0; col < cols; col++) {
997 GLfloat *v;
998 if (offset >= slots) {
999 /* Ignore writes beyond the end of (the used part of) an array */
1000 return;
1001 }
1002 v = program->Parameters->ParameterValues[index + offset];
1003 for (row = 0; row < rows; row++) {
1004 if (transpose) {
1005 v[row] = values[src + row * cols + col];
1006 }
1007 else {
1008 v[row] = values[src + col * rows + row];
1009 }
1010 }
1011
1012 offset++;
1013 }
1014
1015 src += rows * cols; /* next matrix */
1016 }
1017 }
1018
1019
1020 /**
1021 * Called by glUniformMatrix*() functions.
1022 * Note: cols=2, rows=4 ==> array[2] of vec4
1023 */
1024 void
1025 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
1026 GLint cols, GLint rows,
1027 GLint location, GLsizei count,
1028 GLboolean transpose, const GLfloat *values)
1029 {
1030 struct gl_uniform *uniform;
1031 GLint offset;
1032
1033 ASSERT_OUTSIDE_BEGIN_END(ctx);
1034
1035 if (!shProg || !shProg->LinkStatus) {
1036 _mesa_error(ctx, GL_INVALID_OPERATION,
1037 "glUniformMatrix(program not linked)");
1038 return;
1039 }
1040
1041 if (location == -1)
1042 return; /* The standard specifies this as a no-op */
1043
1044 if (location < -1) {
1045 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
1046 return;
1047 }
1048
1049 split_location_offset(&location, &offset);
1050
1051 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1052 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
1053 return;
1054 }
1055 if (values == NULL) {
1056 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
1057 return;
1058 }
1059
1060 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1061
1062 uniform = &shProg->Uniforms->Uniforms[location];
1063
1064 if (shProg->VertexProgram) {
1065 /* convert uniform location to program parameter index */
1066 GLint index = uniform->VertPos;
1067 if (index >= 0) {
1068 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
1069 index, offset,
1070 count, rows, cols, transpose, values);
1071 }
1072 }
1073
1074 if (shProg->FragmentProgram) {
1075 /* convert uniform location to program parameter index */
1076 GLint index = uniform->FragPos;
1077 if (index >= 0) {
1078 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
1079 index, offset,
1080 count, rows, cols, transpose, values);
1081 }
1082 }
1083
1084 if (shProg->GeometryProgram) {
1085 /* convert uniform location to program parameter index */
1086 GLint index = uniform->GeomPos;
1087 if (index >= 0) {
1088 set_program_uniform_matrix(ctx, &shProg->GeometryProgram->Base,
1089 index, offset,
1090 count, rows, cols, transpose, values);
1091 }
1092 }
1093
1094 uniform->Initialized = GL_TRUE;
1095 }
1096
1097
1098 void GLAPIENTRY
1099 _mesa_Uniform1fARB(GLint location, GLfloat v0)
1100 {
1101 GET_CURRENT_CONTEXT(ctx);
1102 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT);
1103 }
1104
1105 void GLAPIENTRY
1106 _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
1107 {
1108 GET_CURRENT_CONTEXT(ctx);
1109 GLfloat v[2];
1110 v[0] = v0;
1111 v[1] = v1;
1112 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
1113 }
1114
1115 void GLAPIENTRY
1116 _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
1117 {
1118 GET_CURRENT_CONTEXT(ctx);
1119 GLfloat v[3];
1120 v[0] = v0;
1121 v[1] = v1;
1122 v[2] = v2;
1123 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
1124 }
1125
1126 void GLAPIENTRY
1127 _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
1128 GLfloat v3)
1129 {
1130 GET_CURRENT_CONTEXT(ctx);
1131 GLfloat v[4];
1132 v[0] = v0;
1133 v[1] = v1;
1134 v[2] = v2;
1135 v[3] = v3;
1136 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
1137 }
1138
1139 void GLAPIENTRY
1140 _mesa_Uniform1iARB(GLint location, GLint v0)
1141 {
1142 GET_CURRENT_CONTEXT(ctx);
1143 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT);
1144 }
1145
1146 void GLAPIENTRY
1147 _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
1148 {
1149 GET_CURRENT_CONTEXT(ctx);
1150 GLint v[2];
1151 v[0] = v0;
1152 v[1] = v1;
1153 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2);
1154 }
1155
1156 void GLAPIENTRY
1157 _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
1158 {
1159 GET_CURRENT_CONTEXT(ctx);
1160 GLint v[3];
1161 v[0] = v0;
1162 v[1] = v1;
1163 v[2] = v2;
1164 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3);
1165 }
1166
1167 void GLAPIENTRY
1168 _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
1169 {
1170 GET_CURRENT_CONTEXT(ctx);
1171 GLint v[4];
1172 v[0] = v0;
1173 v[1] = v1;
1174 v[2] = v2;
1175 v[3] = v3;
1176 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4);
1177 }
1178
1179 void GLAPIENTRY
1180 _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
1181 {
1182 GET_CURRENT_CONTEXT(ctx);
1183 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT);
1184 }
1185
1186 void GLAPIENTRY
1187 _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
1188 {
1189 GET_CURRENT_CONTEXT(ctx);
1190 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2);
1191 }
1192
1193 void GLAPIENTRY
1194 _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
1195 {
1196 GET_CURRENT_CONTEXT(ctx);
1197 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3);
1198 }
1199
1200 void GLAPIENTRY
1201 _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
1202 {
1203 GET_CURRENT_CONTEXT(ctx);
1204 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4);
1205 }
1206
1207 void GLAPIENTRY
1208 _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
1209 {
1210 GET_CURRENT_CONTEXT(ctx);
1211 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT);
1212 }
1213
1214 void GLAPIENTRY
1215 _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
1216 {
1217 GET_CURRENT_CONTEXT(ctx);
1218 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2);
1219 }
1220
1221 void GLAPIENTRY
1222 _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
1223 {
1224 GET_CURRENT_CONTEXT(ctx);
1225 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3);
1226 }
1227
1228 void GLAPIENTRY
1229 _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
1230 {
1231 GET_CURRENT_CONTEXT(ctx);
1232 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
1233 }
1234
1235
1236 /** OpenGL 3.0 GLuint-valued functions **/
1237 void GLAPIENTRY
1238 _mesa_Uniform1ui(GLint location, GLuint v0)
1239 {
1240 GET_CURRENT_CONTEXT(ctx);
1241 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
1242 }
1243
1244 void GLAPIENTRY
1245 _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
1246 {
1247 GET_CURRENT_CONTEXT(ctx);
1248 GLuint v[2];
1249 v[0] = v0;
1250 v[1] = v1;
1251 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
1252 }
1253
1254 void GLAPIENTRY
1255 _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
1256 {
1257 GET_CURRENT_CONTEXT(ctx);
1258 GLuint v[3];
1259 v[0] = v0;
1260 v[1] = v1;
1261 v[2] = v2;
1262 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
1263 }
1264
1265 void GLAPIENTRY
1266 _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
1267 {
1268 GET_CURRENT_CONTEXT(ctx);
1269 GLuint v[4];
1270 v[0] = v0;
1271 v[1] = v1;
1272 v[2] = v2;
1273 v[3] = v3;
1274 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
1275 }
1276
1277 void GLAPIENTRY
1278 _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
1279 {
1280 GET_CURRENT_CONTEXT(ctx);
1281 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT);
1282 }
1283
1284 void GLAPIENTRY
1285 _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
1286 {
1287 GET_CURRENT_CONTEXT(ctx);
1288 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
1289 }
1290
1291 void GLAPIENTRY
1292 _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
1293 {
1294 GET_CURRENT_CONTEXT(ctx);
1295 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
1296 }
1297
1298 void GLAPIENTRY
1299 _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
1300 {
1301 GET_CURRENT_CONTEXT(ctx);
1302 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
1303 }
1304
1305
1306
1307 void GLAPIENTRY
1308 _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
1309 const GLfloat * value)
1310 {
1311 GET_CURRENT_CONTEXT(ctx);
1312 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1313 2, 2, location, count, transpose, value);
1314 }
1315
1316 void GLAPIENTRY
1317 _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
1318 const GLfloat * value)
1319 {
1320 GET_CURRENT_CONTEXT(ctx);
1321 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1322 3, 3, location, count, transpose, value);
1323 }
1324
1325 void GLAPIENTRY
1326 _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
1327 const GLfloat * value)
1328 {
1329 GET_CURRENT_CONTEXT(ctx);
1330 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1331 4, 4, location, count, transpose, value);
1332 }
1333
1334
1335 /**
1336 * Non-square UniformMatrix are OpenGL 2.1
1337 */
1338 void GLAPIENTRY
1339 _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
1340 const GLfloat *value)
1341 {
1342 GET_CURRENT_CONTEXT(ctx);
1343 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1344 2, 3, location, count, transpose, value);
1345 }
1346
1347 void GLAPIENTRY
1348 _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
1349 const GLfloat *value)
1350 {
1351 GET_CURRENT_CONTEXT(ctx);
1352 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1353 3, 2, location, count, transpose, value);
1354 }
1355
1356 void GLAPIENTRY
1357 _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
1358 const GLfloat *value)
1359 {
1360 GET_CURRENT_CONTEXT(ctx);
1361 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1362 2, 4, location, count, transpose, value);
1363 }
1364
1365 void GLAPIENTRY
1366 _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
1367 const GLfloat *value)
1368 {
1369 GET_CURRENT_CONTEXT(ctx);
1370 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1371 4, 2, location, count, transpose, value);
1372 }
1373
1374 void GLAPIENTRY
1375 _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
1376 const GLfloat *value)
1377 {
1378 GET_CURRENT_CONTEXT(ctx);
1379 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1380 3, 4, location, count, transpose, value);
1381 }
1382
1383 void GLAPIENTRY
1384 _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
1385 const GLfloat *value)
1386 {
1387 GET_CURRENT_CONTEXT(ctx);
1388 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1389 4, 3, location, count, transpose, value);
1390 }
1391
1392
1393 void GLAPIENTRY
1394 _mesa_GetnUniformfvARB(GLhandleARB program, GLint location,
1395 GLsizei bufSize, GLfloat *params)
1396 {
1397 GET_CURRENT_CONTEXT(ctx);
1398 _mesa_get_uniformfv(ctx, program, location, bufSize, params);
1399 }
1400
1401 void GLAPIENTRY
1402 _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
1403 {
1404 _mesa_GetnUniformfvARB(program, location, INT_MAX, params);
1405 }
1406
1407
1408 void GLAPIENTRY
1409 _mesa_GetnUniformivARB(GLhandleARB program, GLint location,
1410 GLsizei bufSize, GLint *params)
1411 {
1412 GET_CURRENT_CONTEXT(ctx);
1413 _mesa_get_uniformiv(ctx, program, location, bufSize, params);
1414 }
1415
1416 void GLAPIENTRY
1417 _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
1418 {
1419 _mesa_GetnUniformivARB(program, location, INT_MAX, params);
1420 }
1421
1422
1423 /* GL3 */
1424 void GLAPIENTRY
1425 _mesa_GetnUniformuivARB(GLhandleARB program, GLint location,
1426 GLsizei bufSize, GLuint *params)
1427 {
1428 GET_CURRENT_CONTEXT(ctx);
1429 _mesa_get_uniformuiv(ctx, program, location, bufSize, params);
1430 }
1431
1432 void GLAPIENTRY
1433 _mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
1434 {
1435 _mesa_GetnUniformuivARB(program, location, INT_MAX, params);
1436 }
1437
1438
1439 /* GL4 */
1440 void GLAPIENTRY
1441 _mesa_GetnUniformdvARB(GLhandleARB program, GLint location,
1442 GLsizei bufSize, GLdouble *params)
1443 {
1444 GET_CURRENT_CONTEXT(ctx);
1445 _mesa_get_uniformdv(ctx, program, location, bufSize, params);
1446 }
1447
1448 void GLAPIENTRY
1449 _mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params)
1450 {
1451 _mesa_GetnUniformdvARB(program, location, INT_MAX, params);
1452 }
1453
1454
1455 GLint GLAPIENTRY
1456 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
1457 {
1458 struct gl_shader_program *shProg;
1459
1460 GET_CURRENT_CONTEXT(ctx);
1461
1462 shProg = _mesa_lookup_shader_program_err(ctx, programObj,
1463 "glGetUniformLocation");
1464 if (!shProg)
1465 return -1;
1466
1467 return _mesa_get_uniform_location(ctx, shProg, name);
1468 }
1469
1470
1471 void GLAPIENTRY
1472 _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
1473 GLsizei maxLength, GLsizei * length, GLint * size,
1474 GLenum * type, GLcharARB * name)
1475 {
1476 GET_CURRENT_CONTEXT(ctx);
1477 _mesa_get_active_uniform(ctx, program, index, maxLength, length, size,
1478 type, name);
1479 }
1480
1481
1482 /**
1483 * Plug in shader uniform-related functions into API dispatch table.
1484 */
1485 void
1486 _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
1487 {
1488 #if FEATURE_GL
1489 SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
1490 SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
1491 SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
1492 SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
1493 SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
1494 SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
1495 SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
1496 SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
1497 SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
1498 SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
1499 SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
1500 SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
1501 SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
1502 SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
1503 SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
1504 SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
1505 SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
1506 SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
1507 SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
1508
1509 SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
1510 SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
1511 SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
1512 SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
1513
1514 /* OpenGL 2.1 */
1515 SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
1516 SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
1517 SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
1518 SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
1519 SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
1520 SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
1521
1522 /* OpenGL 3.0 */
1523 /* XXX finish dispatch */
1524 SET_Uniform1uiEXT(exec, _mesa_Uniform1ui);
1525 SET_Uniform2uiEXT(exec, _mesa_Uniform2ui);
1526 SET_Uniform3uiEXT(exec, _mesa_Uniform3ui);
1527 SET_Uniform4uiEXT(exec, _mesa_Uniform4ui);
1528 SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv);
1529 SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv);
1530 SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv);
1531 SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv);
1532 SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv);
1533
1534 /* GL_ARB_robustness */
1535 SET_GetnUniformfvARB(exec, _mesa_GetnUniformfvARB);
1536 SET_GetnUniformivARB(exec, _mesa_GetnUniformivARB);
1537 SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB);
1538 SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */
1539
1540 #endif /* FEATURE_GL */
1541 }