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 _mesa_free_shader_program_data(ctx
, shProg
);
139 if (shProg
->Shaders
) {
140 _mesa_free(shProg
->Shaders
);
141 shProg
->Shaders
= NULL
;
148 * Set ptr to point to shProg.
149 * If ptr is pointing to another object, decrement its refcount (and delete
150 * if refcount hits zero).
151 * Then set ptr to point to shProg, incrementing its refcount.
153 /* XXX this could be static */
155 _mesa_reference_shader_program(GLcontext
*ctx
,
156 struct gl_shader_program
**ptr
,
157 struct gl_shader_program
*shProg
)
160 if (*ptr
== shProg
) {
165 /* Unreference the old shader program */
166 GLboolean deleteFlag
= GL_FALSE
;
167 struct gl_shader_program
*old
= *ptr
;
169 ASSERT(old
->RefCount
> 0);
171 /*printf("SHPROG DECR %p (%d) to %d\n",
172 (void*) old, old->Name, old->RefCount);*/
173 deleteFlag
= (old
->RefCount
== 0);
176 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
177 _mesa_free_shader_program(ctx
, old
);
186 /*printf("SHPROG INCR %p (%d) to %d\n",
187 (void*) shProg, shProg->Name, shProg->RefCount);*/
194 * Lookup a GLSL program object.
196 struct gl_shader_program
*
197 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
199 struct gl_shader_program
*shProg
;
201 shProg
= (struct gl_shader_program
*)
202 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
203 /* Note that both gl_shader and gl_shader_program objects are kept
204 * in the same hash table. Check the object's type to be sure it's
205 * what we're expecting.
207 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM
) {
217 * Allocate a new gl_shader object, initialize it.
220 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
222 struct gl_shader
*shader
;
223 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
224 shader
= CALLOC_STRUCT(gl_shader
);
228 shader
->RefCount
= 1;
235 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
239 _mesa_free((void *) sh
->Source
);
241 _mesa_free(sh
->InfoLog
);
242 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
243 assert(sh
->Programs
[i
]);
244 _mesa_delete_program(ctx
, sh
->Programs
[i
]);
247 _mesa_free(sh
->Programs
);
253 * Set ptr to point to sh.
254 * If ptr is pointing to another shader, decrement its refcount (and delete
255 * if refcount hits zero).
256 * Then set ptr to point to sh, incrementing its refcount.
258 /* XXX this could be static */
260 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
261 struct gl_shader
*sh
)
269 /* Unreference the old shader */
270 GLboolean deleteFlag
= GL_FALSE
;
271 struct gl_shader
*old
= *ptr
;
273 ASSERT(old
->RefCount
> 0);
275 /*printf("SHADER DECR %p (%d) to %d\n",
276 (void*) old, old->Name, old->RefCount);*/
277 deleteFlag
= (old
->RefCount
== 0);
280 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
281 _mesa_free_shader(ctx
, old
);
291 /*printf("SHADER INCR %p (%d) to %d\n",
292 (void*) sh, sh->Name, sh->RefCount);*/
299 * Lookup a GLSL shader object.
302 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
305 struct gl_shader
*sh
= (struct gl_shader
*)
306 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
307 /* Note that both gl_shader and gl_shader_program objects are kept
308 * in the same hash table. Check the object's type to be sure it's
309 * what we're expecting.
311 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM
) {
312 assert(sh
->Type
== GL_VERTEX_SHADER
||
313 sh
->Type
== GL_FRAGMENT_SHADER
);
323 * Initialize context's shader state.
326 _mesa_init_shader_state(GLcontext
* ctx
)
328 /* Device drivers may override these to control what kind of instructions
329 * are generated by the GLSL compiler.
331 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
332 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
333 ctx
->Shader
.EmitComments
= GL_FALSE
;
338 * Free the per-context shader-related state.
341 _mesa_free_shader_state(GLcontext
*ctx
)
343 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
348 * Copy string from <src> to <dst>, up to maxLength characters, returning
349 * length of <dst> in <length>.
350 * \param src the strings source
351 * \param maxLength max chars to copy
352 * \param length returns number of chars copied
353 * \param dst the string destination
356 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
359 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
369 * Called via ctx->Driver.AttachShader()
372 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
374 struct gl_shader_program
*shProg
375 = _mesa_lookup_shader_program(ctx
, program
);
376 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
377 const GLuint n
= shProg
->NumShaders
;
380 if (!shProg
|| !sh
) {
381 _mesa_error(ctx
, GL_INVALID_VALUE
,
382 "glAttachShader(bad program or shader name)");
386 for (i
= 0; i
< n
; i
++) {
387 if (shProg
->Shaders
[i
] == sh
) {
388 /* already attached */
394 shProg
->Shaders
= (struct gl_shader
**)
395 _mesa_realloc(shProg
->Shaders
,
396 n
* sizeof(struct gl_shader
*),
397 (n
+ 1) * sizeof(struct gl_shader
*));
398 if (!shProg
->Shaders
) {
399 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
404 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
405 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
406 shProg
->NumShaders
++;
411 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
414 struct gl_shader_program
*shProg
415 = _mesa_lookup_shader_program(ctx
, program
);
416 const GLint size
= -1; /* unknown size */
420 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
427 if (strncmp(name
, "gl_", 3) == 0) {
428 _mesa_error(ctx
, GL_INVALID_OPERATION
,
429 "glBindAttribLocation(illegal name)");
433 if (shProg
->LinkStatus
) {
434 /* get current index/location for the attribute */
435 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
441 /* this will replace the current value if it's already in the list */
442 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
444 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
447 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
448 /* If the index changed, need to search/replace references to that attribute
449 * in the vertex program.
451 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
457 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
459 struct gl_shader
*sh
;
462 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
465 case GL_FRAGMENT_SHADER
:
466 case GL_VERTEX_SHADER
:
467 sh
= _mesa_new_shader(ctx
, name
, type
);
470 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
474 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
481 _mesa_create_program(GLcontext
*ctx
)
484 struct gl_shader_program
*shProg
;
486 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
487 shProg
= _mesa_new_shader_program(ctx
, name
);
489 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
491 assert(shProg
->RefCount
== 1);
498 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
502 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
505 * NOTE: deleting shaders/programs works a bit differently than
506 * texture objects (and buffer objects, etc). Shader/program
507 * handles/IDs exist in the hash table until the object is really
508 * deleted (refcount==0). With texture objects, the handle/ID is
509 * removed from the hash table in glDeleteTextures() while the tex
510 * object itself might linger until its refcount goes to zero.
512 struct gl_shader_program
*shProg
;
514 shProg
= _mesa_lookup_shader_program(ctx
, name
);
516 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
520 shProg
->DeletePending
= GL_TRUE
;
522 /* effectively, decr shProg's refcount */
523 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
528 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
530 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
535 sh
->DeletePending
= GL_TRUE
;
537 /* effectively, decr sh's refcount */
538 _mesa_reference_shader(ctx
, &sh
, NULL
);
543 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
545 struct gl_shader_program
*shProg
546 = _mesa_lookup_shader_program(ctx
, program
);
547 const GLuint n
= shProg
->NumShaders
;
551 _mesa_error(ctx
, GL_INVALID_VALUE
,
552 "glDetachShader(bad program or shader name)");
556 for (i
= 0; i
< n
; i
++) {
557 if (shProg
->Shaders
[i
]->Name
== shader
) {
559 struct gl_shader
**newList
;
562 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
564 /* alloc new, smaller array */
565 newList
= (struct gl_shader
**)
566 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
568 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
571 for (j
= 0; j
< i
; j
++) {
572 newList
[j
] = shProg
->Shaders
[j
];
575 newList
[j
++] = shProg
->Shaders
[i
];
576 _mesa_free(shProg
->Shaders
);
578 shProg
->Shaders
= newList
;
584 _mesa_error(ctx
, GL_INVALID_VALUE
,
585 "glDetachShader(shader not found)");
590 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
591 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
592 GLenum
*type
, GLchar
*nameOut
)
594 static const GLenum vec_types
[] = {
595 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
597 struct gl_shader_program
*shProg
598 = _mesa_lookup_shader_program(ctx
, program
);
602 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
606 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
607 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
611 copy_string(nameOut
, maxLength
, length
,
612 shProg
->Attributes
->Parameters
[index
].Name
);
613 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
617 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
622 * Called via ctx->Driver.GetActiveUniform().
625 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
626 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
627 GLenum
*type
, GLchar
*nameOut
)
629 static const GLenum vec_types
[] = {
630 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
632 struct gl_shader_program
*shProg
633 = _mesa_lookup_shader_program(ctx
, program
);
637 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
641 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
642 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
646 copy_string(nameOut
, maxLength
, length
,
647 shProg
->Uniforms
->Parameters
[index
].Name
);
648 sz
= shProg
->Uniforms
->Parameters
[index
].Size
;
652 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
657 * Called via ctx->Driver.GetAttachedShaders().
660 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
661 GLsizei
*count
, GLuint
*obj
)
663 struct gl_shader_program
*shProg
664 = _mesa_lookup_shader_program(ctx
, program
);
667 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
668 obj
[i
] = shProg
->Shaders
[i
]->Name
;
674 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
680 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
683 struct gl_shader_program
*shProg
684 = _mesa_lookup_shader_program(ctx
, program
);
687 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
691 if (!shProg
->LinkStatus
) {
692 _mesa_error(ctx
, GL_INVALID_OPERATION
,
693 "glGetAttribLocation(program not linked)");
700 if (shProg
->Attributes
) {
701 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
703 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
711 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
714 GET_CURRENT_CONTEXT(ctx
);
717 case GL_PROGRAM_OBJECT_ARB
:
719 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
722 return (**pro
)._container
._generic
.
723 GetName((struct gl2_generic_intf
**) (pro
));
727 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
735 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
736 GLenum pname
, GLint
*params
)
738 struct gl_shader_program
*shProg
739 = _mesa_lookup_shader_program(ctx
, program
);
742 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
747 case GL_DELETE_STATUS
:
748 *params
= shProg
->DeletePending
;
751 *params
= shProg
->LinkStatus
;
753 case GL_VALIDATE_STATUS
:
754 *params
= shProg
->Validated
;
756 case GL_INFO_LOG_LENGTH
:
757 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) : 0;
759 case GL_ATTACHED_SHADERS
:
760 *params
= shProg
->NumShaders
;
762 case GL_ACTIVE_ATTRIBUTES
:
763 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
765 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
766 *params
= _mesa_parameter_longest_name(shProg
->Attributes
);
768 case GL_ACTIVE_UNIFORMS
:
769 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumParameters
: 0;
771 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
772 *params
= _mesa_parameter_longest_name(shProg
->Uniforms
);
775 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
782 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
784 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
787 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
793 *params
= shader
->Type
;
795 case GL_DELETE_STATUS
:
796 *params
= shader
->DeletePending
;
798 case GL_COMPILE_STATUS
:
799 *params
= shader
->CompileStatus
;
801 case GL_INFO_LOG_LENGTH
:
802 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) : 0;
804 case GL_SHADER_SOURCE_LENGTH
:
805 *params
= shader
->Source
? strlen((char *) shader
->Source
) : 0;
808 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
815 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
816 GLsizei
*length
, GLchar
*infoLog
)
818 struct gl_shader_program
*shProg
819 = _mesa_lookup_shader_program(ctx
, program
);
821 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
824 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
829 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
830 GLsizei
*length
, GLchar
*infoLog
)
832 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
834 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
837 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
842 * Called via ctx->Driver.GetShaderSource().
845 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
846 GLsizei
*length
, GLchar
*sourceOut
)
848 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
850 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
853 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
858 * Called via ctx->Driver.GetUniformfv().
861 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
864 struct gl_shader_program
*shProg
865 = _mesa_lookup_shader_program(ctx
, program
);
868 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
869 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
870 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
874 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
878 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
884 * Called via ctx->Driver.GetUniformLocation().
887 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
889 struct gl_shader_program
*shProg
890 = _mesa_lookup_shader_program(ctx
, program
);
893 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
894 const struct gl_program_parameter
*u
895 = shProg
->Uniforms
->Parameters
+ loc
;
896 /* XXX this is a temporary simplification / short-cut.
897 * We need to handle things like "e.c[0].b" as seen in the
898 * GLSL orange book, page 189.
900 if ((u
->Type
== PROGRAM_UNIFORM
||
901 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
912 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
914 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
915 return shProg
? GL_TRUE
: GL_FALSE
;
920 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
922 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
923 return shader
? GL_TRUE
: GL_FALSE
;
929 * Called via ctx->Driver.ShaderSource()
932 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
934 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
936 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
940 /* free old shader source string and install new one */
942 _mesa_free((void *) sh
->Source
);
945 sh
->CompileStatus
= GL_FALSE
;
950 * Called via ctx->Driver.CompileShader()
953 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
955 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
958 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
962 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
967 * Called via ctx->Driver.LinkProgram()
970 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
972 struct gl_shader_program
*shProg
;
974 shProg
= _mesa_lookup_shader_program(ctx
, program
);
976 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
980 _slang_link(ctx
, program
, shProg
);
985 * Called via ctx->Driver.UseProgram()
988 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
990 struct gl_shader_program
*shProg
;
992 if (ctx
->Shader
.CurrentProgram
&&
993 ctx
->Shader
.CurrentProgram
->Name
== program
) {
998 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1001 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1003 _mesa_error(ctx
, GL_INVALID_VALUE
,
1004 "glUseProgramObjectARB(programObj)");
1012 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1017 * Called via ctx->Driver.Uniform().
1020 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1021 const GLvoid
*values
, GLenum type
)
1023 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1026 if (!shProg
|| !shProg
->LinkStatus
) {
1027 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1031 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1032 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1036 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1039 * If we're setting a sampler, we must use glUniformi1()!
1041 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1042 if (type
!= GL_INT
|| count
!= 1) {
1043 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1044 "glUniform(only glUniform1i can be used "
1045 "to set sampler uniforms)");
1051 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1073 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1077 if (count
* elems
> shProg
->Uniforms
->Parameters
[location
].Size
) {
1078 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1082 for (k
= 0; k
< count
; k
++) {
1083 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
1084 if (type
== GL_INT
||
1085 type
== GL_INT_VEC2
||
1086 type
== GL_INT_VEC3
||
1087 type
== GL_INT_VEC4
) {
1088 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1089 for (i
= 0; i
< elems
; i
++) {
1090 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1094 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1095 for (i
= 0; i
< elems
; i
++) {
1096 uniformVal
[i
] = fValues
[i
];
1101 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1102 if (shProg
->VertexProgram
)
1103 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
1104 if (shProg
->FragmentProgram
)
1105 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
1106 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1112 * Called by ctx->Driver.UniformMatrix().
1115 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1116 GLenum matrixType
, GLint location
, GLsizei count
,
1117 GLboolean transpose
, const GLfloat
*values
)
1119 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1120 if (!shProg
|| !shProg
->LinkStatus
) {
1121 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1122 "glUniformMatrix(program not linked)");
1125 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
1126 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1129 if (values
== NULL
) {
1130 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1134 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1137 * Note: the _columns_ of a matrix are stored in program registers, not
1140 /* XXXX need to test 3x3 and 2x2 matrices... */
1143 for (col
= 0; col
< cols
; col
++) {
1144 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1145 for (row
= 0; row
< rows
; row
++) {
1146 v
[row
] = values
[row
* cols
+ col
];
1152 for (col
= 0; col
< cols
; col
++) {
1153 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1154 for (row
= 0; row
< rows
; row
++) {
1155 v
[row
] = values
[col
* rows
+ row
];
1163 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1165 struct gl_shader_program
*shProg
;
1166 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1168 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1172 shProg
->Validated
= GL_TRUE
;
1174 /* From the GL spec:
1175 any two active samplers in the current program object are of
1176 different types, but refer to the same texture image unit,
1178 any active sampler in the current program object refers to a texture
1179 image unit where fixed-function fragment processing accesses a
1180 texture target that does not match the sampler type, or
1182 the sum of the number of active samplers in the program and the
1183 number of texture image units enabled for fixed-function fragment
1184 processing exceeds the combined limit on the total number of texture
1185 image units allowed.