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 * Allocate a new gl_shader object, initialize it.
219 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
221 struct gl_shader
*shader
;
222 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
223 shader
= CALLOC_STRUCT(gl_shader
);
227 shader
->RefCount
= 1;
234 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
238 _mesa_free((void *) sh
->Source
);
240 _mesa_free(sh
->InfoLog
);
241 for (i
= 0; i
< sh
->NumPrograms
; i
++)
242 _mesa_reference_program(ctx
, &sh
->Programs
[i
], NULL
);
244 _mesa_free(sh
->Programs
);
250 * Set ptr to point to sh.
251 * If ptr is pointing to another shader, decrement its refcount (and delete
252 * if refcount hits zero).
253 * Then set ptr to point to sh, incrementing its refcount.
255 /* XXX this could be static */
257 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
258 struct gl_shader
*sh
)
266 /* Unreference the old shader */
267 GLboolean deleteFlag
= GL_FALSE
;
268 struct gl_shader
*old
= *ptr
;
270 ASSERT(old
->RefCount
> 0);
272 /*printf("SHADER DECR %p (%d) to %d\n",
273 (void*) old, old->Name, old->RefCount);*/
274 deleteFlag
= (old
->RefCount
== 0);
277 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
278 _mesa_free_shader(ctx
, old
);
288 /*printf("SHADER INCR %p (%d) to %d\n",
289 (void*) sh, sh->Name, sh->RefCount);*/
296 * Lookup a GLSL shader object.
299 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
302 struct gl_shader
*sh
= (struct gl_shader
*)
303 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
304 /* Note that both gl_shader and gl_shader_program objects are kept
305 * in the same hash table. Check the object's type to be sure it's
306 * what we're expecting.
308 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
318 * Initialize context's shader state.
321 _mesa_init_shader_state(GLcontext
* ctx
)
323 /* Device drivers may override these to control what kind of instructions
324 * are generated by the GLSL compiler.
326 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
327 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
328 ctx
->Shader
.EmitComments
= GL_FALSE
;
333 * Free the per-context shader-related state.
336 _mesa_free_shader_state(GLcontext
*ctx
)
338 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
343 * Copy string from <src> to <dst>, up to maxLength characters, returning
344 * length of <dst> in <length>.
345 * \param src the strings source
346 * \param maxLength max chars to copy
347 * \param length returns number of chars copied
348 * \param dst the string destination
351 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
354 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
364 * Called via ctx->Driver.AttachShader()
367 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
369 struct gl_shader_program
*shProg
370 = _mesa_lookup_shader_program(ctx
, program
);
371 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
375 if (!shProg
|| !sh
) {
376 _mesa_error(ctx
, GL_INVALID_VALUE
,
377 "glAttachShader(bad program or shader name)");
381 n
= shProg
->NumShaders
;
383 for (i
= 0; i
< n
; i
++) {
384 if (shProg
->Shaders
[i
] == sh
) {
385 /* already attached */
391 shProg
->Shaders
= (struct gl_shader
**)
392 _mesa_realloc(shProg
->Shaders
,
393 n
* sizeof(struct gl_shader
*),
394 (n
+ 1) * sizeof(struct gl_shader
*));
395 if (!shProg
->Shaders
) {
396 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
401 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
402 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
403 shProg
->NumShaders
++;
408 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
411 struct gl_shader_program
*shProg
412 = _mesa_lookup_shader_program(ctx
, program
);
415 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
419 if (!shProg
->LinkStatus
) {
420 _mesa_error(ctx
, GL_INVALID_OPERATION
,
421 "glGetAttribLocation(program not linked)");
428 if (shProg
->Attributes
) {
429 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
431 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
439 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
442 struct gl_shader_program
*shProg
443 = _mesa_lookup_shader_program(ctx
, program
);
444 const GLint size
= -1; /* unknown size */
448 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
455 if (strncmp(name
, "gl_", 3) == 0) {
456 _mesa_error(ctx
, GL_INVALID_OPERATION
,
457 "glBindAttribLocation(illegal name)");
461 if (shProg
->LinkStatus
) {
462 /* get current index/location for the attribute */
463 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
469 /* this will replace the current value if it's already in the list */
470 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
472 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
475 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
476 /* If the index changed, need to search/replace references to that attribute
477 * in the vertex program.
479 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
485 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
487 struct gl_shader
*sh
;
490 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
493 case GL_FRAGMENT_SHADER
:
494 case GL_VERTEX_SHADER
:
495 sh
= _mesa_new_shader(ctx
, name
, type
);
498 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
502 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
509 _mesa_create_program(GLcontext
*ctx
)
512 struct gl_shader_program
*shProg
;
514 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
515 shProg
= _mesa_new_shader_program(ctx
, name
);
517 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
519 assert(shProg
->RefCount
== 1);
526 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
530 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
533 * NOTE: deleting shaders/programs works a bit differently than
534 * texture objects (and buffer objects, etc). Shader/program
535 * handles/IDs exist in the hash table until the object is really
536 * deleted (refcount==0). With texture objects, the handle/ID is
537 * removed from the hash table in glDeleteTextures() while the tex
538 * object itself might linger until its refcount goes to zero.
540 struct gl_shader_program
*shProg
;
542 shProg
= _mesa_lookup_shader_program(ctx
, name
);
544 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
548 shProg
->DeletePending
= GL_TRUE
;
550 /* effectively, decr shProg's refcount */
551 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
556 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
558 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
563 sh
->DeletePending
= GL_TRUE
;
565 /* effectively, decr sh's refcount */
566 _mesa_reference_shader(ctx
, &sh
, NULL
);
571 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
573 struct gl_shader_program
*shProg
574 = _mesa_lookup_shader_program(ctx
, program
);
579 _mesa_error(ctx
, GL_INVALID_VALUE
,
580 "glDetachShader(bad program or shader name)");
584 n
= shProg
->NumShaders
;
586 for (i
= 0; i
< n
; i
++) {
587 if (shProg
->Shaders
[i
]->Name
== shader
) {
589 struct gl_shader
**newList
;
592 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
594 /* alloc new, smaller array */
595 newList
= (struct gl_shader
**)
596 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
598 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
601 for (j
= 0; j
< i
; j
++) {
602 newList
[j
] = shProg
->Shaders
[j
];
605 newList
[j
++] = shProg
->Shaders
[i
];
606 _mesa_free(shProg
->Shaders
);
608 shProg
->Shaders
= newList
;
609 shProg
->NumShaders
= n
- 1;
614 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
615 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
616 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
617 assert(shProg
->Shaders
[j
]->RefCount
> 0);
627 _mesa_error(ctx
, GL_INVALID_VALUE
,
628 "glDetachShader(shader not found)");
633 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
634 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
635 GLenum
*type
, GLchar
*nameOut
)
637 static const GLenum vec_types
[] = {
638 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
640 struct gl_shader_program
*shProg
641 = _mesa_lookup_shader_program(ctx
, program
);
645 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
649 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
650 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
654 copy_string(nameOut
, maxLength
, length
,
655 shProg
->Attributes
->Parameters
[index
].Name
);
656 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
660 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
665 * Called via ctx->Driver.GetActiveUniform().
668 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
669 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
670 GLenum
*type
, GLchar
*nameOut
)
672 const struct gl_shader_program
*shProg
673 = _mesa_lookup_shader_program(ctx
, program
);
674 const struct gl_program
*prog
;
678 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
682 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
683 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
687 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
689 prog
= &shProg
->VertexProgram
->Base
;
692 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
694 prog
= &shProg
->FragmentProgram
->Base
;
698 if (!prog
|| progPos
< 0)
699 return; /* should never happen */
702 copy_string(nameOut
, maxLength
, length
,
703 prog
->Parameters
->Parameters
[progPos
].Name
);
705 *size
= prog
->Parameters
->Parameters
[progPos
].Size
;
708 *type
= prog
->Parameters
->Parameters
[progPos
].DataType
;
713 * Called via ctx->Driver.GetAttachedShaders().
716 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
717 GLsizei
*count
, GLuint
*obj
)
719 struct gl_shader_program
*shProg
720 = _mesa_lookup_shader_program(ctx
, program
);
723 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
724 obj
[i
] = shProg
->Shaders
[i
]->Name
;
730 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
736 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
739 GET_CURRENT_CONTEXT(ctx
);
742 case GL_PROGRAM_OBJECT_ARB
:
744 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
747 return (**pro
)._container
._generic
.
748 GetName((struct gl2_generic_intf
**) (pro
));
752 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
760 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
761 GLenum pname
, GLint
*params
)
763 struct gl_shader_program
*shProg
764 = _mesa_lookup_shader_program(ctx
, program
);
767 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
772 case GL_DELETE_STATUS
:
773 *params
= shProg
->DeletePending
;
776 *params
= shProg
->LinkStatus
;
778 case GL_VALIDATE_STATUS
:
779 *params
= shProg
->Validated
;
781 case GL_INFO_LOG_LENGTH
:
782 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
784 case GL_ATTACHED_SHADERS
:
785 *params
= shProg
->NumShaders
;
787 case GL_ACTIVE_ATTRIBUTES
:
788 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
790 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
791 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
794 case GL_ACTIVE_UNIFORMS
:
795 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
797 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
798 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
800 (*params
)++; /* add one for terminating zero */
803 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
810 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
812 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
815 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
821 *params
= shader
->Type
;
823 case GL_DELETE_STATUS
:
824 *params
= shader
->DeletePending
;
826 case GL_COMPILE_STATUS
:
827 *params
= shader
->CompileStatus
;
829 case GL_INFO_LOG_LENGTH
:
830 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
832 case GL_SHADER_SOURCE_LENGTH
:
833 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
836 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
843 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
844 GLsizei
*length
, GLchar
*infoLog
)
846 struct gl_shader_program
*shProg
847 = _mesa_lookup_shader_program(ctx
, program
);
849 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
852 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
857 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
858 GLsizei
*length
, GLchar
*infoLog
)
860 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
862 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
865 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
870 * Called via ctx->Driver.GetShaderSource().
873 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
874 GLsizei
*length
, GLchar
*sourceOut
)
876 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
879 if (_mesa_lookup_shader_program(ctx
, shader
))
880 err
= GL_INVALID_OPERATION
;
882 err
= GL_INVALID_VALUE
;
883 _mesa_error(ctx
, err
, "glGetShaderSource(shader)");
886 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
891 * Called via ctx->Driver.GetUniformfv().
894 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
897 struct gl_shader_program
*shProg
898 = _mesa_lookup_shader_program(ctx
, program
);
900 if (shProg
->Uniforms
&&
901 location
>= 0 && location
< shProg
->Uniforms
->NumUniforms
) {
904 const struct gl_program
*prog
= NULL
;
906 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
908 prog
= &shProg
->VertexProgram
->Base
;
911 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
913 prog
= &shProg
->FragmentProgram
->Base
;
919 for (i
= 0; i
< prog
->Parameters
->Parameters
[progPos
].Size
; i
++) {
920 params
[i
] = prog
->Parameters
->ParameterValues
[progPos
][i
];
925 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
929 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
935 * Called via ctx->Driver.GetUniformLocation().
938 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
940 struct gl_shader_program
*shProg
941 = _mesa_lookup_shader_program(ctx
, program
);
945 return _mesa_lookup_uniform(shProg
->Uniforms
, name
);
950 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
952 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
953 return shProg
? GL_TRUE
: GL_FALSE
;
958 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
960 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
961 return shader
? GL_TRUE
: GL_FALSE
;
967 * Called via ctx->Driver.ShaderSource()
970 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
972 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
975 if (_mesa_lookup_shader_program(ctx
, shader
))
976 err
= GL_INVALID_OPERATION
;
978 err
= GL_INVALID_VALUE
;
979 _mesa_error(ctx
, err
, "glShaderSource(shaderObj)");
983 /* free old shader source string and install new one */
985 _mesa_free((void *) sh
->Source
);
988 sh
->CompileStatus
= GL_FALSE
;
993 * Called via ctx->Driver.CompileShader()
996 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
998 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
1001 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
1005 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
1010 * Called via ctx->Driver.LinkProgram()
1013 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1015 struct gl_shader_program
*shProg
;
1017 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1019 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1023 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1025 _slang_link(ctx
, program
, shProg
);
1030 * Called via ctx->Driver.UseProgram()
1033 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1035 struct gl_shader_program
*shProg
;
1037 if (ctx
->Shader
.CurrentProgram
&&
1038 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1043 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1046 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1048 _mesa_error(ctx
, GL_INVALID_VALUE
,
1049 "glUseProgramObjectARB(programObj)");
1057 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1063 * Update the vertex and fragment program's TexturesUsed arrays.
1066 update_textures_used(struct gl_program
*prog
)
1070 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1072 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1073 if (prog
->SamplersUsed
& (1 << s
)) {
1074 GLuint u
= prog
->SamplerUnits
[s
];
1075 GLuint t
= prog
->SamplerTargets
[s
];
1076 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1077 prog
->TexturesUsed
[u
] |= (1 << t
);
1084 * Set the value of a program's uniform variable.
1085 * \param program the program whose uniform to update
1086 * \param location the location/index of the uniform
1087 * \param type the datatype of the uniform
1088 * \param count the number of uniforms to set
1089 * \param elems number of elements per uniform
1090 * \param values the new values
1093 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
, GLint location
,
1094 GLenum type
, GLsizei count
, GLint elems
, const void *values
)
1096 if (program
->Parameters
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1097 /* This controls which texture unit which is used by a sampler */
1098 GLuint texUnit
, sampler
;
1100 /* data type for setting samplers must be int */
1101 if (type
!= GL_INT
|| count
!= 1) {
1102 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1103 "glUniform(only glUniform1i can be used "
1104 "to set sampler uniforms)");
1108 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[location
][0];
1109 texUnit
= ((GLuint
*) values
)[0];
1111 /* check that the sampler (tex unit index) is legal */
1112 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1113 _mesa_error(ctx
, GL_INVALID_VALUE
,
1114 "glUniform1(invalid sampler/tex unit index)");
1118 /* This maps a sampler to a texture unit: */
1119 program
->SamplerUnits
[sampler
] = texUnit
;
1120 update_textures_used(program
);
1122 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1125 /* ordinary uniform variable */
1128 if (count
* elems
> program
->Parameters
->Parameters
[location
].Size
) {
1129 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1133 for (k
= 0; k
< count
; k
++) {
1134 GLfloat
*uniformVal
= program
->Parameters
->ParameterValues
[location
+ k
];
1135 if (type
== GL_INT
||
1136 type
== GL_INT_VEC2
||
1137 type
== GL_INT_VEC3
||
1138 type
== GL_INT_VEC4
) {
1139 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1140 for (i
= 0; i
< elems
; i
++) {
1141 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1145 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1146 for (i
= 0; i
< elems
; i
++) {
1147 uniformVal
[i
] = fValues
[i
];
1156 * Called via ctx->Driver.Uniform().
1159 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1160 const GLvoid
*values
, GLenum type
)
1162 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1165 if (!shProg
|| !shProg
->LinkStatus
) {
1166 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1171 return; /* The standard specifies this as a no-op */
1174 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1175 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1180 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1202 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1206 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1208 /* A uniform var may be used by both a vertex shader and a fragment
1209 * shader. We may need to update one or both shader's uniform here:
1211 if (shProg
->VertexProgram
) {
1212 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1214 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1215 loc
, type
, count
, elems
, values
);
1219 if (shProg
->FragmentProgram
) {
1220 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1222 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1223 loc
, type
, count
, elems
, values
);
1230 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1231 GLuint location
, GLuint rows
, GLuint cols
,
1232 GLboolean transpose
, const GLfloat
*values
)
1235 * Note: the _columns_ of a matrix are stored in program registers, not
1238 /* XXXX need to test 3x3 and 2x2 matrices... */
1241 for (col
= 0; col
< cols
; col
++) {
1242 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1243 for (row
= 0; row
< rows
; row
++) {
1244 v
[row
] = values
[row
* cols
+ col
];
1250 for (col
= 0; col
< cols
; col
++) {
1251 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1252 for (row
= 0; row
< rows
; row
++) {
1253 v
[row
] = values
[col
* rows
+ row
];
1261 * Called by ctx->Driver.UniformMatrix().
1264 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1265 GLenum matrixType
, GLint location
, GLsizei count
,
1266 GLboolean transpose
, const GLfloat
*values
)
1268 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1270 if (!shProg
|| !shProg
->LinkStatus
) {
1271 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1272 "glUniformMatrix(program not linked)");
1277 return; /* The standard specifies this as a no-op */
1279 if (location
< 0 || location
>= shProg
->Uniforms
->NumUniforms
) {
1280 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1283 if (values
== NULL
) {
1284 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1288 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1290 if (shProg
->VertexProgram
) {
1291 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1293 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1294 loc
, rows
, cols
, transpose
, values
);
1298 if (shProg
->FragmentProgram
) {
1299 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1301 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1302 loc
, rows
, cols
, transpose
, values
);
1309 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1311 struct gl_shader_program
*shProg
;
1312 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1314 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1318 shProg
->Validated
= GL_TRUE
;
1320 /* From the GL spec:
1321 any two active samplers in the current program object are of
1322 different types, but refer to the same texture image unit,
1324 any active sampler in the current program object refers to a texture
1325 image unit where fixed-function fragment processing accesses a
1326 texture target that does not match the sampler type, or
1328 the sum of the number of active samplers in the program and the
1329 number of texture image units enabled for fixed-function fragment
1330 processing exceeds the combined limit on the total number of texture
1331 image units allowed.
1337 * Plug in Mesa's GLSL functions into the device driver function table.
1340 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
1342 driver
->AttachShader
= _mesa_attach_shader
;
1343 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
1344 driver
->CompileShader
= _mesa_compile_shader
;
1345 driver
->CreateProgram
= _mesa_create_program
;
1346 driver
->CreateShader
= _mesa_create_shader
;
1347 driver
->DeleteProgram2
= _mesa_delete_program2
;
1348 driver
->DeleteShader
= _mesa_delete_shader
;
1349 driver
->DetachShader
= _mesa_detach_shader
;
1350 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
1351 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
1352 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
1353 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
1354 driver
->GetHandle
= _mesa_get_handle
;
1355 driver
->GetProgramiv
= _mesa_get_programiv
;
1356 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
1357 driver
->GetShaderiv
= _mesa_get_shaderiv
;
1358 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
1359 driver
->GetShaderSource
= _mesa_get_shader_source
;
1360 driver
->GetUniformfv
= _mesa_get_uniformfv
;
1361 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
1362 driver
->IsProgram
= _mesa_is_program
;
1363 driver
->IsShader
= _mesa_is_shader
;
1364 driver
->LinkProgram
= _mesa_link_program
;
1365 driver
->ShaderSource
= _mesa_shader_source
;
1366 driver
->Uniform
= _mesa_uniform
;
1367 driver
->UniformMatrix
= _mesa_uniform_matrix
;
1368 driver
->UseProgram
= _mesa_use_program
;
1369 driver
->ValidateProgram
= _mesa_validate_program
;