2 * Mesa 3-D graphics library
4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Functions related to GLSL uniform variables.
33 * 1. Check that the right error code is generated for all _mesa_error() calls.
34 * 2. Insert FLUSH_VERTICES calls in various places
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 "program/prog_parameter.h"
45 #include "program/prog_statevars.h"
46 #include "program/prog_uniform.h"
51 base_uniform_type(GLenum type
)
54 #if 0 /* not needed, for now */
67 case GL_UNSIGNED_INT_VEC2
:
68 case GL_UNSIGNED_INT_VEC3
:
69 case GL_UNSIGNED_INT_VEC4
:
70 return GL_UNSIGNED_INT
;
77 _mesa_problem(NULL
, "Invalid type in base_uniform_type()");
84 is_boolean_type(GLenum type
)
99 is_sampler_type(GLenum type
)
105 case GL_SAMPLER_CUBE
:
106 case GL_SAMPLER_1D_SHADOW
:
107 case GL_SAMPLER_2D_SHADOW
:
108 case GL_SAMPLER_2D_RECT_ARB
:
109 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
110 case GL_SAMPLER_1D_ARRAY_EXT
:
111 case GL_SAMPLER_2D_ARRAY_EXT
:
112 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
113 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
121 static struct gl_program_parameter
*
122 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
124 const struct gl_program
*prog
= NULL
;
127 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
129 prog
= &shProg
->VertexProgram
->Base
;
132 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
134 prog
= &shProg
->FragmentProgram
->Base
;
138 if (!prog
|| progPos
< 0)
139 return NULL
; /* should never happen */
141 return &prog
->Parameters
->Parameters
[progPos
];
146 * Called by glGetActiveUniform().
149 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
150 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
151 GLenum
*type
, GLchar
*nameOut
)
153 const struct gl_shader_program
*shProg
;
154 const struct gl_program
*prog
= NULL
;
155 const struct gl_program_parameter
*param
;
158 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
162 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
163 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
167 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
169 prog
= &shProg
->VertexProgram
->Base
;
172 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
174 prog
= &shProg
->FragmentProgram
->Base
;
178 if (!prog
|| progPos
< 0)
179 return; /* should never happen */
181 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
182 param
= &prog
->Parameters
->Parameters
[progPos
];
185 _mesa_copy_string(nameOut
, maxLength
, length
, param
->Name
);
189 GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
190 if ((GLint
) param
->Size
> typeSize
) {
192 * Array elements are placed on vector[4] boundaries so they're
193 * a multiple of four floats. We round typeSize up to next multiple
194 * of four to get the right size below.
196 typeSize
= (typeSize
+ 3) & ~3;
198 /* Note that the returned size is in units of the <type>, not bytes */
199 *size
= param
->Size
/ typeSize
;
203 *type
= param
->DataType
;
210 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
216 case GL_FLOAT_MAT2x3
:
220 case GL_FLOAT_MAT2x4
:
228 case GL_FLOAT_MAT3x2
:
232 case GL_FLOAT_MAT3x4
:
240 case GL_FLOAT_MAT4x2
:
244 case GL_FLOAT_MAT4x3
:
255 * Determine the number of rows and columns occupied by a uniform
256 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
257 * the number of rows = 1 and cols = number of elements in the vector.
260 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
261 GLint
*rows
, GLint
*cols
)
263 get_matrix_dims(p
->DataType
, rows
, cols
);
264 if (*rows
== 0 && *cols
== 0) {
265 /* not a matrix type, probably a float or vector */
271 *rows
= p
->Size
/ 4 + 1;
272 if (p
->Size
% 4 == 0)
282 * Helper for get_uniform[fi]v() functions.
283 * Given a shader program name and uniform location, return a pointer
284 * to the shader program and return the program parameter position.
287 lookup_uniform_parameter(GLcontext
*ctx
, GLuint program
, GLint location
,
288 struct gl_program
**progOut
, GLint
*paramPosOut
)
290 struct gl_shader_program
*shProg
291 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
292 struct gl_program
*prog
= NULL
;
295 /* if shProg is NULL, we'll have already recorded an error */
298 if (!shProg
->Uniforms
||
300 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
301 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
304 /* OK, find the gl_program and program parameter location */
305 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
307 prog
= &shProg
->VertexProgram
->Base
;
310 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
312 prog
= &shProg
->FragmentProgram
->Base
;
319 *paramPosOut
= progPos
;
324 * GLGL uniform arrays and structs require special handling.
326 * The GL_ARB_shader_objects spec says that if you use
327 * glGetUniformLocation to get the location of an array, you CANNOT
328 * access other elements of the array by adding an offset to the
329 * returned location. For example, you must call
330 * glGetUniformLocation("foo[16]") if you want to set the 16th element
331 * of the array with glUniform().
333 * HOWEVER, some other OpenGL drivers allow accessing array elements
334 * by adding an offset to the returned array location. And some apps
335 * seem to depend on that behaviour.
337 * Mesa's gl_uniform_list doesn't directly support this since each
338 * entry in the list describes one uniform variable, not one uniform
339 * element. We could insert dummy entries in the list for each array
340 * element after [0] but that causes complications elsewhere.
342 * We solve this problem by encoding two values in the location that's
343 * returned by glGetUniformLocation():
344 * a) index into gl_uniform_list::Uniforms[] for the uniform
345 * b) an array/field offset (0 for simple types)
347 * These two values are encoded in the high and low halves of a GLint.
348 * By putting the uniform number in the high part and the offset in the
349 * low part, we can support the unofficial ability to index into arrays
350 * by adding offsets to the location value.
353 merge_location_offset(GLint
*location
, GLint offset
)
355 *location
= (*location
<< 16) | offset
;
360 * Separate the uniform location and parameter offset. See above.
363 split_location_offset(GLint
*location
, GLint
*offset
)
365 *offset
= *location
& 0xffff;
366 *location
= *location
>> 16;
372 * Called via glGetUniformfv().
375 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
378 struct gl_program
*prog
;
382 split_location_offset(&location
, &offset
);
384 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
387 const struct gl_program_parameter
*p
=
388 &prog
->Parameters
->Parameters
[paramPos
];
389 GLint rows
, cols
, i
, j
, k
;
391 get_uniform_rows_cols(p
, &rows
, &cols
);
394 for (i
= 0; i
< rows
; i
++) {
395 for (j
= 0; j
< cols
; j
++ ) {
396 params
[k
++] = prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
404 * Called via glGetUniformiv().
405 * \sa _mesa_get_uniformfv, only difference is a cast.
408 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
411 struct gl_program
*prog
;
415 split_location_offset(&location
, &offset
);
417 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
420 const struct gl_program_parameter
*p
=
421 &prog
->Parameters
->Parameters
[paramPos
];
422 GLint rows
, cols
, i
, j
, k
;
424 get_uniform_rows_cols(p
, &rows
, &cols
);
427 for (i
= 0; i
< rows
; i
++) {
428 for (j
= 0; j
< cols
; j
++ ) {
429 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
437 * Called via glGetUniformLocation().
439 * The return value will encode two values, the uniform location and an
440 * offset (used for arrays, structs).
443 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
445 GLint offset
= 0, location
= -1;
447 struct gl_shader_program
*shProg
=
448 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
453 if (shProg
->LinkStatus
== GL_FALSE
) {
454 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
458 /* XXX we should return -1 if the uniform was declared, but not
462 /* XXX we need to be able to parse uniform names for structs and arrays
469 /* handle 1-dimension arrays here... */
470 char *c
= strchr(name
, '[');
472 /* truncate name at [ */
473 const GLint len
= c
- name
;
474 GLchar
*newName
= malloc(len
+ 1);
476 return -1; /* out of mem */
477 memcpy(newName
, name
, len
);
480 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
482 const GLint element
= atoi(c
+ 1);
484 /* get type of the uniform array element */
485 struct gl_program_parameter
*p
;
486 p
= get_uniform_parameter(shProg
, location
);
489 get_matrix_dims(p
->DataType
, &rows
, &cols
);
492 offset
= element
* rows
;
502 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
506 merge_location_offset(&location
, offset
);
515 * Update the vertex/fragment program's TexturesUsed array.
517 * This needs to be called after glUniform(set sampler var) is called.
518 * A call to glUniform(samplerVar, value) causes a sampler to point to a
519 * particular texture unit. We know the sampler's texture target
520 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
521 * set by glUniform() calls.
523 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
524 * information to update the prog->TexturesUsed[] values.
525 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
526 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
527 * We'll use that info for state validation before rendering.
530 _mesa_update_shader_textures_used(struct gl_program
*prog
)
534 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
536 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
537 if (prog
->SamplersUsed
& (1 << s
)) {
538 GLuint unit
= prog
->SamplerUnits
[s
];
539 GLuint tgt
= prog
->SamplerTargets
[s
];
540 assert(unit
< MAX_TEXTURE_IMAGE_UNITS
);
541 assert(tgt
< NUM_TEXTURE_TARGETS
);
542 prog
->TexturesUsed
[unit
] |= (1 << tgt
);
549 * Check if the type given by userType is allowed to set a uniform of the
550 * target type. Generally, equivalence is required, but setting Boolean
551 * uniforms can be done with glUniformiv or glUniformfv.
554 compatible_types(GLenum userType
, GLenum targetType
)
556 if (userType
== targetType
)
559 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
||
560 userType
== GL_UNSIGNED_INT
||
564 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
565 userType
== GL_UNSIGNED_INT_VEC2
||
566 userType
== GL_INT_VEC2
))
569 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
570 userType
== GL_UNSIGNED_INT_VEC3
||
571 userType
== GL_INT_VEC3
))
574 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
575 userType
== GL_UNSIGNED_INT_VEC4
||
576 userType
== GL_INT_VEC4
))
579 if (is_sampler_type(targetType
) && userType
== GL_INT
)
587 * Set the value of a program's uniform variable.
588 * \param program the program whose uniform to update
589 * \param index the index of the program parameter for the uniform
590 * \param offset additional parameter slot offset (for arrays)
591 * \param type the incoming datatype of 'values'
592 * \param count the number of uniforms to set
593 * \param elems number of elements per uniform (1, 2, 3 or 4)
594 * \param values the new values, of datatype 'type'
597 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
598 GLint index
, GLint offset
,
599 GLenum type
, GLsizei count
, GLint elems
,
602 const struct gl_program_parameter
*param
=
603 &program
->Parameters
->Parameters
[index
];
609 if (!compatible_types(type
, param
->DataType
)) {
610 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
614 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
619 if (param
->Type
== PROGRAM_SAMPLER
) {
620 /* This controls which texture unit which is used by a sampler */
621 GLboolean changed
= GL_FALSE
;
624 /* this should have been caught by the compatible_types() check */
625 ASSERT(type
== GL_INT
);
627 /* loop over number of samplers to change */
628 for (i
= 0; i
< count
; i
++) {
630 (GLuint
) program
->Parameters
->ParameterValues
[index
+ offset
+ i
][0];
631 GLuint texUnit
= ((GLuint
*) values
)[i
];
633 /* check that the sampler (tex unit index) is legal */
634 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
635 _mesa_error(ctx
, GL_INVALID_VALUE
,
636 "glUniform1(invalid sampler/tex unit index for '%s')",
641 /* This maps a sampler to a texture unit: */
642 if (sampler
< MAX_SAMPLERS
) {
644 printf("Set program %p sampler %d '%s' to unit %u\n",
645 program
, sampler
, param
->Name
, texUnit
);
647 if (program
->SamplerUnits
[sampler
] != texUnit
) {
648 program
->SamplerUnits
[sampler
] = texUnit
;
655 /* When a sampler's value changes it usually requires rewriting
656 * a GPU program's TEX instructions since there may not be a
657 * sampler->texture lookup table. We signal this with the
658 * ProgramStringNotify() callback.
660 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
| _NEW_PROGRAM
);
661 _mesa_update_shader_textures_used(program
);
662 /* Do we need to care about the return value here?
663 * This should not be the first time the driver was notified of
666 (void) ctx
->Driver
.ProgramStringNotify(ctx
, program
->Target
, program
);
670 /* ordinary uniform variable */
671 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
672 const GLenum basicType
= base_uniform_type(type
);
673 const GLint slots
= (param
->Size
+ 3) / 4;
674 const GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
677 if ((GLint
) param
->Size
> typeSize
) {
679 /* we'll ignore extra data below */
682 /* non-array: count must be at most one; count == 0 is handled by the loop below */
684 _mesa_error(ctx
, GL_INVALID_OPERATION
,
685 "glUniform(uniform '%s' is not an array)",
691 /* loop over number of array elements */
692 for (k
= 0; k
< count
; k
++) {
695 if (offset
+ k
>= slots
) {
696 /* Extra array data is ignored */
700 /* uniformVal (the destination) is always float[4] */
701 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
703 if (basicType
== GL_INT
) {
704 /* convert user's ints to floats */
705 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
706 for (i
= 0; i
< elems
; i
++) {
707 uniformVal
[i
] = (GLfloat
) iValues
[i
];
710 else if (basicType
== GL_UNSIGNED_INT
) {
711 /* convert user's uints to floats */
712 const GLuint
*iValues
= ((const GLuint
*) values
) + k
* elems
;
713 for (i
= 0; i
< elems
; i
++) {
714 uniformVal
[i
] = (GLfloat
) iValues
[i
];
718 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
719 assert(basicType
== GL_FLOAT
);
720 for (i
= 0; i
< elems
; i
++) {
721 uniformVal
[i
] = fValues
[i
];
725 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
727 for (i
= 0; i
< elems
; i
++) {
728 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
737 * Called via glUniform*() functions.
740 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
741 const GLvoid
*values
, GLenum type
)
743 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
744 struct gl_uniform
*uniform
;
747 if (!shProg
|| !shProg
->LinkStatus
) {
748 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
753 return; /* The standard specifies this as a no-op */
756 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location=%d)",
761 split_location_offset(&location
, &offset
);
763 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
764 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location=%d)", location
);
769 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
773 elems
= _mesa_sizeof_glsl_type(type
);
775 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
777 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
779 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
780 const GLenum basicType
= base_uniform_type(type
);
782 printf("Mesa: set program %u uniform %s (loc %d) to: ",
783 shProg
->Name
, uniform
->Name
, location
);
784 if (basicType
== GL_INT
) {
785 const GLint
*v
= (const GLint
*) values
;
786 for (i
= 0; i
< count
* elems
; i
++) {
790 else if (basicType
== GL_UNSIGNED_INT
) {
791 const GLuint
*v
= (const GLuint
*) values
;
792 for (i
= 0; i
< count
* elems
; i
++) {
797 const GLfloat
*v
= (const GLfloat
*) values
;
798 assert(basicType
== GL_FLOAT
);
799 for (i
= 0; i
< count
* elems
; i
++) {
806 /* A uniform var may be used by both a vertex shader and a fragment
807 * shader. We may need to update one or both shader's uniform here:
809 if (shProg
->VertexProgram
) {
810 /* convert uniform location to program parameter index */
811 GLint index
= uniform
->VertPos
;
813 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
814 index
, offset
, type
, count
, elems
, values
);
818 if (shProg
->FragmentProgram
) {
819 /* convert uniform location to program parameter index */
820 GLint index
= uniform
->FragPos
;
822 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
823 index
, offset
, type
, count
, elems
, values
);
827 uniform
->Initialized
= GL_TRUE
;
832 * Set a matrix-valued program parameter.
835 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
836 GLuint index
, GLuint offset
,
837 GLuint count
, GLuint rows
, GLuint cols
,
838 GLboolean transpose
, const GLfloat
*values
)
840 GLuint mat
, row
, col
;
842 const struct gl_program_parameter
* param
= &program
->Parameters
->Parameters
[index
];
843 const GLuint slots
= (param
->Size
+ 3) / 4;
844 const GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
847 /* check that the number of rows, columns is correct */
848 get_matrix_dims(param
->DataType
, &nr
, &nc
);
849 if (rows
!= nr
|| cols
!= nc
) {
850 _mesa_error(ctx
, GL_INVALID_OPERATION
,
851 "glUniformMatrix(matrix size mismatch)");
855 if ((GLint
) param
->Size
<= typeSize
) {
856 /* non-array: count must be at most one; count == 0 is handled by the loop below */
858 _mesa_error(ctx
, GL_INVALID_OPERATION
,
859 "glUniformMatrix(uniform is not an array)");
865 * Note: the _columns_ of a matrix are stored in program registers, not
866 * the rows. So, the loops below look a little funny.
867 * XXX could optimize this a bit...
870 /* loop over matrices */
871 for (mat
= 0; mat
< count
; mat
++) {
874 for (col
= 0; col
< cols
; col
++) {
876 if (offset
>= slots
) {
877 /* Ignore writes beyond the end of (the used part of) an array */
880 v
= program
->Parameters
->ParameterValues
[index
+ offset
];
881 for (row
= 0; row
< rows
; row
++) {
883 v
[row
] = values
[src
+ row
* cols
+ col
];
886 v
[row
] = values
[src
+ col
* rows
+ row
];
893 src
+= rows
* cols
; /* next matrix */
899 * Called by glUniformMatrix*() functions.
900 * Note: cols=2, rows=4 ==> array[2] of vec4
903 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
904 GLint location
, GLsizei count
,
905 GLboolean transpose
, const GLfloat
*values
)
907 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
908 struct gl_uniform
*uniform
;
911 if (!shProg
|| !shProg
->LinkStatus
) {
912 _mesa_error(ctx
, GL_INVALID_OPERATION
,
913 "glUniformMatrix(program not linked)");
918 return; /* The standard specifies this as a no-op */
921 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
925 split_location_offset(&location
, &offset
);
927 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
928 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
931 if (values
== NULL
) {
932 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
936 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
938 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
940 if (shProg
->VertexProgram
) {
941 /* convert uniform location to program parameter index */
942 GLint index
= uniform
->VertPos
;
944 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
946 count
, rows
, cols
, transpose
, values
);
950 if (shProg
->FragmentProgram
) {
951 /* convert uniform location to program parameter index */
952 GLint index
= uniform
->FragPos
;
954 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
956 count
, rows
, cols
, transpose
, values
);
960 uniform
->Initialized
= GL_TRUE
;
965 _mesa_Uniform1fARB(GLint location
, GLfloat v0
)
967 GET_CURRENT_CONTEXT(ctx
);
968 _mesa_uniform(ctx
, location
, 1, &v0
, GL_FLOAT
);
972 _mesa_Uniform2fARB(GLint location
, GLfloat v0
, GLfloat v1
)
974 GET_CURRENT_CONTEXT(ctx
);
978 _mesa_uniform(ctx
, location
, 1, v
, GL_FLOAT_VEC2
);
982 _mesa_Uniform3fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
)
984 GET_CURRENT_CONTEXT(ctx
);
989 _mesa_uniform(ctx
, location
, 1, v
, GL_FLOAT_VEC3
);
993 _mesa_Uniform4fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
,
996 GET_CURRENT_CONTEXT(ctx
);
1002 _mesa_uniform(ctx
, location
, 1, v
, GL_FLOAT_VEC4
);
1006 _mesa_Uniform1iARB(GLint location
, GLint v0
)
1008 GET_CURRENT_CONTEXT(ctx
);
1009 _mesa_uniform(ctx
, location
, 1, &v0
, GL_INT
);
1013 _mesa_Uniform2iARB(GLint location
, GLint v0
, GLint v1
)
1015 GET_CURRENT_CONTEXT(ctx
);
1019 _mesa_uniform(ctx
, location
, 1, v
, GL_INT_VEC2
);
1023 _mesa_Uniform3iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
)
1025 GET_CURRENT_CONTEXT(ctx
);
1030 _mesa_uniform(ctx
, location
, 1, v
, GL_INT_VEC3
);
1034 _mesa_Uniform4iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
, GLint v3
)
1036 GET_CURRENT_CONTEXT(ctx
);
1042 _mesa_uniform(ctx
, location
, 1, v
, GL_INT_VEC4
);
1046 _mesa_Uniform1fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1048 GET_CURRENT_CONTEXT(ctx
);
1049 _mesa_uniform(ctx
, location
, count
, value
, GL_FLOAT
);
1053 _mesa_Uniform2fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1055 GET_CURRENT_CONTEXT(ctx
);
1056 _mesa_uniform(ctx
, location
, count
, value
, GL_FLOAT_VEC2
);
1060 _mesa_Uniform3fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1062 GET_CURRENT_CONTEXT(ctx
);
1063 _mesa_uniform(ctx
, location
, count
, value
, GL_FLOAT_VEC3
);
1067 _mesa_Uniform4fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1069 GET_CURRENT_CONTEXT(ctx
);
1070 _mesa_uniform(ctx
, location
, count
, value
, GL_FLOAT_VEC4
);
1074 _mesa_Uniform1ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1076 GET_CURRENT_CONTEXT(ctx
);
1077 _mesa_uniform(ctx
, location
, count
, value
, GL_INT
);
1081 _mesa_Uniform2ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1083 GET_CURRENT_CONTEXT(ctx
);
1084 _mesa_uniform(ctx
, location
, count
, value
, GL_INT_VEC2
);
1088 _mesa_Uniform3ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1090 GET_CURRENT_CONTEXT(ctx
);
1091 _mesa_uniform(ctx
, location
, count
, value
, GL_INT_VEC3
);
1095 _mesa_Uniform4ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1097 GET_CURRENT_CONTEXT(ctx
);
1098 _mesa_uniform(ctx
, location
, count
, value
, GL_INT_VEC4
);
1102 /** OpenGL 3.0 GLuint-valued functions **/
1104 _mesa_Uniform1ui(GLint location
, GLuint v0
)
1106 GET_CURRENT_CONTEXT(ctx
);
1107 _mesa_uniform(ctx
, location
, 1, &v0
, GL_UNSIGNED_INT
);
1111 _mesa_Uniform2ui(GLint location
, GLuint v0
, GLuint v1
)
1113 GET_CURRENT_CONTEXT(ctx
);
1117 _mesa_uniform(ctx
, location
, 1, v
, GL_UNSIGNED_INT_VEC2
);
1121 _mesa_Uniform3ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
)
1123 GET_CURRENT_CONTEXT(ctx
);
1128 _mesa_uniform(ctx
, location
, 1, v
, GL_UNSIGNED_INT_VEC3
);
1132 _mesa_Uniform4ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
, GLuint v3
)
1134 GET_CURRENT_CONTEXT(ctx
);
1140 _mesa_uniform(ctx
, location
, 1, v
, GL_UNSIGNED_INT_VEC4
);
1144 _mesa_Uniform1uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1146 GET_CURRENT_CONTEXT(ctx
);
1147 _mesa_uniform(ctx
, location
, count
, value
, GL_UNSIGNED_INT
);
1151 _mesa_Uniform2uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1153 GET_CURRENT_CONTEXT(ctx
);
1154 _mesa_uniform(ctx
, location
, count
, value
, GL_UNSIGNED_INT_VEC2
);
1158 _mesa_Uniform3uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1160 GET_CURRENT_CONTEXT(ctx
);
1161 _mesa_uniform(ctx
, location
, count
, value
, GL_UNSIGNED_INT_VEC3
);
1165 _mesa_Uniform4uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1167 GET_CURRENT_CONTEXT(ctx
);
1168 _mesa_uniform(ctx
, location
, count
, value
, GL_UNSIGNED_INT_VEC4
);
1174 _mesa_UniformMatrix2fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1175 const GLfloat
* value
)
1177 GET_CURRENT_CONTEXT(ctx
);
1178 _mesa_uniform_matrix(ctx
, 2, 2, location
, count
, transpose
, value
);
1182 _mesa_UniformMatrix3fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1183 const GLfloat
* value
)
1185 GET_CURRENT_CONTEXT(ctx
);
1186 _mesa_uniform_matrix(ctx
, 3, 3, location
, count
, transpose
, value
);
1190 _mesa_UniformMatrix4fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1191 const GLfloat
* value
)
1193 GET_CURRENT_CONTEXT(ctx
);
1194 _mesa_uniform_matrix(ctx
, 4, 4, location
, count
, transpose
, value
);
1199 * Non-square UniformMatrix are OpenGL 2.1
1202 _mesa_UniformMatrix2x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
1203 const GLfloat
*value
)
1205 GET_CURRENT_CONTEXT(ctx
);
1206 _mesa_uniform_matrix(ctx
, 2, 3, location
, count
, transpose
, value
);
1210 _mesa_UniformMatrix3x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
1211 const GLfloat
*value
)
1213 GET_CURRENT_CONTEXT(ctx
);
1214 _mesa_uniform_matrix(ctx
, 3, 2, location
, count
, transpose
, value
);
1218 _mesa_UniformMatrix2x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
1219 const GLfloat
*value
)
1221 GET_CURRENT_CONTEXT(ctx
);
1222 _mesa_uniform_matrix(ctx
, 2, 4, location
, count
, transpose
, value
);
1226 _mesa_UniformMatrix4x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
1227 const GLfloat
*value
)
1229 GET_CURRENT_CONTEXT(ctx
);
1230 _mesa_uniform_matrix(ctx
, 4, 2, location
, count
, transpose
, value
);
1234 _mesa_UniformMatrix3x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
1235 const GLfloat
*value
)
1237 GET_CURRENT_CONTEXT(ctx
);
1238 _mesa_uniform_matrix(ctx
, 3, 4, location
, count
, transpose
, value
);
1242 _mesa_UniformMatrix4x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
1243 const GLfloat
*value
)
1245 GET_CURRENT_CONTEXT(ctx
);
1246 _mesa_uniform_matrix(ctx
, 4, 3, location
, count
, transpose
, value
);
1251 _mesa_GetUniformfvARB(GLhandleARB program
, GLint location
, GLfloat
*params
)
1253 GET_CURRENT_CONTEXT(ctx
);
1254 _mesa_get_uniformfv(ctx
, program
, location
, params
);
1259 _mesa_GetUniformivARB(GLhandleARB program
, GLint location
, GLint
*params
)
1261 GET_CURRENT_CONTEXT(ctx
);
1262 _mesa_get_uniformiv(ctx
, program
, location
, params
);
1267 _mesa_GetUniformLocationARB(GLhandleARB programObj
, const GLcharARB
*name
)
1269 GET_CURRENT_CONTEXT(ctx
);
1270 return _mesa_get_uniform_location(ctx
, programObj
, name
);
1275 _mesa_GetActiveUniformARB(GLhandleARB program
, GLuint index
,
1276 GLsizei maxLength
, GLsizei
* length
, GLint
* size
,
1277 GLenum
* type
, GLcharARB
* name
)
1279 GET_CURRENT_CONTEXT(ctx
);
1280 _mesa_get_active_uniform(ctx
, program
, index
, maxLength
, length
, size
,
1286 * Plug in shader uniform-related functions into API dispatch table.
1289 _mesa_init_shader_uniform_dispatch(struct _glapi_table
*exec
)
1291 SET_Uniform1fARB(exec
, _mesa_Uniform1fARB
);
1292 SET_Uniform2fARB(exec
, _mesa_Uniform2fARB
);
1293 SET_Uniform3fARB(exec
, _mesa_Uniform3fARB
);
1294 SET_Uniform4fARB(exec
, _mesa_Uniform4fARB
);
1295 SET_Uniform1iARB(exec
, _mesa_Uniform1iARB
);
1296 SET_Uniform2iARB(exec
, _mesa_Uniform2iARB
);
1297 SET_Uniform3iARB(exec
, _mesa_Uniform3iARB
);
1298 SET_Uniform4iARB(exec
, _mesa_Uniform4iARB
);
1299 SET_Uniform1fvARB(exec
, _mesa_Uniform1fvARB
);
1300 SET_Uniform2fvARB(exec
, _mesa_Uniform2fvARB
);
1301 SET_Uniform3fvARB(exec
, _mesa_Uniform3fvARB
);
1302 SET_Uniform4fvARB(exec
, _mesa_Uniform4fvARB
);
1303 SET_Uniform1ivARB(exec
, _mesa_Uniform1ivARB
);
1304 SET_Uniform2ivARB(exec
, _mesa_Uniform2ivARB
);
1305 SET_Uniform3ivARB(exec
, _mesa_Uniform3ivARB
);
1306 SET_Uniform4ivARB(exec
, _mesa_Uniform4ivARB
);
1307 SET_UniformMatrix2fvARB(exec
, _mesa_UniformMatrix2fvARB
);
1308 SET_UniformMatrix3fvARB(exec
, _mesa_UniformMatrix3fvARB
);
1309 SET_UniformMatrix4fvARB(exec
, _mesa_UniformMatrix4fvARB
);
1311 SET_GetActiveUniformARB(exec
, _mesa_GetActiveUniformARB
);
1312 SET_GetUniformLocationARB(exec
, _mesa_GetUniformLocationARB
);
1313 SET_GetUniformfvARB(exec
, _mesa_GetUniformfvARB
);
1314 SET_GetUniformivARB(exec
, _mesa_GetUniformivARB
);
1317 SET_UniformMatrix2x3fv(exec
, _mesa_UniformMatrix2x3fv
);
1318 SET_UniformMatrix3x2fv(exec
, _mesa_UniformMatrix3x2fv
);
1319 SET_UniformMatrix2x4fv(exec
, _mesa_UniformMatrix2x4fv
);
1320 SET_UniformMatrix4x2fv(exec
, _mesa_UniformMatrix4x2fv
);
1321 SET_UniformMatrix3x4fv(exec
, _mesa_UniformMatrix3x4fv
);
1322 SET_UniformMatrix4x3fv(exec
, _mesa_UniformMatrix4x3fv
);
1325 /* XXX finish dispatch */
1326 (void) _mesa_Uniform1ui
;
1327 (void) _mesa_Uniform2ui
;
1328 (void) _mesa_Uniform3ui
;
1329 (void) _mesa_Uniform4ui
;
1330 (void) _mesa_Uniform1uiv
;
1331 (void) _mesa_Uniform2uiv
;
1332 (void) _mesa_Uniform3uiv
;
1333 (void) _mesa_Uniform4uiv
;