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
;
137 if (shProg
->InfoLog
) {
138 _mesa_free(shProg
->InfoLog
);
139 shProg
->InfoLog
= NULL
;
145 * Free/delete a shader program object.
148 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
150 _mesa_free_shader_program_data(ctx
, shProg
);
157 * Set ptr to point to shProg.
158 * If ptr is pointing to another object, decrement its refcount (and delete
159 * if refcount hits zero).
160 * Then set ptr to point to shProg, incrementing its refcount.
162 /* XXX this could be static */
164 _mesa_reference_shader_program(GLcontext
*ctx
,
165 struct gl_shader_program
**ptr
,
166 struct gl_shader_program
*shProg
)
169 if (*ptr
== shProg
) {
174 /* Unreference the old shader program */
175 GLboolean deleteFlag
= GL_FALSE
;
176 struct gl_shader_program
*old
= *ptr
;
178 ASSERT(old
->RefCount
> 0);
180 /*printf("SHPROG DECR %p (%d) to %d\n",
181 (void*) old, old->Name, old->RefCount);*/
182 deleteFlag
= (old
->RefCount
== 0);
185 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
186 _mesa_free_shader_program(ctx
, old
);
195 /*printf("SHPROG INCR %p (%d) to %d\n",
196 (void*) shProg, shProg->Name, shProg->RefCount);*/
203 * Lookup a GLSL program object.
205 struct gl_shader_program
*
206 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
208 struct gl_shader_program
*shProg
;
210 shProg
= (struct gl_shader_program
*)
211 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
212 /* Note that both gl_shader and gl_shader_program objects are kept
213 * in the same hash table. Check the object's type to be sure it's
214 * what we're expecting.
216 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
226 * Allocate a new gl_shader object, initialize it.
229 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
231 struct gl_shader
*shader
;
232 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
233 shader
= CALLOC_STRUCT(gl_shader
);
237 shader
->RefCount
= 1;
244 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
248 _mesa_free((void *) sh
->Source
);
250 _mesa_free(sh
->InfoLog
);
251 for (i
= 0; i
< sh
->NumPrograms
; i
++) {
252 assert(sh
->Programs
[i
]);
253 ctx
->Driver
.DeleteProgram(ctx
, sh
->Programs
[i
]);
256 _mesa_free(sh
->Programs
);
262 * Set ptr to point to sh.
263 * If ptr is pointing to another shader, decrement its refcount (and delete
264 * if refcount hits zero).
265 * Then set ptr to point to sh, incrementing its refcount.
267 /* XXX this could be static */
269 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
270 struct gl_shader
*sh
)
278 /* Unreference the old shader */
279 GLboolean deleteFlag
= GL_FALSE
;
280 struct gl_shader
*old
= *ptr
;
282 ASSERT(old
->RefCount
> 0);
284 /*printf("SHADER DECR %p (%d) to %d\n",
285 (void*) old, old->Name, old->RefCount);*/
286 deleteFlag
= (old
->RefCount
== 0);
289 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
290 _mesa_free_shader(ctx
, old
);
300 /*printf("SHADER INCR %p (%d) to %d\n",
301 (void*) sh, sh->Name, sh->RefCount);*/
308 * Lookup a GLSL shader object.
311 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
314 struct gl_shader
*sh
= (struct gl_shader
*)
315 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
316 /* Note that both gl_shader and gl_shader_program objects are kept
317 * in the same hash table. Check the object's type to be sure it's
318 * what we're expecting.
320 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
330 * Initialize context's shader state.
333 _mesa_init_shader_state(GLcontext
* ctx
)
335 /* Device drivers may override these to control what kind of instructions
336 * are generated by the GLSL compiler.
338 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
339 ctx
->Shader
.EmitCondCodes
= GL_TRUE
; /* XXX probably want GL_FALSE... */
340 ctx
->Shader
.EmitComments
= GL_FALSE
;
345 * Free the per-context shader-related state.
348 _mesa_free_shader_state(GLcontext
*ctx
)
350 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
355 * Copy string from <src> to <dst>, up to maxLength characters, returning
356 * length of <dst> in <length>.
357 * \param src the strings source
358 * \param maxLength max chars to copy
359 * \param length returns number of chars copied
360 * \param dst the string destination
363 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
366 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
376 * Return size (in floats) of the given GLSL type.
377 * See also _slang_sizeof_type_specifier().
380 sizeof_glsl_type(GLenum type
)
400 return 8; /* 2 rows of 4, actually */
402 return 12; /* 3 rows of 4, actually */
405 case GL_FLOAT_MAT2x3
:
406 return 8; /* 2 rows of 4, actually */
407 case GL_FLOAT_MAT2x4
:
409 case GL_FLOAT_MAT3x2
:
410 return 12; /* 3 rows of 4, actually */
411 case GL_FLOAT_MAT3x4
:
413 case GL_FLOAT_MAT4x2
:
414 return 16; /* 4 rows of 4, actually */
415 case GL_FLOAT_MAT4x3
:
416 return 16; /* 4 rows of 4, actually */
418 return 0; /* error */
424 * Called via ctx->Driver.AttachShader()
427 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
429 struct gl_shader_program
*shProg
430 = _mesa_lookup_shader_program(ctx
, program
);
431 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
435 if (!shProg
|| !sh
) {
436 _mesa_error(ctx
, GL_INVALID_VALUE
,
437 "glAttachShader(bad program or shader name)");
441 n
= shProg
->NumShaders
;
443 for (i
= 0; i
< n
; i
++) {
444 if (shProg
->Shaders
[i
] == sh
) {
445 /* already attached */
451 shProg
->Shaders
= (struct gl_shader
**)
452 _mesa_realloc(shProg
->Shaders
,
453 n
* sizeof(struct gl_shader
*),
454 (n
+ 1) * sizeof(struct gl_shader
*));
455 if (!shProg
->Shaders
) {
456 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
461 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
462 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
463 shProg
->NumShaders
++;
468 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
471 struct gl_shader_program
*shProg
472 = _mesa_lookup_shader_program(ctx
, program
);
473 const GLint size
= -1; /* unknown size */
477 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
484 if (strncmp(name
, "gl_", 3) == 0) {
485 _mesa_error(ctx
, GL_INVALID_OPERATION
,
486 "glBindAttribLocation(illegal name)");
490 if (shProg
->LinkStatus
) {
491 /* get current index/location for the attribute */
492 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
498 /* this will replace the current value if it's already in the list */
499 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
501 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
504 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
505 /* If the index changed, need to search/replace references to that attribute
506 * in the vertex program.
508 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
514 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
516 struct gl_shader
*sh
;
519 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
522 case GL_FRAGMENT_SHADER
:
523 case GL_VERTEX_SHADER
:
524 sh
= _mesa_new_shader(ctx
, name
, type
);
527 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
531 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
538 _mesa_create_program(GLcontext
*ctx
)
541 struct gl_shader_program
*shProg
;
543 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
544 shProg
= _mesa_new_shader_program(ctx
, name
);
546 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
548 assert(shProg
->RefCount
== 1);
555 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
559 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
562 * NOTE: deleting shaders/programs works a bit differently than
563 * texture objects (and buffer objects, etc). Shader/program
564 * handles/IDs exist in the hash table until the object is really
565 * deleted (refcount==0). With texture objects, the handle/ID is
566 * removed from the hash table in glDeleteTextures() while the tex
567 * object itself might linger until its refcount goes to zero.
569 struct gl_shader_program
*shProg
;
571 shProg
= _mesa_lookup_shader_program(ctx
, name
);
573 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
577 shProg
->DeletePending
= GL_TRUE
;
579 /* effectively, decr shProg's refcount */
580 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
585 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
587 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
592 sh
->DeletePending
= GL_TRUE
;
594 /* effectively, decr sh's refcount */
595 _mesa_reference_shader(ctx
, &sh
, NULL
);
600 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
602 struct gl_shader_program
*shProg
603 = _mesa_lookup_shader_program(ctx
, program
);
608 _mesa_error(ctx
, GL_INVALID_VALUE
,
609 "glDetachShader(bad program or shader name)");
613 n
= shProg
->NumShaders
;
615 for (i
= 0; i
< n
; i
++) {
616 if (shProg
->Shaders
[i
]->Name
== shader
) {
618 struct gl_shader
**newList
;
621 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
623 /* alloc new, smaller array */
624 newList
= (struct gl_shader
**)
625 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
627 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
630 for (j
= 0; j
< i
; j
++) {
631 newList
[j
] = shProg
->Shaders
[j
];
634 newList
[j
++] = shProg
->Shaders
[i
];
635 _mesa_free(shProg
->Shaders
);
637 shProg
->Shaders
= newList
;
638 shProg
->NumShaders
= n
- 1;
643 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
644 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
645 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
646 assert(shProg
->Shaders
[j
]->RefCount
> 0);
656 _mesa_error(ctx
, GL_INVALID_VALUE
,
657 "glDetachShader(shader not found)");
662 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
663 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
664 GLenum
*type
, GLchar
*nameOut
)
666 static const GLenum vec_types
[] = {
667 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
669 struct gl_shader_program
*shProg
670 = _mesa_lookup_shader_program(ctx
, program
);
674 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
678 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
679 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
683 copy_string(nameOut
, maxLength
, length
,
684 shProg
->Attributes
->Parameters
[index
].Name
);
685 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
687 *size
= 1; /* attributes may not be arrays */
688 if (type
&& sz
> 0 && sz
<= 4) /* XXX this is a temporary hack */
689 *type
= vec_types
[sz
- 1];
694 * Called via ctx->Driver.GetActiveUniform().
697 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
698 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
699 GLenum
*type
, GLchar
*nameOut
)
701 struct gl_shader_program
*shProg
702 = _mesa_lookup_shader_program(ctx
, program
);
706 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
710 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
711 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
716 for (j
= 0; j
< shProg
->Uniforms
->NumParameters
; j
++) {
717 if (shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_UNIFORM
||
718 shProg
->Uniforms
->Parameters
[j
].Type
== PROGRAM_SAMPLER
) {
720 GLuint uSize
= shProg
->Uniforms
->Parameters
[j
].Size
;
721 GLenum uType
= shProg
->Uniforms
->Parameters
[j
].DataType
;
723 copy_string(nameOut
, maxLength
, length
,
724 shProg
->Uniforms
->Parameters
[j
].Name
);
726 /* convert from floats to 'type' (eg: sizeof(mat4x4)=1) */
727 *size
= uSize
/ sizeof_glsl_type(uType
);
737 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
742 * Called via ctx->Driver.GetAttachedShaders().
745 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
746 GLsizei
*count
, GLuint
*obj
)
748 struct gl_shader_program
*shProg
749 = _mesa_lookup_shader_program(ctx
, program
);
752 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
753 obj
[i
] = shProg
->Shaders
[i
]->Name
;
759 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
765 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
768 struct gl_shader_program
*shProg
769 = _mesa_lookup_shader_program(ctx
, program
);
772 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
776 if (!shProg
->LinkStatus
) {
777 _mesa_error(ctx
, GL_INVALID_OPERATION
,
778 "glGetAttribLocation(program not linked)");
785 if (shProg
->Attributes
) {
786 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
788 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
796 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
799 GET_CURRENT_CONTEXT(ctx
);
802 case GL_PROGRAM_OBJECT_ARB
:
804 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
807 return (**pro
)._container
._generic
.
808 GetName((struct gl2_generic_intf
**) (pro
));
812 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
820 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
821 GLenum pname
, GLint
*params
)
823 struct gl_shader_program
*shProg
824 = _mesa_lookup_shader_program(ctx
, program
);
827 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
832 case GL_DELETE_STATUS
:
833 *params
= shProg
->DeletePending
;
836 *params
= shProg
->LinkStatus
;
838 case GL_VALIDATE_STATUS
:
839 *params
= shProg
->Validated
;
841 case GL_INFO_LOG_LENGTH
:
842 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
844 case GL_ATTACHED_SHADERS
:
845 *params
= shProg
->NumShaders
;
847 case GL_ACTIVE_ATTRIBUTES
:
848 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
850 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
851 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
854 case GL_ACTIVE_UNIFORMS
:
856 = _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_UNIFORM
)
857 + _mesa_num_parameters_of_type(shProg
->Uniforms
, PROGRAM_SAMPLER
);
859 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
861 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_UNIFORM
),
862 _mesa_longest_parameter_name(shProg
->Uniforms
, PROGRAM_SAMPLER
));
864 (*params
)++; /* add one for terminating zero */
867 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
874 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
876 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
879 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
885 *params
= shader
->Type
;
887 case GL_DELETE_STATUS
:
888 *params
= shader
->DeletePending
;
890 case GL_COMPILE_STATUS
:
891 *params
= shader
->CompileStatus
;
893 case GL_INFO_LOG_LENGTH
:
894 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
896 case GL_SHADER_SOURCE_LENGTH
:
897 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
900 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
907 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
908 GLsizei
*length
, GLchar
*infoLog
)
910 struct gl_shader_program
*shProg
911 = _mesa_lookup_shader_program(ctx
, program
);
913 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
916 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
921 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
922 GLsizei
*length
, GLchar
*infoLog
)
924 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
926 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
929 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
934 * Called via ctx->Driver.GetShaderSource().
937 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
938 GLsizei
*length
, GLchar
*sourceOut
)
940 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
942 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
945 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
950 * Called via ctx->Driver.GetUniformfv().
953 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
956 struct gl_shader_program
*shProg
957 = _mesa_lookup_shader_program(ctx
, program
);
960 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
964 uType
= shProg
->Uniforms
->Parameters
[location
].DataType
;
965 uSize
= sizeof_glsl_type(uType
);
966 /* Matrix types need special handling, because they span several
967 * parameters, and may also not be fully packed.
969 switch (shProg
->Uniforms
->Parameters
[location
].DataType
) {
971 case GL_FLOAT_MAT3x2
:
972 case GL_FLOAT_MAT4x2
:
975 case GL_FLOAT_MAT2x3
:
977 case GL_FLOAT_MAT4x3
:
980 case GL_FLOAT_MAT2x4
:
981 case GL_FLOAT_MAT3x4
:
987 for (c
= 0, i
= 0; c
* 4 < uSize
; c
++)
988 for (r
= 0; r
< rows
; r
++, i
++)
989 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
+ c
][r
];
992 for (i
= 0; i
< uSize
; i
++) {
993 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
997 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
1001 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
1007 * Called via ctx->Driver.GetUniformLocation().
1010 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1012 struct gl_shader_program
*shProg
1013 = _mesa_lookup_shader_program(ctx
, program
);
1016 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
1017 const struct gl_program_parameter
*u
1018 = shProg
->Uniforms
->Parameters
+ loc
;
1019 /* XXX this is a temporary simplification / short-cut.
1020 * We need to handle things like "e.c[0].b" as seen in the
1021 * GLSL orange book, page 189.
1023 if ((u
->Type
== PROGRAM_UNIFORM
||
1024 u
->Type
== PROGRAM_SAMPLER
) && !strcmp(u
->Name
, name
)) {
1035 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
1037 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
1038 return shProg
? GL_TRUE
: GL_FALSE
;
1043 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
1045 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
1046 return shader
? GL_TRUE
: GL_FALSE
;
1052 * Called via ctx->Driver.ShaderSource()
1055 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1057 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1059 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
1063 /* free old shader source string and install new one */
1065 _mesa_free((void *) sh
->Source
);
1067 sh
->Source
= source
;
1068 sh
->CompileStatus
= GL_FALSE
;
1073 * Called via ctx->Driver.CompileShader()
1076 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1078 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
1081 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
1085 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1090 * Called via ctx->Driver.LinkProgram()
1093 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1095 struct gl_shader_program
*shProg
;
1097 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1099 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1103 _slang_link(ctx
, program
, shProg
);
1108 * Called via ctx->Driver.UseProgram()
1111 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1113 struct gl_shader_program
*shProg
;
1115 if (ctx
->Shader
.CurrentProgram
&&
1116 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1121 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1124 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1126 _mesa_error(ctx
, GL_INVALID_VALUE
,
1127 "glUseProgramObjectARB(programObj)");
1135 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1140 * Called via ctx->Driver.Uniform().
1143 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1144 const GLvoid
*values
, GLenum type
)
1146 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1151 if (!shProg
|| !shProg
->LinkStatus
) {
1152 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1157 return; /* The standard specifies this as a no-op */
1159 /* The spec says this is GL_INVALID_OPERATION, although it seems like it
1160 * ought to be GL_INVALID_VALUE
1162 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1163 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1167 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1169 uType
= shProg
->Uniforms
->Parameters
[location
].DataType
;
1171 * If we're setting a sampler, we must use glUniformi1()!
1173 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1175 if (type
!= GL_INT
|| count
!= 1) {
1176 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1177 "glUniform(only glUniform1i can be used "
1178 "to set sampler uniforms)");
1181 /* check that the sampler (tex unit index) is legal */
1182 unit
= ((GLint
*) values
)[0];
1183 if (unit
>= ctx
->Const
.MaxTextureImageUnits
) {
1184 _mesa_error(ctx
, GL_INVALID_VALUE
,
1185 "glUniform1(invalid sampler/tex unit index)");
1191 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1213 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1217 /* OpenGL requires types to match exactly, except that one can convert
1218 * float or int array to boolean array.
1226 if (elems
!= sizeof_glsl_type(uType
)) {
1227 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count mismatch)");
1230 case PROGRAM_SAMPLER
:
1233 if (shProg
->Uniforms
->Parameters
[location
].Type
!= PROGRAM_SAMPLER
1235 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1240 /* XXX if this is a base type, then count must equal 1. However, we
1241 * don't have enough information from the compiler to distinguish a
1242 * base type from a 1-element array of that type. The standard allows
1243 * count to overrun an array, in which case the overflow is ignored.
1245 maxCount
= shProg
->Uniforms
->Parameters
[location
].Size
/ elems
;
1246 if (count
> maxCount
) count
= maxCount
;
1248 for (k
= 0; k
< count
; k
++) {
1249 GLfloat
*uniformVal
= shProg
->Uniforms
->ParameterValues
[location
+ k
];
1250 if (type
== GL_INT
||
1251 type
== GL_INT_VEC2
||
1252 type
== GL_INT_VEC3
||
1253 type
== GL_INT_VEC4
) {
1254 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1255 for (i
= 0; i
< elems
; i
++) {
1256 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1260 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1261 for (i
= 0; i
< elems
; i
++) {
1262 uniformVal
[i
] = fValues
[i
];
1265 if (uType
== GL_BOOL
||
1266 uType
== GL_BOOL_VEC2
||
1267 uType
== GL_BOOL_VEC3
||
1268 uType
== GL_BOOL_VEC4
) {
1269 for (i
= 0; i
< elems
; i
++)
1270 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1274 if (shProg
->Uniforms
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1275 if (shProg
->VertexProgram
)
1276 _slang_resolve_samplers(shProg
, &shProg
->VertexProgram
->Base
);
1277 if (shProg
->FragmentProgram
)
1278 _slang_resolve_samplers(shProg
, &shProg
->FragmentProgram
->Base
);
1279 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1285 * Called by ctx->Driver.UniformMatrix().
1288 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1289 GLenum matrixType
, GLint location
, GLsizei count
,
1290 GLboolean transpose
, const GLfloat
*values
)
1292 GLsizei maxCount
, i
;
1293 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1294 if (!shProg
|| !shProg
->LinkStatus
) {
1295 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1296 "glUniformMatrix(program not linked)");
1300 return; /* The standard specifies this as a no-op */
1301 /* The spec says this is GL_INVALID_OPERATION, although it seems like it
1302 * ought to be GL_INVALID_VALUE
1304 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumParameters
) {
1305 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
1308 if (values
== NULL
) {
1309 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1313 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(count < 0)");
1317 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1320 * Note: the _columns_ of a matrix are stored in program registers, not
1323 /* XXXX need to test 3x3 and 2x2 matrices... */
1324 maxCount
= shProg
->Uniforms
->Parameters
[location
].Size
/ (4 * cols
);
1325 if (count
> maxCount
)
1327 for (i
= 0; i
< count
; i
++) {
1330 for (col
= 0; col
< cols
; col
++) {
1331 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1332 for (row
= 0; row
< rows
; row
++) {
1333 v
[row
] = values
[row
* cols
+ col
];
1339 for (col
= 0; col
< cols
; col
++) {
1340 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
+ col
];
1341 for (row
= 0; row
< rows
; row
++) {
1342 v
[row
] = values
[col
* rows
+ row
];
1347 values
+= rows
* cols
;
1353 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1355 struct gl_shader_program
*shProg
;
1356 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1358 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1362 shProg
->Validated
= GL_TRUE
;
1364 /* From the GL spec:
1365 any two active samplers in the current program object are of
1366 different types, but refer to the same texture image unit,
1368 any active sampler in the current program object refers to a texture
1369 image unit where fixed-function fragment processing accesses a
1370 texture target that does not match the sampler type, or
1372 the sum of the number of active samplers in the program and the
1373 number of texture image units enabled for fixed-function fragment
1374 processing exceeds the combined limit on the total number of texture
1375 image units allowed.