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.
6 * Copyright © 2010 Intel Corporation
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
28 * Functions related to GLSL uniform variables.
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/dispatch.h"
42 #include "main/image.h"
43 #include "main/mfeatures.h"
44 #include "main/mtypes.h"
45 #include "main/shaderapi.h"
46 #include "main/shaderobj.h"
47 #include "main/uniforms.h"
48 #include "program/prog_parameter.h"
49 #include "program/prog_statevars.h"
50 #include "program/prog_uniform.h"
51 #include "program/prog_instruction.h"
55 base_uniform_type(GLenum type
)
78 case GL_UNSIGNED_INT_VEC2
:
79 case GL_UNSIGNED_INT_VEC3
:
80 case GL_UNSIGNED_INT_VEC4
:
81 return GL_UNSIGNED_INT
;
88 _mesa_problem(NULL
, "Invalid type in base_uniform_type()");
95 is_boolean_type(GLenum type
)
110 is_sampler_type(GLenum type
)
114 case GL_INT_SAMPLER_1D
:
115 case GL_UNSIGNED_INT_SAMPLER_1D
:
117 case GL_INT_SAMPLER_2D
:
118 case GL_UNSIGNED_INT_SAMPLER_2D
:
120 case GL_INT_SAMPLER_3D
:
121 case GL_UNSIGNED_INT_SAMPLER_3D
:
122 case GL_SAMPLER_CUBE
:
123 case GL_INT_SAMPLER_CUBE
:
124 case GL_UNSIGNED_INT_SAMPLER_CUBE
:
125 case GL_SAMPLER_1D_SHADOW
:
126 case GL_SAMPLER_2D_SHADOW
:
127 case GL_SAMPLER_CUBE_SHADOW
:
128 case GL_SAMPLER_2D_RECT_ARB
:
129 case GL_INT_SAMPLER_2D_RECT
:
130 case GL_UNSIGNED_INT_SAMPLER_2D_RECT
:
131 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
132 case GL_SAMPLER_1D_ARRAY_EXT
:
133 case GL_INT_SAMPLER_1D_ARRAY
:
134 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY
:
135 case GL_SAMPLER_2D_ARRAY_EXT
:
136 case GL_INT_SAMPLER_2D_ARRAY
:
137 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY
:
138 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
139 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
140 case GL_SAMPLER_CUBE_MAP_ARRAY
:
141 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW
:
142 case GL_SAMPLER_BUFFER
:
143 case GL_INT_SAMPLER_BUFFER
:
144 case GL_UNSIGNED_INT_SAMPLER_BUFFER
:
145 case GL_SAMPLER_2D_MULTISAMPLE
:
146 case GL_INT_SAMPLER_2D_MULTISAMPLE
:
147 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE
:
148 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY
:
149 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
:
150 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY
:
151 case GL_SAMPLER_EXTERNAL_OES
:
160 * Given a uniform index, return the vertex/geometry/fragment program
161 * that has that parameter, plus the position of the parameter in the
162 * parameter/constant buffer.
163 * \param shProg the shader program
164 * \param index the uniform index in [0, NumUniforms-1]
165 * \param progOut returns containing program
166 * \param posOut returns position of the uniform in the param/const buffer
167 * \return GL_TRUE for success, GL_FALSE for invalid index
170 find_uniform_parameter_pos(struct gl_shader_program
*shProg
, GLint index
,
171 struct gl_program
**progOut
, GLint
*posOut
)
173 struct gl_program
*prog
= NULL
;
176 if (!shProg
->Uniforms
||
178 index
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
182 pos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
184 prog
= shProg
->_LinkedShaders
[MESA_SHADER_VERTEX
]->Program
;
187 pos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
189 prog
= shProg
->_LinkedShaders
[MESA_SHADER_FRAGMENT
]->Program
;
192 pos
= shProg
->Uniforms
->Uniforms
[index
].GeomPos
;
194 prog
= shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->Program
;
199 if (!prog
|| pos
< 0)
200 return GL_FALSE
; /* should really never happen */
210 * Return pointer to a gl_program_parameter which corresponds to a uniform.
211 * \param shProg the shader program
212 * \param index the uniform index in [0, NumUniforms-1]
213 * \return gl_program_parameter point or NULL if index is invalid
215 const struct gl_program_parameter
*
216 get_uniform_parameter(struct gl_shader_program
*shProg
, GLint index
)
218 struct gl_program
*prog
;
221 if (find_uniform_parameter_pos(shProg
, index
, &prog
, &progPos
))
222 return &prog
->Parameters
->Parameters
[progPos
];
229 get_vector_elements(GLenum type
)
235 case GL_UNSIGNED_INT
:
236 default: /* Catch all the various sampler types. */
242 case GL_UNSIGNED_INT_VEC2
:
248 case GL_UNSIGNED_INT_VEC3
:
254 case GL_UNSIGNED_INT_VEC4
:
260 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
266 case GL_FLOAT_MAT2x3
:
270 case GL_FLOAT_MAT2x4
:
278 case GL_FLOAT_MAT3x2
:
282 case GL_FLOAT_MAT3x4
:
290 case GL_FLOAT_MAT4x2
:
294 case GL_FLOAT_MAT4x3
:
305 * Determine the number of rows and columns occupied by a uniform
306 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
307 * the number of rows = 1 and cols = number of elements in the vector.
310 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
311 GLint
*rows
, GLint
*cols
)
313 get_matrix_dims(p
->DataType
, rows
, cols
);
314 if (*rows
== 0 && *cols
== 0) {
315 /* not a matrix type, probably a float or vector */
317 *cols
= get_vector_elements(p
->DataType
);
323 * GLSL uniform arrays and structs require special handling.
325 * The GL_ARB_shader_objects spec says that if you use
326 * glGetUniformLocation to get the location of an array, you CANNOT
327 * access other elements of the array by adding an offset to the
328 * returned location. For example, you must call
329 * glGetUniformLocation("foo[16]") if you want to set the 16th element
330 * of the array with glUniform().
332 * HOWEVER, some other OpenGL drivers allow accessing array elements
333 * by adding an offset to the returned array location. And some apps
334 * seem to depend on that behaviour.
336 * Mesa's gl_uniform_list doesn't directly support this since each
337 * entry in the list describes one uniform variable, not one uniform
338 * element. We could insert dummy entries in the list for each array
339 * element after [0] but that causes complications elsewhere.
341 * We solve this problem by encoding two values in the location that's
342 * returned by glGetUniformLocation():
343 * a) index into gl_uniform_list::Uniforms[] for the uniform
344 * b) an array/field offset (0 for simple types)
346 * These two values are encoded in the high and low halves of a GLint.
347 * By putting the uniform number in the high part and the offset in the
348 * low part, we can support the unofficial ability to index into arrays
349 * by adding offsets to the location value.
352 merge_location_offset(GLint
*location
, GLint offset
)
354 *location
= (*location
<< 16) | offset
;
359 * Separate the uniform location and parameter offset. See above.
362 split_location_offset(GLint
*location
, GLint
*offset
)
364 *offset
= *location
& 0xffff;
365 *location
= *location
>> 16;
371 * Called via glGetUniform[fiui]v() to get the current value of a uniform.
374 get_uniform(struct gl_context
*ctx
, GLuint program
, GLint location
,
375 GLsizei bufSize
, GLenum returnType
, GLvoid
*paramsOut
)
377 struct gl_shader_program
*shProg
=
378 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformfv");
379 struct gl_program
*prog
;
380 GLint paramPos
, offset
;
385 split_location_offset(&location
, &offset
);
387 if (!find_uniform_parameter_pos(shProg
, location
, &prog
, ¶mPos
)) {
388 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
391 const struct gl_program_parameter
*p
=
392 &prog
->Parameters
->Parameters
[paramPos
];
393 gl_constant_value (*values
)[4];
394 GLint rows
, cols
, i
, j
, k
;
398 values
= prog
->Parameters
->ParameterValues
+ paramPos
+ offset
;
400 get_uniform_rows_cols(p
, &rows
, &cols
);
402 numBytes
= rows
* cols
* _mesa_sizeof_type(returnType
);
403 if (bufSize
< numBytes
) {
404 _mesa_error( ctx
, GL_INVALID_OPERATION
,
405 "glGetnUniformfvARB(out of bounds: bufSize is %d,"
406 " but %d bytes are required)", bufSize
, numBytes
);
410 if (ctx
->Const
.NativeIntegers
) {
411 storage_type
= base_uniform_type(p
->DataType
);
413 storage_type
= GL_FLOAT
;
417 for (i
= 0; i
< rows
; i
++) {
418 for (j
= 0; j
< cols
; j
++ ) {
419 void *out
= (char *)paramsOut
+ 4 * k
;
421 switch (returnType
) {
423 switch (storage_type
) {
425 *(float *)out
= values
[i
][j
].f
;
428 case GL_BOOL
: /* boolean is just an integer 1 or 0. */
429 *(float *)out
= values
[i
][j
].i
;
431 case GL_UNSIGNED_INT
:
432 *(float *)out
= values
[i
][j
].u
;
438 case GL_UNSIGNED_INT
:
439 switch (storage_type
) {
441 /* While the GL 3.2 core spec doesn't explicitly
442 * state how conversion of float uniforms to integer
443 * values works, in section 6.2 "State Tables" on
446 * "Unless otherwise specified, when floating
447 * point state is returned as integer values or
448 * integer state is returned as floating-point
449 * values it is converted in the fashion
450 * described in section 6.1.2"
452 * That section, on page 248, says:
454 * "If GetIntegerv or GetInteger64v are called,
455 * a floating-point value is rounded to the
456 * nearest integer..."
458 *(int *)out
= IROUND(values
[i
][j
].f
);
462 case GL_UNSIGNED_INT
:
464 /* type conversions for these to int/uint are just
467 *(int *)out
= values
[i
][j
].i
;
482 * Called via glGetUniformLocation().
484 * The return value will encode two values, the uniform location and an
485 * offset (used for arrays, structs).
488 _mesa_get_uniform_location(struct gl_context
*ctx
,
489 struct gl_shader_program
*shProg
,
492 GLint offset
= 0, location
= -1;
494 /* XXX we should return -1 if the uniform was declared, but not
498 /* XXX we need to be able to parse uniform names for structs and arrays
505 /* handle 1-dimension arrays here... */
506 char *c
= strchr(name
, '[');
508 /* truncate name at [ */
509 const GLint len
= c
- name
;
510 GLchar
*newName
= malloc(len
+ 1);
512 return -1; /* out of mem */
513 memcpy(newName
, name
, len
);
516 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
518 const GLint element
= atoi(c
+ 1);
520 /* get type of the uniform array element */
521 const struct gl_program_parameter
*p
=
522 get_uniform_parameter(shProg
, location
);
525 get_matrix_dims(p
->DataType
, &rows
, &cols
);
528 offset
= element
* rows
;
538 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
542 merge_location_offset(&location
, offset
);
551 * Update the vertex/fragment program's TexturesUsed array.
553 * This needs to be called after glUniform(set sampler var) is called.
554 * A call to glUniform(samplerVar, value) causes a sampler to point to a
555 * particular texture unit. We know the sampler's texture target
556 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
557 * set by glUniform() calls.
559 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
560 * information to update the prog->TexturesUsed[] values.
561 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
562 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
563 * We'll use that info for state validation before rendering.
566 _mesa_update_shader_textures_used(struct gl_program
*prog
)
570 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
572 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
573 if (prog
->SamplersUsed
& (1 << s
)) {
574 GLuint unit
= prog
->SamplerUnits
[s
];
575 GLuint tgt
= prog
->SamplerTargets
[s
];
576 assert(unit
< Elements(prog
->TexturesUsed
));
577 assert(tgt
< NUM_TEXTURE_TARGETS
);
578 prog
->TexturesUsed
[unit
] |= (1 << tgt
);
585 * Check if the type given by userType is allowed to set a uniform of the
586 * target type. Generally, equivalence is required, but setting Boolean
587 * uniforms can be done with glUniformiv or glUniformfv.
590 compatible_types(GLenum userType
, GLenum targetType
)
592 if (userType
== targetType
)
595 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
||
596 userType
== GL_UNSIGNED_INT
||
600 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
601 userType
== GL_UNSIGNED_INT_VEC2
||
602 userType
== GL_INT_VEC2
))
605 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
606 userType
== GL_UNSIGNED_INT_VEC3
||
607 userType
== GL_INT_VEC3
))
610 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
611 userType
== GL_UNSIGNED_INT_VEC4
||
612 userType
== GL_INT_VEC4
))
615 if (is_sampler_type(targetType
) && userType
== GL_INT
)
623 * Set the value of a program's uniform variable.
624 * \param program the program whose uniform to update
625 * \param index the index of the program parameter for the uniform
626 * \param offset additional parameter slot offset (for arrays)
627 * \param type the incoming datatype of 'values'
628 * \param count the number of uniforms to set
629 * \param elems number of elements per uniform (1, 2, 3 or 4)
630 * \param values the new values, of datatype 'type'
633 set_program_uniform(struct gl_context
*ctx
, struct gl_program
*program
,
634 GLint index
, GLint offset
,
635 GLenum type
, GLsizei count
, GLint elems
,
638 const struct gl_program_parameter
*param
=
639 &program
->Parameters
->Parameters
[index
];
645 if (!compatible_types(type
, param
->DataType
)) {
646 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
650 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
655 if (param
->Type
== PROGRAM_SAMPLER
) {
656 /* This controls which texture unit which is used by a sampler */
657 GLboolean changed
= GL_FALSE
;
660 /* this should have been caught by the compatible_types() check */
661 ASSERT(type
== GL_INT
);
663 /* loop over number of samplers to change */
664 for (i
= 0; i
< count
; i
++) {
665 GLuint sampler
= (GLuint
)
666 program
->Parameters
->ParameterValues
[index
+offset
+ i
][0].f
;
667 GLuint texUnit
= ((GLuint
*) values
)[i
];
669 /* check that the sampler (tex unit index) is legal */
670 if (texUnit
>= ctx
->Const
.MaxCombinedTextureImageUnits
) {
671 _mesa_error(ctx
, GL_INVALID_VALUE
,
672 "glUniform1(invalid sampler/tex unit index for '%s')",
677 /* This maps a sampler to a texture unit: */
678 if (sampler
< MAX_SAMPLERS
) {
680 printf("Set program %p sampler %d '%s' to unit %u\n",
681 program
, sampler
, param
->Name
, texUnit
);
683 if (program
->SamplerUnits
[sampler
] != texUnit
) {
684 program
->SamplerUnits
[sampler
] = texUnit
;
691 /* When a sampler's value changes it usually requires rewriting
692 * a GPU program's TEX instructions since there may not be a
693 * sampler->texture lookup table. We signal this with the
694 * ProgramStringNotify() callback.
696 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
| _NEW_PROGRAM
);
697 _mesa_update_shader_textures_used(program
);
698 /* Do we need to care about the return value here?
699 * This should not be the first time the driver was notified of
702 (void) ctx
->Driver
.ProgramStringNotify(ctx
, program
->Target
, program
);
706 /* ordinary uniform variable */
707 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
708 const GLenum basicType
= base_uniform_type(type
);
709 const GLint slots
= (param
->Size
+ 3) / 4;
710 const GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
713 if ((GLint
) param
->Size
> typeSize
) {
715 /* we'll ignore extra data below */
718 /* non-array: count must be at most one; count == 0 is handled
722 _mesa_error(ctx
, GL_INVALID_OPERATION
,
723 "glUniform(uniform '%s' is not an array)",
729 /* loop over number of array elements */
730 for (k
= 0; k
< count
; k
++) {
731 gl_constant_value
*uniformVal
;
733 if (offset
+ k
>= slots
) {
734 /* Extra array data is ignored */
738 /* uniformVal (the destination) is always gl_constant_value[4] */
739 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
741 if (basicType
== GL_INT
) {
742 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
743 for (i
= 0; i
< elems
; i
++) {
744 if (!ctx
->Const
.NativeIntegers
)
745 uniformVal
[i
].f
= (GLfloat
) iValues
[i
];
747 uniformVal
[i
].i
= iValues
[i
];
750 else if (basicType
== GL_UNSIGNED_INT
) {
751 const GLuint
*iValues
= ((const GLuint
*) values
) + k
* elems
;
752 for (i
= 0; i
< elems
; i
++) {
753 if (!ctx
->Const
.NativeIntegers
)
754 uniformVal
[i
].f
= (GLfloat
)(GLuint
) iValues
[i
];
756 uniformVal
[i
].u
= iValues
[i
];
760 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
761 assert(basicType
== GL_FLOAT
);
762 for (i
= 0; i
< elems
; i
++) {
763 uniformVal
[i
].f
= fValues
[i
];
767 /* if the uniform is bool-valued, convert to 1 or 0 */
769 for (i
= 0; i
< elems
; i
++) {
770 if (basicType
== GL_FLOAT
)
771 uniformVal
[i
].b
= uniformVal
[i
].f
!= 0.0f
? 1 : 0;
773 uniformVal
[i
].b
= uniformVal
[i
].u
? 1 : 0;
775 if (ctx
->Const
.NativeIntegers
)
777 uniformVal
[i
].b
? ctx
->Const
.UniformBooleanTrue
: 0;
779 uniformVal
[i
].f
= uniformVal
[i
].b
? 1.0f
: 0.0f
;
788 * Called via glUniform*() functions.
791 _mesa_uniform(struct gl_context
*ctx
, struct gl_shader_program
*shProg
,
792 GLint location
, GLsizei count
,
793 const GLvoid
*values
, GLenum type
)
795 struct gl_uniform
*uniform
;
798 ASSERT_OUTSIDE_BEGIN_END(ctx
);
800 if (!shProg
|| !shProg
->LinkStatus
) {
801 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
806 return; /* The standard specifies this as a no-op */
809 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location=%d)",
814 split_location_offset(&location
, &offset
);
816 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
817 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location=%d)", location
);
822 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
826 elems
= _mesa_sizeof_glsl_type(type
);
828 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
830 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
832 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
833 const GLenum basicType
= base_uniform_type(type
);
835 printf("Mesa: set program %u uniform %s (loc %d) to: ",
836 shProg
->Name
, uniform
->Name
, location
);
837 if (basicType
== GL_INT
) {
838 const GLint
*v
= (const GLint
*) values
;
839 for (i
= 0; i
< count
* elems
; i
++) {
843 else if (basicType
== GL_UNSIGNED_INT
) {
844 const GLuint
*v
= (const GLuint
*) values
;
845 for (i
= 0; i
< count
* elems
; i
++) {
850 const GLfloat
*v
= (const GLfloat
*) values
;
851 assert(basicType
== GL_FLOAT
);
852 for (i
= 0; i
< count
* elems
; i
++) {
859 /* A uniform var may be used by both a vertex shader and a fragment
860 * shader. We may need to update one or both shader's uniform here:
862 if (shProg
->_LinkedShaders
[MESA_SHADER_VERTEX
]) {
863 /* convert uniform location to program parameter index */
864 GLint index
= uniform
->VertPos
;
866 set_program_uniform(ctx
,
867 shProg
->_LinkedShaders
[MESA_SHADER_VERTEX
]->Program
,
868 index
, offset
, type
, count
, elems
, values
);
872 if (shProg
->_LinkedShaders
[MESA_SHADER_FRAGMENT
]) {
873 /* convert uniform location to program parameter index */
874 GLint index
= uniform
->FragPos
;
876 set_program_uniform(ctx
,
877 shProg
->_LinkedShaders
[MESA_SHADER_FRAGMENT
]->Program
,
878 index
, offset
, type
, count
, elems
, values
);
882 if (shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]) {
883 /* convert uniform location to program parameter index */
884 GLint index
= uniform
->GeomPos
;
886 set_program_uniform(ctx
,
887 shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->Program
,
888 index
, offset
, type
, count
, elems
, values
);
892 uniform
->Initialized
= GL_TRUE
;
897 * Set a matrix-valued program parameter.
900 set_program_uniform_matrix(struct gl_context
*ctx
, struct gl_program
*program
,
901 GLuint index
, GLuint offset
,
902 GLuint count
, GLuint rows
, GLuint cols
,
903 GLboolean transpose
, const GLfloat
*values
)
905 GLuint mat
, row
, col
;
907 const struct gl_program_parameter
*param
=
908 &program
->Parameters
->Parameters
[index
];
909 const GLuint slots
= (param
->Size
+ 3) / 4;
910 const GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
913 /* check that the number of rows, columns is correct */
914 get_matrix_dims(param
->DataType
, &nr
, &nc
);
915 if (rows
!= nr
|| cols
!= nc
) {
916 _mesa_error(ctx
, GL_INVALID_OPERATION
,
917 "glUniformMatrix(matrix size mismatch)");
921 if ((GLint
) param
->Size
<= typeSize
) {
922 /* non-array: count must be at most one; count == 0 is handled
926 _mesa_error(ctx
, GL_INVALID_OPERATION
,
927 "glUniformMatrix(uniform is not an array)");
933 * Note: the _columns_ of a matrix are stored in program registers, not
934 * the rows. So, the loops below look a little funny.
935 * XXX could optimize this a bit...
938 /* loop over matrices */
939 for (mat
= 0; mat
< count
; mat
++) {
942 for (col
= 0; col
< cols
; col
++) {
944 if (offset
>= slots
) {
945 /* Ignore writes beyond the end of (the used part of) an array */
948 v
= (GLfloat
*) program
->Parameters
->ParameterValues
[index
+ offset
];
949 for (row
= 0; row
< rows
; row
++) {
951 v
[row
] = values
[src
+ row
* cols
+ col
];
954 v
[row
] = values
[src
+ col
* rows
+ row
];
961 src
+= rows
* cols
; /* next matrix */
967 * Called by glUniformMatrix*() functions.
968 * Note: cols=2, rows=4 ==> array[2] of vec4
971 _mesa_uniform_matrix(struct gl_context
*ctx
, struct gl_shader_program
*shProg
,
972 GLint cols
, GLint rows
,
973 GLint location
, GLsizei count
,
974 GLboolean transpose
, const GLfloat
*values
)
976 struct gl_uniform
*uniform
;
979 ASSERT_OUTSIDE_BEGIN_END(ctx
);
981 if (!shProg
|| !shProg
->LinkStatus
) {
982 _mesa_error(ctx
, GL_INVALID_OPERATION
,
983 "glUniformMatrix(program not linked)");
988 return; /* The standard specifies this as a no-op */
991 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
995 split_location_offset(&location
, &offset
);
997 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
998 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1001 if (values
== NULL
) {
1002 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1006 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1008 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1010 if (shProg
->_LinkedShaders
[MESA_SHADER_VERTEX
]) {
1011 /* convert uniform location to program parameter index */
1012 GLint index
= uniform
->VertPos
;
1014 set_program_uniform_matrix(ctx
,
1015 shProg
->_LinkedShaders
[MESA_SHADER_VERTEX
]->Program
,
1017 count
, rows
, cols
, transpose
, values
);
1021 if (shProg
->_LinkedShaders
[MESA_SHADER_FRAGMENT
]) {
1022 /* convert uniform location to program parameter index */
1023 GLint index
= uniform
->FragPos
;
1025 set_program_uniform_matrix(ctx
,
1026 shProg
->_LinkedShaders
[MESA_SHADER_FRAGMENT
]->Program
,
1028 count
, rows
, cols
, transpose
, values
);
1032 if (shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]) {
1033 /* convert uniform location to program parameter index */
1034 GLint index
= uniform
->GeomPos
;
1036 set_program_uniform_matrix(ctx
,
1037 shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->Program
,
1039 count
, rows
, cols
, transpose
, values
);
1043 uniform
->Initialized
= GL_TRUE
;
1048 _mesa_Uniform1fARB(GLint location
, GLfloat v0
)
1050 GET_CURRENT_CONTEXT(ctx
);
1051 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_FLOAT
);
1055 _mesa_Uniform2fARB(GLint location
, GLfloat v0
, GLfloat v1
)
1057 GET_CURRENT_CONTEXT(ctx
);
1061 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC2
);
1065 _mesa_Uniform3fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
)
1067 GET_CURRENT_CONTEXT(ctx
);
1072 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC3
);
1076 _mesa_Uniform4fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
,
1079 GET_CURRENT_CONTEXT(ctx
);
1085 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC4
);
1089 _mesa_Uniform1iARB(GLint location
, GLint v0
)
1091 GET_CURRENT_CONTEXT(ctx
);
1092 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_INT
);
1096 _mesa_Uniform2iARB(GLint location
, GLint v0
, GLint v1
)
1098 GET_CURRENT_CONTEXT(ctx
);
1102 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC2
);
1106 _mesa_Uniform3iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
)
1108 GET_CURRENT_CONTEXT(ctx
);
1113 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC3
);
1117 _mesa_Uniform4iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
, GLint v3
)
1119 GET_CURRENT_CONTEXT(ctx
);
1125 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC4
);
1129 _mesa_Uniform1fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1131 GET_CURRENT_CONTEXT(ctx
);
1132 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT
);
1136 _mesa_Uniform2fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1138 GET_CURRENT_CONTEXT(ctx
);
1139 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC2
);
1143 _mesa_Uniform3fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1145 GET_CURRENT_CONTEXT(ctx
);
1146 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC3
);
1150 _mesa_Uniform4fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1152 GET_CURRENT_CONTEXT(ctx
);
1153 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC4
);
1157 _mesa_Uniform1ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1159 GET_CURRENT_CONTEXT(ctx
);
1160 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT
);
1164 _mesa_Uniform2ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1166 GET_CURRENT_CONTEXT(ctx
);
1167 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC2
);
1171 _mesa_Uniform3ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1173 GET_CURRENT_CONTEXT(ctx
);
1174 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC3
);
1178 _mesa_Uniform4ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1180 GET_CURRENT_CONTEXT(ctx
);
1181 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC4
);
1185 /** OpenGL 3.0 GLuint-valued functions **/
1187 _mesa_Uniform1ui(GLint location
, GLuint v0
)
1189 GET_CURRENT_CONTEXT(ctx
);
1190 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_UNSIGNED_INT
);
1194 _mesa_Uniform2ui(GLint location
, GLuint v0
, GLuint v1
)
1196 GET_CURRENT_CONTEXT(ctx
);
1200 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC2
);
1204 _mesa_Uniform3ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
)
1206 GET_CURRENT_CONTEXT(ctx
);
1211 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC3
);
1215 _mesa_Uniform4ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
, GLuint v3
)
1217 GET_CURRENT_CONTEXT(ctx
);
1223 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC4
);
1227 _mesa_Uniform1uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1229 GET_CURRENT_CONTEXT(ctx
);
1230 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT
);
1234 _mesa_Uniform2uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1236 GET_CURRENT_CONTEXT(ctx
);
1237 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC2
);
1241 _mesa_Uniform3uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1243 GET_CURRENT_CONTEXT(ctx
);
1244 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC3
);
1248 _mesa_Uniform4uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1250 GET_CURRENT_CONTEXT(ctx
);
1251 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC4
);
1257 _mesa_UniformMatrix2fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1258 const GLfloat
* value
)
1260 GET_CURRENT_CONTEXT(ctx
);
1261 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1262 2, 2, location
, count
, transpose
, value
);
1266 _mesa_UniformMatrix3fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1267 const GLfloat
* value
)
1269 GET_CURRENT_CONTEXT(ctx
);
1270 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1271 3, 3, location
, count
, transpose
, value
);
1275 _mesa_UniformMatrix4fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1276 const GLfloat
* value
)
1278 GET_CURRENT_CONTEXT(ctx
);
1279 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1280 4, 4, location
, count
, transpose
, value
);
1285 * Non-square UniformMatrix are OpenGL 2.1
1288 _mesa_UniformMatrix2x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
1289 const GLfloat
*value
)
1291 GET_CURRENT_CONTEXT(ctx
);
1292 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1293 2, 3, location
, count
, transpose
, value
);
1297 _mesa_UniformMatrix3x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
1298 const GLfloat
*value
)
1300 GET_CURRENT_CONTEXT(ctx
);
1301 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1302 3, 2, location
, count
, transpose
, value
);
1306 _mesa_UniformMatrix2x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
1307 const GLfloat
*value
)
1309 GET_CURRENT_CONTEXT(ctx
);
1310 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1311 2, 4, location
, count
, transpose
, value
);
1315 _mesa_UniformMatrix4x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
1316 const GLfloat
*value
)
1318 GET_CURRENT_CONTEXT(ctx
);
1319 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1320 4, 2, location
, count
, transpose
, value
);
1324 _mesa_UniformMatrix3x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
1325 const GLfloat
*value
)
1327 GET_CURRENT_CONTEXT(ctx
);
1328 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1329 3, 4, location
, count
, transpose
, value
);
1333 _mesa_UniformMatrix4x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
1334 const GLfloat
*value
)
1336 GET_CURRENT_CONTEXT(ctx
);
1337 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1338 4, 3, location
, count
, transpose
, value
);
1343 _mesa_GetnUniformfvARB(GLhandleARB program
, GLint location
,
1344 GLsizei bufSize
, GLfloat
*params
)
1346 GET_CURRENT_CONTEXT(ctx
);
1347 get_uniform(ctx
, program
, location
, bufSize
, GL_FLOAT
, params
);
1351 _mesa_GetUniformfvARB(GLhandleARB program
, GLint location
, GLfloat
*params
)
1353 _mesa_GetnUniformfvARB(program
, location
, INT_MAX
, params
);
1358 _mesa_GetnUniformivARB(GLhandleARB program
, GLint location
,
1359 GLsizei bufSize
, GLint
*params
)
1361 GET_CURRENT_CONTEXT(ctx
);
1362 get_uniform(ctx
, program
, location
, bufSize
, GL_INT
, params
);
1366 _mesa_GetUniformivARB(GLhandleARB program
, GLint location
, GLint
*params
)
1368 _mesa_GetnUniformivARB(program
, location
, INT_MAX
, params
);
1374 _mesa_GetnUniformuivARB(GLhandleARB program
, GLint location
,
1375 GLsizei bufSize
, GLuint
*params
)
1377 GET_CURRENT_CONTEXT(ctx
);
1378 get_uniform(ctx
, program
, location
, bufSize
, GL_UNSIGNED_INT
, params
);
1382 _mesa_GetUniformuiv(GLhandleARB program
, GLint location
, GLuint
*params
)
1384 _mesa_GetnUniformuivARB(program
, location
, INT_MAX
, params
);
1390 _mesa_GetnUniformdvARB(GLhandleARB program
, GLint location
,
1391 GLsizei bufSize
, GLdouble
*params
)
1393 GET_CURRENT_CONTEXT(ctx
);
1401 get_uniform(ctx, program, location, bufSize, GL_DOUBLE, params);
1403 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformdvARB"
1404 "(GL_ARB_gpu_shader_fp64 not implemented)");
1408 _mesa_GetUniformdv(GLhandleARB program
, GLint location
, GLdouble
*params
)
1410 _mesa_GetnUniformdvARB(program
, location
, INT_MAX
, params
);
1415 _mesa_GetUniformLocationARB(GLhandleARB programObj
, const GLcharARB
*name
)
1417 struct gl_shader_program
*shProg
;
1419 GET_CURRENT_CONTEXT(ctx
);
1421 shProg
= _mesa_lookup_shader_program_err(ctx
, programObj
,
1422 "glGetUniformLocation");
1426 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
1428 * "If program has not been successfully linked, the error
1429 * INVALID_OPERATION is generated."
1431 if (shProg
->LinkStatus
== GL_FALSE
) {
1432 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1433 "glGetUniformLocation(program not linked)");
1437 return _mesa_get_uniform_location(ctx
, shProg
, name
);
1442 * Plug in shader uniform-related functions into API dispatch table.
1445 _mesa_init_shader_uniform_dispatch(struct _glapi_table
*exec
)
1448 SET_Uniform1fARB(exec
, _mesa_Uniform1fARB
);
1449 SET_Uniform2fARB(exec
, _mesa_Uniform2fARB
);
1450 SET_Uniform3fARB(exec
, _mesa_Uniform3fARB
);
1451 SET_Uniform4fARB(exec
, _mesa_Uniform4fARB
);
1452 SET_Uniform1iARB(exec
, _mesa_Uniform1iARB
);
1453 SET_Uniform2iARB(exec
, _mesa_Uniform2iARB
);
1454 SET_Uniform3iARB(exec
, _mesa_Uniform3iARB
);
1455 SET_Uniform4iARB(exec
, _mesa_Uniform4iARB
);
1456 SET_Uniform1fvARB(exec
, _mesa_Uniform1fvARB
);
1457 SET_Uniform2fvARB(exec
, _mesa_Uniform2fvARB
);
1458 SET_Uniform3fvARB(exec
, _mesa_Uniform3fvARB
);
1459 SET_Uniform4fvARB(exec
, _mesa_Uniform4fvARB
);
1460 SET_Uniform1ivARB(exec
, _mesa_Uniform1ivARB
);
1461 SET_Uniform2ivARB(exec
, _mesa_Uniform2ivARB
);
1462 SET_Uniform3ivARB(exec
, _mesa_Uniform3ivARB
);
1463 SET_Uniform4ivARB(exec
, _mesa_Uniform4ivARB
);
1464 SET_UniformMatrix2fvARB(exec
, _mesa_UniformMatrix2fvARB
);
1465 SET_UniformMatrix3fvARB(exec
, _mesa_UniformMatrix3fvARB
);
1466 SET_UniformMatrix4fvARB(exec
, _mesa_UniformMatrix4fvARB
);
1468 SET_GetActiveUniformARB(exec
, _mesa_GetActiveUniformARB
);
1469 SET_GetUniformLocationARB(exec
, _mesa_GetUniformLocationARB
);
1470 SET_GetUniformfvARB(exec
, _mesa_GetUniformfvARB
);
1471 SET_GetUniformivARB(exec
, _mesa_GetUniformivARB
);
1474 SET_UniformMatrix2x3fv(exec
, _mesa_UniformMatrix2x3fv
);
1475 SET_UniformMatrix3x2fv(exec
, _mesa_UniformMatrix3x2fv
);
1476 SET_UniformMatrix2x4fv(exec
, _mesa_UniformMatrix2x4fv
);
1477 SET_UniformMatrix4x2fv(exec
, _mesa_UniformMatrix4x2fv
);
1478 SET_UniformMatrix3x4fv(exec
, _mesa_UniformMatrix3x4fv
);
1479 SET_UniformMatrix4x3fv(exec
, _mesa_UniformMatrix4x3fv
);
1482 SET_Uniform1uiEXT(exec
, _mesa_Uniform1ui
);
1483 SET_Uniform2uiEXT(exec
, _mesa_Uniform2ui
);
1484 SET_Uniform3uiEXT(exec
, _mesa_Uniform3ui
);
1485 SET_Uniform4uiEXT(exec
, _mesa_Uniform4ui
);
1486 SET_Uniform1uivEXT(exec
, _mesa_Uniform1uiv
);
1487 SET_Uniform2uivEXT(exec
, _mesa_Uniform2uiv
);
1488 SET_Uniform3uivEXT(exec
, _mesa_Uniform3uiv
);
1489 SET_Uniform4uivEXT(exec
, _mesa_Uniform4uiv
);
1490 SET_GetUniformuivEXT(exec
, _mesa_GetUniformuiv
);
1492 /* GL_ARB_robustness */
1493 SET_GetnUniformfvARB(exec
, _mesa_GetnUniformfvARB
);
1494 SET_GetnUniformivARB(exec
, _mesa_GetnUniformivARB
);
1495 SET_GetnUniformuivARB(exec
, _mesa_GetnUniformuivARB
);
1496 SET_GetnUniformdvARB(exec
, _mesa_GetnUniformdvARB
); /* GL 4.0 */
1498 #endif /* FEATURE_GL */