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
43 #include "prog_parameter.h"
44 #include "prog_print.h"
45 #include "prog_statevars.h"
46 #include "shader_api.h"
48 #include "slang_compile.h"
49 #include "slang_link.h"
54 * Allocate a new gl_shader_program object, initialize it.
56 struct gl_shader_program
*
57 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
59 struct gl_shader_program
*shProg
;
60 shProg
= CALLOC_STRUCT(gl_shader_program
);
62 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
65 shProg
->Attributes
= _mesa_new_parameter_list();
72 * Clear (free) the shader program state that gets produced by linking.
75 _mesa_clear_shader_program_data(GLcontext
*ctx
,
76 struct gl_shader_program
*shProg
)
78 if (shProg
->VertexProgram
) {
79 if (shProg
->VertexProgram
->Base
.Parameters
== shProg
->Uniforms
) {
80 /* to prevent a double-free in the next call */
81 shProg
->VertexProgram
->Base
.Parameters
= NULL
;
83 _mesa_delete_program(ctx
, &shProg
->VertexProgram
->Base
);
84 shProg
->VertexProgram
= NULL
;
87 if (shProg
->FragmentProgram
) {
88 if (shProg
->FragmentProgram
->Base
.Parameters
== shProg
->Uniforms
) {
89 /* to prevent a double-free in the next call */
90 shProg
->FragmentProgram
->Base
.Parameters
= NULL
;
92 _mesa_delete_program(ctx
, &shProg
->FragmentProgram
->Base
);
93 shProg
->FragmentProgram
= NULL
;
96 if (shProg
->Uniforms
) {
97 _mesa_free_parameter_list(shProg
->Uniforms
);
98 shProg
->Uniforms
= NULL
;
101 if (shProg
->Varying
) {
102 _mesa_free_parameter_list(shProg
->Varying
);
103 shProg
->Varying
= NULL
;
109 * Free all the data that hangs off a shader program object, but not the
113 _mesa_free_shader_program_data(GLcontext
*ctx
,
114 struct gl_shader_program
*shProg
)
118 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
120 _mesa_clear_shader_program_data(ctx
, shProg
);
122 if (shProg
->Attributes
) {
123 _mesa_free_parameter_list(shProg
->Attributes
);
124 shProg
->Attributes
= NULL
;
128 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
129 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
131 if (shProg
->Shaders
) {
132 _mesa_free(shProg
->Shaders
);
133 shProg
->Shaders
= NULL
;
139 * Free/delete a shader program object.
142 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
144 _mesa_free_shader_program_data(ctx
, shProg
);
145 if (shProg
->Shaders
) {
146 _mesa_free(shProg
->Shaders
);
147 shProg
->Shaders
= NULL
;
154 * Set ptr to point to shProg.
155 * If ptr is pointing to another object, decrement its refcount (and delete
156 * if refcount hits zero).
157 * Then set ptr to point to shProg, incrementing its refcount.
159 /* XXX this could be static */
161 _mesa_reference_shader_program(GLcontext
*ctx
,
162 struct gl_shader_program
**ptr
,
163 struct gl_shader_program
*shProg
)
166 if (*ptr
== shProg
) {
171 /* Unreference the old shader program */
172 GLboolean deleteFlag
= GL_FALSE
;
173 struct gl_shader_program
*old
= *ptr
;
175 ASSERT(old
->RefCount
> 0);
177 /*printf("SHPROG DECR %p (%d) to %d\n",
178 (void*) old, old->Name, old->RefCount);*/
179 deleteFlag
= (old
->RefCount
== 0);
182 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
183 _mesa_free_shader_program(ctx
, old
);
192 /*printf("SHPROG INCR %p (%d) to %d\n",
193 (void*) shProg, shProg->Name, shProg->RefCount);*/
200 * Lookup a GLSL program object.
202 struct gl_shader_program
*
203 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
205 struct gl_shader_program
*shProg
;
207 shProg
= (struct gl_shader_program
*)
208 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
209 /* Note that both gl_shader and gl_shader_program objects are kept
210 * in the same hash table. Check the object's type to be sure it's
211 * what we're expecting.
213 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
223 * Allocate a new gl_shader object, initialize it.
226 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
228 struct gl_shader
*shader
;
229 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
230 shader
= CALLOC_STRUCT(gl_shader
);
234 shader
->RefCount
= 1;
241 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
245 _mesa_free((void *) sh
->Source
);
247 _mesa_free(sh
->InfoLog
);
248 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
249 assert(sh
->Programs
[i
]);
250 _mesa_delete_program(ctx
, sh
->Programs
[i
]);
253 _mesa_free(sh
->Programs
);
259 * Set ptr to point to sh.
260 * If ptr is pointing to another shader, decrement its refcount (and delete
261 * if refcount hits zero).
262 * Then set ptr to point to sh, incrementing its refcount.
264 /* XXX this could be static */
266 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
267 struct gl_shader
*sh
)
275 /* Unreference the old shader */
276 GLboolean deleteFlag
= GL_FALSE
;
277 struct gl_shader
*old
= *ptr
;
279 ASSERT(old
->RefCount
> 0);
281 /*printf("SHADER DECR %p (%d) to %d\n",
282 (void*) old, old->Name, old->RefCount);*/
283 deleteFlag
= (old
->RefCount
== 0);
286 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
287 _mesa_free_shader(ctx
, old
);
297 /*printf("SHADER INCR %p (%d) to %d\n",
298 (void*) sh, sh->Name, sh->RefCount);*/
305 * Lookup a GLSL shader object.
308 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
311 struct gl_shader
*sh
= (struct gl_shader
*)
312 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
313 /* Note that both gl_shader and gl_shader_program objects are kept
314 * in the same hash table. Check the object's type to be sure it's
315 * what we're expecting.
317 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
327 * Initialize context's shader state.
330 _mesa_init_shader_state(GLcontext
* ctx
)
332 /* Device drivers may override these to control what kind of instructions
333 * are generated by the GLSL compiler.
335 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
336 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
337 ctx
->Shader
.EmitComments
= GL_FALSE
;
342 * Free the per-context shader-related state.
345 _mesa_free_shader_state(GLcontext
*ctx
)
347 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
352 * Copy string from <src> to <dst>, up to maxLength characters, returning
353 * length of <dst> in <length>.
354 * \param src the strings source
355 * \param maxLength max chars to copy
356 * \param length returns number of chars copied
357 * \param dst the string destination
360 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
363 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
373 * Called via ctx->Driver.AttachShader()
376 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
378 struct gl_shader_program
*shProg
379 = _mesa_lookup_shader_program(ctx
, program
);
380 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
381 const GLuint n
= shProg
->NumShaders
;
384 if (!shProg
|| !sh
) {
385 _mesa_error(ctx
, GL_INVALID_VALUE
,
386 "glAttachShader(bad program or shader name)");
390 for (i
= 0; i
< n
; i
++) {
391 if (shProg
->Shaders
[i
] == sh
) {
392 /* already attached */
398 shProg
->Shaders
= (struct gl_shader
**)
399 _mesa_realloc(shProg
->Shaders
,
400 n
* sizeof(struct gl_shader
*),
401 (n
+ 1) * sizeof(struct gl_shader
*));
402 if (!shProg
->Shaders
) {
403 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
408 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
409 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
410 shProg
->NumShaders
++;
415 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
418 struct gl_shader_program
*shProg
419 = _mesa_lookup_shader_program(ctx
, program
);
420 const GLint size
= -1; /* unknown size */
424 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
431 if (strncmp(name
, "gl_", 3) == 0) {
432 _mesa_error(ctx
, GL_INVALID_OPERATION
,
433 "glBindAttribLocation(illegal name)");
437 if (shProg
->LinkStatus
) {
438 /* get current index/location for the attribute */
439 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
445 /* this will replace the current value if it's already in the list */
446 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
448 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
451 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
452 /* If the index changed, need to search/replace references to that attribute
453 * in the vertex program.
455 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
461 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
463 struct gl_shader
*sh
;
466 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
469 case GL_FRAGMENT_SHADER
:
470 case GL_VERTEX_SHADER
:
471 sh
= _mesa_new_shader(ctx
, name
, type
);
474 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
478 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
485 _mesa_create_program(GLcontext
*ctx
)
488 struct gl_shader_program
*shProg
;
490 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
491 shProg
= _mesa_new_shader_program(ctx
, name
);
493 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
495 assert(shProg
->RefCount
== 1);
502 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
506 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
509 * NOTE: deleting shaders/programs works a bit differently than
510 * texture objects (and buffer objects, etc). Shader/program
511 * handles/IDs exist in the hash table until the object is really
512 * deleted (refcount==0). With texture objects, the handle/ID is
513 * removed from the hash table in glDeleteTextures() while the tex
514 * object itself might linger until its refcount goes to zero.
516 struct gl_shader_program
*shProg
;
518 shProg
= _mesa_lookup_shader_program(ctx
, name
);
520 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
524 shProg
->DeletePending
= GL_TRUE
;
526 /* effectively, decr shProg's refcount */
527 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
532 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
534 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
539 sh
->DeletePending
= GL_TRUE
;
541 /* effectively, decr sh's refcount */
542 _mesa_reference_shader(ctx
, &sh
, NULL
);
547 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
549 struct gl_shader_program
*shProg
550 = _mesa_lookup_shader_program(ctx
, program
);
551 const GLuint n
= shProg
->NumShaders
;
555 _mesa_error(ctx
, GL_INVALID_VALUE
,
556 "glDetachShader(bad program or shader name)");
560 for (i
= 0; i
< n
; i
++) {
561 if (shProg
->Shaders
[i
]->Name
== shader
) {
563 struct gl_shader
**newList
;
566 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
568 /* alloc new, smaller array */
569 newList
= (struct gl_shader
**)
570 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
572 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
575 for (j
= 0; j
< i
; j
++) {
576 newList
[j
] = shProg
->Shaders
[j
];
579 newList
[j
++] = shProg
->Shaders
[i
];
580 _mesa_free(shProg
->Shaders
);
582 shProg
->Shaders
= newList
;
583 shProg
->NumShaders
= n
- 1;
588 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
589 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
590 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
591 assert(shProg
->Shaders
[j
]->RefCount
> 0);
601 _mesa_error(ctx
, GL_INVALID_VALUE
,
602 "glDetachShader(shader not found)");
607 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
608 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
609 GLenum
*type
, GLchar
*nameOut
)
611 static const GLenum vec_types
[] = {
612 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
614 struct gl_shader_program
*shProg
615 = _mesa_lookup_shader_program(ctx
, program
);
619 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
623 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
624 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
628 copy_string(nameOut
, maxLength
, length
,
629 shProg
->Attributes
->Parameters
[index
].Name
);
630 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
634 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
639 * Called via ctx->Driver.GetActiveUniform().
642 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
643 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
644 GLenum
*type
, GLchar
*nameOut
)
646 struct gl_shader_program
*shProg
647 = _mesa_lookup_shader_program(ctx
, program
);
651 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
655 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
656 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
661 for (j
= 0; j
< shProg
->Uniforms
->NumParameters
; j
++) {
662 if (shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_UNIFORM
||
663 shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_SAMPLER
) {
666 copy_string(nameOut
, maxLength
, length
,
667 shProg
->Uniforms
->Parameters
[j
].Name
);
669 *size
= shProg
->Uniforms
->Parameters
[j
].Size
;
671 *type
= shProg
->Uniforms
->Parameters
[j
].DataType
;
678 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
683 * Called via ctx->Driver.GetAttachedShaders().
686 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
687 GLsizei
*count
, GLuint
*obj
)
689 struct gl_shader_program
*shProg
690 = _mesa_lookup_shader_program(ctx
, program
);
693 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
694 obj
[i
] = shProg
->Shaders
[i
]->Name
;
700 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
706 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
709 struct gl_shader_program
*shProg
710 = _mesa_lookup_shader_program(ctx
, program
);
713 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
717 if (!shProg
->LinkStatus
) {
718 _mesa_error(ctx
, GL_INVALID_OPERATION
,
719 "glGetAttribLocation(program not linked)");
726 if (shProg
->Attributes
) {
727 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
729 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
737 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
740 GET_CURRENT_CONTEXT(ctx
);
743 case GL_PROGRAM_OBJECT_ARB
:
745 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
748 return (**pro
)._container
._generic
.
749 GetName((struct gl2_generic_intf
**) (pro
));
753 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
761 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
762 GLenum pname
, GLint
*params
)
764 struct gl_shader_program
*shProg
765 = _mesa_lookup_shader_program(ctx
, program
);
768 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
773 case GL_DELETE_STATUS
:
774 *params
= shProg
->DeletePending
;
777 *params
= shProg
->LinkStatus
;
779 case GL_VALIDATE_STATUS
:
780 *params
= shProg
->Validated
;
782 case GL_INFO_LOG_LENGTH
:
783 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) : 0;
785 case GL_ATTACHED_SHADERS
:
786 *params
= shProg
->NumShaders
;
788 case GL_ACTIVE_ATTRIBUTES
:
789 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
791 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
792 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
795 case GL_ACTIVE_UNIFORMS
:
797 = _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_UNIFORM
)
798 + _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_SAMPLER
);
800 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
802 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_UNIFORM
),
803 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_SAMPLER
));
805 (*params
)++; /* add one for terminating zero */
808 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
815 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
817 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
820 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
826 *params
= shader
->Type
;
828 case GL_DELETE_STATUS
:
829 *params
= shader
->DeletePending
;
831 case GL_COMPILE_STATUS
:
832 *params
= shader
->CompileStatus
;
834 case GL_INFO_LOG_LENGTH
:
835 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) : 0;
837 case GL_SHADER_SOURCE_LENGTH
:
838 *params
= shader
->Source
? strlen((char *) shader
->Source
) : 0;
841 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
848 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
849 GLsizei
*length
, GLchar
*infoLog
)
851 struct gl_shader_program
*shProg
852 = _mesa_lookup_shader_program(ctx
, program
);
854 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
857 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
862 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
863 GLsizei
*length
, GLchar
*infoLog
)
865 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
867 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
870 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
875 * Called via ctx->Driver.GetShaderSource().
878 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
879 GLsizei
*length
, GLchar
*sourceOut
)
881 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
883 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
886 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
891 * Called via ctx->Driver.GetUniformfv().
894 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
897 struct gl_shader_program
*shProg
898 = _mesa_lookup_shader_program(ctx
, program
);
901 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
902 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
903 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
907 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
911 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
917 * Called via ctx->Driver.GetUniformLocation().
920 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
922 struct gl_shader_program
*shProg
923 = _mesa_lookup_shader_program(ctx
, program
);
926 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
927 const struct gl_program_parameter
*u
928 = shProg
->Uniforms
->Parameters
+ loc
;
929 /* XXX this is a temporary simplification / short-cut.
930 * We need to handle things like "e.c[0].b" as seen in the
931 * GLSL orange book, page 189.
933 if ((u
->Type
== PROGRAM_UNIFORM
||
934 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
945 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
947 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
948 return shProg
? GL_TRUE
: GL_FALSE
;
953 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
955 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
956 return shader
? GL_TRUE
: GL_FALSE
;
962 * Called via ctx->Driver.ShaderSource()
965 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
967 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
969 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
973 /* free old shader source string and install new one */
975 _mesa_free((void *) sh
->Source
);
978 sh
->CompileStatus
= GL_FALSE
;
983 * Called via ctx->Driver.CompileShader()
986 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
988 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
991 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
995 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1000 * Called via ctx->Driver.LinkProgram()
1003 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1005 struct gl_shader_program
*shProg
;
1007 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1009 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1013 _slang_link(ctx
, program
, shProg
);
1018 * Called via ctx->Driver.UseProgram()
1021 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1023 struct gl_shader_program
*shProg
;
1025 if (ctx
->Shader
.CurrentProgram
&&
1026 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1031 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1034 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1036 _mesa_error(ctx
, GL_INVALID_VALUE
,
1037 "glUseProgramObjectARB(programObj)");
1045 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1050 * Called via ctx->Driver.Uniform().
1053 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1054 const GLvoid
*values
, GLenum type
)
1056 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1059 if (!shProg
|| !shProg
->LinkStatus
) {
1060 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1064 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1065 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1069 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1072 * If we're setting a sampler, we must use glUniformi1()!
1074 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1076 if (type
!= GL_INT
|| count
!= 1) {
1077 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1078 "glUniform(only glUniform1i can be used "
1079 "to set sampler uniforms)");
1082 /* check that the sampler (tex unit index) is legal */
1083 unit
= ((GLint
*) values
)[0];
1084 if (unit
>= ctx
->Const
.MaxTextureImageUnits
) {
1085 _mesa_error(ctx
, GL_INVALID_VALUE
,
1086 "glUniform1(invalid sampler/tex unit index)");
1092 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1114 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1118 if (count
* elems
> shProg
->Uniforms
->Parameters
[location
].Size
) {
1119 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1123 for (k
= 0; k
< count
; k
++) {
1124 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
1125 if (type
== GL_INT
||
1126 type
== GL_INT_VEC2
||
1127 type
== GL_INT_VEC3
||
1128 type
== GL_INT_VEC4
) {
1129 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1130 for (i
= 0; i
< elems
; i
++) {
1131 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1135 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1136 for (i
= 0; i
< elems
; i
++) {
1137 uniformVal
[i
] = fValues
[i
];
1142 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1143 if (shProg
->VertexProgram
)
1144 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
1145 if (shProg
->FragmentProgram
)
1146 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
1147 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1153 * Called by ctx->Driver.UniformMatrix().
1156 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1157 GLenum matrixType
, GLint location
, GLsizei count
,
1158 GLboolean transpose
, const GLfloat
*values
)
1160 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1161 if (!shProg
|| !shProg
->LinkStatus
) {
1162 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1163 "glUniformMatrix(program not linked)");
1166 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
1167 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1170 if (values
== NULL
) {
1171 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1175 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1178 * Note: the _columns_ of a matrix are stored in program registers, not
1181 /* XXXX need to test 3x3 and 2x2 matrices... */
1184 for (col
= 0; col
< cols
; col
++) {
1185 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1186 for (row
= 0; row
< rows
; row
++) {
1187 v
[row
] = values
[row
* cols
+ col
];
1193 for (col
= 0; col
< cols
; col
++) {
1194 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1195 for (row
= 0; row
< rows
; row
++) {
1196 v
[row
] = values
[col
* rows
+ row
];
1204 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1206 struct gl_shader_program
*shProg
;
1207 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1209 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1213 shProg
->Validated
= GL_TRUE
;
1215 /* From the GL spec:
1216 any two active samplers in the current program object are of
1217 different types, but refer to the same texture image unit,
1219 any active sampler in the current program object refers to a texture
1220 image unit where fixed-function fragment processing accesses a
1221 texture target that does not match the sampler type, or
1223 the sum of the number of active samplers in the program and the
1224 number of texture image units enabled for fixed-function fragment
1225 processing exceeds the combined limit on the total number of texture
1226 image units allowed.