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 struct gl_shader_program
*shProg
745 = _mesa_lookup_shader_program(ctx
, program
);
748 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
749 const struct gl_program_parameter
*u
750 = shProg
->Uniforms
->Parameters
+ loc
;
751 /* XXX this is a temporary simplification / short-cut.
752 * We need to handle things like "e.c[0].b" as seen in the
753 * GLSL orange book, page 189.
755 if ((u
->Type
== PROGRAM_UNIFORM
||
756 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
767 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
769 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
770 return shProg
? GL_TRUE
: GL_FALSE
;
775 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
777 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
778 return shader
? GL_TRUE
: GL_FALSE
;
784 * Called via ctx->Driver.ShaderSource()
787 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
789 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
791 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
795 /* free old shader source string and install new one */
797 _mesa_free((void *) sh
->Source
);
800 sh
->CompileStatus
= GL_FALSE
;
805 * Called via ctx->Driver.CompileShader()
808 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
810 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
813 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
817 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
822 * Called via ctx->Driver.LinkProgram()
825 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
827 struct gl_shader_program
*shProg
;
829 shProg
= _mesa_lookup_shader_program(ctx
, program
);
831 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
835 _slang_link2(ctx
, program
, shProg
);
840 * Called via ctx->Driver.UseProgram()
843 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
846 if (ctx
->Shader
.CurrentProgram
) {
847 ctx
->Shader
.CurrentProgram
->RefCount
--;
848 if (ctx
->Shader
.CurrentProgram
->RefCount
<= 0) {
849 _mesa_free_shader_program(ctx
, ctx
->Shader
.CurrentProgram
);
851 ctx
->Shader
.CurrentProgram
= NULL
;
855 struct gl_shader_program
*shProg
;
856 shProg
= _mesa_lookup_shader_program(ctx
, program
);
858 _mesa_error(ctx
, GL_INVALID_VALUE
,
859 "glUseProgramObjectARB(programObj)");
862 ctx
->Shader
.CurrentProgram
= shProg
;
866 /* don't use a shader program */
867 ctx
->Shader
.CurrentProgram
= NULL
;
873 * Called via ctx->Driver.Uniform().
876 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
877 const GLvoid
*values
, GLenum type
)
879 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
882 if (!shProg
|| !shProg
->LinkStatus
) {
883 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
887 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
888 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
892 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
894 uniformVal
= shProg
->Uniforms
->ParameterValues
[location
];
896 if (type
== GL_INT
||
897 type
== GL_INT_VEC2
||
898 type
== GL_INT_VEC3
||
899 type
== GL_INT_VEC4
) {
900 const GLint
*iValues
= (const GLint
*) values
;
903 uniformVal
[3] = (GLfloat
) iValues
[3];
906 uniformVal
[2] = (GLfloat
) iValues
[2];
909 uniformVal
[1] = (GLfloat
) iValues
[1];
912 uniformVal
[0] = (GLfloat
) iValues
[0];
915 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
920 const GLfloat
*fValues
= (const GLfloat
*) values
;
923 uniformVal
[3] = fValues
[3];
926 uniformVal
[2] = fValues
[2];
929 uniformVal
[1] = fValues
[1];
932 uniformVal
[0] = fValues
[0];
935 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
940 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
941 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
942 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
943 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
949 * Called by ctx->Driver.UniformMatrix().
952 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
953 GLenum matrixType
, GLint location
, GLsizei count
,
954 GLboolean transpose
, const GLfloat
*values
)
956 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
957 if (!shProg
|| !shProg
->LinkStatus
) {
958 _mesa_error(ctx
, GL_INVALID_OPERATION
,
959 "glUniformMatrix(program not linked)");
962 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
963 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
966 if (values
== NULL
) {
967 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
971 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
974 * Note: the _columns_ of a matrix are stored in program registers, not
977 /* XXXX need to test 3x3 and 2x2 matrices... */
980 for (col
= 0; col
< cols
; col
++) {
981 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
982 for (row
= 0; row
< rows
; row
++) {
983 v
[row
] = values
[col
* rows
+ row
];
989 for (col
= 0; col
< cols
; col
++) {
990 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
991 for (row
= 0; row
< rows
; row
++) {
992 v
[row
] = values
[row
* cols
+ col
];
1000 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1002 struct gl_shader_program
*shProg
;
1003 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1005 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1009 shProg
->Validated
= GL_TRUE
;
1011 /* From the GL spec:
1012 any two active samplers in the current program object are of
1013 different types, but refer to the same texture image unit,
1015 any active sampler in the current program object refers to a texture
1016 image unit where fixed-function fragment processing accesses a
1017 texture target that does not match the sampler type, or
1019 the sum of the number of active samplers in the program and the
1020 number of texture image units enabled for fixed-function fragment
1021 processing exceeds the combined limit on the total number of texture
1022 image units allowed.