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 "prog_uniform.h"
47 #include "shader/shader_api.h"
48 #include "shader/slang/slang_compile.h"
49 #include "shader/slang/slang_link.h"
54 * Allocate a new gl_shader_program object, initialize it.
56 static struct gl_shader_program
*
57 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
59 struct gl_shader_program
*shProg
;
60 shProg
= CALLOC_STRUCT(gl_shader_program
);
62 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
65 shProg
->Attributes
= _mesa_new_parameter_list();
72 * Clear (free) the shader program state that gets produced by linking.
75 _mesa_clear_shader_program_data(GLcontext
*ctx
,
76 struct gl_shader_program
*shProg
)
78 if (shProg
->VertexProgram
) {
79 /* Set ptr to NULL since the param list is shared with the
80 * original/unlinked program.
82 shProg
->VertexProgram
->Base
.Parameters
= NULL
;
83 _mesa_reference_vertprog(ctx
, &shProg
->VertexProgram
, NULL
);
86 if (shProg
->FragmentProgram
) {
87 /* Set ptr to NULL since the param list is shared with the
88 * original/unlinked program.
90 shProg
->FragmentProgram
->Base
.Parameters
= NULL
;
91 _mesa_reference_fragprog(ctx
, &shProg
->FragmentProgram
, NULL
);
94 if (shProg
->Uniforms
) {
95 _mesa_free_uniform_list(shProg
->Uniforms
);
96 shProg
->Uniforms
= NULL
;
99 if (shProg
->Varying
) {
100 _mesa_free_parameter_list(shProg
->Varying
);
101 shProg
->Varying
= NULL
;
107 * Free all the data that hangs off a shader program object, but not the
111 _mesa_free_shader_program_data(GLcontext
*ctx
,
112 struct gl_shader_program
*shProg
)
116 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
118 _mesa_clear_shader_program_data(ctx
, shProg
);
120 if (shProg
->Attributes
) {
121 _mesa_free_parameter_list(shProg
->Attributes
);
122 shProg
->Attributes
= NULL
;
126 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
127 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
129 if (shProg
->Shaders
) {
130 _mesa_free(shProg
->Shaders
);
131 shProg
->Shaders
= NULL
;
137 * Free/delete a shader program object.
140 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
142 _mesa_free_shader_program_data(ctx
, shProg
);
143 if (shProg
->Shaders
) {
144 _mesa_free(shProg
->Shaders
);
145 shProg
->Shaders
= NULL
;
152 * Set ptr to point to shProg.
153 * If ptr is pointing to another object, decrement its refcount (and delete
154 * if refcount hits zero).
155 * Then set ptr to point to shProg, incrementing its refcount.
157 /* XXX this could be static */
159 _mesa_reference_shader_program(GLcontext
*ctx
,
160 struct gl_shader_program
**ptr
,
161 struct gl_shader_program
*shProg
)
164 if (*ptr
== shProg
) {
169 /* Unreference the old shader program */
170 GLboolean deleteFlag
= GL_FALSE
;
171 struct gl_shader_program
*old
= *ptr
;
173 ASSERT(old
->RefCount
> 0);
175 /*printf("SHPROG DECR %p (%d) to %d\n",
176 (void*) old, old->Name, old->RefCount);*/
177 deleteFlag
= (old
->RefCount
== 0);
180 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
181 _mesa_free_shader_program(ctx
, old
);
190 /*printf("SHPROG INCR %p (%d) to %d\n",
191 (void*) shProg, shProg->Name, shProg->RefCount);*/
198 * Lookup a GLSL program object.
200 struct gl_shader_program
*
201 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
203 struct gl_shader_program
*shProg
;
205 shProg
= (struct gl_shader_program
*)
206 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
207 /* Note that both gl_shader and gl_shader_program objects are kept
208 * in the same hash table. Check the object's type to be sure it's
209 * what we're expecting.
211 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
221 * Allocate a new gl_shader object, initialize it.
224 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
226 struct gl_shader
*shader
;
227 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
228 shader
= CALLOC_STRUCT(gl_shader
);
232 shader
->RefCount
= 1;
239 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
243 _mesa_free((void *) sh
->Source
);
245 _mesa_free(sh
->InfoLog
);
246 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
247 assert(sh
->Programs
[i
]);
248 ctx
->Driver
.DeleteProgram(ctx
, sh
->Programs
[i
]);
251 _mesa_free(sh
->Programs
);
257 * Set ptr to point to sh.
258 * If ptr is pointing to another shader, decrement its refcount (and delete
259 * if refcount hits zero).
260 * Then set ptr to point to sh, incrementing its refcount.
262 /* XXX this could be static */
264 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
265 struct gl_shader
*sh
)
273 /* Unreference the old shader */
274 GLboolean deleteFlag
= GL_FALSE
;
275 struct gl_shader
*old
= *ptr
;
277 ASSERT(old
->RefCount
> 0);
279 /*printf("SHADER DECR %p (%d) to %d\n",
280 (void*) old, old->Name, old->RefCount);*/
281 deleteFlag
= (old
->RefCount
== 0);
284 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
285 _mesa_free_shader(ctx
, old
);
295 /*printf("SHADER INCR %p (%d) to %d\n",
296 (void*) sh, sh->Name, sh->RefCount);*/
303 * Lookup a GLSL shader object.
306 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
309 struct gl_shader
*sh
= (struct gl_shader
*)
310 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
311 /* Note that both gl_shader and gl_shader_program objects are kept
312 * in the same hash table. Check the object's type to be sure it's
313 * what we're expecting.
315 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
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_FALSE
;/*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_get_attrib_location(GLcontext
*ctx
, GLuint program
,
416 struct gl_shader_program
*shProg
417 = _mesa_lookup_shader_program(ctx
, program
);
420 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
424 if (!shProg
->LinkStatus
) {
425 _mesa_error(ctx
, GL_INVALID_OPERATION
,
426 "glGetAttribLocation(program not linked)");
433 if (shProg
->Attributes
) {
434 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
436 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
444 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
447 struct gl_shader_program
*shProg
448 = _mesa_lookup_shader_program(ctx
, program
);
449 const GLint size
= -1; /* unknown size */
453 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
460 if (strncmp(name
, "gl_", 3) == 0) {
461 _mesa_error(ctx
, GL_INVALID_OPERATION
,
462 "glBindAttribLocation(illegal name)");
466 if (shProg
->LinkStatus
) {
467 /* get current index/location for the attribute */
468 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
474 /* this will replace the current value if it's already in the list */
475 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
477 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
480 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
481 /* If the index changed, need to search/replace references to that attribute
482 * in the vertex program.
484 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
490 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
492 struct gl_shader
*sh
;
495 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
498 case GL_FRAGMENT_SHADER
:
499 case GL_VERTEX_SHADER
:
500 sh
= _mesa_new_shader(ctx
, name
, type
);
503 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
507 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
514 _mesa_create_program(GLcontext
*ctx
)
517 struct gl_shader_program
*shProg
;
519 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
520 shProg
= _mesa_new_shader_program(ctx
, name
);
522 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
524 assert(shProg
->RefCount
== 1);
531 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
535 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
538 * NOTE: deleting shaders/programs works a bit differently than
539 * texture objects (and buffer objects, etc). Shader/program
540 * handles/IDs exist in the hash table until the object is really
541 * deleted (refcount==0). With texture objects, the handle/ID is
542 * removed from the hash table in glDeleteTextures() while the tex
543 * object itself might linger until its refcount goes to zero.
545 struct gl_shader_program
*shProg
;
547 shProg
= _mesa_lookup_shader_program(ctx
, name
);
549 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
553 shProg
->DeletePending
= GL_TRUE
;
555 /* effectively, decr shProg's refcount */
556 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
561 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
563 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
568 sh
->DeletePending
= GL_TRUE
;
570 /* effectively, decr sh's refcount */
571 _mesa_reference_shader(ctx
, &sh
, NULL
);
576 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
578 struct gl_shader_program
*shProg
579 = _mesa_lookup_shader_program(ctx
, program
);
580 const GLuint n
= shProg
->NumShaders
;
584 _mesa_error(ctx
, GL_INVALID_VALUE
,
585 "glDetachShader(bad program or shader name)");
589 for (i
= 0; i
< n
; i
++) {
590 if (shProg
->Shaders
[i
]->Name
== shader
) {
592 struct gl_shader
**newList
;
595 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
597 /* alloc new, smaller array */
598 newList
= (struct gl_shader
**)
599 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
601 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
604 for (j
= 0; j
< i
; j
++) {
605 newList
[j
] = shProg
->Shaders
[j
];
608 newList
[j
++] = shProg
->Shaders
[i
];
609 _mesa_free(shProg
->Shaders
);
611 shProg
->Shaders
= newList
;
612 shProg
->NumShaders
= n
- 1;
617 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
618 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
619 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
620 assert(shProg
->Shaders
[j
]->RefCount
> 0);
630 _mesa_error(ctx
, GL_INVALID_VALUE
,
631 "glDetachShader(shader not found)");
636 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
637 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
638 GLenum
*type
, GLchar
*nameOut
)
640 static const GLenum vec_types
[] = {
641 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
643 struct gl_shader_program
*shProg
644 = _mesa_lookup_shader_program(ctx
, program
);
648 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
652 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
653 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
657 copy_string(nameOut
, maxLength
, length
,
658 shProg
->Attributes
->Parameters
[index
].Name
);
659 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
663 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
668 * Called via ctx->Driver.GetActiveUniform().
671 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
672 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
673 GLenum
*type
, GLchar
*nameOut
)
675 const struct gl_shader_program
*shProg
676 = _mesa_lookup_shader_program(ctx
, program
);
677 const struct gl_program
*prog
;
681 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
685 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
686 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
690 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
692 prog
= &shProg
->VertexProgram
->Base
;
695 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
697 prog
= &shProg
->FragmentProgram
->Base
;
701 if (!prog
|| progPos
< 0)
702 return; /* should never happen */
705 copy_string(nameOut
, maxLength
, length
,
706 prog
->Parameters
->Parameters
[progPos
].Name
);
708 *size
= prog
->Parameters
->Parameters
[progPos
].Size
;
711 *type
= prog
->Parameters
->Parameters
[progPos
].DataType
;
716 * Called via ctx->Driver.GetAttachedShaders().
719 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
720 GLsizei
*count
, GLuint
*obj
)
722 struct gl_shader_program
*shProg
723 = _mesa_lookup_shader_program(ctx
, program
);
726 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
727 obj
[i
] = shProg
->Shaders
[i
]->Name
;
733 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
739 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
742 GET_CURRENT_CONTEXT(ctx
);
745 case GL_PROGRAM_OBJECT_ARB
:
747 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
750 return (**pro
)._container
._generic
.
751 GetName((struct gl2_generic_intf
**) (pro
));
755 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
763 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
764 GLenum pname
, GLint
*params
)
766 struct gl_shader_program
*shProg
767 = _mesa_lookup_shader_program(ctx
, program
);
770 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
775 case GL_DELETE_STATUS
:
776 *params
= shProg
->DeletePending
;
779 *params
= shProg
->LinkStatus
;
781 case GL_VALIDATE_STATUS
:
782 *params
= shProg
->Validated
;
784 case GL_INFO_LOG_LENGTH
:
785 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
787 case GL_ATTACHED_SHADERS
:
788 *params
= shProg
->NumShaders
;
790 case GL_ACTIVE_ATTRIBUTES
:
791 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
793 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
794 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
797 case GL_ACTIVE_UNIFORMS
:
798 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
800 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
801 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
803 (*params
)++; /* add one for terminating zero */
806 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
813 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
815 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
818 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
824 *params
= shader
->Type
;
826 case GL_DELETE_STATUS
:
827 *params
= shader
->DeletePending
;
829 case GL_COMPILE_STATUS
:
830 *params
= shader
->CompileStatus
;
832 case GL_INFO_LOG_LENGTH
:
833 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
835 case GL_SHADER_SOURCE_LENGTH
:
836 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
839 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
846 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
847 GLsizei
*length
, GLchar
*infoLog
)
849 struct gl_shader_program
*shProg
850 = _mesa_lookup_shader_program(ctx
, program
);
852 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
855 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
860 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
861 GLsizei
*length
, GLchar
*infoLog
)
863 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
865 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
868 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
873 * Called via ctx->Driver.GetShaderSource().
876 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
877 GLsizei
*length
, GLchar
*sourceOut
)
879 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
881 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
884 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
889 * Called via ctx->Driver.GetUniformfv().
892 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
895 struct gl_shader_program
*shProg
896 = _mesa_lookup_shader_program(ctx
, program
);
898 if (location
< shProg
->Uniforms
->NumUniforms
) {
900 const struct gl_program
*prog
;
902 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
904 prog
= &shProg
->VertexProgram
->Base
;
907 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
909 prog
= &shProg
->FragmentProgram
->Base
;
913 for (i
= 0; i
< prog
->Parameters
->Parameters
[progPos
].Size
; i
++) {
914 params
[i
] = prog
->Parameters
->ParameterValues
[progPos
][i
];
918 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
922 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
928 * Called via ctx->Driver.GetUniformLocation().
931 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
933 struct gl_shader_program
*shProg
934 = _mesa_lookup_shader_program(ctx
, program
);
938 return _mesa_lookup_uniform(shProg
->Uniforms
, name
);
943 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
945 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
946 return shProg
? GL_TRUE
: GL_FALSE
;
951 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
953 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
954 return shader
? GL_TRUE
: GL_FALSE
;
960 * Called via ctx->Driver.ShaderSource()
963 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
965 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
967 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
971 /* free old shader source string and install new one */
973 _mesa_free((void *) sh
->Source
);
976 sh
->CompileStatus
= GL_FALSE
;
981 * Called via ctx->Driver.CompileShader()
984 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
986 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
989 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
993 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
998 * Called via ctx->Driver.LinkProgram()
1001 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1003 struct gl_shader_program
*shProg
;
1005 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1007 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1011 _slang_link(ctx
, program
, shProg
);
1016 * Called via ctx->Driver.UseProgram()
1019 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1021 struct gl_shader_program
*shProg
;
1023 if (ctx
->Shader
.CurrentProgram
&&
1024 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1029 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1032 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1034 _mesa_error(ctx
, GL_INVALID_VALUE
,
1035 "glUseProgramObjectARB(programObj)");
1043 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1049 * Update the vertex and fragment program's TexturesUsed arrays.
1052 update_textures_used(struct gl_program
*prog
)
1056 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1058 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1059 if (prog
->SamplersUsed
& (1 << s
)) {
1060 GLuint u
= prog
->SamplerUnits
[s
];
1061 GLuint t
= prog
->SamplerTargets
[s
];
1062 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1063 prog
->TexturesUsed
[u
] |= (1 << t
);
1070 * Set the value of a program's uniform variable.
1071 * \param program the program whose uniform to update
1072 * \param location the location/index of the uniform
1073 * \param type the datatype of the uniform
1074 * \param count the number of uniforms to set
1075 * \param elems number of elements per uniform
1076 * \param values the new values
1079 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
, GLint location
,
1080 GLenum type
, GLint count
, GLint elems
, const void *values
)
1082 if (program
->Parameters
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1083 /* This controls which texture unit which is used by a sampler */
1084 GLuint texUnit
, sampler
;
1086 /* data type for setting samplers must be int */
1087 if (type
!= GL_INT
|| count
!= 1) {
1088 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1089 "glUniform(only glUniform1i can be used "
1090 "to set sampler uniforms)");
1094 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[location
][0];
1095 texUnit
= ((GLuint
*) values
)[0];
1097 /* check that the sampler (tex unit index) is legal */
1098 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1099 _mesa_error(ctx
, GL_INVALID_VALUE
,
1100 "glUniform1(invalid sampler/tex unit index)");
1104 /* This maps a sampler to a texture unit: */
1105 program
->SamplerUnits
[sampler
] = texUnit
;
1106 update_textures_used(program
);
1108 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1111 /* ordinary uniform variable */
1114 if (count
* elems
> program
->Parameters
->Parameters
[location
].Size
) {
1115 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1119 for (k
= 0; k
< count
; k
++) {
1120 GLfloat
*uniformVal
= program
->Parameters
->ParameterValues
[location
+ k
];
1121 if (type
== GL_INT
||
1122 type
== GL_INT_VEC2
||
1123 type
== GL_INT_VEC3
||
1124 type
== GL_INT_VEC4
) {
1125 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1126 for (i
= 0; i
< elems
; i
++) {
1127 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1131 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1132 for (i
= 0; i
< elems
; i
++) {
1133 uniformVal
[i
] = fValues
[i
];
1142 * Called via ctx->Driver.Uniform().
1145 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1146 const GLvoid
*values
, GLenum type
)
1148 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1151 if (!shProg
|| !shProg
->LinkStatus
) {
1152 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1156 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1157 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1162 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1184 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1188 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1190 /* A uniform var may be used by both a vertex shader and a fragment
1191 * shader. We may need to update one or both shader's uniform here:
1193 if (shProg
->VertexProgram
) {
1194 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1196 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1197 loc
, type
, count
, elems
, values
);
1201 if (shProg
->FragmentProgram
) {
1202 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1204 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1205 loc
, type
, count
, elems
, values
);
1212 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1213 GLuint location
, GLuint rows
, GLuint cols
,
1214 GLboolean transpose
, const GLfloat
*values
)
1217 * Note: the _columns_ of a matrix are stored in program registers, not
1220 /* XXXX need to test 3x3 and 2x2 matrices... */
1223 for (col
= 0; col
< cols
; col
++) {
1224 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1225 for (row
= 0; row
< rows
; row
++) {
1226 v
[row
] = values
[row
* cols
+ col
];
1232 for (col
= 0; col
< cols
; col
++) {
1233 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1234 for (row
= 0; row
< rows
; row
++) {
1235 v
[row
] = values
[col
* rows
+ row
];
1243 * Called by ctx->Driver.UniformMatrix().
1246 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1247 GLenum matrixType
, GLint location
, GLsizei count
,
1248 GLboolean transpose
, const GLfloat
*values
)
1250 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1251 if (!shProg
|| !shProg
->LinkStatus
) {
1252 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1253 "glUniformMatrix(program not linked)");
1256 if (location
< 0 || location
>= shProg
->Uniforms
->NumUniforms
) {
1257 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1260 if (values
== NULL
) {
1261 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1265 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1267 if (shProg
->VertexProgram
) {
1268 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1270 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1271 loc
, rows
, cols
, transpose
, values
);
1275 if (shProg
->FragmentProgram
) {
1276 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1278 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1279 loc
, rows
, cols
, transpose
, values
);
1286 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1288 struct gl_shader_program
*shProg
;
1289 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1291 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1295 shProg
->Validated
= GL_TRUE
;
1297 /* From the GL spec:
1298 any two active samplers in the current program object are of
1299 different types, but refer to the same texture image unit,
1301 any active sampler in the current program object refers to a texture
1302 image unit where fixed-function fragment processing accesses a
1303 texture target that does not match the sampler type, or
1305 the sum of the number of active samplers in the program and the
1306 number of texture image units enabled for fixed-function fragment
1307 processing exceeds the combined limit on the total number of texture
1308 image units allowed.
1314 * Plug in Mesa's GLSL functions into the device driver function table.
1317 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
1319 driver
->AttachShader
= _mesa_attach_shader
;
1320 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
1321 driver
->CompileShader
= _mesa_compile_shader
;
1322 driver
->CreateProgram
= _mesa_create_program
;
1323 driver
->CreateShader
= _mesa_create_shader
;
1324 driver
->DeleteProgram2
= _mesa_delete_program2
;
1325 driver
->DeleteShader
= _mesa_delete_shader
;
1326 driver
->DetachShader
= _mesa_detach_shader
;
1327 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
1328 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
1329 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
1330 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
1331 driver
->GetHandle
= _mesa_get_handle
;
1332 driver
->GetProgramiv
= _mesa_get_programiv
;
1333 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
1334 driver
->GetShaderiv
= _mesa_get_shaderiv
;
1335 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
1336 driver
->GetShaderSource
= _mesa_get_shader_source
;
1337 driver
->GetUniformfv
= _mesa_get_uniformfv
;
1338 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
1339 driver
->IsProgram
= _mesa_is_program
;
1340 driver
->IsShader
= _mesa_is_shader
;
1341 driver
->LinkProgram
= _mesa_link_program
;
1342 driver
->ShaderSource
= _mesa_shader_source
;
1343 driver
->Uniform
= _mesa_uniform
;
1344 driver
->UniformMatrix
= _mesa_uniform_matrix
;
1345 driver
->UseProgram
= _mesa_use_program
;
1346 driver
->ValidateProgram
= _mesa_validate_program
;