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 * Clear (free) the shader program state that gets produced by linking.
74 _mesa_clear_shader_program_data(GLcontext
*ctx
,
75 struct gl_shader_program
*shProg
)
77 if (shProg
->VertexProgram
) {
78 if (shProg
->VertexProgram
->Base
.Parameters
== shProg
->Uniforms
) {
79 /* to prevent a double-free in the next call */
80 shProg
->VertexProgram
->Base
.Parameters
= NULL
;
82 _mesa_delete_program(ctx
, &shProg
->VertexProgram
->Base
);
83 shProg
->VertexProgram
= NULL
;
86 if (shProg
->FragmentProgram
) {
87 if (shProg
->FragmentProgram
->Base
.Parameters
== shProg
->Uniforms
) {
88 /* to prevent a double-free in the next call */
89 shProg
->FragmentProgram
->Base
.Parameters
= NULL
;
91 _mesa_delete_program(ctx
, &shProg
->FragmentProgram
->Base
);
92 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
;
108 * Free all the data that hangs off a shader program object, but not the
112 _mesa_free_shader_program_data(GLcontext
*ctx
,
113 struct gl_shader_program
*shProg
)
117 assert(shProg
->Type
== GL_SHADER_PROGRAM
);
119 _mesa_clear_shader_program_data(ctx
, shProg
);
122 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
123 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
125 if (shProg
->Shaders
) {
126 _mesa_free(shProg
->Shaders
);
127 shProg
->Shaders
= NULL
;
133 * Free/delete a shader program object.
136 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
138 printf("FREE SHADER PROG %d\n", shProg
->Name
);
139 _mesa_free_shader_program_data(ctx
, shProg
);
140 if (shProg
->Shaders
) {
141 _mesa_free(shProg
->Shaders
);
142 shProg
->Shaders
= NULL
;
149 * Set ptr to point to shProg.
150 * If ptr is pointing to another object, decrement its refcount (and delete
151 * if refcount hits zero).
152 * Then set ptr to point to shProg, incrementing its refcount.
154 /* XXX this could be static */
156 _mesa_reference_shader_program(GLcontext
*ctx
,
157 struct gl_shader_program
**ptr
,
158 struct gl_shader_program
*shProg
)
161 if (*ptr
== shProg
) {
166 /* Unreference the old shader program */
167 GLboolean deleteFlag
= GL_FALSE
;
168 struct gl_shader_program
*old
= *ptr
;
170 ASSERT(old
->RefCount
> 0);
172 /*printf("SHPROG DECR %p (%d) to %d\n",
173 (void*) old, old->Name, old->RefCount);*/
174 deleteFlag
= (old
->RefCount
== 0);
177 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
178 _mesa_free_shader_program(ctx
, old
);
187 printf("SHPROG INCR %p (%d) to %d\n",
188 (void*) shProg
, shProg
->Name
, shProg
->RefCount
);
195 * Lookup a GLSL program object.
197 struct gl_shader_program
*
198 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
200 struct gl_shader_program
*shProg
;
202 shProg
= (struct gl_shader_program
*)
203 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
204 /* Note that both gl_shader and gl_shader_program objects are kept
205 * in the same hash table. Check the object's type to be sure it's
206 * what we're expecting.
208 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM
) {
218 * Allocate a new gl_shader object, initialize it.
221 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
223 struct gl_shader
*shader
;
224 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
225 shader
= CALLOC_STRUCT(gl_shader
);
229 shader
->RefCount
= 1;
236 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
239 printf("FREE SHADER %d\n", sh
->Name
);
241 _mesa_free((void *) sh
->Source
);
243 _mesa_free(sh
->InfoLog
);
244 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
245 assert(sh
->Programs
[i
]);
246 _mesa_delete_program(ctx
, sh
->Programs
[i
]);
249 _mesa_free(sh
->Programs
);
255 * Set ptr to point to sh.
256 * If ptr is pointing to another shader, decrement its refcount (and delete
257 * if refcount hits zero).
258 * Then set ptr to point to sh, incrementing its refcount.
260 /* XXX this could be static */
262 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
263 struct gl_shader
*sh
)
271 /* Unreference the old shader */
272 GLboolean deleteFlag
= GL_FALSE
;
273 struct gl_shader
*old
= *ptr
;
275 ASSERT(old
->RefCount
> 0);
277 printf("SHADER DECR %p (%d) to %d\n",
278 (void*) old
, old
->Name
, old
->RefCount
);
279 deleteFlag
= (old
->RefCount
== 0);
282 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
283 _mesa_free_shader(ctx
, old
);
293 printf("SHADER INCR %p (%d) to %d\n",
294 (void*) sh
, sh
->Name
, sh
->RefCount
);
301 * Lookup a GLSL shader object.
304 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
307 struct gl_shader
*sh
= (struct gl_shader
*)
308 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
309 /* Note that both gl_shader and gl_shader_program objects are kept
310 * in the same hash table. Check the object's type to be sure it's
311 * what we're expecting.
313 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM
) {
314 assert(sh
->Type
== GL_VERTEX_SHADER
||
315 sh
->Type
== GL_FRAGMENT_SHADER
);
325 * Initialize context's shader state.
328 _mesa_init_shader_state(GLcontext
* ctx
)
330 /* Device drivers may override these to control what kind of instructions
331 * are generated by the GLSL compiler.
333 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
334 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
335 ctx
->Shader
.EmitComments
= GL_FALSE
;
340 * Free the per-context shader-related state.
343 _mesa_free_shader_state(GLcontext
*ctx
)
345 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
350 * Copy string from <src> to <dst>, up to maxLength characters, returning
351 * length of <dst> in <length>.
352 * \param src the strings source
353 * \param maxLength max chars to copy
354 * \param length returns number of chars copied
355 * \param dst the string destination
358 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
361 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
371 * Called via ctx->Driver.AttachShader()
374 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
376 struct gl_shader_program
*shProg
377 = _mesa_lookup_shader_program(ctx
, program
);
378 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
379 const GLuint n
= shProg
->NumShaders
;
382 if (!shProg
|| !sh
) {
383 _mesa_error(ctx
, GL_INVALID_VALUE
,
384 "glAttachShader(bad program or shader name)");
388 for (i
= 0; i
< n
; i
++) {
389 if (shProg
->Shaders
[i
] == sh
) {
390 /* already attached */
396 shProg
->Shaders
= (struct gl_shader
**)
397 _mesa_realloc(shProg
->Shaders
,
398 n
* sizeof(struct gl_shader
*),
399 (n
+ 1) * sizeof(struct gl_shader
*));
400 if (!shProg
->Shaders
) {
401 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
406 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
407 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
408 shProg
->NumShaders
++;
413 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
416 struct gl_shader_program
*shProg
417 = _mesa_lookup_shader_program(ctx
, program
);
418 const GLint size
= -1; /* unknown size */
422 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
429 if (strncmp(name
, "gl_", 3) == 0) {
430 _mesa_error(ctx
, GL_INVALID_OPERATION
,
431 "glBindAttribLocation(illegal name)");
435 if (shProg
->LinkStatus
) {
436 /* get current index/location for the attribute */
437 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
443 /* this will replace the current value if it's already in the list */
444 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
446 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
449 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
450 /* If the index changed, need to search/replace references to that attribute
451 * in the vertex program.
453 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
459 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
461 struct gl_shader
*sh
;
464 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
467 case GL_FRAGMENT_SHADER
:
468 case GL_VERTEX_SHADER
:
469 sh
= _mesa_new_shader(ctx
, name
, type
);
472 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
476 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
483 _mesa_create_program(GLcontext
*ctx
)
486 struct gl_shader_program
*shProg
;
488 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
489 shProg
= _mesa_new_shader_program(ctx
, name
);
491 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
493 assert(shProg
->RefCount
== 1);
500 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
504 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
507 * NOTE: deleting shaders/programs works a bit differently than
508 * texture objects (and buffer objects, etc). Shader/program
509 * handles/IDs exist in the hash table until the object is really
510 * deleted (refcount==0). With texture objects, the handle/ID is
511 * removed from the hash table in glDeleteTextures() while the tex
512 * object itself might linger until its refcount goes to zero.
514 struct gl_shader_program
*shProg
;
516 shProg
= _mesa_lookup_shader_program(ctx
, name
);
518 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
522 shProg
->DeletePending
= GL_TRUE
;
524 /* effectively, decr shProg's refcount */
525 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
530 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
532 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
537 sh
->DeletePending
= GL_TRUE
;
539 /* effectively, decr sh's refcount */
540 _mesa_reference_shader(ctx
, &sh
, NULL
);
545 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
547 struct gl_shader_program
*shProg
548 = _mesa_lookup_shader_program(ctx
, program
);
549 const GLuint n
= shProg
->NumShaders
;
553 _mesa_error(ctx
, GL_INVALID_VALUE
,
554 "glDetachShader(bad program or shader name)");
558 for (i
= 0; i
< n
; i
++) {
559 if (shProg
->Shaders
[i
]->Name
== shader
) {
561 struct gl_shader
**newList
;
564 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
566 /* alloc new, smaller array */
567 newList
= (struct gl_shader
**)
568 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
570 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
573 for (j
= 0; j
< i
; j
++) {
574 newList
[j
] = shProg
->Shaders
[j
];
577 newList
[j
++] = shProg
->Shaders
[i
];
578 _mesa_free(shProg
->Shaders
);
580 shProg
->Shaders
= newList
;
586 _mesa_error(ctx
, GL_INVALID_VALUE
,
587 "glDetachShader(shader not found)");
592 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
593 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
594 GLenum
*type
, GLchar
*nameOut
)
596 static const GLenum vec_types
[] = {
597 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
599 struct gl_shader_program
*shProg
600 = _mesa_lookup_shader_program(ctx
, program
);
604 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
608 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
609 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
613 copy_string(nameOut
, maxLength
, length
,
614 shProg
->Attributes
->Parameters
[index
].Name
);
615 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
619 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
624 * Called via ctx->Driver.GetActiveUniform().
627 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
628 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
629 GLenum
*type
, GLchar
*nameOut
)
631 static const GLenum vec_types
[] = {
632 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
634 struct gl_shader_program
*shProg
635 = _mesa_lookup_shader_program(ctx
, program
);
639 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
643 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
644 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
648 copy_string(nameOut
, maxLength
, length
,
649 shProg
->Uniforms
->Parameters
[index
].Name
);
650 sz
= shProg
->Uniforms
->Parameters
[index
].Size
;
654 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
659 * Called via ctx->Driver.GetAttachedShaders().
662 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
663 GLsizei
*count
, GLuint
*obj
)
665 struct gl_shader_program
*shProg
666 = _mesa_lookup_shader_program(ctx
, program
);
669 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
670 obj
[i
] = shProg
->Shaders
[i
]->Name
;
676 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
682 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
685 struct gl_shader_program
*shProg
686 = _mesa_lookup_shader_program(ctx
, program
);
689 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
693 if (!shProg
->LinkStatus
) {
694 _mesa_error(ctx
, GL_INVALID_OPERATION
,
695 "glGetAttribLocation(program not linked)");
702 if (shProg
->Attributes
) {
703 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
705 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
713 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
716 GET_CURRENT_CONTEXT(ctx
);
719 case GL_PROGRAM_OBJECT_ARB
:
721 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
724 return (**pro
)._container
._generic
.
725 GetName((struct gl2_generic_intf
**) (pro
));
729 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
737 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
738 GLenum pname
, GLint
*params
)
740 struct gl_shader_program
*shProg
741 = _mesa_lookup_shader_program(ctx
, program
);
744 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
749 case GL_DELETE_STATUS
:
750 *params
= shProg
->DeletePending
;
753 *params
= shProg
->LinkStatus
;
755 case GL_VALIDATE_STATUS
:
756 *params
= shProg
->Validated
;
758 case GL_INFO_LOG_LENGTH
:
759 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) : 0;
761 case GL_ATTACHED_SHADERS
:
762 *params
= shProg
->NumShaders
;
764 case GL_ACTIVE_ATTRIBUTES
:
765 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
767 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
768 *params
= _mesa_parameter_longest_name(shProg
->Attributes
);
770 case GL_ACTIVE_UNIFORMS
:
771 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumParameters
: 0;
773 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
774 *params
= _mesa_parameter_longest_name(shProg
->Uniforms
);
777 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
784 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
786 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
789 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
795 *params
= shader
->Type
;
797 case GL_DELETE_STATUS
:
798 *params
= shader
->DeletePending
;
800 case GL_COMPILE_STATUS
:
801 *params
= shader
->CompileStatus
;
803 case GL_INFO_LOG_LENGTH
:
804 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) : 0;
806 case GL_SHADER_SOURCE_LENGTH
:
807 *params
= shader
->Source
? strlen((char *) shader
->Source
) : 0;
810 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
817 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
818 GLsizei
*length
, GLchar
*infoLog
)
820 struct gl_shader_program
*shProg
821 = _mesa_lookup_shader_program(ctx
, program
);
823 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
826 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
831 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
832 GLsizei
*length
, GLchar
*infoLog
)
834 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
836 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
839 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
844 * Called via ctx->Driver.GetShaderSource().
847 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
848 GLsizei
*length
, GLchar
*sourceOut
)
850 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
852 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
855 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
860 * Called via ctx->Driver.GetUniformfv().
863 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
866 struct gl_shader_program
*shProg
867 = _mesa_lookup_shader_program(ctx
, program
);
870 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
871 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
872 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
876 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
880 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
886 * Called via ctx->Driver.GetUniformLocation().
889 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
891 struct gl_shader_program
*shProg
892 = _mesa_lookup_shader_program(ctx
, program
);
895 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
896 const struct gl_program_parameter
*u
897 = shProg
->Uniforms
->Parameters
+ loc
;
898 /* XXX this is a temporary simplification / short-cut.
899 * We need to handle things like "e.c[0].b" as seen in the
900 * GLSL orange book, page 189.
902 if ((u
->Type
== PROGRAM_UNIFORM
||
903 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
914 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
916 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
917 return shProg
? GL_TRUE
: GL_FALSE
;
922 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
924 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
925 return shader
? GL_TRUE
: GL_FALSE
;
931 * Called via ctx->Driver.ShaderSource()
934 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
936 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
938 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
942 /* free old shader source string and install new one */
944 _mesa_free((void *) sh
->Source
);
947 sh
->CompileStatus
= GL_FALSE
;
952 * Called via ctx->Driver.CompileShader()
955 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
957 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
960 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
964 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
969 * Called via ctx->Driver.LinkProgram()
972 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
974 struct gl_shader_program
*shProg
;
976 shProg
= _mesa_lookup_shader_program(ctx
, program
);
978 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
982 _slang_link(ctx
, program
, shProg
);
987 * Called via ctx->Driver.UseProgram()
990 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
992 struct gl_shader_program
*shProg
;
994 if (ctx
->Shader
.CurrentProgram
&&
995 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1000 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1003 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1005 _mesa_error(ctx
, GL_INVALID_VALUE
,
1006 "glUseProgramObjectARB(programObj)");
1014 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1019 * Called via ctx->Driver.Uniform().
1022 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1023 const GLvoid
*values
, GLenum type
)
1025 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1028 if (!shProg
|| !shProg
->LinkStatus
) {
1029 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1033 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1034 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1038 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1041 * If we're setting a sampler, we must use glUniformi1()!
1043 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1044 if (type
!= GL_INT
|| count
!= 1) {
1045 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1046 "glUniform(only glUniform1i can be used "
1047 "to set sampler uniforms)");
1053 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1075 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1079 if (count
* elems
> shProg
->Uniforms
->Parameters
[location
].Size
) {
1080 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1084 for (k
= 0; k
< count
; k
++) {
1085 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
1086 if (type
== GL_INT
||
1087 type
== GL_INT_VEC2
||
1088 type
== GL_INT_VEC3
||
1089 type
== GL_INT_VEC4
) {
1090 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1091 for (i
= 0; i
< elems
; i
++) {
1092 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1096 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1097 for (i
= 0; i
< elems
; i
++) {
1098 uniformVal
[i
] = fValues
[i
];
1103 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1104 if (shProg
->VertexProgram
)
1105 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
1106 if (shProg
->FragmentProgram
)
1107 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
1108 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1114 * Called by ctx->Driver.UniformMatrix().
1117 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1118 GLenum matrixType
, GLint location
, GLsizei count
,
1119 GLboolean transpose
, const GLfloat
*values
)
1121 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1122 if (!shProg
|| !shProg
->LinkStatus
) {
1123 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1124 "glUniformMatrix(program not linked)");
1127 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
1128 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1131 if (values
== NULL
) {
1132 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1136 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1139 * Note: the _columns_ of a matrix are stored in program registers, not
1142 /* XXXX need to test 3x3 and 2x2 matrices... */
1145 for (col
= 0; col
< cols
; col
++) {
1146 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1147 for (row
= 0; row
< rows
; row
++) {
1148 v
[row
] = values
[row
* cols
+ col
];
1154 for (col
= 0; col
< cols
; col
++) {
1155 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1156 for (row
= 0; row
< rows
; row
++) {
1157 v
[row
] = values
[col
* rows
+ row
];
1165 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1167 struct gl_shader_program
*shProg
;
1168 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1170 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1174 shProg
->Validated
= GL_TRUE
;
1176 /* From the GL spec:
1177 any two active samplers in the current program object are of
1178 different types, but refer to the same texture image unit,
1180 any active sampler in the current program object refers to a texture
1181 image unit where fixed-function fragment processing accesses a
1182 texture target that does not match the sampler type, or
1184 the sum of the number of active samplers in the program and the
1185 number of texture image units enabled for fixed-function fragment
1186 processing exceeds the combined limit on the total number of texture
1187 image units allowed.