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 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 _mesa_reference_vertprog(ctx
, &shProg
->VertexProgram
, NULL
);
79 _mesa_reference_fragprog(ctx
, &shProg
->FragmentProgram
, NULL
);
81 if (shProg
->Uniforms
) {
82 _mesa_free_uniform_list(shProg
->Uniforms
);
83 shProg
->Uniforms
= NULL
;
86 if (shProg
->Varying
) {
87 _mesa_free_parameter_list(shProg
->Varying
);
88 shProg
->Varying
= NULL
;
94 * Free all the data that hangs off a shader program object, but not the
98 _mesa_free_shader_program_data(GLcontext
*ctx
,
99 struct gl_shader_program
*shProg
)
103 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
105 _mesa_clear_shader_program_data(ctx
, shProg
);
107 if (shProg
->Attributes
) {
108 _mesa_free_parameter_list(shProg
->Attributes
);
109 shProg
->Attributes
= NULL
;
113 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
114 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
116 shProg
->NumShaders
= 0;
118 if (shProg
->Shaders
) {
119 _mesa_free(shProg
->Shaders
);
120 shProg
->Shaders
= NULL
;
123 if (shProg
->InfoLog
) {
124 _mesa_free(shProg
->InfoLog
);
125 shProg
->InfoLog
= NULL
;
131 * Free/delete a shader program object.
134 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
136 _mesa_free_shader_program_data(ctx
, shProg
);
143 * Set ptr to point to shProg.
144 * If ptr is pointing to another object, decrement its refcount (and delete
145 * if refcount hits zero).
146 * Then set ptr to point to shProg, incrementing its refcount.
148 /* XXX this could be static */
150 _mesa_reference_shader_program(GLcontext
*ctx
,
151 struct gl_shader_program
**ptr
,
152 struct gl_shader_program
*shProg
)
155 if (*ptr
== shProg
) {
160 /* Unreference the old shader program */
161 GLboolean deleteFlag
= GL_FALSE
;
162 struct gl_shader_program
*old
= *ptr
;
164 ASSERT(old
->RefCount
> 0);
167 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
168 (void *) old
, old
->Name
, old
->RefCount
);
170 deleteFlag
= (old
->RefCount
== 0);
173 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
174 _mesa_free_shader_program(ctx
, old
);
184 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
185 (void *) shProg
, shProg
->Name
, shProg
->RefCount
);
193 * Lookup a GLSL program object.
195 struct gl_shader_program
*
196 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
198 struct gl_shader_program
*shProg
;
200 shProg
= (struct gl_shader_program
*)
201 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
202 /* Note that both gl_shader and gl_shader_program objects are kept
203 * in the same hash table. Check the object's type to be sure it's
204 * what we're expecting.
206 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
216 * Allocate a new gl_shader object, initialize it.
219 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
221 struct gl_shader
*shader
;
222 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
223 shader
= CALLOC_STRUCT(gl_shader
);
227 shader
->RefCount
= 1;
234 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
238 _mesa_free((void *) sh
->Source
);
240 _mesa_free(sh
->InfoLog
);
241 for (i
= 0; i
< sh
->NumPrograms
; i
++)
242 _mesa_reference_program(ctx
, &sh
->Programs
[i
], NULL
);
244 _mesa_free(sh
->Programs
);
250 * Set ptr to point to sh.
251 * If ptr is pointing to another shader, decrement its refcount (and delete
252 * if refcount hits zero).
253 * Then set ptr to point to sh, incrementing its refcount.
255 /* XXX this could be static */
257 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
258 struct gl_shader
*sh
)
266 /* Unreference the old shader */
267 GLboolean deleteFlag
= GL_FALSE
;
268 struct gl_shader
*old
= *ptr
;
270 ASSERT(old
->RefCount
> 0);
272 /*printf("SHADER DECR %p (%d) to %d\n",
273 (void*) old, old->Name, old->RefCount);*/
274 deleteFlag
= (old
->RefCount
== 0);
277 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
278 _mesa_free_shader(ctx
, old
);
288 /*printf("SHADER INCR %p (%d) to %d\n",
289 (void*) sh, sh->Name, sh->RefCount);*/
296 * Lookup a GLSL shader object.
299 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
302 struct gl_shader
*sh
= (struct gl_shader
*)
303 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
304 /* Note that both gl_shader and gl_shader_program objects are kept
305 * in the same hash table. Check the object's type to be sure it's
306 * what we're expecting.
308 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
318 * Initialize context's shader state.
321 _mesa_init_shader_state(GLcontext
* ctx
)
323 /* Device drivers may override these to control what kind of instructions
324 * are generated by the GLSL compiler.
326 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
327 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
328 ctx
->Shader
.EmitComments
= GL_FALSE
;
333 * Free the per-context shader-related state.
336 _mesa_free_shader_state(GLcontext
*ctx
)
338 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
343 * Copy string from <src> to <dst>, up to maxLength characters, returning
344 * length of <dst> in <length>.
345 * \param src the strings source
346 * \param maxLength max chars to copy
347 * \param length returns number of chars copied
348 * \param dst the string destination
351 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
354 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
364 * Return size (in floats) of the given GLSL type.
365 * See also _slang_sizeof_type_specifier().
368 sizeof_glsl_type(GLenum type
)
388 return 8; /* 2 rows of 4, actually */
390 return 12; /* 3 rows of 4, actually */
393 case GL_FLOAT_MAT2x3
:
394 return 8; /* 2 rows of 4, actually */
395 case GL_FLOAT_MAT2x4
:
397 case GL_FLOAT_MAT3x2
:
398 return 12; /* 3 rows of 4, actually */
399 case GL_FLOAT_MAT3x4
:
401 case GL_FLOAT_MAT4x2
:
402 return 16; /* 4 rows of 4, actually */
403 case GL_FLOAT_MAT4x3
:
404 return 16; /* 4 rows of 4, actually */
406 return 0; /* error */
412 * Called via ctx->Driver.AttachShader()
415 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
417 struct gl_shader_program
*shProg
418 = _mesa_lookup_shader_program(ctx
, program
);
419 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
423 if (!shProg
|| !sh
) {
424 _mesa_error(ctx
, GL_INVALID_VALUE
,
425 "glAttachShader(bad program or shader name)");
429 n
= shProg
->NumShaders
;
431 for (i
= 0; i
< n
; i
++) {
432 if (shProg
->Shaders
[i
] == sh
) {
433 /* already attached */
439 shProg
->Shaders
= (struct gl_shader
**)
440 _mesa_realloc(shProg
->Shaders
,
441 n
* sizeof(struct gl_shader
*),
442 (n
+ 1) * sizeof(struct gl_shader
*));
443 if (!shProg
->Shaders
) {
444 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
449 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
450 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
451 shProg
->NumShaders
++;
456 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
459 struct gl_shader_program
*shProg
460 = _mesa_lookup_shader_program(ctx
, program
);
461 const GLint size
= -1; /* unknown size */
465 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
472 if (strncmp(name
, "gl_", 3) == 0) {
473 _mesa_error(ctx
, GL_INVALID_OPERATION
,
474 "glBindAttribLocation(illegal name)");
478 if (shProg
->LinkStatus
) {
479 /* get current index/location for the attribute */
480 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
486 /* this will replace the current value if it's already in the list */
487 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
489 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
492 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
493 /* If the index changed, need to search/replace references to that attribute
494 * in the vertex program.
496 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
502 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
504 struct gl_shader
*sh
;
507 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
510 case GL_FRAGMENT_SHADER
:
511 case GL_VERTEX_SHADER
:
512 sh
= _mesa_new_shader(ctx
, name
, type
);
515 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
519 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
526 _mesa_create_program(GLcontext
*ctx
)
529 struct gl_shader_program
*shProg
;
531 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
532 shProg
= _mesa_new_shader_program(ctx
, name
);
534 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
536 assert(shProg
->RefCount
== 1);
543 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
547 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
550 * NOTE: deleting shaders/programs works a bit differently than
551 * texture objects (and buffer objects, etc). Shader/program
552 * handles/IDs exist in the hash table until the object is really
553 * deleted (refcount==0). With texture objects, the handle/ID is
554 * removed from the hash table in glDeleteTextures() while the tex
555 * object itself might linger until its refcount goes to zero.
557 struct gl_shader_program
*shProg
;
559 shProg
= _mesa_lookup_shader_program(ctx
, name
);
561 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
565 shProg
->DeletePending
= GL_TRUE
;
567 /* effectively, decr shProg's refcount */
568 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
573 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
575 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
580 sh
->DeletePending
= GL_TRUE
;
582 /* effectively, decr sh's refcount */
583 _mesa_reference_shader(ctx
, &sh
, NULL
);
588 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
590 struct gl_shader_program
*shProg
591 = _mesa_lookup_shader_program(ctx
, program
);
596 _mesa_error(ctx
, GL_INVALID_VALUE
,
597 "glDetachShader(bad program or shader name)");
601 n
= shProg
->NumShaders
;
603 for (i
= 0; i
< n
; i
++) {
604 if (shProg
->Shaders
[i
]->Name
== shader
) {
606 struct gl_shader
**newList
;
609 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
611 /* alloc new, smaller array */
612 newList
= (struct gl_shader
**)
613 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
615 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
618 for (j
= 0; j
< i
; j
++) {
619 newList
[j
] = shProg
->Shaders
[j
];
622 newList
[j
++] = shProg
->Shaders
[i
];
623 _mesa_free(shProg
->Shaders
);
625 shProg
->Shaders
= newList
;
626 shProg
->NumShaders
= n
- 1;
631 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
632 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
633 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
634 assert(shProg
->Shaders
[j
]->RefCount
> 0);
644 _mesa_error(ctx
, GL_INVALID_VALUE
,
645 "glDetachShader(shader not found)");
650 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
651 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
652 GLenum
*type
, GLchar
*nameOut
)
654 static const GLenum vec_types
[] = {
655 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
657 struct gl_shader_program
*shProg
658 = _mesa_lookup_shader_program(ctx
, program
);
662 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
666 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
667 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
671 copy_string(nameOut
, maxLength
, length
,
672 shProg
->Attributes
->Parameters
[index
].Name
);
673 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
677 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
682 * Called via ctx->Driver.GetActiveUniform().
685 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
686 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
687 GLenum
*type
, GLchar
*nameOut
)
689 struct gl_shader_program
*shProg
690 = _mesa_lookup_shader_program(ctx
, program
);
691 const struct gl_program
*prog
;
695 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
699 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
700 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
704 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
706 prog
= &shProg
->VertexProgram
->Base
;
709 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
711 prog
= &shProg
->FragmentProgram
->Base
;
715 if (!prog
|| progPos
< 0)
716 return; /* should never happen */
719 copy_string(nameOut
, maxLength
, length
,
720 prog
->Parameters
->Parameters
[progPos
].Name
);
722 *size
= prog
->Parameters
->Parameters
[progPos
].Size
;
725 *type
= prog
->Parameters
->Parameters
[progPos
].DataType
;
730 * Called via ctx->Driver.GetAttachedShaders().
733 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
734 GLsizei
*count
, GLuint
*obj
)
736 struct gl_shader_program
*shProg
737 = _mesa_lookup_shader_program(ctx
, program
);
740 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
741 obj
[i
] = shProg
->Shaders
[i
]->Name
;
747 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
753 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
756 struct gl_shader_program
*shProg
757 = _mesa_lookup_shader_program(ctx
, program
);
760 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
764 if (!shProg
->LinkStatus
) {
765 _mesa_error(ctx
, GL_INVALID_OPERATION
,
766 "glGetAttribLocation(program not linked)");
773 if (shProg
->Attributes
) {
774 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
776 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
784 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
787 GET_CURRENT_CONTEXT(ctx
);
790 case GL_PROGRAM_OBJECT_ARB
:
792 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
795 return (**pro
)._container
._generic
.
796 GetName((struct gl2_generic_intf
**) (pro
));
800 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
808 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
809 GLenum pname
, GLint
*params
)
811 struct gl_shader_program
*shProg
812 = _mesa_lookup_shader_program(ctx
, program
);
815 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
820 case GL_DELETE_STATUS
:
821 *params
= shProg
->DeletePending
;
824 *params
= shProg
->LinkStatus
;
826 case GL_VALIDATE_STATUS
:
827 *params
= shProg
->Validated
;
829 case GL_INFO_LOG_LENGTH
:
830 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
832 case GL_ATTACHED_SHADERS
:
833 *params
= shProg
->NumShaders
;
835 case GL_ACTIVE_ATTRIBUTES
:
836 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
838 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
839 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
842 case GL_ACTIVE_UNIFORMS
:
843 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
845 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
846 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
848 (*params
)++; /* add one for terminating zero */
851 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
858 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
860 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
863 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
869 *params
= shader
->Type
;
871 case GL_DELETE_STATUS
:
872 *params
= shader
->DeletePending
;
874 case GL_COMPILE_STATUS
:
875 *params
= shader
->CompileStatus
;
877 case GL_INFO_LOG_LENGTH
:
878 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
880 case GL_SHADER_SOURCE_LENGTH
:
881 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
884 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
891 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
892 GLsizei
*length
, GLchar
*infoLog
)
894 struct gl_shader_program
*shProg
895 = _mesa_lookup_shader_program(ctx
, program
);
897 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
900 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
905 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
906 GLsizei
*length
, GLchar
*infoLog
)
908 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
910 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
913 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
918 * Called via ctx->Driver.GetShaderSource().
921 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
922 GLsizei
*length
, GLchar
*sourceOut
)
924 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
926 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
929 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
934 * Called via ctx->Driver.GetUniformfv().
937 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
940 struct gl_shader_program
*shProg
941 = _mesa_lookup_shader_program(ctx
, program
);
943 if (location
< shProg
->Uniforms
->NumUniforms
) {
945 const struct gl_program
*prog
;
947 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
949 prog
= &shProg
->VertexProgram
->Base
;
952 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
954 prog
= &shProg
->FragmentProgram
->Base
;
958 for (i
= 0; i
< prog
->Parameters
->Parameters
[progPos
].Size
; i
++) {
959 params
[i
] = prog
->Parameters
->ParameterValues
[progPos
][i
];
963 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
967 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
973 * Called via ctx->Driver.GetUniformLocation().
976 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
978 struct gl_shader_program
*shProg
979 = _mesa_lookup_shader_program(ctx
, program
);
983 return _mesa_lookup_uniform(shProg
->Uniforms
, name
);
988 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
990 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
991 return shProg
? GL_TRUE
: GL_FALSE
;
996 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
998 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
999 return shader
? GL_TRUE
: GL_FALSE
;
1005 * Called via ctx->Driver.ShaderSource()
1008 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1010 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1012 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
1016 /* free old shader source string and install new one */
1018 _mesa_free((void *) sh
->Source
);
1020 sh
->Source
= source
;
1021 sh
->CompileStatus
= GL_FALSE
;
1026 * Called via ctx->Driver.CompileShader()
1029 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1031 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
1034 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
1038 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1043 * Called via ctx->Driver.LinkProgram()
1046 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1048 struct gl_shader_program
*shProg
;
1050 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1052 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1056 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1058 _slang_link(ctx
, program
, shProg
);
1063 * Called via ctx->Driver.UseProgram()
1066 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1068 struct gl_shader_program
*shProg
;
1070 if (ctx
->Shader
.CurrentProgram
&&
1071 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1076 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1079 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1081 _mesa_error(ctx
, GL_INVALID_VALUE
,
1082 "glUseProgramObjectARB(programObj)");
1090 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1096 * Update the vertex and fragment program's TexturesUsed arrays.
1099 update_textures_used(struct gl_program
*prog
)
1103 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1105 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1106 if (prog
->SamplersUsed
& (1 << s
)) {
1107 GLuint u
= prog
->SamplerUnits
[s
];
1108 GLuint t
= prog
->SamplerTargets
[s
];
1109 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1110 prog
->TexturesUsed
[u
] |= (1 << t
);
1117 * Set the value of a program's uniform variable.
1118 * \param program the program whose uniform to update
1119 * \param location the location/index of the uniform
1120 * \param type the datatype of the uniform
1121 * \param count the number of uniforms to set
1122 * \param elems number of elements per uniform
1123 * \param values the new values
1126 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
, GLint location
,
1127 GLenum type
, GLint count
, GLint elems
, const void *values
)
1129 if (program
->Parameters
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1130 /* This controls which texture unit which is used by a sampler */
1131 GLuint texUnit
, sampler
;
1133 /* data type for setting samplers must be int */
1134 if (type
!= GL_INT
|| count
!= 1) {
1135 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1136 "glUniform(only glUniform1i can be used "
1137 "to set sampler uniforms)");
1141 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[location
][0];
1142 texUnit
= ((GLuint
*) values
)[0];
1144 /* check that the sampler (tex unit index) is legal */
1145 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1146 _mesa_error(ctx
, GL_INVALID_VALUE
,
1147 "glUniform1(invalid sampler/tex unit index)");
1151 /* This maps a sampler to a texture unit: */
1152 program
->SamplerUnits
[sampler
] = texUnit
;
1153 update_textures_used(program
);
1155 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1158 /* ordinary uniform variable */
1161 if (count
* elems
> program
->Parameters
->Parameters
[location
].Size
) {
1162 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1166 for (k
= 0; k
< count
; k
++) {
1167 GLfloat
*uniformVal
= program
->Parameters
->ParameterValues
[location
+ k
];
1168 if (type
== GL_INT
||
1169 type
== GL_INT_VEC2
||
1170 type
== GL_INT_VEC3
||
1171 type
== GL_INT_VEC4
) {
1172 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1173 for (i
= 0; i
< elems
; i
++) {
1174 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1178 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1179 for (i
= 0; i
< elems
; i
++) {
1180 uniformVal
[i
] = fValues
[i
];
1189 * Called via ctx->Driver.Uniform().
1192 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1193 const GLvoid
*values
, GLenum type
)
1195 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1198 if (!shProg
|| !shProg
->LinkStatus
) {
1199 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1204 return; /* The standard specifies this as a no-op */
1206 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1207 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1212 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1234 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1238 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1240 /* A uniform var may be used by both a vertex shader and a fragment
1241 * shader. We may need to update one or both shader's uniform here:
1243 if (shProg
->VertexProgram
) {
1244 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1246 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1247 loc
, type
, count
, elems
, values
);
1251 if (shProg
->FragmentProgram
) {
1252 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1254 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1255 loc
, type
, count
, elems
, values
);
1262 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1263 GLuint location
, GLuint rows
, GLuint cols
,
1264 GLboolean transpose
, const GLfloat
*values
)
1267 * Note: the _columns_ of a matrix are stored in program registers, not
1270 /* XXXX need to test 3x3 and 2x2 matrices... */
1273 for (col
= 0; col
< cols
; col
++) {
1274 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1275 for (row
= 0; row
< rows
; row
++) {
1276 v
[row
] = values
[row
* cols
+ col
];
1282 for (col
= 0; col
< cols
; col
++) {
1283 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1284 for (row
= 0; row
< rows
; row
++) {
1285 v
[row
] = values
[col
* rows
+ row
];
1293 * Called by ctx->Driver.UniformMatrix().
1296 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1297 GLenum matrixType
, GLint location
, GLsizei count
,
1298 GLboolean transpose
, const GLfloat
*values
)
1300 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1302 if (!shProg
|| !shProg
->LinkStatus
) {
1303 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1304 "glUniformMatrix(program not linked)");
1309 return; /* The standard specifies this as a no-op */
1311 if (location
< 0 || location
>= shProg
->Uniforms
->NumUniforms
) {
1312 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1315 if (values
== NULL
) {
1316 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1320 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1322 if (shProg
->VertexProgram
) {
1323 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1325 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1326 loc
, rows
, cols
, transpose
, values
);
1330 if (shProg
->FragmentProgram
) {
1331 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1333 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1334 loc
, rows
, cols
, transpose
, values
);
1341 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1343 struct gl_shader_program
*shProg
;
1344 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1346 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1350 shProg
->Validated
= GL_TRUE
;
1352 /* From the GL spec:
1353 any two active samplers in the current program object are of
1354 different types, but refer to the same texture image unit,
1356 any active sampler in the current program object refers to a texture
1357 image unit where fixed-function fragment processing accesses a
1358 texture target that does not match the sampler type, or
1360 the sum of the number of active samplers in the program and the
1361 number of texture image units enabled for fixed-function fragment
1362 processing exceeds the combined limit on the total number of texture
1363 image units allowed.