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 "shader/shader_api.h"
47 #include "shader/slang/slang_compile.h"
48 #include "shader/slang/slang_link.h"
53 * Allocate a new gl_shader_program object, initialize it.
55 struct gl_shader_program
*
56 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
58 struct gl_shader_program
*shProg
;
59 shProg
= CALLOC_STRUCT(gl_shader_program
);
61 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
64 shProg
->Attributes
= _mesa_new_parameter_list();
71 * Clear (free) the shader program state that gets produced by linking.
74 _mesa_clear_shader_program_data(GLcontext
*ctx
,
75 struct gl_shader_program
*shProg
)
77 if (shProg
->VertexProgram
) {
78 if (shProg
->VertexProgram
->Base
.Parameters
== shProg
->Uniforms
) {
79 /* to prevent a double-free in the next call */
80 shProg
->VertexProgram
->Base
.Parameters
= NULL
;
82 ctx
->Driver
.DeleteProgram(ctx
, &shProg
->VertexProgram
->Base
);
83 shProg
->VertexProgram
= NULL
;
86 if (shProg
->FragmentProgram
) {
87 if (shProg
->FragmentProgram
->Base
.Parameters
== shProg
->Uniforms
) {
88 /* to prevent a double-free in the next call */
89 shProg
->FragmentProgram
->Base
.Parameters
= NULL
;
91 ctx
->Driver
.DeleteProgram(ctx
, &shProg
->FragmentProgram
->Base
);
92 shProg
->FragmentProgram
= NULL
;
95 if (shProg
->Uniforms
) {
96 _mesa_free_parameter_list(shProg
->Uniforms
);
97 shProg
->Uniforms
= NULL
;
100 if (shProg
->Varying
) {
101 _mesa_free_parameter_list(shProg
->Varying
);
102 shProg
->Varying
= NULL
;
108 * Free all the data that hangs off a shader program object, but not the
112 _mesa_free_shader_program_data(GLcontext
*ctx
,
113 struct gl_shader_program
*shProg
)
117 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
119 _mesa_clear_shader_program_data(ctx
, shProg
);
121 if (shProg
->Attributes
) {
122 _mesa_free_parameter_list(shProg
->Attributes
);
123 shProg
->Attributes
= NULL
;
127 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
128 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
130 shProg
->NumShaders
= 0;
132 if (shProg
->Shaders
) {
133 _mesa_free(shProg
->Shaders
);
134 shProg
->Shaders
= NULL
;
140 * Free/delete a shader program object.
143 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
145 _mesa_free_shader_program_data(ctx
, shProg
);
146 if (shProg
->Shaders
) {
147 _mesa_free(shProg
->Shaders
);
148 shProg
->Shaders
= NULL
;
155 * Set ptr to point to shProg.
156 * If ptr is pointing to another object, decrement its refcount (and delete
157 * if refcount hits zero).
158 * Then set ptr to point to shProg, incrementing its refcount.
160 /* XXX this could be static */
162 _mesa_reference_shader_program(GLcontext
*ctx
,
163 struct gl_shader_program
**ptr
,
164 struct gl_shader_program
*shProg
)
167 if (*ptr
== shProg
) {
172 /* Unreference the old shader program */
173 GLboolean deleteFlag
= GL_FALSE
;
174 struct gl_shader_program
*old
= *ptr
;
176 ASSERT(old
->RefCount
> 0);
178 /*printf("SHPROG DECR %p (%d) to %d\n",
179 (void*) old, old->Name, old->RefCount);*/
180 deleteFlag
= (old
->RefCount
== 0);
183 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
184 _mesa_free_shader_program(ctx
, old
);
193 /*printf("SHPROG INCR %p (%d) to %d\n",
194 (void*) shProg, shProg->Name, shProg->RefCount);*/
201 * Lookup a GLSL program object.
203 struct gl_shader_program
*
204 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
206 struct gl_shader_program
*shProg
;
208 shProg
= (struct gl_shader_program
*)
209 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
210 /* Note that both gl_shader and gl_shader_program objects are kept
211 * in the same hash table. Check the object's type to be sure it's
212 * what we're expecting.
214 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
224 * Allocate a new gl_shader object, initialize it.
227 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
229 struct gl_shader
*shader
;
230 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
231 shader
= CALLOC_STRUCT(gl_shader
);
235 shader
->RefCount
= 1;
242 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
246 _mesa_free((void *) sh
->Source
);
248 _mesa_free(sh
->InfoLog
);
249 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
250 assert(sh
->Programs
[i
]);
251 ctx
->Driver
.DeleteProgram(ctx
, sh
->Programs
[i
]);
254 _mesa_free(sh
->Programs
);
260 * Set ptr to point to sh.
261 * If ptr is pointing to another shader, decrement its refcount (and delete
262 * if refcount hits zero).
263 * Then set ptr to point to sh, incrementing its refcount.
265 /* XXX this could be static */
267 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
268 struct gl_shader
*sh
)
276 /* Unreference the old shader */
277 GLboolean deleteFlag
= GL_FALSE
;
278 struct gl_shader
*old
= *ptr
;
280 ASSERT(old
->RefCount
> 0);
282 /*printf("SHADER DECR %p (%d) to %d\n",
283 (void*) old, old->Name, old->RefCount);*/
284 deleteFlag
= (old
->RefCount
== 0);
287 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
288 _mesa_free_shader(ctx
, old
);
298 /*printf("SHADER INCR %p (%d) to %d\n",
299 (void*) sh, sh->Name, sh->RefCount);*/
306 * Lookup a GLSL shader object.
309 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
312 struct gl_shader
*sh
= (struct gl_shader
*)
313 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
314 /* Note that both gl_shader and gl_shader_program objects are kept
315 * in the same hash table. Check the object's type to be sure it's
316 * what we're expecting.
318 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
328 * Initialize context's shader state.
331 _mesa_init_shader_state(GLcontext
* ctx
)
333 /* Device drivers may override these to control what kind of instructions
334 * are generated by the GLSL compiler.
336 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
337 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
338 ctx
->Shader
.EmitComments
= GL_FALSE
;
343 * Free the per-context shader-related state.
346 _mesa_free_shader_state(GLcontext
*ctx
)
348 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
353 * Copy string from <src> to <dst>, up to maxLength characters, returning
354 * length of <dst> in <length>.
355 * \param src the strings source
356 * \param maxLength max chars to copy
357 * \param length returns number of chars copied
358 * \param dst the string destination
361 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
364 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
374 * Return size (in floats) of the given GLSL type.
375 * See also _slang_sizeof_type_specifier().
378 sizeof_glsl_type(GLenum type
)
398 return 8; /* 2 rows of 4, actually */
400 return 12; /* 3 rows of 4, actually */
403 case GL_FLOAT_MAT2x3
:
404 return 8; /* 2 rows of 4, actually */
405 case GL_FLOAT_MAT2x4
:
407 case GL_FLOAT_MAT3x2
:
408 return 12; /* 3 rows of 4, actually */
409 case GL_FLOAT_MAT3x4
:
411 case GL_FLOAT_MAT4x2
:
412 return 16; /* 4 rows of 4, actually */
413 case GL_FLOAT_MAT4x3
:
414 return 16; /* 4 rows of 4, actually */
416 return 0; /* error */
422 * Called via ctx->Driver.AttachShader()
425 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
427 struct gl_shader_program
*shProg
428 = _mesa_lookup_shader_program(ctx
, program
);
429 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
433 if (!shProg
|| !sh
) {
434 _mesa_error(ctx
, GL_INVALID_VALUE
,
435 "glAttachShader(bad program or shader name)");
439 n
= shProg
->NumShaders
;
441 for (i
= 0; i
< n
; i
++) {
442 if (shProg
->Shaders
[i
] == sh
) {
443 /* already attached */
449 shProg
->Shaders
= (struct gl_shader
**)
450 _mesa_realloc(shProg
->Shaders
,
451 n
* sizeof(struct gl_shader
*),
452 (n
+ 1) * sizeof(struct gl_shader
*));
453 if (!shProg
->Shaders
) {
454 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
459 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
460 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
461 shProg
->NumShaders
++;
466 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
469 struct gl_shader_program
*shProg
470 = _mesa_lookup_shader_program(ctx
, program
);
471 const GLint size
= -1; /* unknown size */
475 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
482 if (strncmp(name
, "gl_", 3) == 0) {
483 _mesa_error(ctx
, GL_INVALID_OPERATION
,
484 "glBindAttribLocation(illegal name)");
488 if (shProg
->LinkStatus
) {
489 /* get current index/location for the attribute */
490 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
496 /* this will replace the current value if it's already in the list */
497 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
499 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
502 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
503 /* If the index changed, need to search/replace references to that attribute
504 * in the vertex program.
506 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
512 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
514 struct gl_shader
*sh
;
517 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
520 case GL_FRAGMENT_SHADER
:
521 case GL_VERTEX_SHADER
:
522 sh
= _mesa_new_shader(ctx
, name
, type
);
525 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
529 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
536 _mesa_create_program(GLcontext
*ctx
)
539 struct gl_shader_program
*shProg
;
541 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
542 shProg
= _mesa_new_shader_program(ctx
, name
);
544 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
546 assert(shProg
->RefCount
== 1);
553 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
557 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
560 * NOTE: deleting shaders/programs works a bit differently than
561 * texture objects (and buffer objects, etc). Shader/program
562 * handles/IDs exist in the hash table until the object is really
563 * deleted (refcount==0). With texture objects, the handle/ID is
564 * removed from the hash table in glDeleteTextures() while the tex
565 * object itself might linger until its refcount goes to zero.
567 struct gl_shader_program
*shProg
;
569 shProg
= _mesa_lookup_shader_program(ctx
, name
);
571 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
575 shProg
->DeletePending
= GL_TRUE
;
577 /* effectively, decr shProg's refcount */
578 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
583 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
585 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
590 sh
->DeletePending
= GL_TRUE
;
592 /* effectively, decr sh's refcount */
593 _mesa_reference_shader(ctx
, &sh
, NULL
);
598 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
600 struct gl_shader_program
*shProg
601 = _mesa_lookup_shader_program(ctx
, program
);
606 _mesa_error(ctx
, GL_INVALID_VALUE
,
607 "glDetachShader(bad program or shader name)");
611 n
= shProg
->NumShaders
;
613 for (i
= 0; i
< n
; i
++) {
614 if (shProg
->Shaders
[i
]->Name
== shader
) {
616 struct gl_shader
**newList
;
619 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
621 /* alloc new, smaller array */
622 newList
= (struct gl_shader
**)
623 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
625 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
628 for (j
= 0; j
< i
; j
++) {
629 newList
[j
] = shProg
->Shaders
[j
];
632 newList
[j
++] = shProg
->Shaders
[i
];
633 _mesa_free(shProg
->Shaders
);
635 shProg
->Shaders
= newList
;
636 shProg
->NumShaders
= n
- 1;
641 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
642 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
643 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
644 assert(shProg
->Shaders
[j
]->RefCount
> 0);
654 _mesa_error(ctx
, GL_INVALID_VALUE
,
655 "glDetachShader(shader not found)");
660 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
661 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
662 GLenum
*type
, GLchar
*nameOut
)
664 static const GLenum vec_types
[] = {
665 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
667 struct gl_shader_program
*shProg
668 = _mesa_lookup_shader_program(ctx
, program
);
672 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
676 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
677 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
681 copy_string(nameOut
, maxLength
, length
,
682 shProg
->Attributes
->Parameters
[index
].Name
);
683 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
685 *size
= 1; /* attributes may not be arrays */
686 if (type
&& sz
> 0 && sz
<= 4) /* XXX this is a temporary hack */
687 *type
= vec_types
[sz
- 1];
692 * Called via ctx->Driver.GetActiveUniform().
695 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
696 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
697 GLenum
*type
, GLchar
*nameOut
)
699 struct gl_shader_program
*shProg
700 = _mesa_lookup_shader_program(ctx
, program
);
704 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
708 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
709 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
714 for (j
= 0; j
< shProg
->Uniforms
->NumParameters
; j
++) {
715 if (shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_UNIFORM
||
716 shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_SAMPLER
) {
718 GLuint uSize
= shProg
->Uniforms
->Parameters
[j
].Size
;
719 GLenum uType
= shProg
->Uniforms
->Parameters
[j
].DataType
;
721 copy_string(nameOut
, maxLength
, length
,
722 shProg
->Uniforms
->Parameters
[j
].Name
);
724 /* convert from floats to 'type' (eg: sizeof(mat4x4)=1) */
725 *size
= uSize
/ sizeof_glsl_type(uType
);
735 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
740 * Called via ctx->Driver.GetAttachedShaders().
743 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
744 GLsizei
*count
, GLuint
*obj
)
746 struct gl_shader_program
*shProg
747 = _mesa_lookup_shader_program(ctx
, program
);
750 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
751 obj
[i
] = shProg
->Shaders
[i
]->Name
;
757 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
763 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
766 struct gl_shader_program
*shProg
767 = _mesa_lookup_shader_program(ctx
, program
);
770 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
774 if (!shProg
->LinkStatus
) {
775 _mesa_error(ctx
, GL_INVALID_OPERATION
,
776 "glGetAttribLocation(program not linked)");
783 if (shProg
->Attributes
) {
784 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
786 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
794 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
797 GET_CURRENT_CONTEXT(ctx
);
800 case GL_PROGRAM_OBJECT_ARB
:
802 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
805 return (**pro
)._container
._generic
.
806 GetName((struct gl2_generic_intf
**) (pro
));
810 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
818 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
819 GLenum pname
, GLint
*params
)
821 struct gl_shader_program
*shProg
822 = _mesa_lookup_shader_program(ctx
, program
);
825 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
830 case GL_DELETE_STATUS
:
831 *params
= shProg
->DeletePending
;
834 *params
= shProg
->LinkStatus
;
836 case GL_VALIDATE_STATUS
:
837 *params
= shProg
->Validated
;
839 case GL_INFO_LOG_LENGTH
:
840 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
842 case GL_ATTACHED_SHADERS
:
843 *params
= shProg
->NumShaders
;
845 case GL_ACTIVE_ATTRIBUTES
:
846 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
848 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
849 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
852 case GL_ACTIVE_UNIFORMS
:
854 = _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_UNIFORM
)
855 + _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_SAMPLER
);
857 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
859 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_UNIFORM
),
860 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_SAMPLER
));
862 (*params
)++; /* add one for terminating zero */
865 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
872 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
874 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
877 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
883 *params
= shader
->Type
;
885 case GL_DELETE_STATUS
:
886 *params
= shader
->DeletePending
;
888 case GL_COMPILE_STATUS
:
889 *params
= shader
->CompileStatus
;
891 case GL_INFO_LOG_LENGTH
:
892 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
894 case GL_SHADER_SOURCE_LENGTH
:
895 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
898 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
905 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
906 GLsizei
*length
, GLchar
*infoLog
)
908 struct gl_shader_program
*shProg
909 = _mesa_lookup_shader_program(ctx
, program
);
911 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
914 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
919 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
920 GLsizei
*length
, GLchar
*infoLog
)
922 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
924 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
927 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
932 * Called via ctx->Driver.GetShaderSource().
935 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
936 GLsizei
*length
, GLchar
*sourceOut
)
938 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
940 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
943 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
948 * Called via ctx->Driver.GetUniformfv().
951 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
954 struct gl_shader_program
*shProg
955 = _mesa_lookup_shader_program(ctx
, program
);
958 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
962 uType
= shProg
->Uniforms
->Parameters
[location
].DataType
;
963 uSize
= sizeof_glsl_type(uType
);
964 /* Matrix types need special handling, because they span several
965 * parameters, and may also not be fully packed.
967 switch (shProg
->Uniforms
->Parameters
[location
].DataType
) {
969 case GL_FLOAT_MAT3x2
:
970 case GL_FLOAT_MAT4x2
:
973 case GL_FLOAT_MAT2x3
:
975 case GL_FLOAT_MAT4x3
:
978 case GL_FLOAT_MAT2x4
:
979 case GL_FLOAT_MAT3x4
:
985 for (c
= 0, i
= 0; c
* 4 < uSize
; c
++)
986 for (r
= 0; r
< rows
; r
++, i
++)
987 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
+ c
][r
];
990 for (i
= 0; i
< uSize
; i
++) {
991 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
995 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
999 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
1005 * Called via ctx->Driver.GetUniformLocation().
1008 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1010 struct gl_shader_program
*shProg
1011 = _mesa_lookup_shader_program(ctx
, program
);
1014 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
1015 const struct gl_program_parameter
*u
1016 = shProg
->Uniforms
->Parameters
+ loc
;
1017 /* XXX this is a temporary simplification / short-cut.
1018 * We need to handle things like "e.c[0].b" as seen in the
1019 * GLSL orange book, page 189.
1021 if ((u
->Type
== PROGRAM_UNIFORM
||
1022 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
1033 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
1035 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
1036 return shProg
? GL_TRUE
: GL_FALSE
;
1041 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
1043 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
1044 return shader
? GL_TRUE
: GL_FALSE
;
1050 * Called via ctx->Driver.ShaderSource()
1053 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1055 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1057 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
1061 /* free old shader source string and install new one */
1063 _mesa_free((void *) sh
->Source
);
1065 sh
->Source
= source
;
1066 sh
->CompileStatus
= GL_FALSE
;
1071 * Called via ctx->Driver.CompileShader()
1074 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1076 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
1079 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
1083 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1088 * Called via ctx->Driver.LinkProgram()
1091 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1093 struct gl_shader_program
*shProg
;
1095 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1097 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1101 _slang_link(ctx
, program
, shProg
);
1106 * Called via ctx->Driver.UseProgram()
1109 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1111 struct gl_shader_program
*shProg
;
1113 if (ctx
->Shader
.CurrentProgram
&&
1114 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1119 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1122 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1124 _mesa_error(ctx
, GL_INVALID_VALUE
,
1125 "glUseProgramObjectARB(programObj)");
1133 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1138 * Called via ctx->Driver.Uniform().
1141 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1142 const GLvoid
*values
, GLenum type
)
1144 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1149 if (!shProg
|| !shProg
->LinkStatus
) {
1150 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1155 return; /* The standard specifies this as a no-op */
1157 /* The spec says this is GL_INVALID_OPERATION, although it seems like it
1158 * ought to be GL_INVALID_VALUE
1160 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1161 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1165 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1167 uType
= shProg
->Uniforms
->Parameters
[location
].DataType
;
1169 * If we're setting a sampler, we must use glUniformi1()!
1171 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1173 if (type
!= GL_INT
|| count
!= 1) {
1174 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1175 "glUniform(only glUniform1i can be used "
1176 "to set sampler uniforms)");
1179 /* check that the sampler (tex unit index) is legal */
1180 unit
= ((GLint
*) values
)[0];
1181 if (unit
>= ctx
->Const
.MaxTextureImageUnits
) {
1182 _mesa_error(ctx
, GL_INVALID_VALUE
,
1183 "glUniform1(invalid sampler/tex unit index)");
1189 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1211 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1215 /* OpenGL requires types to match exactly, except that one can convert
1216 * float or int array to boolean array.
1224 if (elems
!= sizeof_glsl_type(uType
)) {
1225 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count mismatch)");
1228 case PROGRAM_SAMPLER
:
1231 if (shProg
->Uniforms
->Parameters
[location
].Type
!= PROGRAM_SAMPLER
1233 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1238 /* XXX if this is a base type, then count must equal 1. However, we
1239 * don't have enough information from the compiler to distinguish a
1240 * base type from a 1-element array of that type. The standard allows
1241 * count to overrun an array, in which case the overflow is ignored.
1243 maxCount
= shProg
->Uniforms
->Parameters
[location
].Size
/ elems
;
1244 if (count
> maxCount
) count
= maxCount
;
1246 for (k
= 0; k
< count
; k
++) {
1247 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
1248 if (type
== GL_INT
||
1249 type
== GL_INT_VEC2
||
1250 type
== GL_INT_VEC3
||
1251 type
== GL_INT_VEC4
) {
1252 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1253 for (i
= 0; i
< elems
; i
++) {
1254 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1258 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1259 for (i
= 0; i
< elems
; i
++) {
1260 uniformVal
[i
] = fValues
[i
];
1263 if (uType
== GL_BOOL
||
1264 uType
== GL_BOOL_VEC2
||
1265 uType
== GL_BOOL_VEC3
||
1266 uType
== GL_BOOL_VEC4
) {
1267 for (i
= 0; i
< elems
; i
++)
1268 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1272 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1273 if (shProg
->VertexProgram
)
1274 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
1275 if (shProg
->FragmentProgram
)
1276 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
1277 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1283 * Called by ctx->Driver.UniformMatrix().
1286 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1287 GLenum matrixType
, GLint location
, GLsizei count
,
1288 GLboolean transpose
, const GLfloat
*values
)
1290 GLsizei maxCount
, i
;
1291 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1292 if (!shProg
|| !shProg
->LinkStatus
) {
1293 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1294 "glUniformMatrix(program not linked)");
1298 return; /* The standard specifies this as a no-op */
1299 /* The spec says this is GL_INVALID_OPERATION, although it seems like it
1300 * ought to be GL_INVALID_VALUE
1302 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1303 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
1306 if (values
== NULL
) {
1307 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1311 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(count < 0)");
1315 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1318 * Note: the _columns_ of a matrix are stored in program registers, not
1321 /* XXXX need to test 3x3 and 2x2 matrices... */
1322 maxCount
= shProg
->Uniforms
->Parameters
[location
].Size
/ (4 * cols
);
1323 if (count
> maxCount
)
1325 for (i
= 0; i
< count
; i
++) {
1328 for (col
= 0; col
< cols
; col
++) {
1329 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1330 for (row
= 0; row
< rows
; row
++) {
1331 v
[row
] = values
[row
* cols
+ col
];
1337 for (col
= 0; col
< cols
; col
++) {
1338 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1339 for (row
= 0; row
< rows
; row
++) {
1340 v
[row
] = values
[col
* rows
+ row
];
1345 values
+= rows
* cols
;
1351 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1353 struct gl_shader_program
*shProg
;
1354 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1356 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1360 shProg
->Validated
= GL_TRUE
;
1362 /* From the GL spec:
1363 any two active samplers in the current program object are of
1364 different types, but refer to the same texture image unit,
1366 any active sampler in the current program object refers to a texture
1367 image unit where fixed-function fragment processing accesses a
1368 texture target that does not match the sampler type, or
1370 the sum of the number of active samplers in the program and the
1371 number of texture image units enabled for fixed-function fragment
1372 processing exceeds the combined limit on the total number of texture
1373 image units allowed.