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/shader_api.h"
47 #include "shader/slang/slang_compile.h"
48 #include "shader/slang/slang_link.h"
53 * Allocate a new gl_shader_program object, initialize it.
55 static 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_MESA
;
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 ctx
->Driver
.DeleteProgram(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 ctx
->Driver
.DeleteProgram(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_MESA
);
119 _mesa_clear_shader_program_data(ctx
, shProg
);
121 if (shProg
->Attributes
) {
122 _mesa_free_parameter_list(shProg
->Attributes
);
123 shProg
->Attributes
= NULL
;
127 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
128 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
130 if (shProg
->Shaders
) {
131 _mesa_free(shProg
->Shaders
);
132 shProg
->Shaders
= NULL
;
138 * Free/delete a shader program object.
141 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
143 _mesa_free_shader_program_data(ctx
, shProg
);
144 if (shProg
->Shaders
) {
145 _mesa_free(shProg
->Shaders
);
146 shProg
->Shaders
= NULL
;
153 * Set ptr to point to shProg.
154 * If ptr is pointing to another object, decrement its refcount (and delete
155 * if refcount hits zero).
156 * Then set ptr to point to shProg, incrementing its refcount.
158 /* XXX this could be static */
160 _mesa_reference_shader_program(GLcontext
*ctx
,
161 struct gl_shader_program
**ptr
,
162 struct gl_shader_program
*shProg
)
165 if (*ptr
== shProg
) {
170 /* Unreference the old shader program */
171 GLboolean deleteFlag
= GL_FALSE
;
172 struct gl_shader_program
*old
= *ptr
;
174 ASSERT(old
->RefCount
> 0);
176 /*printf("SHPROG DECR %p (%d) to %d\n",
177 (void*) old, old->Name, old->RefCount);*/
178 deleteFlag
= (old
->RefCount
== 0);
181 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
182 _mesa_free_shader_program(ctx
, old
);
191 /*printf("SHPROG INCR %p (%d) to %d\n",
192 (void*) shProg, shProg->Name, shProg->RefCount);*/
199 * Lookup a GLSL program object.
201 struct gl_shader_program
*
202 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
204 struct gl_shader_program
*shProg
;
206 shProg
= (struct gl_shader_program
*)
207 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
208 /* Note that both gl_shader and gl_shader_program objects are kept
209 * in the same hash table. Check the object's type to be sure it's
210 * what we're expecting.
212 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
222 * Allocate a new gl_shader object, initialize it.
225 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
227 struct gl_shader
*shader
;
228 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
229 shader
= CALLOC_STRUCT(gl_shader
);
233 shader
->RefCount
= 1;
240 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
244 _mesa_free((void *) sh
->Source
);
246 _mesa_free(sh
->InfoLog
);
247 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
248 assert(sh
->Programs
[i
]);
249 ctx
->Driver
.DeleteProgram(ctx
, sh
->Programs
[i
]);
252 _mesa_free(sh
->Programs
);
258 * Set ptr to point to sh.
259 * If ptr is pointing to another shader, decrement its refcount (and delete
260 * if refcount hits zero).
261 * Then set ptr to point to sh, incrementing its refcount.
263 /* XXX this could be static */
265 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
266 struct gl_shader
*sh
)
274 /* Unreference the old shader */
275 GLboolean deleteFlag
= GL_FALSE
;
276 struct gl_shader
*old
= *ptr
;
278 ASSERT(old
->RefCount
> 0);
280 /*printf("SHADER DECR %p (%d) to %d\n",
281 (void*) old, old->Name, old->RefCount);*/
282 deleteFlag
= (old
->RefCount
== 0);
285 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
286 _mesa_free_shader(ctx
, old
);
296 /*printf("SHADER INCR %p (%d) to %d\n",
297 (void*) sh, sh->Name, sh->RefCount);*/
304 * Lookup a GLSL shader object.
307 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
310 struct gl_shader
*sh
= (struct gl_shader
*)
311 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
312 /* Note that both gl_shader and gl_shader_program objects are kept
313 * in the same hash table. Check the object's type to be sure it's
314 * what we're expecting.
316 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
326 * Initialize context's shader state.
329 _mesa_init_shader_state(GLcontext
* ctx
)
331 /* Device drivers may override these to control what kind of instructions
332 * are generated by the GLSL compiler.
334 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
335 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
336 ctx
->Shader
.EmitComments
= GL_FALSE
;
341 * Free the per-context shader-related state.
344 _mesa_free_shader_state(GLcontext
*ctx
)
346 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
351 * Copy string from <src> to <dst>, up to maxLength characters, returning
352 * length of <dst> in <length>.
353 * \param src the strings source
354 * \param maxLength max chars to copy
355 * \param length returns number of chars copied
356 * \param dst the string destination
359 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
362 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
372 * Called via ctx->Driver.AttachShader()
375 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
377 struct gl_shader_program
*shProg
378 = _mesa_lookup_shader_program(ctx
, program
);
379 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
380 const GLuint n
= shProg
->NumShaders
;
383 if (!shProg
|| !sh
) {
384 _mesa_error(ctx
, GL_INVALID_VALUE
,
385 "glAttachShader(bad program or shader name)");
389 for (i
= 0; i
< n
; i
++) {
390 if (shProg
->Shaders
[i
] == sh
) {
391 /* already attached */
397 shProg
->Shaders
= (struct gl_shader
**)
398 _mesa_realloc(shProg
->Shaders
,
399 n
* sizeof(struct gl_shader
*),
400 (n
+ 1) * sizeof(struct gl_shader
*));
401 if (!shProg
->Shaders
) {
402 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
407 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
408 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
409 shProg
->NumShaders
++;
414 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
417 struct gl_shader_program
*shProg
418 = _mesa_lookup_shader_program(ctx
, program
);
421 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
425 if (!shProg
->LinkStatus
) {
426 _mesa_error(ctx
, GL_INVALID_OPERATION
,
427 "glGetAttribLocation(program not linked)");
434 if (shProg
->Attributes
) {
435 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
437 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
445 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
448 struct gl_shader_program
*shProg
449 = _mesa_lookup_shader_program(ctx
, program
);
450 const GLint size
= -1; /* unknown size */
454 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
461 if (strncmp(name
, "gl_", 3) == 0) {
462 _mesa_error(ctx
, GL_INVALID_OPERATION
,
463 "glBindAttribLocation(illegal name)");
467 if (shProg
->LinkStatus
) {
468 /* get current index/location for the attribute */
469 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
475 /* this will replace the current value if it's already in the list */
476 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
478 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
481 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
482 /* If the index changed, need to search/replace references to that attribute
483 * in the vertex program.
485 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
491 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
493 struct gl_shader
*sh
;
496 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
499 case GL_FRAGMENT_SHADER
:
500 case GL_VERTEX_SHADER
:
501 sh
= _mesa_new_shader(ctx
, name
, type
);
504 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
508 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
515 _mesa_create_program(GLcontext
*ctx
)
518 struct gl_shader_program
*shProg
;
520 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
521 shProg
= _mesa_new_shader_program(ctx
, name
);
523 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
525 assert(shProg
->RefCount
== 1);
532 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
536 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
539 * NOTE: deleting shaders/programs works a bit differently than
540 * texture objects (and buffer objects, etc). Shader/program
541 * handles/IDs exist in the hash table until the object is really
542 * deleted (refcount==0). With texture objects, the handle/ID is
543 * removed from the hash table in glDeleteTextures() while the tex
544 * object itself might linger until its refcount goes to zero.
546 struct gl_shader_program
*shProg
;
548 shProg
= _mesa_lookup_shader_program(ctx
, name
);
550 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
554 shProg
->DeletePending
= GL_TRUE
;
556 /* effectively, decr shProg's refcount */
557 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
562 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
564 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
569 sh
->DeletePending
= GL_TRUE
;
571 /* effectively, decr sh's refcount */
572 _mesa_reference_shader(ctx
, &sh
, NULL
);
577 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
579 struct gl_shader_program
*shProg
580 = _mesa_lookup_shader_program(ctx
, program
);
581 const GLuint n
= shProg
->NumShaders
;
585 _mesa_error(ctx
, GL_INVALID_VALUE
,
586 "glDetachShader(bad program or shader name)");
590 for (i
= 0; i
< n
; i
++) {
591 if (shProg
->Shaders
[i
]->Name
== shader
) {
593 struct gl_shader
**newList
;
596 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
598 /* alloc new, smaller array */
599 newList
= (struct gl_shader
**)
600 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
602 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
605 for (j
= 0; j
< i
; j
++) {
606 newList
[j
] = shProg
->Shaders
[j
];
609 newList
[j
++] = shProg
->Shaders
[i
];
610 _mesa_free(shProg
->Shaders
);
612 shProg
->Shaders
= newList
;
613 shProg
->NumShaders
= n
- 1;
618 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
619 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
620 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
621 assert(shProg
->Shaders
[j
]->RefCount
> 0);
631 _mesa_error(ctx
, GL_INVALID_VALUE
,
632 "glDetachShader(shader not found)");
637 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
638 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
639 GLenum
*type
, GLchar
*nameOut
)
641 static const GLenum vec_types
[] = {
642 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
644 struct gl_shader_program
*shProg
645 = _mesa_lookup_shader_program(ctx
, program
);
649 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
653 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
654 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
658 copy_string(nameOut
, maxLength
, length
,
659 shProg
->Attributes
->Parameters
[index
].Name
);
660 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
664 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
669 * Called via ctx->Driver.GetActiveUniform().
672 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
673 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
674 GLenum
*type
, GLchar
*nameOut
)
676 struct gl_shader_program
*shProg
677 = _mesa_lookup_shader_program(ctx
, program
);
681 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
685 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
686 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
691 for (j
= 0; j
< shProg
->Uniforms
->NumParameters
; j
++) {
692 if (shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_UNIFORM
||
693 shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_SAMPLER
) {
696 copy_string(nameOut
, maxLength
, length
,
697 shProg
->Uniforms
->Parameters
[j
].Name
);
699 *size
= shProg
->Uniforms
->Parameters
[j
].Size
;
701 *type
= shProg
->Uniforms
->Parameters
[j
].DataType
;
708 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
713 * Called via ctx->Driver.GetAttachedShaders().
716 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
717 GLsizei
*count
, GLuint
*obj
)
719 struct gl_shader_program
*shProg
720 = _mesa_lookup_shader_program(ctx
, program
);
723 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
724 obj
[i
] = shProg
->Shaders
[i
]->Name
;
730 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
736 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
739 GET_CURRENT_CONTEXT(ctx
);
742 case GL_PROGRAM_OBJECT_ARB
:
744 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
747 return (**pro
)._container
._generic
.
748 GetName((struct gl2_generic_intf
**) (pro
));
752 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
760 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
761 GLenum pname
, GLint
*params
)
763 struct gl_shader_program
*shProg
764 = _mesa_lookup_shader_program(ctx
, program
);
767 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
772 case GL_DELETE_STATUS
:
773 *params
= shProg
->DeletePending
;
776 *params
= shProg
->LinkStatus
;
778 case GL_VALIDATE_STATUS
:
779 *params
= shProg
->Validated
;
781 case GL_INFO_LOG_LENGTH
:
782 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
784 case GL_ATTACHED_SHADERS
:
785 *params
= shProg
->NumShaders
;
787 case GL_ACTIVE_ATTRIBUTES
:
788 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
790 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
791 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
794 case GL_ACTIVE_UNIFORMS
:
796 = _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_UNIFORM
)
797 + _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_SAMPLER
);
799 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
801 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_UNIFORM
),
802 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_SAMPLER
));
804 (*params
)++; /* add one for terminating zero */
807 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
814 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
816 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
819 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
825 *params
= shader
->Type
;
827 case GL_DELETE_STATUS
:
828 *params
= shader
->DeletePending
;
830 case GL_COMPILE_STATUS
:
831 *params
= shader
->CompileStatus
;
833 case GL_INFO_LOG_LENGTH
:
834 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
836 case GL_SHADER_SOURCE_LENGTH
:
837 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
840 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
847 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
848 GLsizei
*length
, GLchar
*infoLog
)
850 struct gl_shader_program
*shProg
851 = _mesa_lookup_shader_program(ctx
, program
);
853 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
856 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
861 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
862 GLsizei
*length
, GLchar
*infoLog
)
864 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
866 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
869 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
874 * Called via ctx->Driver.GetShaderSource().
877 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
878 GLsizei
*length
, GLchar
*sourceOut
)
880 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
882 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
885 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
890 * Called via ctx->Driver.GetUniformfv().
893 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
896 struct gl_shader_program
*shProg
897 = _mesa_lookup_shader_program(ctx
, program
);
900 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
901 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
902 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
906 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
910 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
916 * Called via ctx->Driver.GetUniformLocation().
919 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
921 struct gl_shader_program
*shProg
922 = _mesa_lookup_shader_program(ctx
, program
);
925 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
926 const struct gl_program_parameter
*u
927 = shProg
->Uniforms
->Parameters
+ loc
;
928 /* XXX this is a temporary simplification / short-cut.
929 * We need to handle things like "e.c[0].b" as seen in the
930 * GLSL orange book, page 189.
932 if ((u
->Type
== PROGRAM_UNIFORM
||
933 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
944 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
946 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
947 return shProg
? GL_TRUE
: GL_FALSE
;
952 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
954 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
955 return shader
? GL_TRUE
: GL_FALSE
;
961 * Called via ctx->Driver.ShaderSource()
964 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
966 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
968 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
972 /* free old shader source string and install new one */
974 _mesa_free((void *) sh
->Source
);
977 sh
->CompileStatus
= GL_FALSE
;
982 * Called via ctx->Driver.CompileShader()
985 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
987 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
990 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
994 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
999 * Called via ctx->Driver.LinkProgram()
1002 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1004 struct gl_shader_program
*shProg
;
1006 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1008 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1012 _slang_link(ctx
, program
, shProg
);
1017 * Called via ctx->Driver.UseProgram()
1020 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1022 struct gl_shader_program
*shProg
;
1024 if (ctx
->Shader
.CurrentProgram
&&
1025 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1030 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1033 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1035 _mesa_error(ctx
, GL_INVALID_VALUE
,
1036 "glUseProgramObjectARB(programObj)");
1044 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1050 * Update the vertex and fragment program's TexturesUsed arrays.
1053 update_textures_used(struct gl_program
*prog
)
1057 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1059 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1060 if (prog
->SamplersUsed
& (1 << s
)) {
1061 GLuint u
= prog
->SamplerUnits
[s
];
1062 GLuint t
= prog
->SamplerTargets
[s
];
1063 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1064 prog
->TexturesUsed
[u
] |= (1 << t
);
1071 * Called via ctx->Driver.Uniform().
1074 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1075 const GLvoid
*values
, GLenum type
)
1077 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1080 if (!shProg
|| !shProg
->LinkStatus
) {
1081 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1085 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1086 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1090 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1093 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1115 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1119 if (count
* elems
> shProg
->Uniforms
->Parameters
[location
].Size
) {
1120 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1124 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1125 /* This controls which texture unit which is used by a sampler */
1126 GLuint texUnit
, sampler
;
1128 /* data type for setting samplers must be int */
1129 if (type
!= GL_INT
|| count
!= 1) {
1130 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1131 "glUniform(only glUniform1i can be used "
1132 "to set sampler uniforms)");
1136 sampler
= (GLuint
) shProg
->Uniforms
->ParameterValues
[location
][0];
1137 texUnit
= ((GLuint
*) values
)[0];
1139 /* check that the sampler (tex unit index) is legal */
1140 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1141 _mesa_error(ctx
, GL_INVALID_VALUE
,
1142 "glUniform1(invalid sampler/tex unit index)");
1146 if (shProg
->VertexProgram
) {
1147 shProg
->VertexProgram
->Base
.SamplerUnits
[sampler
] = texUnit
;
1148 update_textures_used(&shProg
->VertexProgram
->Base
);
1150 if (shProg
->FragmentProgram
) {
1151 shProg
->FragmentProgram
->Base
.SamplerUnits
[sampler
] = texUnit
;
1152 update_textures_used(&shProg
->FragmentProgram
->Base
);
1156 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1159 /* ordinary uniform variable */
1160 for (k
= 0; k
< count
; k
++) {
1161 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
1162 if (type
== GL_INT
||
1163 type
== GL_INT_VEC2
||
1164 type
== GL_INT_VEC3
||
1165 type
== GL_INT_VEC4
) {
1166 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1167 for (i
= 0; i
< elems
; i
++) {
1168 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1172 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1173 for (i
= 0; i
< elems
; i
++) {
1174 uniformVal
[i
] = fValues
[i
];
1183 * Called by ctx->Driver.UniformMatrix().
1186 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1187 GLenum matrixType
, GLint location
, GLsizei count
,
1188 GLboolean transpose
, const GLfloat
*values
)
1190 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1191 if (!shProg
|| !shProg
->LinkStatus
) {
1192 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1193 "glUniformMatrix(program not linked)");
1196 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
1197 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1200 if (values
== NULL
) {
1201 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1205 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1208 * Note: the _columns_ of a matrix are stored in program registers, not
1211 /* XXXX need to test 3x3 and 2x2 matrices... */
1214 for (col
= 0; col
< cols
; col
++) {
1215 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1216 for (row
= 0; row
< rows
; row
++) {
1217 v
[row
] = values
[row
* cols
+ col
];
1223 for (col
= 0; col
< cols
; col
++) {
1224 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1225 for (row
= 0; row
< rows
; row
++) {
1226 v
[row
] = values
[col
* rows
+ row
];
1234 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1236 struct gl_shader_program
*shProg
;
1237 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1239 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1243 shProg
->Validated
= GL_TRUE
;
1245 /* From the GL spec:
1246 any two active samplers in the current program object are of
1247 different types, but refer to the same texture image unit,
1249 any active sampler in the current program object refers to a texture
1250 image unit where fixed-function fragment processing accesses a
1251 texture target that does not match the sampler type, or
1253 the sum of the number of active samplers in the program and the
1254 number of texture image units enabled for fixed-function fragment
1255 processing exceeds the combined limit on the total number of texture
1256 image units allowed.
1262 * Plug in Mesa's GLSL functions into the device driver function table.
1265 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
1267 driver
->AttachShader
= _mesa_attach_shader
;
1268 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
1269 driver
->CompileShader
= _mesa_compile_shader
;
1270 driver
->CreateProgram
= _mesa_create_program
;
1271 driver
->CreateShader
= _mesa_create_shader
;
1272 driver
->DeleteProgram2
= _mesa_delete_program2
;
1273 driver
->DeleteShader
= _mesa_delete_shader
;
1274 driver
->DetachShader
= _mesa_detach_shader
;
1275 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
1276 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
1277 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
1278 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
1279 driver
->GetHandle
= _mesa_get_handle
;
1280 driver
->GetProgramiv
= _mesa_get_programiv
;
1281 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
1282 driver
->GetShaderiv
= _mesa_get_shaderiv
;
1283 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
1284 driver
->GetShaderSource
= _mesa_get_shader_source
;
1285 driver
->GetUniformfv
= _mesa_get_uniformfv
;
1286 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
1287 driver
->IsProgram
= _mesa_is_program
;
1288 driver
->IsShader
= _mesa_is_shader
;
1289 driver
->LinkProgram
= _mesa_link_program
;
1290 driver
->ShaderSource
= _mesa_shader_source
;
1291 driver
->Uniform
= _mesa_uniform
;
1292 driver
->UniformMatrix
= _mesa_uniform_matrix
;
1293 driver
->UseProgram
= _mesa_use_program
;
1294 driver
->ValidateProgram
= _mesa_validate_program
;