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
)
202 ctx
->Shader
._FragmentShaderPresent
= GL_FALSE
;
203 ctx
->Shader
._VertexShaderPresent
= GL_FALSE
;
211 * Copy string from <src> to <dst>, up to maxLength characters, returning
212 * length of <dst> in <length>.
213 * \param src the strings source
214 * \param maxLength max chars to copy
215 * \param length returns number of chars copied
216 * \param dst the string destination
219 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
222 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
234 * Called via ctx->Driver.AttachShader()
237 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
239 struct gl_shader_program
*shProg
240 = _mesa_lookup_shader_program(ctx
, program
);
241 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
242 const GLuint n
= shProg
->NumShaders
;
245 if (!shProg
|| !sh
) {
246 _mesa_error(ctx
, GL_INVALID_VALUE
,
247 "glAttachShader(bad program or shader name)");
251 for (i
= 0; i
< n
; i
++) {
252 if (shProg
->Shaders
[i
] == sh
) {
253 /* already attached */
259 shProg
->Shaders
= (struct gl_shader
**)
260 _mesa_realloc(shProg
->Shaders
,
261 n
* sizeof(struct gl_shader
*),
262 (n
+ 1) * sizeof(struct gl_shader
*));
263 if (!shProg
->Shaders
) {
264 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
269 shProg
->Shaders
[n
] = sh
;
271 shProg
->NumShaders
++;
276 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
279 struct gl_shader_program
*shProg
280 = _mesa_lookup_shader_program(ctx
, program
);
281 const GLint size
= -1; /* unknown size */
285 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
292 if (strncmp(name
, "gl_", 3) == 0) {
293 _mesa_error(ctx
, GL_INVALID_OPERATION
,
294 "glBindAttribLocation(illegal name)");
298 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
300 /* this will replace the current value if it's already in the list */
301 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
303 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
306 if (shProg
->VertexProgram
&& oldIndex
>= 0) {
307 _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 if (ctx
->Shader
.CurrentProgram
) {
744 const struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
746 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
747 const struct gl_program_parameter
*u
748 = shProg
->Uniforms
->Parameters
+ loc
;
749 /* XXX this is a temporary simplification / short-cut.
750 * We need to handle things like "e.c[0].b" as seen in the
751 * GLSL orange book, page 189.
753 if ((u
->Type
== PROGRAM_UNIFORM
||
754 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
765 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
767 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
768 return shProg
? GL_TRUE
: GL_FALSE
;
773 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
775 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
776 return shader
? GL_TRUE
: GL_FALSE
;
782 * Called via ctx->Driver.ShaderSource()
785 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
787 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
789 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
793 /* free old shader source string and install new one */
795 _mesa_free((void *) sh
->Source
);
798 sh
->CompileStatus
= GL_FALSE
;
803 * Called via ctx->Driver.CompileShader()
806 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
808 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
811 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
815 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
820 * Called via ctx->Driver.LinkProgram()
823 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
825 struct gl_shader_program
*shProg
;
827 shProg
= _mesa_lookup_shader_program(ctx
, program
);
829 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
833 _slang_link2(ctx
, program
, shProg
);
838 * Called via ctx->Driver.UseProgram()
841 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
844 if (ctx
->Shader
.CurrentProgram
) {
845 ctx
->Shader
.CurrentProgram
->RefCount
--;
846 if (ctx
->Shader
.CurrentProgram
->RefCount
<= 0) {
847 _mesa_free_shader_program(ctx
, ctx
->Shader
.CurrentProgram
);
849 ctx
->Shader
.CurrentProgram
= NULL
;
853 struct gl_shader_program
*shProg
;
854 shProg
= _mesa_lookup_shader_program(ctx
, program
);
856 _mesa_error(ctx
, GL_INVALID_VALUE
,
857 "glUseProgramObjectARB(programObj)");
860 ctx
->Shader
.CurrentProgram
= shProg
;
864 /* don't use a shader program */
865 ctx
->Shader
.CurrentProgram
= NULL
;
871 * Called via ctx->Driver.Uniform().
874 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
875 const GLvoid
*values
, GLenum type
)
877 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
880 if (!shProg
|| !shProg
->LinkStatus
) {
881 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
885 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
886 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
890 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
892 uniformVal
= shProg
->Uniforms
->ParameterValues
[location
];
894 if (type
== GL_INT
||
895 type
== GL_INT_VEC2
||
896 type
== GL_INT_VEC3
||
897 type
== GL_INT_VEC4
) {
898 const GLint
*iValues
= (const GLint
*) values
;
901 uniformVal
[3] = (GLfloat
) iValues
[3];
904 uniformVal
[2] = (GLfloat
) iValues
[2];
907 uniformVal
[1] = (GLfloat
) iValues
[1];
910 uniformVal
[0] = (GLfloat
) iValues
[0];
913 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
918 const GLfloat
*fValues
= (const GLfloat
*) values
;
921 uniformVal
[3] = fValues
[3];
924 uniformVal
[2] = fValues
[2];
927 uniformVal
[1] = fValues
[1];
930 uniformVal
[0] = fValues
[0];
933 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
938 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
939 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
940 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
941 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
947 * Called by ctx->Driver.UniformMatrix().
950 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
951 GLenum matrixType
, GLint location
, GLsizei count
,
952 GLboolean transpose
, const GLfloat
*values
)
954 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
955 if (!shProg
|| !shProg
->LinkStatus
) {
956 _mesa_error(ctx
, GL_INVALID_OPERATION
,
957 "glUniformMatrix(program not linked)");
960 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
961 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
964 if (values
== NULL
) {
965 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
969 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
972 * Note: the _columns_ of a matrix are stored in program registers, not
975 /* XXXX need to test 3x3 and 2x2 matrices... */
978 for (col
= 0; col
< cols
; col
++) {
979 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
980 for (row
= 0; row
< rows
; row
++) {
981 v
[row
] = values
[col
* rows
+ row
];
987 for (col
= 0; col
< cols
; col
++) {
988 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
989 for (row
= 0; row
< rows
; row
++) {
990 v
[row
] = values
[row
* cols
+ col
];
998 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1000 struct gl_shader_program
*shProg
;
1001 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1003 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1007 shProg
->Validated
= GL_TRUE
;
1009 /* From the GL spec:
1010 any two active samplers in the current program object are of
1011 different types, but refer to the same texture image unit,
1013 any active sampler in the current program object refers to a texture
1014 image unit where fixed-function fragment processing accesses a
1015 texture target that does not match the sampler type, or
1017 the sum of the number of active samplers in the program and the
1018 number of texture image units enabled for fixed-function fragment
1019 processing exceeds the combined limit on the total number of texture
1020 image units allowed.