2 * Mesa 3-D graphics library
5 * Copyright (C) 2004-2007 Brian Paul 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 * Implementation of GLSL-related API functions
33 * 1. Check that the right error code is generated for all _mesa_error() calls.
34 * 2. Insert FLUSH_VERTICES calls in various places
42 #include "prog_parameter.h"
43 #include "prog_print.h"
44 #include "prog_statevars.h"
45 #include "shader_api.h"
47 #include "slang_compile.h"
48 #include "slang_link.h"
53 * Allocate a new gl_shader_program object, initialize it.
55 struct gl_shader_program
*
56 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
58 struct gl_shader_program
*shProg
;
59 shProg
= CALLOC_STRUCT(gl_shader_program
);
61 shProg
->Type
= GL_SHADER_PROGRAM
;
64 shProg
->Attributes
= _mesa_new_parameter_list();
71 _mesa_free_shader_program_data(GLcontext
*ctx
,
72 struct gl_shader_program
*shProg
)
74 assert(shProg
->Type
== GL_SHADER_PROGRAM
);
76 if (shProg
->VertexProgram
) {
77 if (shProg
->VertexProgram
->Base
.Parameters
== shProg
->Uniforms
) {
78 /* to prevent a double-free in the next call */
79 shProg
->VertexProgram
->Base
.Parameters
= NULL
;
81 _mesa_delete_program(ctx
, &shProg
->VertexProgram
->Base
);
82 shProg
->VertexProgram
= NULL
;
85 if (shProg
->FragmentProgram
) {
86 if (shProg
->FragmentProgram
->Base
.Parameters
== shProg
->Uniforms
) {
87 /* to prevent a double-free in the next call */
88 shProg
->FragmentProgram
->Base
.Parameters
= NULL
;
90 _mesa_delete_program(ctx
, &shProg
->FragmentProgram
->Base
);
91 shProg
->FragmentProgram
= NULL
;
95 if (shProg
->Uniforms
) {
96 _mesa_free_parameter_list(shProg
->Uniforms
);
97 shProg
->Uniforms
= NULL
;
100 if (shProg
->Varying
) {
101 _mesa_free_parameter_list(shProg
->Varying
);
102 shProg
->Varying
= NULL
;
109 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
111 _mesa_free_shader_program_data(ctx
, shProg
);
117 * Lookup a GLSL program object.
119 struct gl_shader_program
*
120 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
122 struct gl_shader_program
*shProg
;
124 shProg
= (struct gl_shader_program
*)
125 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
126 /* Note that both gl_shader and gl_shader_program objects are kept
127 * in the same hash table. Check the object's type to be sure it's
128 * what we're expecting.
130 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM
) {
140 * Allocate a new gl_shader object, initialize it.
143 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
145 struct gl_shader
*shader
;
146 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
147 shader
= CALLOC_STRUCT(gl_shader
);
151 shader
->RefCount
= 1;
158 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
162 _mesa_free((void *) sh
->Source
);
164 _mesa_free(sh
->InfoLog
);
165 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
166 assert(sh
->Programs
[i
]);
167 _mesa_delete_program(ctx
, sh
->Programs
[i
]);
170 _mesa_free(sh
->Programs
);
176 * Lookup a GLSL shader object.
179 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
182 struct gl_shader
*sh
= (struct gl_shader
*)
183 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
184 /* Note that both gl_shader and gl_shader_program objects are kept
185 * in the same hash table. Check the object's type to be sure it's
186 * what we're expecting.
188 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM
) {
189 assert(sh
->Type
== GL_VERTEX_SHADER
||
190 sh
->Type
== GL_FRAGMENT_SHADER
);
200 _mesa_init_shader_state(GLcontext
* ctx
)
210 * Copy string from <src> to <dst>, up to maxLength characters, returning
211 * length of <dst> in <length>.
212 * \param src the strings source
213 * \param maxLength max chars to copy
214 * \param length returns number of chars copied
215 * \param dst the string destination
218 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
221 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
233 * Called via ctx->Driver.AttachShader()
236 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
238 struct gl_shader_program
*shProg
239 = _mesa_lookup_shader_program(ctx
, program
);
240 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
241 const GLuint n
= shProg
->NumShaders
;
244 if (!shProg
|| !sh
) {
245 _mesa_error(ctx
, GL_INVALID_VALUE
,
246 "glAttachShader(bad program or shader name)");
250 for (i
= 0; i
< n
; i
++) {
251 if (shProg
->Shaders
[i
] == sh
) {
252 /* already attached */
258 shProg
->Shaders
= (struct gl_shader
**)
259 _mesa_realloc(shProg
->Shaders
,
260 n
* sizeof(struct gl_shader
*),
261 (n
+ 1) * sizeof(struct gl_shader
*));
262 if (!shProg
->Shaders
) {
263 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
268 shProg
->Shaders
[n
] = sh
;
270 shProg
->NumShaders
++;
275 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
278 struct gl_shader_program
*shProg
279 = _mesa_lookup_shader_program(ctx
, program
);
280 const GLint size
= -1; /* unknown size */
284 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
291 if (strncmp(name
, "gl_", 3) == 0) {
292 _mesa_error(ctx
, GL_INVALID_OPERATION
,
293 "glBindAttribLocation(illegal name)");
297 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
299 /* this will replace the current value if it's already in the list */
300 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
302 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
305 if (shProg
->VertexProgram
&& oldIndex
>= 0) {
306 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
310 printf("===== post BindAttrib:\n");
311 _mesa_print_program(&shProg
->VertexProgram
->Base
);
317 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
319 struct gl_shader
*sh
;
322 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
325 case GL_FRAGMENT_SHADER
:
326 case GL_VERTEX_SHADER
:
327 sh
= _mesa_new_shader(ctx
, name
, type
);
330 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
334 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
341 _mesa_create_program(GLcontext
*ctx
)
344 struct gl_shader_program
*shProg
;
346 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
347 shProg
= _mesa_new_shader_program(ctx
, name
);
349 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
356 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
358 struct gl_shader_program
*shProg
;
360 shProg
= _mesa_lookup_shader_program(ctx
, name
);
362 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
366 /* always remove from hash table */
367 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, name
);
369 shProg
->DeletePending
= GL_TRUE
;
371 /* decrement refcount, delete if zero */
373 if (shProg
->RefCount
<= 0) {
374 _mesa_free_shader_program(ctx
, shProg
);
380 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
382 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
387 sh
->DeletePending
= GL_TRUE
;
389 if (sh
->RefCount
<= 0) {
390 _mesa_free_shader(ctx
, sh
);
396 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
398 struct gl_shader_program
*shProg
399 = _mesa_lookup_shader_program(ctx
, program
);
400 const GLuint n
= shProg
->NumShaders
;
404 _mesa_error(ctx
, GL_INVALID_VALUE
,
405 "glDetachShader(bad program or shader name)");
409 for (i
= 0; i
< n
; i
++) {
410 if (shProg
->Shaders
[i
]->Name
== shader
) {
411 struct gl_shader
**newList
;
414 shProg
->Shaders
[i
]->RefCount
--;
416 /* alloc new, smaller array */
417 newList
= (struct gl_shader
**)
418 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
420 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
423 for (j
= 0; j
< i
; j
++) {
424 newList
[j
] = shProg
->Shaders
[j
];
427 newList
[j
++] = shProg
->Shaders
[i
];
428 _mesa_free(shProg
->Shaders
);
430 /* XXX refcounting! */
432 shProg
->Shaders
= newList
;
438 _mesa_error(ctx
, GL_INVALID_VALUE
,
439 "glDetachShader(shader not found)");
444 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
445 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
446 GLenum
*type
, GLchar
*nameOut
)
448 static const GLenum vec_types
[] = {
449 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
451 struct gl_shader_program
*shProg
452 = _mesa_lookup_shader_program(ctx
, program
);
456 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
460 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
461 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
465 copy_string(nameOut
, maxLength
, length
,
466 shProg
->Attributes
->Parameters
[index
].Name
);
467 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
471 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
476 * Called via ctx->Driver.GetActiveUniform().
479 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
480 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
481 GLenum
*type
, GLchar
*nameOut
)
483 static const GLenum vec_types
[] = {
484 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
486 struct gl_shader_program
*shProg
487 = _mesa_lookup_shader_program(ctx
, program
);
491 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
495 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
496 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
500 copy_string(nameOut
, maxLength
, length
,
501 shProg
->Uniforms
->Parameters
[index
].Name
);
502 sz
= shProg
->Uniforms
->Parameters
[index
].Size
;
506 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
511 * Called via ctx->Driver.GetAttachedShaders().
514 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
515 GLsizei
*count
, GLuint
*obj
)
517 struct gl_shader_program
*shProg
518 = _mesa_lookup_shader_program(ctx
, program
);
521 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
522 obj
[i
] = shProg
->Shaders
[i
]->Name
;
528 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
534 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
537 struct gl_shader_program
*shProg
538 = _mesa_lookup_shader_program(ctx
, program
);
541 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
545 if (!shProg
->LinkStatus
) {
546 _mesa_error(ctx
, GL_INVALID_OPERATION
,
547 "glGetAttribLocation(program not linked)");
554 if (shProg
->Attributes
) {
555 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
557 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
565 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
568 GET_CURRENT_CONTEXT(ctx
);
571 case GL_PROGRAM_OBJECT_ARB
:
573 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
576 return (**pro
)._container
._generic
.
577 GetName((struct gl2_generic_intf
**) (pro
));
581 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
589 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
590 GLenum pname
, GLint
*params
)
592 struct gl_shader_program
*shProg
593 = _mesa_lookup_shader_program(ctx
, program
);
596 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
601 case GL_DELETE_STATUS
:
602 *params
= shProg
->DeletePending
;
605 *params
= shProg
->LinkStatus
;
607 case GL_VALIDATE_STATUS
:
608 *params
= shProg
->Validated
;
610 case GL_INFO_LOG_LENGTH
:
611 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) : 0;
613 case GL_ATTACHED_SHADERS
:
614 *params
= shProg
->NumShaders
;
616 case GL_ACTIVE_ATTRIBUTES
:
617 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
619 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
620 *params
= _mesa_parameter_longest_name(shProg
->Attributes
);
622 case GL_ACTIVE_UNIFORMS
:
623 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumParameters
: 0;
625 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
626 *params
= _mesa_parameter_longest_name(shProg
->Uniforms
);
629 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
636 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
638 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
641 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
647 *params
= shader
->Type
;
649 case GL_DELETE_STATUS
:
650 *params
= shader
->DeletePending
;
652 case GL_COMPILE_STATUS
:
653 *params
= shader
->CompileStatus
;
655 case GL_INFO_LOG_LENGTH
:
656 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) : 0;
658 case GL_SHADER_SOURCE_LENGTH
:
659 *params
= shader
->Source
? strlen((char *) shader
->Source
) : 0;
662 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
669 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
670 GLsizei
*length
, GLchar
*infoLog
)
672 struct gl_shader_program
*shProg
673 = _mesa_lookup_shader_program(ctx
, program
);
675 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
678 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
683 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
684 GLsizei
*length
, GLchar
*infoLog
)
686 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
688 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
691 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
696 * Called via ctx->Driver.GetShaderSource().
699 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
700 GLsizei
*length
, GLchar
*sourceOut
)
702 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
704 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
707 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
712 * Called via ctx->Driver.GetUniformfv().
715 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
718 struct gl_shader_program
*shProg
719 = _mesa_lookup_shader_program(ctx
, program
);
722 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
723 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
724 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
728 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
732 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
738 * Called via ctx->Driver.GetUniformLocation().
741 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
743 struct gl_shader_program
*shProg
744 = _mesa_lookup_shader_program(ctx
, program
);
747 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
748 const struct gl_program_parameter
*u
749 = shProg
->Uniforms
->Parameters
+ loc
;
750 /* XXX this is a temporary simplification / short-cut.
751 * We need to handle things like "e.c[0].b" as seen in the
752 * GLSL orange book, page 189.
754 if ((u
->Type
== PROGRAM_UNIFORM
||
755 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
766 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
768 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
769 return shProg
? GL_TRUE
: GL_FALSE
;
774 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
776 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
777 return shader
? GL_TRUE
: GL_FALSE
;
783 * Called via ctx->Driver.ShaderSource()
786 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
788 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
790 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
794 /* free old shader source string and install new one */
796 _mesa_free((void *) sh
->Source
);
799 sh
->CompileStatus
= GL_FALSE
;
804 * Called via ctx->Driver.CompileShader()
807 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
809 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
812 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
816 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
821 * Called via ctx->Driver.LinkProgram()
824 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
826 struct gl_shader_program
*shProg
;
828 shProg
= _mesa_lookup_shader_program(ctx
, program
);
830 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
834 _slang_link(ctx
, program
, shProg
);
839 * Called via ctx->Driver.UseProgram()
842 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
844 if (ctx
->Shader
.CurrentProgram
&&
845 ctx
->Shader
.CurrentProgram
->Name
== program
) {
850 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
853 if (ctx
->Shader
.CurrentProgram
) {
854 ctx
->Shader
.CurrentProgram
->RefCount
--;
855 if (ctx
->Shader
.CurrentProgram
->RefCount
<= 0) {
856 _mesa_free_shader_program(ctx
, ctx
->Shader
.CurrentProgram
);
858 ctx
->Shader
.CurrentProgram
= NULL
;
862 struct gl_shader_program
*shProg
;
863 shProg
= _mesa_lookup_shader_program(ctx
, program
);
865 _mesa_error(ctx
, GL_INVALID_VALUE
,
866 "glUseProgramObjectARB(programObj)");
869 ctx
->Shader
.CurrentProgram
= shProg
;
873 /* don't use a shader program */
874 ctx
->Shader
.CurrentProgram
= NULL
;
880 * Called via ctx->Driver.Uniform().
883 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
884 const GLvoid
*values
, GLenum type
)
886 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
889 if (!shProg
|| !shProg
->LinkStatus
) {
890 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
894 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
895 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
899 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
902 * If we're setting a sampler, we must use glUniformi1()!
904 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
905 if (type
!= GL_INT
|| count
!= 1) {
906 _mesa_error(ctx
, GL_INVALID_OPERATION
,
907 "glUniform(only glUniform1i can be used "
908 "to set sampler uniforms)");
913 uniformVal
= shProg
->Uniforms
->ParameterValues
[location
];
915 /* XXX obey 'count' parameter! */
917 if (type
== GL_INT
||
918 type
== GL_INT_VEC2
||
919 type
== GL_INT_VEC3
||
920 type
== GL_INT_VEC4
) {
921 const GLint
*iValues
= (const GLint
*) values
;
924 uniformVal
[3] = (GLfloat
) iValues
[3];
927 uniformVal
[2] = (GLfloat
) iValues
[2];
930 uniformVal
[1] = (GLfloat
) iValues
[1];
933 uniformVal
[0] = (GLfloat
) iValues
[0];
936 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
941 const GLfloat
*fValues
= (const GLfloat
*) values
;
944 uniformVal
[3] = fValues
[3];
947 uniformVal
[2] = fValues
[2];
950 uniformVal
[1] = fValues
[1];
953 uniformVal
[0] = fValues
[0];
956 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
961 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
962 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
963 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
964 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
970 * Called by ctx->Driver.UniformMatrix().
973 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
974 GLenum matrixType
, GLint location
, GLsizei count
,
975 GLboolean transpose
, const GLfloat
*values
)
977 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
978 if (!shProg
|| !shProg
->LinkStatus
) {
979 _mesa_error(ctx
, GL_INVALID_OPERATION
,
980 "glUniformMatrix(program not linked)");
983 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
984 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
987 if (values
== NULL
) {
988 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
992 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
995 * Note: the _columns_ of a matrix are stored in program registers, not
998 /* XXXX need to test 3x3 and 2x2 matrices... */
1001 for (col
= 0; col
< cols
; col
++) {
1002 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1003 for (row
= 0; row
< rows
; row
++) {
1004 v
[row
] = values
[col
* rows
+ row
];
1010 for (col
= 0; col
< cols
; col
++) {
1011 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1012 for (row
= 0; row
< rows
; row
++) {
1013 v
[row
] = values
[row
* cols
+ col
];
1021 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1023 struct gl_shader_program
*shProg
;
1024 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1026 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1030 shProg
->Validated
= GL_TRUE
;
1032 /* From the GL spec:
1033 any two active samplers in the current program object are of
1034 different types, but refer to the same texture image unit,
1036 any active sampler in the current program object refers to a texture
1037 image unit where fixed-function fragment processing accesses a
1038 texture target that does not match the sampler type, or
1040 the sum of the number of active samplers in the program and the
1041 number of texture image units enabled for fixed-function fragment
1042 processing exceeds the combined limit on the total number of texture
1043 image units allowed.