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/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"
54 base_uniform_type(GLenum type
)
57 #if 0 /* not needed, for now */
70 case GL_UNSIGNED_INT_VEC2
:
71 case GL_UNSIGNED_INT_VEC3
:
72 case GL_UNSIGNED_INT_VEC4
:
73 return GL_UNSIGNED_INT
;
80 _mesa_problem(NULL
, "Invalid type in base_uniform_type()");
87 is_boolean_type(GLenum type
)
102 is_sampler_type(GLenum type
)
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
:
124 static struct gl_program_parameter
*
125 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
127 const struct gl_program
*prog
= NULL
;
130 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
132 prog
= &shProg
->VertexProgram
->Base
;
135 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
137 prog
= &shProg
->FragmentProgram
->Base
;
139 progPos
= shProg
->Uniforms
->Uniforms
[index
].GeomPos
;
141 prog
= &shProg
->GeometryProgram
->Base
;
146 if (!prog
|| progPos
< 0)
147 return NULL
; /* should never happen */
149 return &prog
->Parameters
->Parameters
[progPos
];
154 * Called by glGetActiveUniform().
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
)
161 const struct gl_shader_program
*shProg
;
162 const struct gl_program
*prog
= NULL
;
163 const struct gl_program_parameter
*param
;
166 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
170 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
171 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
175 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
177 prog
= &shProg
->VertexProgram
->Base
;
180 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
182 prog
= &shProg
->FragmentProgram
->Base
;
184 progPos
= shProg
->Uniforms
->Uniforms
[index
].GeomPos
;
186 prog
= &shProg
->GeometryProgram
->Base
;
191 if (!prog
|| progPos
< 0)
192 return; /* should never happen */
194 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
195 param
= &prog
->Parameters
->Parameters
[progPos
];
198 _mesa_copy_string(nameOut
, maxLength
, length
, param
->Name
);
202 GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
203 if ((GLint
) param
->Size
> typeSize
) {
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.
209 typeSize
= (typeSize
+ 3) & ~3;
211 /* Note that the returned size is in units of the <type>, not bytes */
212 *size
= param
->Size
/ typeSize
;
216 *type
= param
->DataType
;
222 get_vector_elements(GLenum type
)
228 case GL_UNSIGNED_INT
:
229 default: /* Catch all the various sampler types. */
235 case GL_UNSIGNED_INT_VEC2
:
241 case GL_UNSIGNED_INT_VEC3
:
247 case GL_UNSIGNED_INT_VEC4
:
253 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
259 case GL_FLOAT_MAT2x3
:
263 case GL_FLOAT_MAT2x4
:
271 case GL_FLOAT_MAT3x2
:
275 case GL_FLOAT_MAT3x4
:
283 case GL_FLOAT_MAT4x2
:
287 case GL_FLOAT_MAT4x3
:
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.
303 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
304 GLint
*rows
, GLint
*cols
)
306 get_matrix_dims(p
->DataType
, rows
, cols
);
307 if (*rows
== 0 && *cols
== 0) {
308 /* not a matrix type, probably a float or vector */
310 *cols
= get_vector_elements(p
->DataType
);
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.
321 lookup_uniform_parameter(struct gl_context
*ctx
, GLuint program
, GLint location
,
322 struct gl_program
**progOut
, GLint
*paramPosOut
)
324 struct gl_shader_program
*shProg
325 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
326 struct gl_program
*prog
= NULL
;
329 /* if shProg is NULL, we'll have already recorded an error */
332 if (!shProg
->Uniforms
||
334 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
335 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
338 /* OK, find the gl_program and program parameter location */
339 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
341 prog
= &shProg
->VertexProgram
->Base
;
344 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
346 prog
= &shProg
->FragmentProgram
->Base
;
348 progPos
= shProg
->Uniforms
->Uniforms
[location
].GeomPos
;
350 prog
= &shProg
->GeometryProgram
->Base
;
358 *paramPosOut
= progPos
;
363 * GLGL uniform arrays and structs require special handling.
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().
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.
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.
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)
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.
392 merge_location_offset(GLint
*location
, GLint offset
)
394 *location
= (*location
<< 16) | offset
;
399 * Separate the uniform location and parameter offset. See above.
402 split_location_offset(GLint
*location
, GLint
*offset
)
404 *offset
= *location
& 0xffff;
405 *location
= *location
>> 16;
411 * Called via glGetUniformfv().
414 _mesa_get_uniformfv(struct gl_context
*ctx
, GLuint program
, GLint location
,
415 GLsizei bufSize
, GLfloat
*params
)
417 struct gl_program
*prog
;
418 GLint paramPos
, offset
;
420 split_location_offset(&location
, &offset
);
422 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
425 const struct gl_program_parameter
*p
=
426 &prog
->Parameters
->Parameters
[paramPos
];
427 GLint rows
, cols
, i
, j
, k
;
430 get_uniform_rows_cols(p
, &rows
, &cols
);
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
);
441 for (i
= 0; i
< rows
; i
++) {
442 const int base
= paramPos
+ offset
+ i
;
444 for (j
= 0; j
< cols
; j
++ ) {
445 params
[k
++] = prog
->Parameters
->ParameterValues
[base
][j
];
453 * Called via glGetUniformiv().
454 * \sa _mesa_get_uniformfv, only difference is a cast.
457 _mesa_get_uniformiv(struct gl_context
*ctx
, GLuint program
, GLint location
,
458 GLsizei bufSize
, GLint
*params
)
460 struct gl_program
*prog
;
461 GLint paramPos
, offset
;
463 split_location_offset(&location
, &offset
);
465 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
468 const struct gl_program_parameter
*p
=
469 &prog
->Parameters
->Parameters
[paramPos
];
470 GLint rows
, cols
, i
, j
, k
;
473 get_uniform_rows_cols(p
, &rows
, &cols
);
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
);
484 for (i
= 0; i
< rows
; i
++) {
485 const int base
= paramPos
+ offset
+ i
;
487 for (j
= 0; j
< cols
; j
++ ) {
488 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[base
][j
];
496 * Called via glGetUniformuiv().
497 * New in GL_EXT_gpu_shader4, OpenGL 3.0
498 * \sa _mesa_get_uniformfv, only difference is a cast.
501 _mesa_get_uniformuiv(struct gl_context
*ctx
, GLuint program
, GLint location
,
502 GLsizei bufSize
, GLuint
*params
)
504 struct gl_program
*prog
;
505 GLint paramPos
, offset
;
507 split_location_offset(&location
, &offset
);
509 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
512 const struct gl_program_parameter
*p
=
513 &prog
->Parameters
->Parameters
[paramPos
];
514 GLint rows
, cols
, i
, j
, k
;
517 get_uniform_rows_cols(p
, &rows
, &cols
);
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
);
528 for (i
= 0; i
< rows
; i
++) {
529 const int base
= paramPos
+ offset
+ i
;
531 for (j
= 0; j
< cols
; j
++ ) {
532 params
[k
++] = (GLuint
) prog
->Parameters
->ParameterValues
[base
][j
];
540 * Called via glGetUniformdv().
541 * New in GL_ARB_gpu_shader_fp64, OpenGL 4.0
544 _mesa_get_uniformdv(struct gl_context
*ctx
, GLuint program
, GLint location
,
545 GLsizei bufSize
, GLdouble
*params
)
547 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformdvARB"
548 "(GL_ARB_gpu_shader_fp64 not implemented)");
553 * Called via glGetUniformLocation().
555 * The return value will encode two values, the uniform location and an
556 * offset (used for arrays, structs).
559 _mesa_get_uniform_location(struct gl_context
*ctx
, struct gl_shader_program
*shProg
,
562 GLint offset
= 0, location
= -1;
564 if (shProg
->LinkStatus
== GL_FALSE
) {
565 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
569 /* XXX we should return -1 if the uniform was declared, but not
573 /* XXX we need to be able to parse uniform names for structs and arrays
580 /* handle 1-dimension arrays here... */
581 char *c
= strchr(name
, '[');
583 /* truncate name at [ */
584 const GLint len
= c
- name
;
585 GLchar
*newName
= malloc(len
+ 1);
587 return -1; /* out of mem */
588 memcpy(newName
, name
, len
);
591 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
593 const GLint element
= atoi(c
+ 1);
595 /* get type of the uniform array element */
596 struct gl_program_parameter
*p
;
597 p
= get_uniform_parameter(shProg
, location
);
600 get_matrix_dims(p
->DataType
, &rows
, &cols
);
603 offset
= element
* rows
;
613 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
617 merge_location_offset(&location
, offset
);
626 * Update the vertex/fragment program's TexturesUsed array.
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.
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.
641 _mesa_update_shader_textures_used(struct gl_program
*prog
)
645 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
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
);
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.
665 compatible_types(GLenum userType
, GLenum targetType
)
667 if (userType
== targetType
)
670 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
||
671 userType
== GL_UNSIGNED_INT
||
675 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
676 userType
== GL_UNSIGNED_INT_VEC2
||
677 userType
== GL_INT_VEC2
))
680 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
681 userType
== GL_UNSIGNED_INT_VEC3
||
682 userType
== GL_INT_VEC3
))
685 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
686 userType
== GL_UNSIGNED_INT_VEC4
||
687 userType
== GL_INT_VEC4
))
690 if (is_sampler_type(targetType
) && userType
== GL_INT
)
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'
708 set_program_uniform(struct gl_context
*ctx
, struct gl_program
*program
,
709 GLint index
, GLint offset
,
710 GLenum type
, GLsizei count
, GLint elems
,
713 const struct gl_program_parameter
*param
=
714 &program
->Parameters
->Parameters
[index
];
720 if (!compatible_types(type
, param
->DataType
)) {
721 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
725 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
730 if (param
->Type
== PROGRAM_SAMPLER
) {
731 /* This controls which texture unit which is used by a sampler */
732 GLboolean changed
= GL_FALSE
;
735 /* this should have been caught by the compatible_types() check */
736 ASSERT(type
== GL_INT
);
738 /* loop over number of samplers to change */
739 for (i
= 0; i
< count
; i
++) {
741 (GLuint
) program
->Parameters
->ParameterValues
[index
+ offset
+ i
][0];
742 GLuint texUnit
= ((GLuint
*) values
)[i
];
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')",
752 /* This maps a sampler to a texture unit: */
753 if (sampler
< MAX_SAMPLERS
) {
755 printf("Set program %p sampler %d '%s' to unit %u\n",
756 program
, sampler
, param
->Name
, texUnit
);
758 if (program
->SamplerUnits
[sampler
] != texUnit
) {
759 program
->SamplerUnits
[sampler
] = texUnit
;
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.
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
777 (void) ctx
->Driver
.ProgramStringNotify(ctx
, program
->Target
, program
);
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
);
788 if ((GLint
) param
->Size
> typeSize
) {
790 /* we'll ignore extra data below */
793 /* non-array: count must be at most one; count == 0 is handled by the loop below */
795 _mesa_error(ctx
, GL_INVALID_OPERATION
,
796 "glUniform(uniform '%s' is not an array)",
802 /* loop over number of array elements */
803 for (k
= 0; k
< count
; k
++) {
806 if (offset
+ k
>= slots
) {
807 /* Extra array data is ignored */
811 /* uniformVal (the destination) is always float[4] */
812 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
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
];
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
];
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
];
836 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
838 for (i
= 0; i
< elems
; i
++) {
839 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
848 * Called via glUniform*() functions.
851 _mesa_uniform(struct gl_context
*ctx
, struct gl_shader_program
*shProg
,
852 GLint location
, GLsizei count
,
853 const GLvoid
*values
, GLenum type
)
855 struct gl_uniform
*uniform
;
858 ASSERT_OUTSIDE_BEGIN_END(ctx
);
860 if (!shProg
|| !shProg
->LinkStatus
) {
861 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
866 return; /* The standard specifies this as a no-op */
869 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location=%d)",
874 split_location_offset(&location
, &offset
);
876 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
877 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location=%d)", location
);
882 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
886 elems
= _mesa_sizeof_glsl_type(type
);
888 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
890 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
892 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
893 const GLenum basicType
= base_uniform_type(type
);
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
++) {
903 else if (basicType
== GL_UNSIGNED_INT
) {
904 const GLuint
*v
= (const GLuint
*) values
;
905 for (i
= 0; i
< count
* elems
; i
++) {
910 const GLfloat
*v
= (const GLfloat
*) values
;
911 assert(basicType
== GL_FLOAT
);
912 for (i
= 0; i
< count
* elems
; i
++) {
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:
922 if (shProg
->VertexProgram
) {
923 /* convert uniform location to program parameter index */
924 GLint index
= uniform
->VertPos
;
926 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
927 index
, offset
, type
, count
, elems
, values
);
931 if (shProg
->FragmentProgram
) {
932 /* convert uniform location to program parameter index */
933 GLint index
= uniform
->FragPos
;
935 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
936 index
, offset
, type
, count
, elems
, values
);
940 if (shProg
->GeometryProgram
) {
941 /* convert uniform location to program parameter index */
942 GLint index
= uniform
->GeomPos
;
944 set_program_uniform(ctx
, &shProg
->GeometryProgram
->Base
,
945 index
, offset
, type
, count
, elems
, values
);
949 uniform
->Initialized
= GL_TRUE
;
954 * Set a matrix-valued program parameter.
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
)
962 GLuint mat
, row
, col
;
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
);
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)");
977 if ((GLint
) param
->Size
<= typeSize
) {
978 /* non-array: count must be at most one; count == 0 is handled by the loop below */
980 _mesa_error(ctx
, GL_INVALID_OPERATION
,
981 "glUniformMatrix(uniform is not an array)");
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...
992 /* loop over matrices */
993 for (mat
= 0; mat
< count
; mat
++) {
996 for (col
= 0; col
< cols
; col
++) {
998 if (offset
>= slots
) {
999 /* Ignore writes beyond the end of (the used part of) an array */
1002 v
= program
->Parameters
->ParameterValues
[index
+ offset
];
1003 for (row
= 0; row
< rows
; row
++) {
1005 v
[row
] = values
[src
+ row
* cols
+ col
];
1008 v
[row
] = values
[src
+ col
* rows
+ row
];
1015 src
+= rows
* cols
; /* next matrix */
1021 * Called by glUniformMatrix*() functions.
1022 * Note: cols=2, rows=4 ==> array[2] of vec4
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
)
1030 struct gl_uniform
*uniform
;
1033 ASSERT_OUTSIDE_BEGIN_END(ctx
);
1035 if (!shProg
|| !shProg
->LinkStatus
) {
1036 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1037 "glUniformMatrix(program not linked)");
1042 return; /* The standard specifies this as a no-op */
1044 if (location
< -1) {
1045 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
1049 split_location_offset(&location
, &offset
);
1051 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1052 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1055 if (values
== NULL
) {
1056 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1060 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1062 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1064 if (shProg
->VertexProgram
) {
1065 /* convert uniform location to program parameter index */
1066 GLint index
= uniform
->VertPos
;
1068 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1070 count
, rows
, cols
, transpose
, values
);
1074 if (shProg
->FragmentProgram
) {
1075 /* convert uniform location to program parameter index */
1076 GLint index
= uniform
->FragPos
;
1078 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1080 count
, rows
, cols
, transpose
, values
);
1084 if (shProg
->GeometryProgram
) {
1085 /* convert uniform location to program parameter index */
1086 GLint index
= uniform
->GeomPos
;
1088 set_program_uniform_matrix(ctx
, &shProg
->GeometryProgram
->Base
,
1090 count
, rows
, cols
, transpose
, values
);
1094 uniform
->Initialized
= GL_TRUE
;
1099 _mesa_Uniform1fARB(GLint location
, GLfloat v0
)
1101 GET_CURRENT_CONTEXT(ctx
);
1102 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_FLOAT
);
1106 _mesa_Uniform2fARB(GLint location
, GLfloat v0
, GLfloat v1
)
1108 GET_CURRENT_CONTEXT(ctx
);
1112 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC2
);
1116 _mesa_Uniform3fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
)
1118 GET_CURRENT_CONTEXT(ctx
);
1123 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC3
);
1127 _mesa_Uniform4fARB(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
,
1130 GET_CURRENT_CONTEXT(ctx
);
1136 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC4
);
1140 _mesa_Uniform1iARB(GLint location
, GLint v0
)
1142 GET_CURRENT_CONTEXT(ctx
);
1143 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_INT
);
1147 _mesa_Uniform2iARB(GLint location
, GLint v0
, GLint v1
)
1149 GET_CURRENT_CONTEXT(ctx
);
1153 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC2
);
1157 _mesa_Uniform3iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
)
1159 GET_CURRENT_CONTEXT(ctx
);
1164 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC3
);
1168 _mesa_Uniform4iARB(GLint location
, GLint v0
, GLint v1
, GLint v2
, GLint v3
)
1170 GET_CURRENT_CONTEXT(ctx
);
1176 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC4
);
1180 _mesa_Uniform1fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1182 GET_CURRENT_CONTEXT(ctx
);
1183 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT
);
1187 _mesa_Uniform2fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1189 GET_CURRENT_CONTEXT(ctx
);
1190 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC2
);
1194 _mesa_Uniform3fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1196 GET_CURRENT_CONTEXT(ctx
);
1197 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC3
);
1201 _mesa_Uniform4fvARB(GLint location
, GLsizei count
, const GLfloat
* value
)
1203 GET_CURRENT_CONTEXT(ctx
);
1204 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC4
);
1208 _mesa_Uniform1ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1210 GET_CURRENT_CONTEXT(ctx
);
1211 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT
);
1215 _mesa_Uniform2ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1217 GET_CURRENT_CONTEXT(ctx
);
1218 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC2
);
1222 _mesa_Uniform3ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1224 GET_CURRENT_CONTEXT(ctx
);
1225 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC3
);
1229 _mesa_Uniform4ivARB(GLint location
, GLsizei count
, const GLint
* value
)
1231 GET_CURRENT_CONTEXT(ctx
);
1232 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC4
);
1236 /** OpenGL 3.0 GLuint-valued functions **/
1238 _mesa_Uniform1ui(GLint location
, GLuint v0
)
1240 GET_CURRENT_CONTEXT(ctx
);
1241 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_UNSIGNED_INT
);
1245 _mesa_Uniform2ui(GLint location
, GLuint v0
, GLuint v1
)
1247 GET_CURRENT_CONTEXT(ctx
);
1251 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC2
);
1255 _mesa_Uniform3ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
)
1257 GET_CURRENT_CONTEXT(ctx
);
1262 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC3
);
1266 _mesa_Uniform4ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
, GLuint v3
)
1268 GET_CURRENT_CONTEXT(ctx
);
1274 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC4
);
1278 _mesa_Uniform1uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1280 GET_CURRENT_CONTEXT(ctx
);
1281 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT
);
1285 _mesa_Uniform2uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1287 GET_CURRENT_CONTEXT(ctx
);
1288 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC2
);
1292 _mesa_Uniform3uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1294 GET_CURRENT_CONTEXT(ctx
);
1295 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC3
);
1299 _mesa_Uniform4uiv(GLint location
, GLsizei count
, const GLuint
*value
)
1301 GET_CURRENT_CONTEXT(ctx
);
1302 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC4
);
1308 _mesa_UniformMatrix2fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1309 const GLfloat
* value
)
1311 GET_CURRENT_CONTEXT(ctx
);
1312 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1313 2, 2, location
, count
, transpose
, value
);
1317 _mesa_UniformMatrix3fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1318 const GLfloat
* value
)
1320 GET_CURRENT_CONTEXT(ctx
);
1321 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1322 3, 3, location
, count
, transpose
, value
);
1326 _mesa_UniformMatrix4fvARB(GLint location
, GLsizei count
, GLboolean transpose
,
1327 const GLfloat
* value
)
1329 GET_CURRENT_CONTEXT(ctx
);
1330 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1331 4, 4, location
, count
, transpose
, value
);
1336 * Non-square UniformMatrix are OpenGL 2.1
1339 _mesa_UniformMatrix2x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
1340 const GLfloat
*value
)
1342 GET_CURRENT_CONTEXT(ctx
);
1343 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1344 2, 3, location
, count
, transpose
, value
);
1348 _mesa_UniformMatrix3x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
1349 const GLfloat
*value
)
1351 GET_CURRENT_CONTEXT(ctx
);
1352 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1353 3, 2, location
, count
, transpose
, value
);
1357 _mesa_UniformMatrix2x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
1358 const GLfloat
*value
)
1360 GET_CURRENT_CONTEXT(ctx
);
1361 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1362 2, 4, location
, count
, transpose
, value
);
1366 _mesa_UniformMatrix4x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
1367 const GLfloat
*value
)
1369 GET_CURRENT_CONTEXT(ctx
);
1370 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1371 4, 2, location
, count
, transpose
, value
);
1375 _mesa_UniformMatrix3x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
1376 const GLfloat
*value
)
1378 GET_CURRENT_CONTEXT(ctx
);
1379 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1380 3, 4, location
, count
, transpose
, value
);
1384 _mesa_UniformMatrix4x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
1385 const GLfloat
*value
)
1387 GET_CURRENT_CONTEXT(ctx
);
1388 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
1389 4, 3, location
, count
, transpose
, value
);
1394 _mesa_GetnUniformfvARB(GLhandleARB program
, GLint location
,
1395 GLsizei bufSize
, GLfloat
*params
)
1397 GET_CURRENT_CONTEXT(ctx
);
1398 _mesa_get_uniformfv(ctx
, program
, location
, bufSize
, params
);
1402 _mesa_GetUniformfvARB(GLhandleARB program
, GLint location
, GLfloat
*params
)
1404 _mesa_GetnUniformfvARB(program
, location
, INT_MAX
, params
);
1409 _mesa_GetnUniformivARB(GLhandleARB program
, GLint location
,
1410 GLsizei bufSize
, GLint
*params
)
1412 GET_CURRENT_CONTEXT(ctx
);
1413 _mesa_get_uniformiv(ctx
, program
, location
, bufSize
, params
);
1417 _mesa_GetUniformivARB(GLhandleARB program
, GLint location
, GLint
*params
)
1419 _mesa_GetnUniformivARB(program
, location
, INT_MAX
, params
);
1425 _mesa_GetnUniformuivARB(GLhandleARB program
, GLint location
,
1426 GLsizei bufSize
, GLuint
*params
)
1428 GET_CURRENT_CONTEXT(ctx
);
1429 _mesa_get_uniformuiv(ctx
, program
, location
, bufSize
, params
);
1433 _mesa_GetUniformuiv(GLhandleARB program
, GLint location
, GLuint
*params
)
1435 _mesa_GetnUniformuivARB(program
, location
, INT_MAX
, params
);
1441 _mesa_GetnUniformdvARB(GLhandleARB program
, GLint location
,
1442 GLsizei bufSize
, GLdouble
*params
)
1444 GET_CURRENT_CONTEXT(ctx
);
1445 _mesa_get_uniformdv(ctx
, program
, location
, bufSize
, params
);
1449 _mesa_GetUniformdv(GLhandleARB program
, GLint location
, GLdouble
*params
)
1451 _mesa_GetnUniformdvARB(program
, location
, INT_MAX
, params
);
1456 _mesa_GetUniformLocationARB(GLhandleARB programObj
, const GLcharARB
*name
)
1458 struct gl_shader_program
*shProg
;
1460 GET_CURRENT_CONTEXT(ctx
);
1462 shProg
= _mesa_lookup_shader_program_err(ctx
, programObj
,
1463 "glGetUniformLocation");
1467 return _mesa_get_uniform_location(ctx
, shProg
, name
);
1472 _mesa_GetActiveUniformARB(GLhandleARB program
, GLuint index
,
1473 GLsizei maxLength
, GLsizei
* length
, GLint
* size
,
1474 GLenum
* type
, GLcharARB
* name
)
1476 GET_CURRENT_CONTEXT(ctx
);
1477 _mesa_get_active_uniform(ctx
, program
, index
, maxLength
, length
, size
,
1483 * Plug in shader uniform-related functions into API dispatch table.
1486 _mesa_init_shader_uniform_dispatch(struct _glapi_table
*exec
)
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
);
1509 SET_GetActiveUniformARB(exec
, _mesa_GetActiveUniformARB
);
1510 SET_GetUniformLocationARB(exec
, _mesa_GetUniformLocationARB
);
1511 SET_GetUniformfvARB(exec
, _mesa_GetUniformfvARB
);
1512 SET_GetUniformivARB(exec
, _mesa_GetUniformivARB
);
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
);
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
);
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 */
1540 #endif /* FEATURE_GL */