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
);
311 printf("===== post BindAttrib:\n");
312 _mesa_print_program(&shProg
->VertexProgram
->Base
);
318 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
320 struct gl_shader
*sh
;
323 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
326 case GL_FRAGMENT_SHADER
:
327 case GL_VERTEX_SHADER
:
328 sh
= _mesa_new_shader(ctx
, name
, type
);
331 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
335 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
342 _mesa_create_program(GLcontext
*ctx
)
345 struct gl_shader_program
*shProg
;
347 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
348 shProg
= _mesa_new_shader_program(ctx
, name
);
350 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
357 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
359 struct gl_shader_program
*shProg
;
361 shProg
= _mesa_lookup_shader_program(ctx
, name
);
363 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
367 /* always remove from hash table */
368 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, name
);
370 shProg
->DeletePending
= GL_TRUE
;
372 /* decrement refcount, delete if zero */
374 if (shProg
->RefCount
<= 0) {
375 _mesa_free_shader_program(ctx
, shProg
);
381 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
383 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
388 sh
->DeletePending
= GL_TRUE
;
390 if (sh
->RefCount
<= 0) {
391 _mesa_free_shader(ctx
, sh
);
397 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
399 struct gl_shader_program
*shProg
400 = _mesa_lookup_shader_program(ctx
, program
);
401 const GLuint n
= shProg
->NumShaders
;
405 _mesa_error(ctx
, GL_INVALID_VALUE
,
406 "glDetachShader(bad program or shader name)");
410 for (i
= 0; i
< n
; i
++) {
411 if (shProg
->Shaders
[i
]->Name
== shader
) {
412 struct gl_shader
**newList
;
415 shProg
->Shaders
[i
]->RefCount
--;
417 /* alloc new, smaller array */
418 newList
= (struct gl_shader
**)
419 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
421 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
424 for (j
= 0; j
< i
; j
++) {
425 newList
[j
] = shProg
->Shaders
[j
];
428 newList
[j
++] = shProg
->Shaders
[i
];
429 _mesa_free(shProg
->Shaders
);
431 /* XXX refcounting! */
433 shProg
->Shaders
= newList
;
439 _mesa_error(ctx
, GL_INVALID_VALUE
,
440 "glDetachShader(shader not found)");
445 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
446 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
447 GLenum
*type
, GLchar
*nameOut
)
449 static const GLenum vec_types
[] = {
450 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
452 struct gl_shader_program
*shProg
453 = _mesa_lookup_shader_program(ctx
, program
);
457 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
461 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
462 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
466 copy_string(nameOut
, maxLength
, length
,
467 shProg
->Attributes
->Parameters
[index
].Name
);
468 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
472 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
477 * Called via ctx->Driver.GetActiveUniform().
480 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
481 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
482 GLenum
*type
, GLchar
*nameOut
)
484 static const GLenum vec_types
[] = {
485 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
487 struct gl_shader_program
*shProg
488 = _mesa_lookup_shader_program(ctx
, program
);
492 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
496 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
497 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
501 copy_string(nameOut
, maxLength
, length
,
502 shProg
->Uniforms
->Parameters
[index
].Name
);
503 sz
= shProg
->Uniforms
->Parameters
[index
].Size
;
507 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
512 * Called via ctx->Driver.GetAttachedShaders().
515 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
516 GLsizei
*count
, GLuint
*obj
)
518 struct gl_shader_program
*shProg
519 = _mesa_lookup_shader_program(ctx
, program
);
522 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
523 obj
[i
] = shProg
->Shaders
[i
]->Name
;
529 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
535 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
538 struct gl_shader_program
*shProg
539 = _mesa_lookup_shader_program(ctx
, program
);
542 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
546 if (!shProg
->LinkStatus
) {
547 _mesa_error(ctx
, GL_INVALID_OPERATION
,
548 "glGetAttribLocation(program not linked)");
555 if (shProg
->Attributes
) {
556 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
558 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
566 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
569 GET_CURRENT_CONTEXT(ctx
);
572 case GL_PROGRAM_OBJECT_ARB
:
574 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
577 return (**pro
)._container
._generic
.
578 GetName((struct gl2_generic_intf
**) (pro
));
582 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
590 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
591 GLenum pname
, GLint
*params
)
593 struct gl_shader_program
*shProg
594 = _mesa_lookup_shader_program(ctx
, program
);
597 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
602 case GL_DELETE_STATUS
:
603 *params
= shProg
->DeletePending
;
606 *params
= shProg
->LinkStatus
;
608 case GL_VALIDATE_STATUS
:
609 *params
= shProg
->Validated
;
611 case GL_INFO_LOG_LENGTH
:
612 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) : 0;
614 case GL_ATTACHED_SHADERS
:
615 *params
= shProg
->NumShaders
;
617 case GL_ACTIVE_ATTRIBUTES
:
618 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
620 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
621 *params
= _mesa_parameter_longest_name(shProg
->Attributes
);
623 case GL_ACTIVE_UNIFORMS
:
624 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumParameters
: 0;
626 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
627 *params
= _mesa_parameter_longest_name(shProg
->Uniforms
);
630 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
637 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
639 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
642 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
648 *params
= shader
->Type
;
650 case GL_DELETE_STATUS
:
651 *params
= shader
->DeletePending
;
653 case GL_COMPILE_STATUS
:
654 *params
= shader
->CompileStatus
;
656 case GL_INFO_LOG_LENGTH
:
657 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) : 0;
659 case GL_SHADER_SOURCE_LENGTH
:
660 *params
= shader
->Source
? strlen((char *) shader
->Source
) : 0;
663 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
670 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
671 GLsizei
*length
, GLchar
*infoLog
)
673 struct gl_shader_program
*shProg
674 = _mesa_lookup_shader_program(ctx
, program
);
676 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
679 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
684 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
685 GLsizei
*length
, GLchar
*infoLog
)
687 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
689 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
692 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
697 * Called via ctx->Driver.GetShaderSource().
700 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
701 GLsizei
*length
, GLchar
*sourceOut
)
703 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
705 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
708 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
713 * Called via ctx->Driver.GetUniformfv().
716 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
719 struct gl_shader_program
*shProg
720 = _mesa_lookup_shader_program(ctx
, program
);
723 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
724 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
725 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
729 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
733 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
739 * Called via ctx->Driver.GetUniformLocation().
742 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
744 if (ctx
->Shader
.CurrentProgram
) {
745 const struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
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_link2(ctx
, program
, shProg
);
839 * Called via ctx->Driver.UseProgram()
842 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
845 if (ctx
->Shader
.CurrentProgram
) {
846 ctx
->Shader
.CurrentProgram
->RefCount
--;
847 if (ctx
->Shader
.CurrentProgram
->RefCount
<= 0) {
848 _mesa_free_shader_program(ctx
, ctx
->Shader
.CurrentProgram
);
850 ctx
->Shader
.CurrentProgram
= NULL
;
854 struct gl_shader_program
*shProg
;
855 shProg
= _mesa_lookup_shader_program(ctx
, program
);
857 _mesa_error(ctx
, GL_INVALID_VALUE
,
858 "glUseProgramObjectARB(programObj)");
861 ctx
->Shader
.CurrentProgram
= shProg
;
865 /* don't use a shader program */
866 ctx
->Shader
.CurrentProgram
= NULL
;
872 * Called via ctx->Driver.Uniform().
875 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
876 const GLvoid
*values
, GLenum type
)
878 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
881 if (!shProg
|| !shProg
->LinkStatus
) {
882 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
886 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
887 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
891 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
893 uniformVal
= shProg
->Uniforms
->ParameterValues
[location
];
895 if (type
== GL_INT
||
896 type
== GL_INT_VEC2
||
897 type
== GL_INT_VEC3
||
898 type
== GL_INT_VEC4
) {
899 const GLint
*iValues
= (const GLint
*) values
;
902 uniformVal
[3] = (GLfloat
) iValues
[3];
905 uniformVal
[2] = (GLfloat
) iValues
[2];
908 uniformVal
[1] = (GLfloat
) iValues
[1];
911 uniformVal
[0] = (GLfloat
) iValues
[0];
914 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
919 const GLfloat
*fValues
= (const GLfloat
*) values
;
922 uniformVal
[3] = fValues
[3];
925 uniformVal
[2] = fValues
[2];
928 uniformVal
[1] = fValues
[1];
931 uniformVal
[0] = fValues
[0];
934 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
939 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
940 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
941 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
942 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
948 * Called by ctx->Driver.UniformMatrix().
951 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
952 GLenum matrixType
, GLint location
, GLsizei count
,
953 GLboolean transpose
, const GLfloat
*values
)
955 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
956 if (!shProg
|| !shProg
->LinkStatus
) {
957 _mesa_error(ctx
, GL_INVALID_OPERATION
,
958 "glUniformMatrix(program not linked)");
961 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
962 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
965 if (values
== NULL
) {
966 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
970 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
973 * Note: the _columns_ of a matrix are stored in program registers, not
976 /* XXXX need to test 3x3 and 2x2 matrices... */
979 for (col
= 0; col
< cols
; col
++) {
980 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
981 for (row
= 0; row
< rows
; row
++) {
982 v
[row
] = values
[col
* rows
+ row
];
988 for (col
= 0; col
< cols
; col
++) {
989 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
990 for (row
= 0; row
< rows
; row
++) {
991 v
[row
] = values
[row
* cols
+ col
];
999 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1001 struct gl_shader_program
*shProg
;
1002 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1004 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1008 shProg
->Validated
= GL_TRUE
;
1010 /* From the GL spec:
1011 any two active samplers in the current program object are of
1012 different types, but refer to the same texture image unit,
1014 any active sampler in the current program object refers to a texture
1015 image unit where fixed-function fragment processing accesses a
1016 texture target that does not match the sampler type, or
1018 the sum of the number of active samplers in the program and the
1019 number of texture image units enabled for fixed-function fragment
1020 processing exceeds the combined limit on the total number of texture
1021 image units allowed.