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 * Free the data that hangs off a shader program object, but not the object
75 _mesa_free_shader_program_data(GLcontext
*ctx
,
76 struct gl_shader_program
*shProg
)
78 assert(shProg
->Type
== GL_SHADER_PROGRAM
);
80 if (shProg
->VertexProgram
) {
81 if (shProg
->VertexProgram
->Base
.Parameters
== shProg
->Uniforms
) {
82 /* to prevent a double-free in the next call */
83 shProg
->VertexProgram
->Base
.Parameters
= NULL
;
85 _mesa_delete_program(ctx
, &shProg
->VertexProgram
->Base
);
86 shProg
->VertexProgram
= NULL
;
89 if (shProg
->FragmentProgram
) {
90 if (shProg
->FragmentProgram
->Base
.Parameters
== shProg
->Uniforms
) {
91 /* to prevent a double-free in the next call */
92 shProg
->FragmentProgram
->Base
.Parameters
= NULL
;
94 _mesa_delete_program(ctx
, &shProg
->FragmentProgram
->Base
);
95 shProg
->FragmentProgram
= NULL
;
99 if (shProg
->Uniforms
) {
100 _mesa_free_parameter_list(shProg
->Uniforms
);
101 shProg
->Uniforms
= NULL
;
104 if (shProg
->Varying
) {
105 _mesa_free_parameter_list(shProg
->Varying
);
106 shProg
->Varying
= NULL
;
112 * Free/delete a shader program object.
115 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
117 _mesa_free_shader_program_data(ctx
, shProg
);
118 if (shProg
->Shaders
) {
119 _mesa_free(shProg
->Shaders
);
120 shProg
->Shaders
= NULL
;
127 * Lookup a GLSL program object.
129 struct gl_shader_program
*
130 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
132 struct gl_shader_program
*shProg
;
134 shProg
= (struct gl_shader_program
*)
135 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
136 /* Note that both gl_shader and gl_shader_program objects are kept
137 * in the same hash table. Check the object's type to be sure it's
138 * what we're expecting.
140 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM
) {
150 * Allocate a new gl_shader object, initialize it.
153 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
155 struct gl_shader
*shader
;
156 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
157 shader
= CALLOC_STRUCT(gl_shader
);
161 shader
->RefCount
= 1;
168 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
172 _mesa_free((void *) sh
->Source
);
174 _mesa_free(sh
->InfoLog
);
175 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
176 assert(sh
->Programs
[i
]);
177 _mesa_delete_program(ctx
, sh
->Programs
[i
]);
180 _mesa_free(sh
->Programs
);
186 * Lookup a GLSL shader object.
189 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
192 struct gl_shader
*sh
= (struct gl_shader
*)
193 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
194 /* Note that both gl_shader and gl_shader_program objects are kept
195 * in the same hash table. Check the object's type to be sure it's
196 * what we're expecting.
198 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM
) {
199 assert(sh
->Type
== GL_VERTEX_SHADER
||
200 sh
->Type
== GL_FRAGMENT_SHADER
);
210 * Initialize context's shader state.
213 _mesa_init_shader_state(GLcontext
* ctx
)
215 /* Device drivers may override these to control what kind of instructions
216 * are generated by the GLSL compiler.
218 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
219 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
220 ctx
->Shader
.EmitComments
= GL_FALSE
;
225 * Free the per-context shader-related state.
228 _mesa_free_shader_state(GLcontext
*ctx
)
230 if (ctx
->Shader
.CurrentProgram
) {
231 ctx
->Shader
.CurrentProgram
->RefCount
--;
232 if (ctx
->Shader
.CurrentProgram
->RefCount
<= 0) {
233 _mesa_free_shader_program(ctx
, ctx
->Shader
.CurrentProgram
);
234 ctx
->Shader
.CurrentProgram
= NULL
;
241 * Copy string from <src> to <dst>, up to maxLength characters, returning
242 * length of <dst> in <length>.
243 * \param src the strings source
244 * \param maxLength max chars to copy
245 * \param length returns number of chars copied
246 * \param dst the string destination
249 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
252 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
262 * Called via ctx->Driver.AttachShader()
265 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
267 struct gl_shader_program
*shProg
268 = _mesa_lookup_shader_program(ctx
, program
);
269 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
270 const GLuint n
= shProg
->NumShaders
;
273 if (!shProg
|| !sh
) {
274 _mesa_error(ctx
, GL_INVALID_VALUE
,
275 "glAttachShader(bad program or shader name)");
279 for (i
= 0; i
< n
; i
++) {
280 if (shProg
->Shaders
[i
] == sh
) {
281 /* already attached */
287 shProg
->Shaders
= (struct gl_shader
**)
288 _mesa_realloc(shProg
->Shaders
,
289 n
* sizeof(struct gl_shader
*),
290 (n
+ 1) * sizeof(struct gl_shader
*));
291 if (!shProg
->Shaders
) {
292 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
297 shProg
->Shaders
[n
] = sh
;
299 shProg
->NumShaders
++;
304 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
307 struct gl_shader_program
*shProg
308 = _mesa_lookup_shader_program(ctx
, program
);
309 const GLint size
= -1; /* unknown size */
313 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
320 if (strncmp(name
, "gl_", 3) == 0) {
321 _mesa_error(ctx
, GL_INVALID_OPERATION
,
322 "glBindAttribLocation(illegal name)");
326 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
328 /* this will replace the current value if it's already in the list */
329 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
331 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
334 if (shProg
->VertexProgram
&& oldIndex
>= 0) {
335 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
339 printf("===== post BindAttrib:\n");
340 _mesa_print_program(&shProg
->VertexProgram
->Base
);
346 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
348 struct gl_shader
*sh
;
351 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
354 case GL_FRAGMENT_SHADER
:
355 case GL_VERTEX_SHADER
:
356 sh
= _mesa_new_shader(ctx
, name
, type
);
359 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
363 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
370 _mesa_create_program(GLcontext
*ctx
)
373 struct gl_shader_program
*shProg
;
375 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
376 shProg
= _mesa_new_shader_program(ctx
, name
);
378 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
385 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
387 struct gl_shader_program
*shProg
;
389 shProg
= _mesa_lookup_shader_program(ctx
, name
);
391 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
395 /* always remove from hash table */
396 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, name
);
398 shProg
->DeletePending
= GL_TRUE
;
400 /* decrement refcount, delete if zero */
402 if (shProg
->RefCount
<= 0) {
403 _mesa_free_shader_program(ctx
, shProg
);
409 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
411 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
416 sh
->DeletePending
= GL_TRUE
;
418 if (sh
->RefCount
<= 0) {
419 _mesa_free_shader(ctx
, sh
);
425 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
427 struct gl_shader_program
*shProg
428 = _mesa_lookup_shader_program(ctx
, program
);
429 const GLuint n
= shProg
->NumShaders
;
433 _mesa_error(ctx
, GL_INVALID_VALUE
,
434 "glDetachShader(bad program or shader name)");
438 for (i
= 0; i
< n
; i
++) {
439 if (shProg
->Shaders
[i
]->Name
== shader
) {
440 struct gl_shader
**newList
;
443 shProg
->Shaders
[i
]->RefCount
--;
444 if (shProg
->Shaders
[i
]->RefCount
== 0) {
446 _mesa_free_shader(ctx
, shProg
->Shaders
[i
]);
449 /* alloc new, smaller array */
450 newList
= (struct gl_shader
**)
451 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
453 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
456 for (j
= 0; j
< i
; j
++) {
457 newList
[j
] = shProg
->Shaders
[j
];
460 newList
[j
++] = shProg
->Shaders
[i
];
461 _mesa_free(shProg
->Shaders
);
463 shProg
->Shaders
= newList
;
469 _mesa_error(ctx
, GL_INVALID_VALUE
,
470 "glDetachShader(shader not found)");
475 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
476 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
477 GLenum
*type
, GLchar
*nameOut
)
479 static const GLenum vec_types
[] = {
480 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
482 struct gl_shader_program
*shProg
483 = _mesa_lookup_shader_program(ctx
, program
);
487 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
491 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
492 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
496 copy_string(nameOut
, maxLength
, length
,
497 shProg
->Attributes
->Parameters
[index
].Name
);
498 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
502 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
507 * Called via ctx->Driver.GetActiveUniform().
510 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
511 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
512 GLenum
*type
, GLchar
*nameOut
)
514 static const GLenum vec_types
[] = {
515 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
517 struct gl_shader_program
*shProg
518 = _mesa_lookup_shader_program(ctx
, program
);
522 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
526 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
527 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
531 copy_string(nameOut
, maxLength
, length
,
532 shProg
->Uniforms
->Parameters
[index
].Name
);
533 sz
= shProg
->Uniforms
->Parameters
[index
].Size
;
537 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
542 * Called via ctx->Driver.GetAttachedShaders().
545 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
546 GLsizei
*count
, GLuint
*obj
)
548 struct gl_shader_program
*shProg
549 = _mesa_lookup_shader_program(ctx
, program
);
552 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
553 obj
[i
] = shProg
->Shaders
[i
]->Name
;
559 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
565 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
568 struct gl_shader_program
*shProg
569 = _mesa_lookup_shader_program(ctx
, program
);
572 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
576 if (!shProg
->LinkStatus
) {
577 _mesa_error(ctx
, GL_INVALID_OPERATION
,
578 "glGetAttribLocation(program not linked)");
585 if (shProg
->Attributes
) {
586 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
588 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
596 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
599 GET_CURRENT_CONTEXT(ctx
);
602 case GL_PROGRAM_OBJECT_ARB
:
604 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
607 return (**pro
)._container
._generic
.
608 GetName((struct gl2_generic_intf
**) (pro
));
612 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
620 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
621 GLenum pname
, GLint
*params
)
623 struct gl_shader_program
*shProg
624 = _mesa_lookup_shader_program(ctx
, program
);
627 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
632 case GL_DELETE_STATUS
:
633 *params
= shProg
->DeletePending
;
636 *params
= shProg
->LinkStatus
;
638 case GL_VALIDATE_STATUS
:
639 *params
= shProg
->Validated
;
641 case GL_INFO_LOG_LENGTH
:
642 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) : 0;
644 case GL_ATTACHED_SHADERS
:
645 *params
= shProg
->NumShaders
;
647 case GL_ACTIVE_ATTRIBUTES
:
648 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
650 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
651 *params
= _mesa_parameter_longest_name(shProg
->Attributes
);
653 case GL_ACTIVE_UNIFORMS
:
654 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumParameters
: 0;
656 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
657 *params
= _mesa_parameter_longest_name(shProg
->Uniforms
);
660 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
667 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
669 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
672 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
678 *params
= shader
->Type
;
680 case GL_DELETE_STATUS
:
681 *params
= shader
->DeletePending
;
683 case GL_COMPILE_STATUS
:
684 *params
= shader
->CompileStatus
;
686 case GL_INFO_LOG_LENGTH
:
687 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) : 0;
689 case GL_SHADER_SOURCE_LENGTH
:
690 *params
= shader
->Source
? strlen((char *) shader
->Source
) : 0;
693 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
700 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
701 GLsizei
*length
, GLchar
*infoLog
)
703 struct gl_shader_program
*shProg
704 = _mesa_lookup_shader_program(ctx
, program
);
706 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
709 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
714 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
715 GLsizei
*length
, GLchar
*infoLog
)
717 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
719 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
722 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
727 * Called via ctx->Driver.GetShaderSource().
730 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
731 GLsizei
*length
, GLchar
*sourceOut
)
733 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
735 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
738 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
743 * Called via ctx->Driver.GetUniformfv().
746 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
749 struct gl_shader_program
*shProg
750 = _mesa_lookup_shader_program(ctx
, program
);
753 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
754 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
755 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
759 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
763 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
769 * Called via ctx->Driver.GetUniformLocation().
772 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
774 struct gl_shader_program
*shProg
775 = _mesa_lookup_shader_program(ctx
, program
);
778 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
779 const struct gl_program_parameter
*u
780 = shProg
->Uniforms
->Parameters
+ loc
;
781 /* XXX this is a temporary simplification / short-cut.
782 * We need to handle things like "e.c[0].b" as seen in the
783 * GLSL orange book, page 189.
785 if ((u
->Type
== PROGRAM_UNIFORM
||
786 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
797 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
799 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
800 return shProg
? GL_TRUE
: GL_FALSE
;
805 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
807 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
808 return shader
? GL_TRUE
: GL_FALSE
;
814 * Called via ctx->Driver.ShaderSource()
817 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
819 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
821 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
825 /* free old shader source string and install new one */
827 _mesa_free((void *) sh
->Source
);
830 sh
->CompileStatus
= GL_FALSE
;
835 * Called via ctx->Driver.CompileShader()
838 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
840 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
843 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
847 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
852 * Called via ctx->Driver.LinkProgram()
855 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
857 struct gl_shader_program
*shProg
;
859 shProg
= _mesa_lookup_shader_program(ctx
, program
);
861 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
865 _slang_link(ctx
, program
, shProg
);
870 * Called via ctx->Driver.UseProgram()
873 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
875 if (ctx
->Shader
.CurrentProgram
&&
876 ctx
->Shader
.CurrentProgram
->Name
== program
) {
881 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
884 if (ctx
->Shader
.CurrentProgram
) {
885 ctx
->Shader
.CurrentProgram
->RefCount
--;
886 if (ctx
->Shader
.CurrentProgram
->RefCount
<= 0) {
887 _mesa_free_shader_program(ctx
, ctx
->Shader
.CurrentProgram
);
889 ctx
->Shader
.CurrentProgram
= NULL
;
893 struct gl_shader_program
*shProg
;
894 shProg
= _mesa_lookup_shader_program(ctx
, program
);
896 _mesa_error(ctx
, GL_INVALID_VALUE
,
897 "glUseProgramObjectARB(programObj)");
900 ctx
->Shader
.CurrentProgram
= shProg
;
904 /* don't use a shader program */
905 ctx
->Shader
.CurrentProgram
= NULL
;
911 * Called via ctx->Driver.Uniform().
914 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
915 const GLvoid
*values
, GLenum type
)
917 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
920 if (!shProg
|| !shProg
->LinkStatus
) {
921 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
925 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
926 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
930 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
933 * If we're setting a sampler, we must use glUniformi1()!
935 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
936 if (type
!= GL_INT
|| count
!= 1) {
937 _mesa_error(ctx
, GL_INVALID_OPERATION
,
938 "glUniform(only glUniform1i can be used "
939 "to set sampler uniforms)");
945 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
967 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
971 if (count
* elems
> shProg
->Uniforms
->Parameters
[location
].Size
) {
972 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
976 for (k
= 0; k
< count
; k
++) {
977 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
978 if (type
== GL_INT
||
979 type
== GL_INT_VEC2
||
980 type
== GL_INT_VEC3
||
981 type
== GL_INT_VEC4
) {
982 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
983 for (i
= 0; i
< elems
; i
++) {
984 uniformVal
[i
] = (GLfloat
) iValues
[i
];
988 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
989 for (i
= 0; i
< elems
; i
++) {
990 uniformVal
[i
] = fValues
[i
];
995 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
996 if (shProg
->VertexProgram
)
997 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
998 if (shProg
->FragmentProgram
)
999 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
1000 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1006 * Called by ctx->Driver.UniformMatrix().
1009 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1010 GLenum matrixType
, GLint location
, GLsizei count
,
1011 GLboolean transpose
, const GLfloat
*values
)
1013 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1014 if (!shProg
|| !shProg
->LinkStatus
) {
1015 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1016 "glUniformMatrix(program not linked)");
1019 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
1020 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1023 if (values
== NULL
) {
1024 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1028 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1031 * Note: the _columns_ of a matrix are stored in program registers, not
1034 /* XXXX need to test 3x3 and 2x2 matrices... */
1037 for (col
= 0; col
< cols
; col
++) {
1038 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1039 for (row
= 0; row
< rows
; row
++) {
1040 v
[row
] = values
[row
* cols
+ col
];
1046 for (col
= 0; col
< cols
; col
++) {
1047 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1048 for (row
= 0; row
< rows
; row
++) {
1049 v
[row
] = values
[col
* rows
+ row
];
1057 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1059 struct gl_shader_program
*shProg
;
1060 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1062 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1066 shProg
->Validated
= GL_TRUE
;
1068 /* From the GL spec:
1069 any two active samplers in the current program object are of
1070 different types, but refer to the same texture image unit,
1072 any active sampler in the current program object refers to a texture
1073 image unit where fixed-function fragment processing accesses a
1074 texture target that does not match the sampler type, or
1076 the sum of the number of active samplers in the program and the
1077 number of texture image units enabled for fixed-function fragment
1078 processing exceeds the combined limit on the total number of texture
1079 image units allowed.