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 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 _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_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 _mesa_delete_program(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_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 * Return size (in floats) of the given GLSL type.
373 * See also _slang_sizeof_type_specifier().
376 sizeof_glsl_type(GLenum type
)
396 return 8; /* 2 rows of 4, actually */
398 return 12; /* 3 rows of 4, actually */
401 case GL_FLOAT_MAT2x3
:
402 return 8; /* 2 rows of 4, actually */
403 case GL_FLOAT_MAT2x4
:
405 case GL_FLOAT_MAT3x2
:
406 return 12; /* 3 rows of 4, actually */
407 case GL_FLOAT_MAT3x4
:
409 case GL_FLOAT_MAT4x2
:
410 return 16; /* 4 rows of 4, actually */
411 case GL_FLOAT_MAT4x3
:
412 return 16; /* 4 rows of 4, actually */
414 return 0; /* error */
420 * Called via ctx->Driver.AttachShader()
423 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
425 struct gl_shader_program
*shProg
426 = _mesa_lookup_shader_program(ctx
, program
);
427 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
431 if (!shProg
|| !sh
) {
432 _mesa_error(ctx
, GL_INVALID_VALUE
,
433 "glAttachShader(bad program or shader name)");
437 n
= shProg
->NumShaders
;
439 for (i
= 0; i
< n
; i
++) {
440 if (shProg
->Shaders
[i
] == sh
) {
441 /* already attached */
447 shProg
->Shaders
= (struct gl_shader
**)
448 _mesa_realloc(shProg
->Shaders
,
449 n
* sizeof(struct gl_shader
*),
450 (n
+ 1) * sizeof(struct gl_shader
*));
451 if (!shProg
->Shaders
) {
452 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
457 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
458 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
459 shProg
->NumShaders
++;
464 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
467 struct gl_shader_program
*shProg
468 = _mesa_lookup_shader_program(ctx
, program
);
469 const GLint size
= -1; /* unknown size */
473 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
480 if (strncmp(name
, "gl_", 3) == 0) {
481 _mesa_error(ctx
, GL_INVALID_OPERATION
,
482 "glBindAttribLocation(illegal name)");
486 if (shProg
->LinkStatus
) {
487 /* get current index/location for the attribute */
488 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
494 /* this will replace the current value if it's already in the list */
495 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
497 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
500 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
501 /* If the index changed, need to search/replace references to that attribute
502 * in the vertex program.
504 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
510 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
512 struct gl_shader
*sh
;
515 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
518 case GL_FRAGMENT_SHADER
:
519 case GL_VERTEX_SHADER
:
520 sh
= _mesa_new_shader(ctx
, name
, type
);
523 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
527 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
534 _mesa_create_program(GLcontext
*ctx
)
537 struct gl_shader_program
*shProg
;
539 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
540 shProg
= _mesa_new_shader_program(ctx
, name
);
542 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
544 assert(shProg
->RefCount
== 1);
551 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
555 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
558 * NOTE: deleting shaders/programs works a bit differently than
559 * texture objects (and buffer objects, etc). Shader/program
560 * handles/IDs exist in the hash table until the object is really
561 * deleted (refcount==0). With texture objects, the handle/ID is
562 * removed from the hash table in glDeleteTextures() while the tex
563 * object itself might linger until its refcount goes to zero.
565 struct gl_shader_program
*shProg
;
567 shProg
= _mesa_lookup_shader_program(ctx
, name
);
569 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
573 shProg
->DeletePending
= GL_TRUE
;
575 /* effectively, decr shProg's refcount */
576 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
581 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
583 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
588 sh
->DeletePending
= GL_TRUE
;
590 /* effectively, decr sh's refcount */
591 _mesa_reference_shader(ctx
, &sh
, NULL
);
596 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
598 struct gl_shader_program
*shProg
599 = _mesa_lookup_shader_program(ctx
, program
);
604 _mesa_error(ctx
, GL_INVALID_VALUE
,
605 "glDetachShader(bad program or shader name)");
609 n
= shProg
->NumShaders
;
611 for (i
= 0; i
< n
; i
++) {
612 if (shProg
->Shaders
[i
]->Name
== shader
) {
614 struct gl_shader
**newList
;
617 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
619 /* alloc new, smaller array */
620 newList
= (struct gl_shader
**)
621 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
623 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
626 for (j
= 0; j
< i
; j
++) {
627 newList
[j
] = shProg
->Shaders
[j
];
630 newList
[j
++] = shProg
->Shaders
[i
];
631 _mesa_free(shProg
->Shaders
);
633 shProg
->Shaders
= newList
;
634 shProg
->NumShaders
= n
- 1;
639 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
640 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
641 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
642 assert(shProg
->Shaders
[j
]->RefCount
> 0);
652 _mesa_error(ctx
, GL_INVALID_VALUE
,
653 "glDetachShader(shader not found)");
658 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
659 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
660 GLenum
*type
, GLchar
*nameOut
)
662 static const GLenum vec_types
[] = {
663 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
665 struct gl_shader_program
*shProg
666 = _mesa_lookup_shader_program(ctx
, program
);
670 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
674 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
675 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
679 copy_string(nameOut
, maxLength
, length
,
680 shProg
->Attributes
->Parameters
[index
].Name
);
681 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
683 *size
= 1; /* attributes may not be arrays */
684 if (type
&& sz
> 0 && sz
<= 4) /* XXX this is a temporary hack */
685 *type
= vec_types
[sz
- 1];
690 * Called via ctx->Driver.GetActiveUniform().
693 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
694 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
695 GLenum
*type
, GLchar
*nameOut
)
697 struct gl_shader_program
*shProg
698 = _mesa_lookup_shader_program(ctx
, program
);
702 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
706 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
707 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
712 for (j
= 0; j
< shProg
->Uniforms
->NumParameters
; j
++) {
713 if (shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_UNIFORM
||
714 shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_SAMPLER
) {
716 GLuint uSize
= shProg
->Uniforms
->Parameters
[j
].Size
;
717 GLenum uType
= shProg
->Uniforms
->Parameters
[j
].DataType
;
719 copy_string(nameOut
, maxLength
, length
,
720 shProg
->Uniforms
->Parameters
[j
].Name
);
722 /* convert from floats to 'type' (eg: sizeof(mat4x4)=1) */
723 *size
= uSize
/ sizeof_glsl_type(uType
);
733 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
738 * Called via ctx->Driver.GetAttachedShaders().
741 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
742 GLsizei
*count
, GLuint
*obj
)
744 struct gl_shader_program
*shProg
745 = _mesa_lookup_shader_program(ctx
, program
);
748 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
749 obj
[i
] = shProg
->Shaders
[i
]->Name
;
755 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
761 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
764 struct gl_shader_program
*shProg
765 = _mesa_lookup_shader_program(ctx
, program
);
768 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
772 if (!shProg
->LinkStatus
) {
773 _mesa_error(ctx
, GL_INVALID_OPERATION
,
774 "glGetAttribLocation(program not linked)");
781 if (shProg
->Attributes
) {
782 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
784 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
792 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
795 GET_CURRENT_CONTEXT(ctx
);
798 case GL_PROGRAM_OBJECT_ARB
:
800 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
803 return (**pro
)._container
._generic
.
804 GetName((struct gl2_generic_intf
**) (pro
));
808 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
816 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
817 GLenum pname
, GLint
*params
)
819 struct gl_shader_program
*shProg
820 = _mesa_lookup_shader_program(ctx
, program
);
823 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
828 case GL_DELETE_STATUS
:
829 *params
= shProg
->DeletePending
;
832 *params
= shProg
->LinkStatus
;
834 case GL_VALIDATE_STATUS
:
835 *params
= shProg
->Validated
;
837 case GL_INFO_LOG_LENGTH
:
838 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
840 case GL_ATTACHED_SHADERS
:
841 *params
= shProg
->NumShaders
;
843 case GL_ACTIVE_ATTRIBUTES
:
844 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
846 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
847 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
850 case GL_ACTIVE_UNIFORMS
:
852 = _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_UNIFORM
)
853 + _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_SAMPLER
);
855 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
857 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_UNIFORM
),
858 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_SAMPLER
));
860 (*params
)++; /* add one for terminating zero */
863 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
870 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
872 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
875 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
881 *params
= shader
->Type
;
883 case GL_DELETE_STATUS
:
884 *params
= shader
->DeletePending
;
886 case GL_COMPILE_STATUS
:
887 *params
= shader
->CompileStatus
;
889 case GL_INFO_LOG_LENGTH
:
890 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
892 case GL_SHADER_SOURCE_LENGTH
:
893 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
896 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
903 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
904 GLsizei
*length
, GLchar
*infoLog
)
906 struct gl_shader_program
*shProg
907 = _mesa_lookup_shader_program(ctx
, program
);
909 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
912 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
917 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
918 GLsizei
*length
, GLchar
*infoLog
)
920 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
922 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
925 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
930 * Called via ctx->Driver.GetShaderSource().
933 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
934 GLsizei
*length
, GLchar
*sourceOut
)
936 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
938 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
941 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
946 * Called via ctx->Driver.GetUniformfv().
949 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
952 struct gl_shader_program
*shProg
953 = _mesa_lookup_shader_program(ctx
, program
);
956 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
960 uType
= shProg
->Uniforms
->Parameters
[location
].DataType
;
961 uSize
= sizeof_glsl_type(uType
);
962 /* Matrix types need special handling, because they span several
963 * parameters, and may also not be fully packed.
965 switch (shProg
->Uniforms
->Parameters
[location
].DataType
) {
967 case GL_FLOAT_MAT3x2
:
968 case GL_FLOAT_MAT4x2
:
971 case GL_FLOAT_MAT2x3
:
973 case GL_FLOAT_MAT4x3
:
976 case GL_FLOAT_MAT2x4
:
977 case GL_FLOAT_MAT3x4
:
983 for (c
= 0, i
= 0; c
* 4 < uSize
; c
++)
984 for (r
= 0; r
< rows
; r
++, i
++)
985 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
+ c
][r
];
988 for (i
= 0; i
< uSize
; i
++) {
989 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
993 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
997 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
1003 * Called via ctx->Driver.GetUniformLocation().
1006 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1008 struct gl_shader_program
*shProg
1009 = _mesa_lookup_shader_program(ctx
, program
);
1012 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
1013 const struct gl_program_parameter
*u
1014 = shProg
->Uniforms
->Parameters
+ loc
;
1015 /* XXX this is a temporary simplification / short-cut.
1016 * We need to handle things like "e.c[0].b" as seen in the
1017 * GLSL orange book, page 189.
1019 if ((u
->Type
== PROGRAM_UNIFORM
||
1020 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
1031 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
1033 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
1034 return shProg
? GL_TRUE
: GL_FALSE
;
1039 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
1041 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
1042 return shader
? GL_TRUE
: GL_FALSE
;
1048 * Called via ctx->Driver.ShaderSource()
1051 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1053 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1055 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
1059 /* free old shader source string and install new one */
1061 _mesa_free((void *) sh
->Source
);
1063 sh
->Source
= source
;
1064 sh
->CompileStatus
= GL_FALSE
;
1069 * Called via ctx->Driver.CompileShader()
1072 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1074 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
1077 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
1081 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1086 * Called via ctx->Driver.LinkProgram()
1089 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1091 struct gl_shader_program
*shProg
;
1093 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1095 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1099 _slang_link(ctx
, program
, shProg
);
1104 * Called via ctx->Driver.UseProgram()
1107 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1109 struct gl_shader_program
*shProg
;
1111 if (ctx
->Shader
.CurrentProgram
&&
1112 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1117 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1120 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1122 _mesa_error(ctx
, GL_INVALID_VALUE
,
1123 "glUseProgramObjectARB(programObj)");
1131 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1136 * Called via ctx->Driver.Uniform().
1139 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1140 const GLvoid
*values
, GLenum type
)
1142 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1147 if (!shProg
|| !shProg
->LinkStatus
) {
1148 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1153 return; /* The standard specifies this as a no-op */
1155 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1156 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1160 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1162 uType
= shProg
->Uniforms
->Parameters
[location
].Type
;
1164 * If we're setting a sampler, we must use glUniformi1()!
1166 if (uType
== PROGRAM_SAMPLER
) {
1168 if (type
!= GL_INT
|| count
!= 1) {
1169 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1170 "glUniform(only glUniform1i can be used "
1171 "to set sampler uniforms)");
1174 /* check that the sampler (tex unit index) is legal */
1175 unit
= ((GLint
*) values
)[0];
1176 if (unit
>= ctx
->Const
.MaxTextureImageUnits
) {
1177 _mesa_error(ctx
, GL_INVALID_VALUE
,
1178 "glUniform1(invalid sampler/tex unit index)");
1184 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1206 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1210 /* OpenGL requires types to match exactly, except that one can convert
1211 * float or int array to boolean array.
1219 if (elems
!= sizeof_glsl_type(shProg
->Uniforms
->Parameters
[location
].DataType
)) {
1220 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count mismatch)");
1223 case PROGRAM_SAMPLER
:
1226 if (uType
!= type
) {
1227 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1232 /* XXX if this is a base type, then count must equal 1. However, we
1233 * don't have enough information from the compiler to distinguish a
1234 * base type from a 1-element array of that type. The standard allows
1235 * count to overrun an array, in which case the overflow is ignored.
1237 maxCount
= shProg
->Uniforms
->Parameters
[location
].Size
/ elems
;
1238 if (count
> maxCount
) count
= maxCount
;
1240 for (k
= 0; k
< count
; k
++) {
1241 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
1242 if (type
== GL_INT
||
1243 type
== GL_INT_VEC2
||
1244 type
== GL_INT_VEC3
||
1245 type
== GL_INT_VEC4
) {
1246 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1247 for (i
= 0; i
< elems
; i
++) {
1248 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1252 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1253 for (i
= 0; i
< elems
; i
++) {
1254 uniformVal
[i
] = fValues
[i
];
1259 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1260 if (shProg
->VertexProgram
)
1261 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
1262 if (shProg
->FragmentProgram
)
1263 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
1264 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1270 * Called by ctx->Driver.UniformMatrix().
1273 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1274 GLenum matrixType
, GLint location
, GLsizei count
,
1275 GLboolean transpose
, const GLfloat
*values
)
1277 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1278 if (!shProg
|| !shProg
->LinkStatus
) {
1279 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1280 "glUniformMatrix(program not linked)");
1283 if (location
< 0 || location
>= shProg
->Uniforms
->NumParameters
) {
1284 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1287 if (values
== NULL
) {
1288 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1292 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1295 * Note: the _columns_ of a matrix are stored in program registers, not
1298 /* XXXX need to test 3x3 and 2x2 matrices... */
1301 for (col
= 0; col
< cols
; col
++) {
1302 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1303 for (row
= 0; row
< rows
; row
++) {
1304 v
[row
] = values
[row
* cols
+ col
];
1310 for (col
= 0; col
< cols
; col
++) {
1311 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1312 for (row
= 0; row
< rows
; row
++) {
1313 v
[row
] = values
[col
* rows
+ row
];
1321 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1323 struct gl_shader_program
*shProg
;
1324 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1326 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1330 shProg
->Validated
= GL_TRUE
;
1332 /* From the GL spec:
1333 any two active samplers in the current program object are of
1334 different types, but refer to the same texture image unit,
1336 any active sampler in the current program object refers to a texture
1337 image unit where fixed-function fragment processing accesses a
1338 texture target that does not match the sampler type, or
1340 the sum of the number of active samplers in the program and the
1341 number of texture image units enabled for fixed-function fragment
1342 processing exceeds the combined limit on the total number of texture
1343 image units allowed.