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 _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 * As above, but record an error if program is not found.
218 static struct gl_shader_program
*
219 _mesa_lookup_shader_program_err(GLcontext
*ctx
, GLuint name
,
223 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
227 struct gl_shader_program
*shProg
= (struct gl_shader_program
*)
228 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
230 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
233 if (shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
234 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
245 * Allocate a new gl_shader object, initialize it.
248 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
250 struct gl_shader
*shader
;
251 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
252 shader
= CALLOC_STRUCT(gl_shader
);
256 shader
->RefCount
= 1;
263 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
266 _mesa_free((void *) sh
->Source
);
268 _mesa_free(sh
->InfoLog
);
269 _mesa_reference_program(ctx
, &sh
->Program
, NULL
);
275 * Set ptr to point to sh.
276 * If ptr is pointing to another shader, decrement its refcount (and delete
277 * if refcount hits zero).
278 * Then set ptr to point to sh, incrementing its refcount.
280 /* XXX this could be static */
282 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
283 struct gl_shader
*sh
)
291 /* Unreference the old shader */
292 GLboolean deleteFlag
= GL_FALSE
;
293 struct gl_shader
*old
= *ptr
;
295 ASSERT(old
->RefCount
> 0);
297 /*printf("SHADER DECR %p (%d) to %d\n",
298 (void*) old, old->Name, old->RefCount);*/
299 deleteFlag
= (old
->RefCount
== 0);
302 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
303 _mesa_free_shader(ctx
, old
);
313 /*printf("SHADER INCR %p (%d) to %d\n",
314 (void*) sh, sh->Name, sh->RefCount);*/
321 * Lookup a GLSL shader object.
324 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
327 struct gl_shader
*sh
= (struct gl_shader
*)
328 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
329 /* Note that both gl_shader and gl_shader_program objects are kept
330 * in the same hash table. Check the object's type to be sure it's
331 * what we're expecting.
333 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
343 * As above, but record an error if shader is not found.
345 static struct gl_shader
*
346 _mesa_lookup_shader_err(GLcontext
*ctx
, GLuint name
, const char *caller
)
349 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
353 struct gl_shader
*sh
= (struct gl_shader
*)
354 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
356 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
359 if (sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
360 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
370 * Initialize context's shader state.
373 _mesa_init_shader_state(GLcontext
* ctx
)
375 /* Device drivers may override these to control what kind of instructions
376 * are generated by the GLSL compiler.
378 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
379 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
380 ctx
->Shader
.EmitComments
= GL_FALSE
;
385 * Free the per-context shader-related state.
388 _mesa_free_shader_state(GLcontext
*ctx
)
390 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
395 * Copy string from <src> to <dst>, up to maxLength characters, returning
396 * length of <dst> in <length>.
397 * \param src the strings source
398 * \param maxLength max chars to copy
399 * \param length returns number of chars copied
400 * \param dst the string destination
403 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
406 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
416 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
418 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
419 return shProg
? GL_TRUE
: GL_FALSE
;
424 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
426 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
427 return shader
? GL_TRUE
: GL_FALSE
;
432 * Called via ctx->Driver.AttachShader()
435 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
437 struct gl_shader_program
*shProg
;
438 struct gl_shader
*sh
;
441 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
445 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
450 n
= shProg
->NumShaders
;
451 for (i
= 0; i
< n
; i
++) {
452 if (shProg
->Shaders
[i
] == sh
) {
453 /* already attached */
459 shProg
->Shaders
= (struct gl_shader
**)
460 _mesa_realloc(shProg
->Shaders
,
461 n
* sizeof(struct gl_shader
*),
462 (n
+ 1) * sizeof(struct gl_shader
*));
463 if (!shProg
->Shaders
) {
464 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
469 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
470 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
471 shProg
->NumShaders
++;
476 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
479 struct gl_shader_program
*shProg
480 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
486 if (!shProg
->LinkStatus
) {
487 _mesa_error(ctx
, GL_INVALID_OPERATION
,
488 "glGetAttribLocation(program not linked)");
495 if (shProg
->Attributes
) {
496 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
498 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
506 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
509 struct gl_shader_program
*shProg
;
510 const GLint size
= -1; /* unknown size */
514 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
515 "glBindAttribLocation");
523 if (strncmp(name
, "gl_", 3) == 0) {
524 _mesa_error(ctx
, GL_INVALID_OPERATION
,
525 "glBindAttribLocation(illegal name)");
529 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
530 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
534 if (shProg
->LinkStatus
) {
535 /* get current index/location for the attribute */
536 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
542 /* this will replace the current value if it's already in the list */
543 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, datatype
, index
);
545 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
548 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
549 /* If the index changed, need to search/replace references to that attribute
550 * in the vertex program.
552 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
558 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
560 struct gl_shader
*sh
;
563 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
566 case GL_FRAGMENT_SHADER
:
567 case GL_VERTEX_SHADER
:
568 sh
= _mesa_new_shader(ctx
, name
, type
);
571 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
575 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
582 _mesa_create_program(GLcontext
*ctx
)
585 struct gl_shader_program
*shProg
;
587 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
588 shProg
= _mesa_new_shader_program(ctx
, name
);
590 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
592 assert(shProg
->RefCount
== 1);
599 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
603 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
606 * NOTE: deleting shaders/programs works a bit differently than
607 * texture objects (and buffer objects, etc). Shader/program
608 * handles/IDs exist in the hash table until the object is really
609 * deleted (refcount==0). With texture objects, the handle/ID is
610 * removed from the hash table in glDeleteTextures() while the tex
611 * object itself might linger until its refcount goes to zero.
613 struct gl_shader_program
*shProg
;
615 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
619 shProg
->DeletePending
= GL_TRUE
;
621 /* effectively, decr shProg's refcount */
622 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
627 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
629 struct gl_shader
*sh
;
631 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
635 sh
->DeletePending
= GL_TRUE
;
637 /* effectively, decr sh's refcount */
638 _mesa_reference_shader(ctx
, &sh
, NULL
);
643 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
645 struct gl_shader_program
*shProg
;
649 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
653 n
= shProg
->NumShaders
;
655 for (i
= 0; i
< n
; i
++) {
656 if (shProg
->Shaders
[i
]->Name
== shader
) {
658 struct gl_shader
**newList
;
661 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
663 /* alloc new, smaller array */
664 newList
= (struct gl_shader
**)
665 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
667 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
670 for (j
= 0; j
< i
; j
++) {
671 newList
[j
] = shProg
->Shaders
[j
];
674 newList
[j
++] = shProg
->Shaders
[i
];
675 _mesa_free(shProg
->Shaders
);
677 shProg
->Shaders
= newList
;
678 shProg
->NumShaders
= n
- 1;
683 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
684 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
685 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
686 assert(shProg
->Shaders
[j
]->RefCount
> 0);
698 if (_mesa_is_shader(ctx
, shader
))
699 err
= GL_INVALID_OPERATION
;
700 else if (_mesa_is_program(ctx
, shader
))
701 err
= GL_INVALID_OPERATION
;
703 err
= GL_INVALID_VALUE
;
704 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
711 sizeof_glsl_type(GLenum type
)
731 case GL_FLOAT_MAT2x3
:
732 case GL_FLOAT_MAT2x4
:
733 return 8; /* two float[4] vectors */
735 case GL_FLOAT_MAT3x2
:
736 case GL_FLOAT_MAT3x4
:
737 return 12; /* three float[4] vectors */
739 case GL_FLOAT_MAT4x2
:
740 case GL_FLOAT_MAT4x3
:
741 return 16; /* four float[4] vectors */
743 _mesa_problem(NULL
, "Invalid type in sizeof_glsl_type()");
750 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
751 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
752 GLenum
*type
, GLchar
*nameOut
)
754 struct gl_shader_program
*shProg
;
756 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
760 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
761 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
765 copy_string(nameOut
, maxLength
, length
,
766 shProg
->Attributes
->Parameters
[index
].Name
);
768 *size
= shProg
->Attributes
->Parameters
[index
].Size
769 / sizeof_glsl_type(shProg
->Attributes
->Parameters
[index
].DataType
);
771 *type
= shProg
->Attributes
->Parameters
[index
].DataType
;
776 * Called via ctx->Driver.GetActiveUniform().
779 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
780 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
781 GLenum
*type
, GLchar
*nameOut
)
783 const struct gl_shader_program
*shProg
;
784 const struct gl_program
*prog
;
787 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
791 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
792 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
796 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
798 prog
= &shProg
->VertexProgram
->Base
;
801 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
803 prog
= &shProg
->FragmentProgram
->Base
;
807 if (!prog
|| progPos
< 0)
808 return; /* should never happen */
811 copy_string(nameOut
, maxLength
, length
,
812 prog
->Parameters
->Parameters
[progPos
].Name
);
814 *size
= prog
->Parameters
->Parameters
[progPos
].Size
815 / sizeof_glsl_type(prog
->Parameters
->Parameters
[progPos
].DataType
);
817 *type
= prog
->Parameters
->Parameters
[progPos
].DataType
;
822 * Called via ctx->Driver.GetAttachedShaders().
825 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
826 GLsizei
*count
, GLuint
*obj
)
828 struct gl_shader_program
*shProg
=
829 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
832 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
833 obj
[i
] = shProg
->Shaders
[i
]->Name
;
842 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
845 GET_CURRENT_CONTEXT(ctx
);
848 case GL_PROGRAM_OBJECT_ARB
:
850 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
853 return (**pro
)._container
._generic
.
854 GetName((struct gl2_generic_intf
**) (pro
));
858 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
866 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
867 GLenum pname
, GLint
*params
)
869 struct gl_shader_program
*shProg
870 = _mesa_lookup_shader_program(ctx
, program
);
873 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
878 case GL_DELETE_STATUS
:
879 *params
= shProg
->DeletePending
;
882 *params
= shProg
->LinkStatus
;
884 case GL_VALIDATE_STATUS
:
885 *params
= shProg
->Validated
;
887 case GL_INFO_LOG_LENGTH
:
888 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
890 case GL_ATTACHED_SHADERS
:
891 *params
= shProg
->NumShaders
;
893 case GL_ACTIVE_ATTRIBUTES
:
894 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
896 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
897 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
900 case GL_ACTIVE_UNIFORMS
:
901 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
903 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
904 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
906 (*params
)++; /* add one for terminating zero */
909 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
916 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
918 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
926 *params
= shader
->Type
;
928 case GL_DELETE_STATUS
:
929 *params
= shader
->DeletePending
;
931 case GL_COMPILE_STATUS
:
932 *params
= shader
->CompileStatus
;
934 case GL_INFO_LOG_LENGTH
:
935 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
937 case GL_SHADER_SOURCE_LENGTH
:
938 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
941 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
948 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
949 GLsizei
*length
, GLchar
*infoLog
)
951 struct gl_shader_program
*shProg
952 = _mesa_lookup_shader_program(ctx
, program
);
954 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
957 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
962 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
963 GLsizei
*length
, GLchar
*infoLog
)
965 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
967 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
970 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
975 * Called via ctx->Driver.GetShaderSource().
978 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
979 GLsizei
*length
, GLchar
*sourceOut
)
981 struct gl_shader
*sh
;
982 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
986 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
990 #define MAX_UNIFORM_ELEMENTS 16
993 * Helper for GetUniformfv(), GetUniformiv()
994 * Returns number of elements written to 'params' output.
997 get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1000 struct gl_shader_program
*shProg
1001 = _mesa_lookup_shader_program(ctx
, program
);
1003 if (shProg
->Uniforms
&&
1004 location
>= 0 && location
< shProg
->Uniforms
->NumUniforms
) {
1007 const struct gl_program
*prog
= NULL
;
1009 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1011 prog
= &shProg
->VertexProgram
->Base
;
1014 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1016 prog
= &shProg
->FragmentProgram
->Base
;
1022 /* See uniformiv() below */
1023 assert(prog
->Parameters
->Parameters
[progPos
].Size
<= MAX_UNIFORM_ELEMENTS
);
1025 for (i
= 0; i
< prog
->Parameters
->Parameters
[progPos
].Size
; i
++) {
1026 params
[i
] = prog
->Parameters
->ParameterValues
[progPos
][i
];
1028 return prog
->Parameters
->Parameters
[progPos
].Size
;
1032 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1036 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1043 * Called via ctx->Driver.GetUniformfv().
1046 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1049 (void) get_uniformfv(ctx
, program
, location
, params
);
1054 * Called via ctx->Driver.GetUniformiv().
1057 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1060 GLfloat fparams
[MAX_UNIFORM_ELEMENTS
];
1061 GLuint n
= get_uniformfv(ctx
, program
, location
, fparams
);
1063 assert(n
<= MAX_UNIFORM_ELEMENTS
);
1064 for (i
= 0; i
< n
; i
++) {
1065 params
[i
] = (GLint
) fparams
[i
];
1071 * Called via ctx->Driver.GetUniformLocation().
1074 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1076 struct gl_shader_program
*shProg
=
1077 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1082 if (shProg
->LinkStatus
== GL_FALSE
) {
1083 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1087 /* XXX we should return -1 if the uniform was declared, but not
1091 return _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1097 * Called via ctx->Driver.ShaderSource()
1100 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1102 struct gl_shader
*sh
;
1104 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1108 /* free old shader source string and install new one */
1110 _mesa_free((void *) sh
->Source
);
1112 sh
->Source
= source
;
1113 sh
->CompileStatus
= GL_FALSE
;
1118 * Called via ctx->Driver.CompileShader()
1121 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1123 struct gl_shader
*sh
;
1125 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1129 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1134 * Called via ctx->Driver.LinkProgram()
1137 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1139 struct gl_shader_program
*shProg
;
1141 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1145 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1147 _slang_link(ctx
, program
, shProg
);
1152 * Called via ctx->Driver.UseProgram()
1155 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1157 struct gl_shader_program
*shProg
;
1159 if (ctx
->Shader
.CurrentProgram
&&
1160 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1165 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1168 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1172 if (!shProg
->LinkStatus
) {
1173 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUseProgram");
1181 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1187 * Update the vertex and fragment program's TexturesUsed arrays.
1190 update_textures_used(struct gl_program
*prog
)
1194 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1196 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1197 if (prog
->SamplersUsed
& (1 << s
)) {
1198 GLuint u
= prog
->SamplerUnits
[s
];
1199 GLuint t
= prog
->SamplerTargets
[s
];
1200 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1201 prog
->TexturesUsed
[u
] |= (1 << t
);
1208 is_sampler_type(GLenum type
)
1214 case GL_SAMPLER_CUBE
:
1215 case GL_SAMPLER_1D_SHADOW
:
1216 case GL_SAMPLER_2D_SHADOW
:
1217 case GL_SAMPLER_2D_RECT_ARB
:
1218 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
1219 case GL_SAMPLER_1D_ARRAY_EXT
:
1220 case GL_SAMPLER_2D_ARRAY_EXT
:
1229 * Check if the type given by userType is allowed to set a uniform of the
1230 * target type. Generally, equivalence is required, but setting Boolean
1231 * uniforms can be done with glUniformiv or glUniformfv.
1234 compatible_types(GLenum userType
, GLenum targetType
)
1236 if (userType
== targetType
)
1239 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1242 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1243 userType
== GL_INT_VEC2
))
1246 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1247 userType
== GL_INT_VEC3
))
1250 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1251 userType
== GL_INT_VEC4
))
1254 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1262 * Set the value of a program's uniform variable.
1263 * \param program the program whose uniform to update
1264 * \param location the location/index of the uniform
1265 * \param type the datatype of the uniform
1266 * \param count the number of uniforms to set
1267 * \param elems number of elements per uniform
1268 * \param values the new values
1271 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
, GLint location
,
1272 GLenum type
, GLsizei count
, GLint elems
, const void *values
)
1274 if (!compatible_types(type
,
1275 program
->Parameters
->Parameters
[location
].DataType
)) {
1276 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1280 if (program
->Parameters
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1281 /* This controls which texture unit which is used by a sampler */
1282 GLuint texUnit
, sampler
;
1284 /* data type for setting samplers must be int */
1285 if (type
!= GL_INT
|| count
!= 1) {
1286 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1287 "glUniform(only glUniform1i can be used "
1288 "to set sampler uniforms)");
1292 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[location
][0];
1293 texUnit
= ((GLuint
*) values
)[0];
1295 /* check that the sampler (tex unit index) is legal */
1296 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1297 _mesa_error(ctx
, GL_INVALID_VALUE
,
1298 "glUniform1(invalid sampler/tex unit index)");
1302 /* This maps a sampler to a texture unit: */
1303 program
->SamplerUnits
[sampler
] = texUnit
;
1304 update_textures_used(program
);
1306 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1309 /* ordinary uniform variable */
1312 if (count
* elems
> program
->Parameters
->Parameters
[location
].Size
) {
1313 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1317 for (k
= 0; k
< count
; k
++) {
1318 GLfloat
*uniformVal
= program
->Parameters
->ParameterValues
[location
+ k
];
1319 if (type
== GL_INT
||
1320 type
== GL_INT_VEC2
||
1321 type
== GL_INT_VEC3
||
1322 type
== GL_INT_VEC4
) {
1323 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1324 for (i
= 0; i
< elems
; i
++) {
1325 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1329 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1330 for (i
= 0; i
< elems
; i
++) {
1331 uniformVal
[i
] = fValues
[i
];
1340 * Called via ctx->Driver.Uniform().
1343 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1344 const GLvoid
*values
, GLenum type
)
1346 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1349 if (!shProg
|| !shProg
->LinkStatus
) {
1350 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1355 return; /* The standard specifies this as a no-op */
1357 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1358 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1363 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1385 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1389 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1391 /* A uniform var may be used by both a vertex shader and a fragment
1392 * shader. We may need to update one or both shader's uniform here:
1394 if (shProg
->VertexProgram
) {
1395 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1397 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1398 loc
, type
, count
, elems
, values
);
1402 if (shProg
->FragmentProgram
) {
1403 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1405 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1406 loc
, type
, count
, elems
, values
);
1413 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1419 case GL_FLOAT_MAT2x3
:
1423 case GL_FLOAT_MAT2x4
:
1431 case GL_FLOAT_MAT3x2
:
1435 case GL_FLOAT_MAT3x4
:
1443 case GL_FLOAT_MAT4x2
:
1447 case GL_FLOAT_MAT4x3
:
1458 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1459 GLuint location
, GLuint count
,
1460 GLuint rows
, GLuint cols
,
1461 GLboolean transpose
, const GLfloat
*values
)
1463 GLuint mat
, row
, col
;
1464 GLuint dst
= location
, src
= 0;
1467 /* check that the number of rows, columns is correct */
1468 get_matrix_dims(program
->Parameters
->Parameters
[location
].DataType
, &nr
, &nc
);
1469 if (rows
!= nr
|| cols
!= nc
) {
1470 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1471 "glUniformMatrix(matrix size mismatch");
1476 * Note: the _columns_ of a matrix are stored in program registers, not
1477 * the rows. So, the loops below look a little funny.
1478 * XXX could optimize this a bit...
1481 /* loop over matrices */
1482 for (mat
= 0; mat
< count
; mat
++) {
1485 for (col
= 0; col
< cols
; col
++) {
1486 GLfloat
*v
= program
->Parameters
->ParameterValues
[dst
];
1487 for (row
= 0; row
< rows
; row
++) {
1489 v
[row
] = values
[src
+ row
* cols
+ col
];
1492 v
[row
] = values
[src
+ col
* rows
+ row
];
1498 src
+= rows
* cols
; /* next matrix */
1504 * Called by ctx->Driver.UniformMatrix().
1505 * Note: cols=2, rows=4 ==> array[2] of vec4
1508 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1509 GLenum matrixType
, GLint location
, GLsizei count
,
1510 GLboolean transpose
, const GLfloat
*values
)
1512 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1514 if (!shProg
|| !shProg
->LinkStatus
) {
1515 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1516 "glUniformMatrix(program not linked)");
1521 return; /* The standard specifies this as a no-op */
1523 if (location
< 0 || location
>= shProg
->Uniforms
->NumUniforms
) {
1524 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1527 if (values
== NULL
) {
1528 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1532 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1534 if (shProg
->VertexProgram
) {
1535 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1537 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1538 loc
, count
, rows
, cols
, transpose
, values
);
1542 if (shProg
->FragmentProgram
) {
1543 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1545 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1546 loc
, count
, rows
, cols
, transpose
, values
);
1553 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1555 struct gl_shader_program
*shProg
;
1557 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
1562 if (!shProg
->LinkStatus
) {
1563 shProg
->Validated
= GL_FALSE
;
1567 /* From the GL spec, a program is invalid if any of these are true:
1569 any two active samplers in the current program object are of
1570 different types, but refer to the same texture image unit,
1572 any active sampler in the current program object refers to a texture
1573 image unit where fixed-function fragment processing accesses a
1574 texture target that does not match the sampler type, or
1576 the sum of the number of active samplers in the program and the
1577 number of texture image units enabled for fixed-function fragment
1578 processing exceeds the combined limit on the total number of texture
1579 image units allowed.
1582 shProg
->Validated
= GL_TRUE
;
1587 * Plug in Mesa's GLSL functions into the device driver function table.
1590 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
1592 driver
->AttachShader
= _mesa_attach_shader
;
1593 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
1594 driver
->CompileShader
= _mesa_compile_shader
;
1595 driver
->CreateProgram
= _mesa_create_program
;
1596 driver
->CreateShader
= _mesa_create_shader
;
1597 driver
->DeleteProgram2
= _mesa_delete_program2
;
1598 driver
->DeleteShader
= _mesa_delete_shader
;
1599 driver
->DetachShader
= _mesa_detach_shader
;
1600 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
1601 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
1602 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
1603 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
1604 driver
->GetHandle
= _mesa_get_handle
;
1605 driver
->GetProgramiv
= _mesa_get_programiv
;
1606 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
1607 driver
->GetShaderiv
= _mesa_get_shaderiv
;
1608 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
1609 driver
->GetShaderSource
= _mesa_get_shader_source
;
1610 driver
->GetUniformfv
= _mesa_get_uniformfv
;
1611 driver
->GetUniformiv
= _mesa_get_uniformiv
;
1612 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
1613 driver
->IsProgram
= _mesa_is_program
;
1614 driver
->IsShader
= _mesa_is_shader
;
1615 driver
->LinkProgram
= _mesa_link_program
;
1616 driver
->ShaderSource
= _mesa_shader_source
;
1617 driver
->Uniform
= _mesa_uniform
;
1618 driver
->UniformMatrix
= _mesa_uniform_matrix
;
1619 driver
->UseProgram
= _mesa_use_program
;
1620 driver
->ValidateProgram
= _mesa_validate_program
;