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
)
267 _mesa_free((void *) sh
->Source
);
269 _mesa_free(sh
->InfoLog
);
270 for (i
= 0; i
< sh
->NumPrograms
; i
++)
271 _mesa_reference_program(ctx
, &sh
->Programs
[i
], NULL
);
273 _mesa_free(sh
->Programs
);
279 * Set ptr to point to sh.
280 * If ptr is pointing to another shader, decrement its refcount (and delete
281 * if refcount hits zero).
282 * Then set ptr to point to sh, incrementing its refcount.
284 /* XXX this could be static */
286 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
287 struct gl_shader
*sh
)
295 /* Unreference the old shader */
296 GLboolean deleteFlag
= GL_FALSE
;
297 struct gl_shader
*old
= *ptr
;
299 ASSERT(old
->RefCount
> 0);
301 /*printf("SHADER DECR %p (%d) to %d\n",
302 (void*) old, old->Name, old->RefCount);*/
303 deleteFlag
= (old
->RefCount
== 0);
306 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
307 _mesa_free_shader(ctx
, old
);
317 /*printf("SHADER INCR %p (%d) to %d\n",
318 (void*) sh, sh->Name, sh->RefCount);*/
325 * Lookup a GLSL shader object.
328 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
331 struct gl_shader
*sh
= (struct gl_shader
*)
332 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
333 /* Note that both gl_shader and gl_shader_program objects are kept
334 * in the same hash table. Check the object's type to be sure it's
335 * what we're expecting.
337 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
347 * As above, but record an error if shader is not found.
349 static struct gl_shader
*
350 _mesa_lookup_shader_err(GLcontext
*ctx
, GLuint name
, const char *caller
)
353 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
357 struct gl_shader
*sh
= (struct gl_shader
*)
358 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
360 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
363 if (sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
364 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
374 * Initialize context's shader state.
377 _mesa_init_shader_state(GLcontext
* ctx
)
379 /* Device drivers may override these to control what kind of instructions
380 * are generated by the GLSL compiler.
382 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
383 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
384 ctx
->Shader
.EmitComments
= GL_FALSE
;
389 * Free the per-context shader-related state.
392 _mesa_free_shader_state(GLcontext
*ctx
)
394 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
399 * Copy string from <src> to <dst>, up to maxLength characters, returning
400 * length of <dst> in <length>.
401 * \param src the strings source
402 * \param maxLength max chars to copy
403 * \param length returns number of chars copied
404 * \param dst the string destination
407 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
410 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
420 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
422 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
423 return shProg
? GL_TRUE
: GL_FALSE
;
428 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
430 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
431 return shader
? GL_TRUE
: GL_FALSE
;
436 * Called via ctx->Driver.AttachShader()
439 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
441 struct gl_shader_program
*shProg
;
442 struct gl_shader
*sh
;
445 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
449 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
454 n
= shProg
->NumShaders
;
455 for (i
= 0; i
< n
; i
++) {
456 if (shProg
->Shaders
[i
] == sh
) {
457 /* already attached */
463 shProg
->Shaders
= (struct gl_shader
**)
464 _mesa_realloc(shProg
->Shaders
,
465 n
* sizeof(struct gl_shader
*),
466 (n
+ 1) * sizeof(struct gl_shader
*));
467 if (!shProg
->Shaders
) {
468 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
473 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
474 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
475 shProg
->NumShaders
++;
480 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
483 struct gl_shader_program
*shProg
484 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
490 if (!shProg
->LinkStatus
) {
491 _mesa_error(ctx
, GL_INVALID_OPERATION
,
492 "glGetAttribLocation(program not linked)");
499 if (shProg
->Attributes
) {
500 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
502 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
510 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
513 struct gl_shader_program
*shProg
;
514 const GLint size
= -1; /* unknown size */
518 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
519 "glBindAttribLocation");
527 if (strncmp(name
, "gl_", 3) == 0) {
528 _mesa_error(ctx
, GL_INVALID_OPERATION
,
529 "glBindAttribLocation(illegal name)");
533 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
534 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
538 if (shProg
->LinkStatus
) {
539 /* get current index/location for the attribute */
540 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");
553 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
554 /* If the index changed, need to search/replace references to that attribute
555 * in the vertex program.
557 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
563 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
565 struct gl_shader
*sh
;
568 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
571 case GL_FRAGMENT_SHADER
:
572 case GL_VERTEX_SHADER
:
573 sh
= _mesa_new_shader(ctx
, name
, type
);
576 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
580 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
587 _mesa_create_program(GLcontext
*ctx
)
590 struct gl_shader_program
*shProg
;
592 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
593 shProg
= _mesa_new_shader_program(ctx
, name
);
595 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
597 assert(shProg
->RefCount
== 1);
604 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
608 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
611 * NOTE: deleting shaders/programs works a bit differently than
612 * texture objects (and buffer objects, etc). Shader/program
613 * handles/IDs exist in the hash table until the object is really
614 * deleted (refcount==0). With texture objects, the handle/ID is
615 * removed from the hash table in glDeleteTextures() while the tex
616 * object itself might linger until its refcount goes to zero.
618 struct gl_shader_program
*shProg
;
620 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
624 shProg
->DeletePending
= GL_TRUE
;
626 /* effectively, decr shProg's refcount */
627 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
632 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
634 struct gl_shader
*sh
;
636 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
640 sh
->DeletePending
= GL_TRUE
;
642 /* effectively, decr sh's refcount */
643 _mesa_reference_shader(ctx
, &sh
, NULL
);
648 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
650 struct gl_shader_program
*shProg
;
654 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
658 n
= shProg
->NumShaders
;
660 for (i
= 0; i
< n
; i
++) {
661 if (shProg
->Shaders
[i
]->Name
== shader
) {
663 struct gl_shader
**newList
;
666 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
668 /* alloc new, smaller array */
669 newList
= (struct gl_shader
**)
670 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
672 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
675 for (j
= 0; j
< i
; j
++) {
676 newList
[j
] = shProg
->Shaders
[j
];
679 newList
[j
++] = shProg
->Shaders
[i
];
680 _mesa_free(shProg
->Shaders
);
682 shProg
->Shaders
= newList
;
683 shProg
->NumShaders
= n
- 1;
688 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
689 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
690 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
691 assert(shProg
->Shaders
[j
]->RefCount
> 0);
703 if (_mesa_is_shader(ctx
, shader
))
704 err
= GL_INVALID_OPERATION
;
705 else if (_mesa_is_program(ctx
, shader
))
706 err
= GL_INVALID_OPERATION
;
708 err
= GL_INVALID_VALUE
;
709 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
716 sizeof_glsl_type(GLenum type
)
736 case GL_FLOAT_MAT2x3
:
737 case GL_FLOAT_MAT2x4
:
738 return 8; /* two float[4] vectors */
740 case GL_FLOAT_MAT3x2
:
741 case GL_FLOAT_MAT3x4
:
742 return 12; /* three float[4] vectors */
744 case GL_FLOAT_MAT4x2
:
745 case GL_FLOAT_MAT4x3
:
746 return 16; /* four float[4] vectors */
748 _mesa_problem(NULL
, "Invalid type in sizeof_glsl_type()");
755 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
756 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
757 GLenum
*type
, GLchar
*nameOut
)
759 struct gl_shader_program
*shProg
;
761 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
765 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
766 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
770 copy_string(nameOut
, maxLength
, length
,
771 shProg
->Attributes
->Parameters
[index
].Name
);
773 *size
= shProg
->Attributes
->Parameters
[index
].Size
774 / sizeof_glsl_type(shProg
->Attributes
->Parameters
[index
].DataType
);
776 *type
= shProg
->Attributes
->Parameters
[index
].DataType
;
781 * Called via ctx->Driver.GetActiveUniform().
784 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
785 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
786 GLenum
*type
, GLchar
*nameOut
)
788 const struct gl_shader_program
*shProg
;
789 const struct gl_program
*prog
;
792 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
796 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
797 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
801 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
803 prog
= &shProg
->VertexProgram
->Base
;
806 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
808 prog
= &shProg
->FragmentProgram
->Base
;
812 if (!prog
|| progPos
< 0)
813 return; /* should never happen */
816 copy_string(nameOut
, maxLength
, length
,
817 prog
->Parameters
->Parameters
[progPos
].Name
);
819 *size
= prog
->Parameters
->Parameters
[progPos
].Size
820 / sizeof_glsl_type(prog
->Parameters
->Parameters
[progPos
].DataType
);
822 *type
= prog
->Parameters
->Parameters
[progPos
].DataType
;
827 * Called via ctx->Driver.GetAttachedShaders().
830 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
831 GLsizei
*count
, GLuint
*obj
)
833 struct gl_shader_program
*shProg
=
834 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
837 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
838 obj
[i
] = shProg
->Shaders
[i
]->Name
;
847 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
850 GET_CURRENT_CONTEXT(ctx
);
853 case GL_PROGRAM_OBJECT_ARB
:
855 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
858 return (**pro
)._container
._generic
.
859 GetName((struct gl2_generic_intf
**) (pro
));
863 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
871 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
872 GLenum pname
, GLint
*params
)
874 struct gl_shader_program
*shProg
875 = _mesa_lookup_shader_program(ctx
, program
);
878 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
883 case GL_DELETE_STATUS
:
884 *params
= shProg
->DeletePending
;
887 *params
= shProg
->LinkStatus
;
889 case GL_VALIDATE_STATUS
:
890 *params
= shProg
->Validated
;
892 case GL_INFO_LOG_LENGTH
:
893 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
895 case GL_ATTACHED_SHADERS
:
896 *params
= shProg
->NumShaders
;
898 case GL_ACTIVE_ATTRIBUTES
:
899 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
901 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
902 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
905 case GL_ACTIVE_UNIFORMS
:
906 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
908 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
909 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
911 (*params
)++; /* add one for terminating zero */
914 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
921 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
923 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
931 *params
= shader
->Type
;
933 case GL_DELETE_STATUS
:
934 *params
= shader
->DeletePending
;
936 case GL_COMPILE_STATUS
:
937 *params
= shader
->CompileStatus
;
939 case GL_INFO_LOG_LENGTH
:
940 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
942 case GL_SHADER_SOURCE_LENGTH
:
943 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
946 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
953 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
954 GLsizei
*length
, GLchar
*infoLog
)
956 struct gl_shader_program
*shProg
957 = _mesa_lookup_shader_program(ctx
, program
);
959 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
962 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
967 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
968 GLsizei
*length
, GLchar
*infoLog
)
970 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
972 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
975 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
980 * Called via ctx->Driver.GetShaderSource().
983 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
984 GLsizei
*length
, GLchar
*sourceOut
)
986 struct gl_shader
*sh
;
987 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
991 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
995 #define MAX_UNIFORM_ELEMENTS 16
998 * Helper for GetUniformfv(), GetUniformiv()
999 * Returns number of elements written to 'params' output.
1002 get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1005 struct gl_shader_program
*shProg
1006 = _mesa_lookup_shader_program(ctx
, program
);
1008 if (shProg
->Uniforms
&&
1009 location
>= 0 && location
< (GLint
) shProg
->Uniforms
->NumUniforms
) {
1012 const struct gl_program
*prog
= NULL
;
1014 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1016 prog
= &shProg
->VertexProgram
->Base
;
1019 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1021 prog
= &shProg
->FragmentProgram
->Base
;
1027 /* See uniformiv() below */
1028 assert(prog
->Parameters
->Parameters
[progPos
].Size
<= MAX_UNIFORM_ELEMENTS
);
1030 for (i
= 0; i
< prog
->Parameters
->Parameters
[progPos
].Size
; i
++) {
1031 params
[i
] = prog
->Parameters
->ParameterValues
[progPos
][i
];
1033 return prog
->Parameters
->Parameters
[progPos
].Size
;
1037 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1041 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1048 * Called via ctx->Driver.GetUniformfv().
1051 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1054 (void) get_uniformfv(ctx
, program
, location
, params
);
1059 * Called via ctx->Driver.GetUniformiv().
1062 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1065 GLfloat fparams
[MAX_UNIFORM_ELEMENTS
];
1066 GLuint n
= get_uniformfv(ctx
, program
, location
, fparams
);
1068 assert(n
<= MAX_UNIFORM_ELEMENTS
);
1069 for (i
= 0; i
< n
; i
++) {
1070 params
[i
] = (GLint
) fparams
[i
];
1076 * Called via ctx->Driver.GetUniformLocation().
1079 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1081 struct gl_shader_program
*shProg
=
1082 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1087 if (shProg
->LinkStatus
== GL_FALSE
) {
1088 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1092 /* XXX we should return -1 if the uniform was declared, but not
1096 return _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1102 * Called via ctx->Driver.ShaderSource()
1105 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1107 struct gl_shader
*sh
;
1109 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1113 /* free old shader source string and install new one */
1115 _mesa_free((void *) sh
->Source
);
1117 sh
->Source
= source
;
1118 sh
->CompileStatus
= GL_FALSE
;
1123 * Called via ctx->Driver.CompileShader()
1126 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1128 struct gl_shader
*sh
;
1130 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1134 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1139 * Called via ctx->Driver.LinkProgram()
1142 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1144 struct gl_shader_program
*shProg
;
1146 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1150 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1152 _slang_link(ctx
, program
, shProg
);
1157 * Called via ctx->Driver.UseProgram()
1160 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1162 struct gl_shader_program
*shProg
;
1164 if (ctx
->Shader
.CurrentProgram
&&
1165 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1170 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1173 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1177 if (!shProg
->LinkStatus
) {
1178 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUseProgram");
1186 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1192 * Update the vertex and fragment program's TexturesUsed arrays.
1195 update_textures_used(struct gl_program
*prog
)
1199 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1201 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1202 if (prog
->SamplersUsed
& (1 << s
)) {
1203 GLuint u
= prog
->SamplerUnits
[s
];
1204 GLuint t
= prog
->SamplerTargets
[s
];
1205 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1206 prog
->TexturesUsed
[u
] |= (1 << t
);
1213 * Check if the type given by userType is allowed to set a uniform of the
1214 * target type. Generally, equivalence is required, but setting Boolean
1215 * uniforms can be done with glUniformiv or glUniformfv.
1218 compatible_types(GLenum userType
, GLenum targetType
)
1220 if (userType
== targetType
)
1223 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1226 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1227 userType
== GL_INT_VEC2
))
1230 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1231 userType
== GL_INT_VEC3
))
1234 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1235 userType
== GL_INT_VEC4
))
1243 * Set the value of a program's uniform variable.
1244 * \param program the program whose uniform to update
1245 * \param location the location/index of the uniform
1246 * \param type the datatype of the uniform
1247 * \param count the number of uniforms to set
1248 * \param elems number of elements per uniform
1249 * \param values the new values
1252 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
, GLint location
,
1253 GLenum type
, GLsizei count
, GLint elems
, const void *values
)
1255 if (!compatible_types(type
,
1256 program
->Parameters
->Parameters
[location
].DataType
)) {
1257 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1261 if (program
->Parameters
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1262 /* This controls which texture unit which is used by a sampler */
1263 GLuint texUnit
, sampler
;
1265 /* data type for setting samplers must be int */
1266 if (type
!= GL_INT
|| count
!= 1) {
1267 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1268 "glUniform(only glUniform1i can be used "
1269 "to set sampler uniforms)");
1273 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[location
][0];
1274 texUnit
= ((GLuint
*) values
)[0];
1276 /* check that the sampler (tex unit index) is legal */
1277 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1278 _mesa_error(ctx
, GL_INVALID_VALUE
,
1279 "glUniform1(invalid sampler/tex unit index)");
1283 /* This maps a sampler to a texture unit: */
1284 program
->SamplerUnits
[sampler
] = texUnit
;
1285 update_textures_used(program
);
1287 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1290 /* ordinary uniform variable */
1293 if (count
* elems
> (GLint
) program
->Parameters
->Parameters
[location
].Size
) {
1294 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1298 for (k
= 0; k
< count
; k
++) {
1299 GLfloat
*uniformVal
= program
->Parameters
->ParameterValues
[location
+ k
];
1300 if (type
== GL_INT
||
1301 type
== GL_INT_VEC2
||
1302 type
== GL_INT_VEC3
||
1303 type
== GL_INT_VEC4
) {
1304 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1305 for (i
= 0; i
< elems
; i
++) {
1306 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1310 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1311 for (i
= 0; i
< elems
; i
++) {
1312 uniformVal
[i
] = fValues
[i
];
1321 * Called via ctx->Driver.Uniform().
1324 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1325 const GLvoid
*values
, GLenum type
)
1327 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1330 if (!shProg
|| !shProg
->LinkStatus
) {
1331 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1336 return; /* The standard specifies this as a no-op */
1338 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1339 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1344 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1366 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1370 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1372 /* A uniform var may be used by both a vertex shader and a fragment
1373 * shader. We may need to update one or both shader's uniform here:
1375 if (shProg
->VertexProgram
) {
1376 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1378 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1379 loc
, type
, count
, elems
, values
);
1383 if (shProg
->FragmentProgram
) {
1384 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1386 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1387 loc
, type
, count
, elems
, values
);
1394 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1400 case GL_FLOAT_MAT2x3
:
1404 case GL_FLOAT_MAT2x4
:
1412 case GL_FLOAT_MAT3x2
:
1416 case GL_FLOAT_MAT3x4
:
1424 case GL_FLOAT_MAT4x2
:
1428 case GL_FLOAT_MAT4x3
:
1439 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1440 GLuint location
, GLuint count
,
1441 GLuint rows
, GLuint cols
,
1442 GLboolean transpose
, const GLfloat
*values
)
1444 GLuint mat
, row
, col
;
1445 GLuint dst
= location
, src
= 0;
1448 /* check that the number of rows, columns is correct */
1449 get_matrix_dims(program
->Parameters
->Parameters
[location
].DataType
, &nr
, &nc
);
1450 if (rows
!= nr
|| cols
!= nc
) {
1451 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1452 "glUniformMatrix(matrix size mismatch");
1457 * Note: the _columns_ of a matrix are stored in program registers, not
1458 * the rows. So, the loops below look a little funny.
1459 * XXX could optimize this a bit...
1462 /* loop over matrices */
1463 for (mat
= 0; mat
< count
; mat
++) {
1466 for (col
= 0; col
< cols
; col
++) {
1467 GLfloat
*v
= program
->Parameters
->ParameterValues
[dst
];
1468 for (row
= 0; row
< rows
; row
++) {
1470 v
[row
] = values
[src
+ row
* cols
+ col
];
1473 v
[row
] = values
[src
+ col
* rows
+ row
];
1479 src
+= rows
* cols
; /* next matrix */
1485 * Called by ctx->Driver.UniformMatrix().
1486 * Note: cols=2, rows=4 ==> array[2] of vec4
1489 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1490 GLenum matrixType
, GLint location
, GLsizei count
,
1491 GLboolean transpose
, const GLfloat
*values
)
1493 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1495 if (!shProg
|| !shProg
->LinkStatus
) {
1496 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1497 "glUniformMatrix(program not linked)");
1502 return; /* The standard specifies this as a no-op */
1504 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1505 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1508 if (values
== NULL
) {
1509 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1513 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1515 if (shProg
->VertexProgram
) {
1516 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1518 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1519 loc
, count
, rows
, cols
, transpose
, values
);
1523 if (shProg
->FragmentProgram
) {
1524 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1526 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1527 loc
, count
, rows
, cols
, transpose
, values
);
1534 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1536 struct gl_shader_program
*shProg
;
1537 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1539 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1543 shProg
->Validated
= GL_TRUE
;
1545 /* From the GL spec:
1546 any two active samplers in the current program object are of
1547 different types, but refer to the same texture image unit,
1549 any active sampler in the current program object refers to a texture
1550 image unit where fixed-function fragment processing accesses a
1551 texture target that does not match the sampler type, or
1553 the sum of the number of active samplers in the program and the
1554 number of texture image units enabled for fixed-function fragment
1555 processing exceeds the combined limit on the total number of texture
1556 image units allowed.
1562 * Plug in Mesa's GLSL functions into the device driver function table.
1565 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
1567 driver
->AttachShader
= _mesa_attach_shader
;
1568 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
1569 driver
->CompileShader
= _mesa_compile_shader
;
1570 driver
->CreateProgram
= _mesa_create_program
;
1571 driver
->CreateShader
= _mesa_create_shader
;
1572 driver
->DeleteProgram2
= _mesa_delete_program2
;
1573 driver
->DeleteShader
= _mesa_delete_shader
;
1574 driver
->DetachShader
= _mesa_detach_shader
;
1575 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
1576 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
1577 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
1578 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
1579 driver
->GetHandle
= _mesa_get_handle
;
1580 driver
->GetProgramiv
= _mesa_get_programiv
;
1581 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
1582 driver
->GetShaderiv
= _mesa_get_shaderiv
;
1583 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
1584 driver
->GetShaderSource
= _mesa_get_shader_source
;
1585 driver
->GetUniformfv
= _mesa_get_uniformfv
;
1586 driver
->GetUniformiv
= _mesa_get_uniformiv
;
1587 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
1588 driver
->IsProgram
= _mesa_is_program
;
1589 driver
->IsShader
= _mesa_is_shader
;
1590 driver
->LinkProgram
= _mesa_link_program
;
1591 driver
->ShaderSource
= _mesa_shader_source
;
1592 driver
->Uniform
= _mesa_uniform
;
1593 driver
->UniformMatrix
= _mesa_uniform_matrix
;
1594 driver
->UseProgram
= _mesa_use_program
;
1595 driver
->ValidateProgram
= _mesa_validate_program
;