2 * Mesa 3-D graphics library
5 * Copyright (C) 2004-2008 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
38 #include "main/glheader.h"
39 #include "main/context.h"
40 #include "main/hash.h"
41 #include "main/macros.h"
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"
53 #ifndef GL_PROGRAM_BINARY_LENGTH_OES
54 #define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
59 * Allocate a new gl_shader_program object, initialize it.
61 static struct gl_shader_program
*
62 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
64 struct gl_shader_program
*shProg
;
65 shProg
= CALLOC_STRUCT(gl_shader_program
);
67 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
70 shProg
->Attributes
= _mesa_new_parameter_list();
77 * Clear (free) the shader program state that gets produced by linking.
80 _mesa_clear_shader_program_data(GLcontext
*ctx
,
81 struct gl_shader_program
*shProg
)
83 _mesa_reference_vertprog(ctx
, &shProg
->VertexProgram
, NULL
);
84 _mesa_reference_fragprog(ctx
, &shProg
->FragmentProgram
, NULL
);
86 if (shProg
->Uniforms
) {
87 _mesa_free_uniform_list(shProg
->Uniforms
);
88 shProg
->Uniforms
= NULL
;
91 if (shProg
->Varying
) {
92 _mesa_free_parameter_list(shProg
->Varying
);
93 shProg
->Varying
= NULL
;
99 * Free all the data that hangs off a shader program object, but not the
103 _mesa_free_shader_program_data(GLcontext
*ctx
,
104 struct gl_shader_program
*shProg
)
108 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
110 _mesa_clear_shader_program_data(ctx
, shProg
);
112 if (shProg
->Attributes
) {
113 _mesa_free_parameter_list(shProg
->Attributes
);
114 shProg
->Attributes
= NULL
;
118 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
119 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
121 shProg
->NumShaders
= 0;
123 if (shProg
->Shaders
) {
124 _mesa_free(shProg
->Shaders
);
125 shProg
->Shaders
= NULL
;
128 if (shProg
->InfoLog
) {
129 _mesa_free(shProg
->InfoLog
);
130 shProg
->InfoLog
= NULL
;
136 * Free/delete a shader program object.
139 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
141 _mesa_free_shader_program_data(ctx
, shProg
);
148 * Set ptr to point to shProg.
149 * If ptr is pointing to another object, decrement its refcount (and delete
150 * if refcount hits zero).
151 * Then set ptr to point to shProg, incrementing its refcount.
153 /* XXX this could be static */
155 _mesa_reference_shader_program(GLcontext
*ctx
,
156 struct gl_shader_program
**ptr
,
157 struct gl_shader_program
*shProg
)
160 if (*ptr
== shProg
) {
165 /* Unreference the old shader program */
166 GLboolean deleteFlag
= GL_FALSE
;
167 struct gl_shader_program
*old
= *ptr
;
169 ASSERT(old
->RefCount
> 0);
172 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
173 (void *) old
, old
->Name
, old
->RefCount
);
175 deleteFlag
= (old
->RefCount
== 0);
178 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
179 _mesa_free_shader_program(ctx
, old
);
189 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
190 (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 * As above, but record an error if program is not found.
223 static struct gl_shader_program
*
224 _mesa_lookup_shader_program_err(GLcontext
*ctx
, GLuint name
,
228 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
232 struct gl_shader_program
*shProg
= (struct gl_shader_program
*)
233 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
235 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
238 if (shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
239 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
250 * Allocate a new gl_shader object, initialize it.
253 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
255 struct gl_shader
*shader
;
256 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
257 shader
= CALLOC_STRUCT(gl_shader
);
261 shader
->RefCount
= 1;
268 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
271 _mesa_free((void *) sh
->Source
);
273 _mesa_free(sh
->InfoLog
);
274 _mesa_reference_program(ctx
, &sh
->Program
, NULL
);
280 * Set ptr to point to sh.
281 * If ptr is pointing to another shader, decrement its refcount (and delete
282 * if refcount hits zero).
283 * Then set ptr to point to sh, incrementing its refcount.
285 /* XXX this could be static */
287 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
288 struct gl_shader
*sh
)
296 /* Unreference the old shader */
297 GLboolean deleteFlag
= GL_FALSE
;
298 struct gl_shader
*old
= *ptr
;
300 ASSERT(old
->RefCount
> 0);
302 /*printf("SHADER DECR %p (%d) to %d\n",
303 (void*) old, old->Name, old->RefCount);*/
304 deleteFlag
= (old
->RefCount
== 0);
307 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
308 _mesa_free_shader(ctx
, old
);
318 /*printf("SHADER INCR %p (%d) to %d\n",
319 (void*) sh, sh->Name, sh->RefCount);*/
326 * Lookup a GLSL shader object.
329 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
332 struct gl_shader
*sh
= (struct gl_shader
*)
333 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
334 /* Note that both gl_shader and gl_shader_program objects are kept
335 * in the same hash table. Check the object's type to be sure it's
336 * what we're expecting.
338 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
348 * As above, but record an error if shader is not found.
350 static struct gl_shader
*
351 _mesa_lookup_shader_err(GLcontext
*ctx
, GLuint name
, const char *caller
)
354 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
358 struct gl_shader
*sh
= (struct gl_shader
*)
359 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
361 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
364 if (sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
365 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
375 * Initialize context's shader state.
378 _mesa_init_shader_state(GLcontext
* ctx
)
380 /* Device drivers may override these to control what kind of instructions
381 * are generated by the GLSL compiler.
383 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
384 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
385 ctx
->Shader
.EmitComments
= GL_FALSE
;
390 * Free the per-context shader-related state.
393 _mesa_free_shader_state(GLcontext
*ctx
)
395 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
400 * Copy string from <src> to <dst>, up to maxLength characters, returning
401 * length of <dst> in <length>.
402 * \param src the strings source
403 * \param maxLength max chars to copy
404 * \param length returns number of chars copied
405 * \param dst the string destination
408 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
411 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
421 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
423 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
424 return shProg
? GL_TRUE
: GL_FALSE
;
429 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
431 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
432 return shader
? GL_TRUE
: GL_FALSE
;
437 * Called via ctx->Driver.AttachShader()
440 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
442 struct gl_shader_program
*shProg
;
443 struct gl_shader
*sh
;
446 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
450 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
455 n
= shProg
->NumShaders
;
456 for (i
= 0; i
< n
; i
++) {
457 if (shProg
->Shaders
[i
] == sh
) {
458 /* already attached */
464 shProg
->Shaders
= (struct gl_shader
**)
465 _mesa_realloc(shProg
->Shaders
,
466 n
* sizeof(struct gl_shader
*),
467 (n
+ 1) * sizeof(struct gl_shader
*));
468 if (!shProg
->Shaders
) {
469 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
474 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
475 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
476 shProg
->NumShaders
++;
481 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
484 struct gl_shader_program
*shProg
485 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
491 if (!shProg
->LinkStatus
) {
492 _mesa_error(ctx
, GL_INVALID_OPERATION
,
493 "glGetAttribLocation(program not linked)");
500 if (shProg
->Attributes
) {
501 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
503 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
511 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
514 struct gl_shader_program
*shProg
;
515 const GLint size
= -1; /* unknown size */
517 GLenum datatype
= GL_FLOAT_VEC4
;
519 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
520 "glBindAttribLocation");
528 if (strncmp(name
, "gl_", 3) == 0) {
529 _mesa_error(ctx
, GL_INVALID_OPERATION
,
530 "glBindAttribLocation(illegal name)");
534 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
535 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
539 if (shProg
->LinkStatus
) {
540 /* get current index/location for the attribute */
541 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
547 /* this will replace the current value if it's already in the list */
548 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, datatype
, index
);
550 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
554 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
555 /* If the index changed, need to search/replace references to that attribute
556 * in the vertex program.
558 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
564 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
566 struct gl_shader
*sh
;
569 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
572 case GL_FRAGMENT_SHADER
:
573 case GL_VERTEX_SHADER
:
574 sh
= _mesa_new_shader(ctx
, name
, type
);
577 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
581 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
588 _mesa_create_program(GLcontext
*ctx
)
591 struct gl_shader_program
*shProg
;
593 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
594 shProg
= _mesa_new_shader_program(ctx
, name
);
596 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
598 assert(shProg
->RefCount
== 1);
605 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
609 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
612 * NOTE: deleting shaders/programs works a bit differently than
613 * texture objects (and buffer objects, etc). Shader/program
614 * handles/IDs exist in the hash table until the object is really
615 * deleted (refcount==0). With texture objects, the handle/ID is
616 * removed from the hash table in glDeleteTextures() while the tex
617 * object itself might linger until its refcount goes to zero.
619 struct gl_shader_program
*shProg
;
621 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
625 shProg
->DeletePending
= GL_TRUE
;
627 /* effectively, decr shProg's refcount */
628 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
633 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
635 struct gl_shader
*sh
;
637 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
641 sh
->DeletePending
= GL_TRUE
;
643 /* effectively, decr sh's refcount */
644 _mesa_reference_shader(ctx
, &sh
, NULL
);
649 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
651 struct gl_shader_program
*shProg
;
655 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
659 n
= shProg
->NumShaders
;
661 for (i
= 0; i
< n
; i
++) {
662 if (shProg
->Shaders
[i
]->Name
== shader
) {
664 struct gl_shader
**newList
;
667 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
669 /* alloc new, smaller array */
670 newList
= (struct gl_shader
**)
671 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
673 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
676 for (j
= 0; j
< i
; j
++) {
677 newList
[j
] = shProg
->Shaders
[j
];
680 newList
[j
++] = shProg
->Shaders
[i
];
681 _mesa_free(shProg
->Shaders
);
683 shProg
->Shaders
= newList
;
684 shProg
->NumShaders
= n
- 1;
689 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
690 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
691 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
692 assert(shProg
->Shaders
[j
]->RefCount
> 0);
704 if (_mesa_is_shader(ctx
, shader
))
705 err
= GL_INVALID_OPERATION
;
706 else if (_mesa_is_program(ctx
, shader
))
707 err
= GL_INVALID_OPERATION
;
709 err
= GL_INVALID_VALUE
;
710 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
717 sizeof_glsl_type(GLenum type
)
726 case GL_SAMPLER_CUBE
:
727 case GL_SAMPLER_1D_SHADOW
:
728 case GL_SAMPLER_2D_SHADOW
:
729 case GL_SAMPLER_2D_RECT_ARB
:
730 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
731 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
732 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
733 case GL_SAMPLER_CUBE_SHADOW_EXT
:
748 case GL_FLOAT_MAT2x3
:
749 case GL_FLOAT_MAT2x4
:
750 return 8; /* two float[4] vectors */
752 case GL_FLOAT_MAT3x2
:
753 case GL_FLOAT_MAT3x4
:
754 return 12; /* three float[4] vectors */
756 case GL_FLOAT_MAT4x2
:
757 case GL_FLOAT_MAT4x3
:
758 return 16; /* four float[4] vectors */
760 _mesa_problem(NULL
, "Invalid type in sizeof_glsl_type()");
767 is_boolean_type(GLenum type
)
782 is_integer_type(GLenum type
)
797 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
798 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
799 GLenum
*type
, GLchar
*nameOut
)
801 struct gl_shader_program
*shProg
;
803 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
807 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
808 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
812 copy_string(nameOut
, maxLength
, length
,
813 shProg
->Attributes
->Parameters
[index
].Name
);
815 *size
= shProg
->Attributes
->Parameters
[index
].Size
816 / sizeof_glsl_type(shProg
->Attributes
->Parameters
[index
].DataType
);
818 *type
= shProg
->Attributes
->Parameters
[index
].DataType
;
822 static struct gl_program_parameter
*
823 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
825 const struct gl_program
*prog
;
828 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
830 prog
= &shProg
->VertexProgram
->Base
;
833 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
835 prog
= &shProg
->FragmentProgram
->Base
;
839 if (!prog
|| progPos
< 0)
840 return NULL
; /* should never happen */
842 return &prog
->Parameters
->Parameters
[progPos
];
847 * Called via ctx->Driver.GetActiveUniform().
850 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
851 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
852 GLenum
*type
, GLchar
*nameOut
)
854 const struct gl_shader_program
*shProg
;
855 const struct gl_program
*prog
;
858 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
862 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
863 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
867 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
869 prog
= &shProg
->VertexProgram
->Base
;
872 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
874 prog
= &shProg
->FragmentProgram
->Base
;
878 if (!prog
|| progPos
< 0)
879 return; /* should never happen */
882 copy_string(nameOut
, maxLength
, length
,
883 prog
->Parameters
->Parameters
[progPos
].Name
);
885 *size
= prog
->Parameters
->Parameters
[progPos
].Size
886 / sizeof_glsl_type(prog
->Parameters
->Parameters
[progPos
].DataType
);
888 *type
= prog
->Parameters
->Parameters
[progPos
].DataType
;
893 * Called via ctx->Driver.GetAttachedShaders().
896 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
897 GLsizei
*count
, GLuint
*obj
)
899 struct gl_shader_program
*shProg
=
900 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
903 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
904 obj
[i
] = shProg
->Shaders
[i
]->Name
;
913 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
916 GET_CURRENT_CONTEXT(ctx
);
919 case GL_PROGRAM_OBJECT_ARB
:
921 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
924 return (**pro
)._container
._generic
.
925 GetName((struct gl2_generic_intf
**) (pro
));
929 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
937 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
938 GLenum pname
, GLint
*params
)
940 struct gl_shader_program
*shProg
941 = _mesa_lookup_shader_program(ctx
, program
);
944 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
949 case GL_DELETE_STATUS
:
950 *params
= shProg
->DeletePending
;
953 *params
= shProg
->LinkStatus
;
955 case GL_VALIDATE_STATUS
:
956 *params
= shProg
->Validated
;
958 case GL_INFO_LOG_LENGTH
:
959 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
961 case GL_ATTACHED_SHADERS
:
962 *params
= shProg
->NumShaders
;
964 case GL_ACTIVE_ATTRIBUTES
:
965 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
967 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
968 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
971 case GL_ACTIVE_UNIFORMS
:
972 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
974 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
975 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
977 (*params
)++; /* add one for terminating zero */
979 case GL_PROGRAM_BINARY_LENGTH_OES
:
983 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
990 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
992 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
1000 *params
= shader
->Type
;
1002 case GL_DELETE_STATUS
:
1003 *params
= shader
->DeletePending
;
1005 case GL_COMPILE_STATUS
:
1006 *params
= shader
->CompileStatus
;
1008 case GL_INFO_LOG_LENGTH
:
1009 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
1011 case GL_SHADER_SOURCE_LENGTH
:
1012 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
1015 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
1022 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
1023 GLsizei
*length
, GLchar
*infoLog
)
1025 struct gl_shader_program
*shProg
1026 = _mesa_lookup_shader_program(ctx
, program
);
1028 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
1031 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
1036 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
1037 GLsizei
*length
, GLchar
*infoLog
)
1039 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1041 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
1044 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
1049 * Called via ctx->Driver.GetShaderSource().
1052 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
1053 GLsizei
*length
, GLchar
*sourceOut
)
1055 struct gl_shader
*sh
;
1056 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
1060 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
1065 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1071 case GL_FLOAT_MAT2x3
:
1075 case GL_FLOAT_MAT2x4
:
1083 case GL_FLOAT_MAT3x2
:
1087 case GL_FLOAT_MAT3x4
:
1095 case GL_FLOAT_MAT4x2
:
1099 case GL_FLOAT_MAT4x3
:
1110 * Determine the number of rows and columns occupied by a uniform
1111 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1112 * the number of rows = 1 and cols = number of elements in the vector.
1115 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
1116 GLint
*rows
, GLint
*cols
)
1118 get_matrix_dims(p
->DataType
, rows
, cols
);
1119 if (*rows
== 0 && *cols
== 0) {
1120 /* not a matrix type, probably a float or vector */
1126 *rows
= p
->Size
/ 4 + 1;
1127 if (p
->Size
% 4 == 0)
1130 *cols
= p
->Size
% 4;
1136 #define MAX_UNIFORM_ELEMENTS 16
1139 * Helper for GetUniformfv(), GetUniformiv()
1140 * Returns number of elements written to 'params' output.
1143 get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1146 struct gl_shader_program
*shProg
1147 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
1149 if (shProg
->Uniforms
&&
1150 location
>= 0 && location
< (GLint
) shProg
->Uniforms
->NumUniforms
) {
1152 const struct gl_program
*prog
= NULL
;
1154 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1156 prog
= &shProg
->VertexProgram
->Base
;
1159 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1161 prog
= &shProg
->FragmentProgram
->Base
;
1167 const struct gl_program_parameter
*p
=
1168 &prog
->Parameters
->Parameters
[progPos
];
1169 GLint rows
, cols
, i
, j
, k
;
1171 /* See uniformiv() below */
1172 assert(p
->Size
<= MAX_UNIFORM_ELEMENTS
);
1174 get_uniform_rows_cols(p
, &rows
, &cols
);
1177 for (i
= 0; i
< rows
; i
++) {
1178 for (j
= 0; j
< cols
; j
++ ) {
1179 params
[k
++] = prog
->Parameters
->ParameterValues
[progPos
+i
][j
];
1187 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1195 * Called via ctx->Driver.GetUniformfv().
1198 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1201 (void) get_uniformfv(ctx
, program
, location
, params
);
1206 * Called via ctx->Driver.GetUniformiv().
1209 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1212 GLfloat fparams
[MAX_UNIFORM_ELEMENTS
];
1213 GLuint n
= get_uniformfv(ctx
, program
, location
, fparams
);
1215 assert(n
<= MAX_UNIFORM_ELEMENTS
);
1216 for (i
= 0; i
< n
; i
++) {
1217 params
[i
] = (GLint
) fparams
[i
];
1223 * The value returned by GetUniformLocation actually encodes two things:
1224 * 1. the index into the prog->Uniforms[] array for the uniform
1225 * 2. an offset in the prog->ParameterValues[] array for specifying array
1226 * elements or structure fields.
1227 * This function merges those two values.
1230 merge_location_offset(GLint
*location
, GLint offset
)
1232 *location
= *location
| (offset
<< 16);
1237 * Seperate the uniform location and parameter offset. See above.
1240 split_location_offset(GLint
*location
, GLint
*offset
)
1242 *offset
= (*location
>> 16);
1243 *location
= *location
& 0xffff;
1248 * Called via ctx->Driver.GetUniformLocation().
1250 * The return value will encode two values, the uniform location and an
1251 * offset (used for arrays, structs).
1254 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1256 GLint offset
= 0, location
= -1;
1258 struct gl_shader_program
*shProg
=
1259 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1264 if (shProg
->LinkStatus
== GL_FALSE
) {
1265 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1269 /* XXX we should return -1 if the uniform was declared, but not
1273 /* XXX we need to be able to parse uniform names for structs and arrays
1280 /* handle 1-dimension arrays here... */
1281 char *c
= strchr(name
, '[');
1283 /* truncate name at [ */
1284 const GLint len
= c
- name
;
1285 GLchar
*newName
= _mesa_malloc(len
+ 1);
1287 return -1; /* out of mem */
1288 _mesa_memcpy(newName
, name
, len
);
1291 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
1292 if (location
>= 0) {
1293 const GLint element
= _mesa_atoi(c
+ 1);
1295 /* get type of the uniform array element */
1296 struct gl_program_parameter
*p
;
1297 p
= get_uniform_parameter(shProg
, location
);
1300 get_matrix_dims(p
->DataType
, &rows
, &cols
);
1303 offset
= element
* rows
;
1308 _mesa_free(newName
);
1313 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1316 if (location
>= 0) {
1317 merge_location_offset(&location
, offset
);
1326 * Called via ctx->Driver.ShaderSource()
1329 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1331 struct gl_shader
*sh
;
1333 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1337 /* free old shader source string and install new one */
1339 _mesa_free((void *) sh
->Source
);
1341 sh
->Source
= source
;
1342 sh
->CompileStatus
= GL_FALSE
;
1347 * Called via ctx->Driver.CompileShader()
1350 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1352 struct gl_shader
*sh
;
1354 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1358 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1363 * Called via ctx->Driver.LinkProgram()
1366 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1368 struct gl_shader_program
*shProg
;
1370 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1374 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1376 _slang_link(ctx
, program
, shProg
);
1381 * Called via ctx->Driver.UseProgram()
1384 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1386 struct gl_shader_program
*shProg
;
1388 if (ctx
->Shader
.CurrentProgram
&&
1389 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1394 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1397 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1401 if (!shProg
->LinkStatus
) {
1402 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUseProgram");
1410 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1416 * Update the vertex and fragment program's TexturesUsed arrays.
1419 update_textures_used(struct gl_program
*prog
)
1423 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1425 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1426 if (prog
->SamplersUsed
& (1 << s
)) {
1427 GLuint u
= prog
->SamplerUnits
[s
];
1428 GLuint t
= prog
->SamplerTargets
[s
];
1429 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1430 prog
->TexturesUsed
[u
] |= (1 << t
);
1437 is_sampler_type(GLenum type
)
1443 case GL_SAMPLER_CUBE
:
1444 case GL_SAMPLER_1D_SHADOW
:
1445 case GL_SAMPLER_2D_SHADOW
:
1446 case GL_SAMPLER_2D_RECT_ARB
:
1447 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
1448 case GL_SAMPLER_1D_ARRAY_EXT
:
1449 case GL_SAMPLER_2D_ARRAY_EXT
:
1458 * Check if the type given by userType is allowed to set a uniform of the
1459 * target type. Generally, equivalence is required, but setting Boolean
1460 * uniforms can be done with glUniformiv or glUniformfv.
1463 compatible_types(GLenum userType
, GLenum targetType
)
1465 if (userType
== targetType
)
1468 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1471 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1472 userType
== GL_INT_VEC2
))
1475 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1476 userType
== GL_INT_VEC3
))
1479 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1480 userType
== GL_INT_VEC4
))
1483 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1491 * Set the value of a program's uniform variable.
1492 * \param program the program whose uniform to update
1493 * \param index the index of the program parameter for the uniform
1494 * \param offset additional parameter slot offset (for arrays)
1495 * \param type the datatype of the uniform
1496 * \param count the number of uniforms to set
1497 * \param elems number of elements per uniform
1498 * \param values the new values
1501 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
1502 GLint index
, GLint offset
,
1503 GLenum type
, GLsizei count
, GLint elems
,
1506 assert(offset
>= 0);
1508 if (!compatible_types(type
,
1509 program
->Parameters
->Parameters
[index
].DataType
)) {
1510 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1514 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
1515 /* out of bounds! */
1519 if (program
->Parameters
->Parameters
[index
].Type
== PROGRAM_SAMPLER
) {
1520 /* This controls which texture unit which is used by a sampler */
1521 GLuint texUnit
, sampler
;
1523 /* data type for setting samplers must be int */
1524 if (type
!= GL_INT
|| count
!= 1) {
1525 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1526 "glUniform(only glUniform1i can be used "
1527 "to set sampler uniforms)");
1531 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[index
][0];
1532 texUnit
= ((GLuint
*) values
)[0];
1534 /* check that the sampler (tex unit index) is legal */
1535 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1536 _mesa_error(ctx
, GL_INVALID_VALUE
,
1537 "glUniform1(invalid sampler/tex unit index)");
1541 /* This maps a sampler to a texture unit: */
1542 program
->SamplerUnits
[sampler
] = texUnit
;
1543 update_textures_used(program
);
1545 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1548 /* ordinary uniform variable */
1550 GLint slots
= (program
->Parameters
->Parameters
[index
].Size
+ 3) / 4;
1552 if (count
* elems
> (GLint
) program
->Parameters
->Parameters
[index
].Size
) {
1553 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1560 for (k
= 0; k
< count
; k
++) {
1561 GLfloat
*uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
1562 if (is_integer_type(type
)) {
1563 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1564 for (i
= 0; i
< elems
; i
++) {
1565 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1569 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1570 for (i
= 0; i
< elems
; i
++) {
1571 uniformVal
[i
] = fValues
[i
];
1575 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1576 if (is_boolean_type(program
->Parameters
->Parameters
[index
].DataType
)) {
1577 for (i
= 0; i
< elems
; i
++) {
1578 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1587 * Called via ctx->Driver.Uniform().
1590 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1591 const GLvoid
*values
, GLenum type
)
1593 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1594 GLint elems
, offset
;
1596 if (!shProg
|| !shProg
->LinkStatus
) {
1597 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1602 return; /* The standard specifies this as a no-op */
1604 split_location_offset(&location
, &offset
);
1606 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1607 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1612 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1634 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1638 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1640 /* A uniform var may be used by both a vertex shader and a fragment
1641 * shader. We may need to update one or both shader's uniform here:
1643 if (shProg
->VertexProgram
) {
1644 /* convert uniform location to program parameter index */
1645 GLint index
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1647 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1648 index
, offset
, type
, count
, elems
, values
);
1652 if (shProg
->FragmentProgram
) {
1653 /* convert uniform location to program parameter index */
1654 GLint index
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1656 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1657 index
, offset
, type
, count
, elems
, values
);
1664 * Set a matrix-valued program parameter.
1667 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1668 GLuint index
, GLuint offset
,
1669 GLuint count
, GLuint rows
, GLuint cols
,
1670 GLboolean transpose
, const GLfloat
*values
)
1672 GLuint mat
, row
, col
;
1673 GLuint dst
= index
+ offset
, src
= 0;
1676 /* check that the number of rows, columns is correct */
1677 get_matrix_dims(program
->Parameters
->Parameters
[index
].DataType
, &nr
, &nc
);
1678 if (rows
!= nr
|| cols
!= nc
) {
1679 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1680 "glUniformMatrix(matrix size mismatch)");
1684 if (index
+ offset
> program
->Parameters
->Size
) {
1685 /* out of bounds! */
1690 * Note: the _columns_ of a matrix are stored in program registers, not
1691 * the rows. So, the loops below look a little funny.
1692 * XXX could optimize this a bit...
1695 /* loop over matrices */
1696 for (mat
= 0; mat
< count
; mat
++) {
1699 for (col
= 0; col
< cols
; col
++) {
1700 GLfloat
*v
= program
->Parameters
->ParameterValues
[dst
];
1701 for (row
= 0; row
< rows
; row
++) {
1703 v
[row
] = values
[src
+ row
* cols
+ col
];
1706 v
[row
] = values
[src
+ col
* rows
+ row
];
1712 src
+= rows
* cols
; /* next matrix */
1718 * Called by ctx->Driver.UniformMatrix().
1719 * Note: cols=2, rows=4 ==> array[2] of vec4
1722 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1723 GLenum matrixType
, GLint location
, GLsizei count
,
1724 GLboolean transpose
, const GLfloat
*values
)
1727 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1729 if (!shProg
|| !shProg
->LinkStatus
) {
1730 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1731 "glUniformMatrix(program not linked)");
1736 return; /* The standard specifies this as a no-op */
1738 split_location_offset(&location
, &offset
);
1740 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1741 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1744 if (values
== NULL
) {
1745 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1749 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1751 if (shProg
->VertexProgram
) {
1752 /* convert uniform location to program parameter index */
1753 GLint index
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1755 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1757 count
, rows
, cols
, transpose
, values
);
1761 if (shProg
->FragmentProgram
) {
1762 /* convert uniform location to program parameter index */
1763 GLint index
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1765 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1767 count
, rows
, cols
, transpose
, values
);
1774 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1776 struct gl_shader_program
*shProg
;
1778 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
1783 if (!shProg
->LinkStatus
) {
1784 shProg
->Validated
= GL_FALSE
;
1788 /* From the GL spec, a program is invalid if any of these are true:
1790 any two active samplers in the current program object are of
1791 different types, but refer to the same texture image unit,
1793 any active sampler in the current program object refers to a texture
1794 image unit where fixed-function fragment processing accesses a
1795 texture target that does not match the sampler type, or
1797 the sum of the number of active samplers in the program and the
1798 number of texture image units enabled for fixed-function fragment
1799 processing exceeds the combined limit on the total number of texture
1800 image units allowed.
1803 shProg
->Validated
= GL_TRUE
;
1808 * Plug in Mesa's GLSL functions into the device driver function table.
1811 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
1813 driver
->AttachShader
= _mesa_attach_shader
;
1814 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
1815 driver
->CompileShader
= _mesa_compile_shader
;
1816 driver
->CreateProgram
= _mesa_create_program
;
1817 driver
->CreateShader
= _mesa_create_shader
;
1818 driver
->DeleteProgram2
= _mesa_delete_program2
;
1819 driver
->DeleteShader
= _mesa_delete_shader
;
1820 driver
->DetachShader
= _mesa_detach_shader
;
1821 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
1822 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
1823 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
1824 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
1825 driver
->GetHandle
= _mesa_get_handle
;
1826 driver
->GetProgramiv
= _mesa_get_programiv
;
1827 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
1828 driver
->GetShaderiv
= _mesa_get_shaderiv
;
1829 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
1830 driver
->GetShaderSource
= _mesa_get_shader_source
;
1831 driver
->GetUniformfv
= _mesa_get_uniformfv
;
1832 driver
->GetUniformiv
= _mesa_get_uniformiv
;
1833 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
1834 driver
->IsProgram
= _mesa_is_program
;
1835 driver
->IsShader
= _mesa_is_shader
;
1836 driver
->LinkProgram
= _mesa_link_program
;
1837 driver
->ShaderSource
= _mesa_shader_source
;
1838 driver
->Uniform
= _mesa_uniform
;
1839 driver
->UniformMatrix
= _mesa_uniform_matrix
;
1840 driver
->UseProgram
= _mesa_use_program
;
1841 driver
->ValidateProgram
= _mesa_validate_program
;