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
);
372 const GLuint n
= shProg
->NumShaders
;
375 if (!shProg
|| !sh
) {
376 _mesa_error(ctx
, GL_INVALID_VALUE
,
377 "glAttachShader(bad program or shader name)");
381 for (i
= 0; i
< n
; i
++) {
382 if (shProg
->Shaders
[i
] == sh
) {
383 /* already attached */
389 shProg
->Shaders
= (struct gl_shader
**)
390 _mesa_realloc(shProg
->Shaders
,
391 n
* sizeof(struct gl_shader
*),
392 (n
+ 1) * sizeof(struct gl_shader
*));
393 if (!shProg
->Shaders
) {
394 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
399 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
400 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
401 shProg
->NumShaders
++;
406 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
409 struct gl_shader_program
*shProg
410 = _mesa_lookup_shader_program(ctx
, program
);
413 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttribLocation");
417 if (!shProg
->LinkStatus
) {
418 _mesa_error(ctx
, GL_INVALID_OPERATION
,
419 "glGetAttribLocation(program not linked)");
426 if (shProg
->Attributes
) {
427 GLint i
= _mesa_lookup_parameter_index(shProg
->Attributes
, -1, name
);
429 return shProg
->Attributes
->Parameters
[i
].StateIndexes
[0];
437 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
440 struct gl_shader_program
*shProg
441 = _mesa_lookup_shader_program(ctx
, program
);
442 const GLint size
= -1; /* unknown size */
446 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(program)");
453 if (strncmp(name
, "gl_", 3) == 0) {
454 _mesa_error(ctx
, GL_INVALID_OPERATION
,
455 "glBindAttribLocation(illegal name)");
459 if (shProg
->LinkStatus
) {
460 /* get current index/location for the attribute */
461 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
467 /* this will replace the current value if it's already in the list */
468 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, index
);
470 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
473 if (shProg
->VertexProgram
&& oldIndex
>= 0 && oldIndex
!= index
) {
474 /* If the index changed, need to search/replace references to that attribute
475 * in the vertex program.
477 _slang_remap_attribute(&shProg
->VertexProgram
->Base
, oldIndex
, index
);
483 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
485 struct gl_shader
*sh
;
488 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
491 case GL_FRAGMENT_SHADER
:
492 case GL_VERTEX_SHADER
:
493 sh
= _mesa_new_shader(ctx
, name
, type
);
496 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
500 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
507 _mesa_create_program(GLcontext
*ctx
)
510 struct gl_shader_program
*shProg
;
512 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
513 shProg
= _mesa_new_shader_program(ctx
, name
);
515 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
517 assert(shProg
->RefCount
== 1);
524 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
528 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
531 * NOTE: deleting shaders/programs works a bit differently than
532 * texture objects (and buffer objects, etc). Shader/program
533 * handles/IDs exist in the hash table until the object is really
534 * deleted (refcount==0). With texture objects, the handle/ID is
535 * removed from the hash table in glDeleteTextures() while the tex
536 * object itself might linger until its refcount goes to zero.
538 struct gl_shader_program
*shProg
;
540 shProg
= _mesa_lookup_shader_program(ctx
, name
);
542 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDeleteProgram(name)");
546 shProg
->DeletePending
= GL_TRUE
;
548 /* effectively, decr shProg's refcount */
549 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
554 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
556 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
561 sh
->DeletePending
= GL_TRUE
;
563 /* effectively, decr sh's refcount */
564 _mesa_reference_shader(ctx
, &sh
, NULL
);
569 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
571 struct gl_shader_program
*shProg
572 = _mesa_lookup_shader_program(ctx
, program
);
573 const GLuint n
= shProg
->NumShaders
;
577 _mesa_error(ctx
, GL_INVALID_VALUE
,
578 "glDetachShader(bad program or shader name)");
582 for (i
= 0; i
< n
; i
++) {
583 if (shProg
->Shaders
[i
]->Name
== shader
) {
585 struct gl_shader
**newList
;
588 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
590 /* alloc new, smaller array */
591 newList
= (struct gl_shader
**)
592 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
594 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
597 for (j
= 0; j
< i
; j
++) {
598 newList
[j
] = shProg
->Shaders
[j
];
601 newList
[j
++] = shProg
->Shaders
[i
];
602 _mesa_free(shProg
->Shaders
);
604 shProg
->Shaders
= newList
;
605 shProg
->NumShaders
= n
- 1;
610 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
611 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
612 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
613 assert(shProg
->Shaders
[j
]->RefCount
> 0);
623 _mesa_error(ctx
, GL_INVALID_VALUE
,
624 "glDetachShader(shader not found)");
629 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
630 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
631 GLenum
*type
, GLchar
*nameOut
)
633 static const GLenum vec_types
[] = {
634 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
636 struct gl_shader_program
*shProg
637 = _mesa_lookup_shader_program(ctx
, program
);
641 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib");
645 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
646 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
650 copy_string(nameOut
, maxLength
, length
,
651 shProg
->Attributes
->Parameters
[index
].Name
);
652 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
656 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
661 * Called via ctx->Driver.GetActiveUniform().
664 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
665 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
666 GLenum
*type
, GLchar
*nameOut
)
668 const struct gl_shader_program
*shProg
669 = _mesa_lookup_shader_program(ctx
, program
);
670 const struct gl_program
*prog
;
674 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform");
678 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
679 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
683 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
685 prog
= &shProg
->VertexProgram
->Base
;
688 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
690 prog
= &shProg
->FragmentProgram
->Base
;
694 if (!prog
|| progPos
< 0)
695 return; /* should never happen */
698 copy_string(nameOut
, maxLength
, length
,
699 prog
->Parameters
->Parameters
[progPos
].Name
);
701 *size
= prog
->Parameters
->Parameters
[progPos
].Size
;
704 *type
= prog
->Parameters
->Parameters
[progPos
].DataType
;
709 * Called via ctx->Driver.GetAttachedShaders().
712 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
713 GLsizei
*count
, GLuint
*obj
)
715 struct gl_shader_program
*shProg
716 = _mesa_lookup_shader_program(ctx
, program
);
719 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
720 obj
[i
] = shProg
->Shaders
[i
]->Name
;
726 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders");
732 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
735 GET_CURRENT_CONTEXT(ctx
);
738 case GL_PROGRAM_OBJECT_ARB
:
740 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
743 return (**pro
)._container
._generic
.
744 GetName((struct gl2_generic_intf
**) (pro
));
748 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
756 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
757 GLenum pname
, GLint
*params
)
759 struct gl_shader_program
*shProg
760 = _mesa_lookup_shader_program(ctx
, program
);
763 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
768 case GL_DELETE_STATUS
:
769 *params
= shProg
->DeletePending
;
772 *params
= shProg
->LinkStatus
;
774 case GL_VALIDATE_STATUS
:
775 *params
= shProg
->Validated
;
777 case GL_INFO_LOG_LENGTH
:
778 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
780 case GL_ATTACHED_SHADERS
:
781 *params
= shProg
->NumShaders
;
783 case GL_ACTIVE_ATTRIBUTES
:
784 *params
= shProg
->Attributes
? shProg
->Attributes
->NumParameters
: 0;
786 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
787 *params
= _mesa_longest_parameter_name(shProg
->Attributes
,
790 case GL_ACTIVE_UNIFORMS
:
791 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
793 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
794 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
796 (*params
)++; /* add one for terminating zero */
799 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
806 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
808 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
811 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
817 *params
= shader
->Type
;
819 case GL_DELETE_STATUS
:
820 *params
= shader
->DeletePending
;
822 case GL_COMPILE_STATUS
:
823 *params
= shader
->CompileStatus
;
825 case GL_INFO_LOG_LENGTH
:
826 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
828 case GL_SHADER_SOURCE_LENGTH
:
829 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
832 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
839 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
840 GLsizei
*length
, GLchar
*infoLog
)
842 struct gl_shader_program
*shProg
843 = _mesa_lookup_shader_program(ctx
, program
);
845 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
848 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
853 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
854 GLsizei
*length
, GLchar
*infoLog
)
856 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
858 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
861 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
866 * Called via ctx->Driver.GetShaderSource().
869 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
870 GLsizei
*length
, GLchar
*sourceOut
)
872 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
874 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
877 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
882 * Called via ctx->Driver.GetUniformfv().
885 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
888 struct gl_shader_program
*shProg
889 = _mesa_lookup_shader_program(ctx
, program
);
891 if (location
< shProg
->Uniforms
->NumUniforms
) {
893 const struct gl_program
*prog
;
895 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
897 prog
= &shProg
->VertexProgram
->Base
;
900 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
902 prog
= &shProg
->FragmentProgram
->Base
;
906 for (i
= 0; i
< prog
->Parameters
->Parameters
[progPos
].Size
; i
++) {
907 params
[i
] = prog
->Parameters
->ParameterValues
[progPos
][i
];
911 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
915 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(program)");
921 * Called via ctx->Driver.GetUniformLocation().
924 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
926 struct gl_shader_program
*shProg
927 = _mesa_lookup_shader_program(ctx
, program
);
931 return _mesa_lookup_uniform(shProg
->Uniforms
, name
);
936 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
938 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
939 return shProg
? GL_TRUE
: GL_FALSE
;
944 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
946 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
947 return shader
? GL_TRUE
: GL_FALSE
;
953 * Called via ctx->Driver.ShaderSource()
956 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
958 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
960 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
964 /* free old shader source string and install new one */
966 _mesa_free((void *) sh
->Source
);
969 sh
->CompileStatus
= GL_FALSE
;
974 * Called via ctx->Driver.CompileShader()
977 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
979 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
982 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
986 sh
->CompileStatus
= _slang_compile(ctx
, sh
);
991 * Called via ctx->Driver.LinkProgram()
994 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
996 struct gl_shader_program
*shProg
;
998 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1000 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLinkProgram(program)");
1004 _slang_link(ctx
, program
, shProg
);
1009 * Called via ctx->Driver.UseProgram()
1012 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1014 struct gl_shader_program
*shProg
;
1016 if (ctx
->Shader
.CurrentProgram
&&
1017 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1022 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1025 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1027 _mesa_error(ctx
, GL_INVALID_VALUE
,
1028 "glUseProgramObjectARB(programObj)");
1036 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1042 * Update the vertex and fragment program's TexturesUsed arrays.
1045 update_textures_used(struct gl_program
*prog
)
1049 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1051 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1052 if (prog
->SamplersUsed
& (1 << s
)) {
1053 GLuint u
= prog
->SamplerUnits
[s
];
1054 GLuint t
= prog
->SamplerTargets
[s
];
1055 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1056 prog
->TexturesUsed
[u
] |= (1 << t
);
1063 * Set the value of a program's uniform variable.
1064 * \param program the program whose uniform to update
1065 * \param location the location/index of the uniform
1066 * \param type the datatype of the uniform
1067 * \param count the number of uniforms to set
1068 * \param elems number of elements per uniform
1069 * \param values the new values
1072 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
, GLint location
,
1073 GLenum type
, GLint count
, GLint elems
, const void *values
)
1075 if (program
->Parameters
->Parameters
[location
].Type
== PROGRAM_SAMPLER
) {
1076 /* This controls which texture unit which is used by a sampler */
1077 GLuint texUnit
, sampler
;
1079 /* data type for setting samplers must be int */
1080 if (type
!= GL_INT
|| count
!= 1) {
1081 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1082 "glUniform(only glUniform1i can be used "
1083 "to set sampler uniforms)");
1087 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[location
][0];
1088 texUnit
= ((GLuint
*) values
)[0];
1090 /* check that the sampler (tex unit index) is legal */
1091 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1092 _mesa_error(ctx
, GL_INVALID_VALUE
,
1093 "glUniform1(invalid sampler/tex unit index)");
1097 /* This maps a sampler to a texture unit: */
1098 program
->SamplerUnits
[sampler
] = texUnit
;
1099 update_textures_used(program
);
1101 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1104 /* ordinary uniform variable */
1107 if (count
* elems
> program
->Parameters
->Parameters
[location
].Size
) {
1108 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(count too large)");
1112 for (k
= 0; k
< count
; k
++) {
1113 GLfloat
*uniformVal
= program
->Parameters
->ParameterValues
[location
+ k
];
1114 if (type
== GL_INT
||
1115 type
== GL_INT_VEC2
||
1116 type
== GL_INT_VEC3
||
1117 type
== GL_INT_VEC4
) {
1118 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1119 for (i
= 0; i
< elems
; i
++) {
1120 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1124 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1125 for (i
= 0; i
< elems
; i
++) {
1126 uniformVal
[i
] = fValues
[i
];
1135 * Called via ctx->Driver.Uniform().
1138 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1139 const GLvoid
*values
, GLenum type
)
1141 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1144 if (!shProg
|| !shProg
->LinkStatus
) {
1145 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1150 return; /* The standard specifies this as a no-op */
1153 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1154 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1159 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1181 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1185 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1187 /* A uniform var may be used by both a vertex shader and a fragment
1188 * shader. We may need to update one or both shader's uniform here:
1190 if (shProg
->VertexProgram
) {
1191 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1193 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1194 loc
, type
, count
, elems
, values
);
1198 if (shProg
->FragmentProgram
) {
1199 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1201 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1202 loc
, type
, count
, elems
, values
);
1209 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1210 GLuint location
, GLuint rows
, GLuint cols
,
1211 GLboolean transpose
, const GLfloat
*values
)
1214 * Note: the _columns_ of a matrix are stored in program registers, not
1217 /* XXXX need to test 3x3 and 2x2 matrices... */
1220 for (col
= 0; col
< cols
; col
++) {
1221 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1222 for (row
= 0; row
< rows
; row
++) {
1223 v
[row
] = values
[row
* cols
+ col
];
1229 for (col
= 0; col
< cols
; col
++) {
1230 GLfloat
*v
= program
->Parameters
->ParameterValues
[location
+ col
];
1231 for (row
= 0; row
< rows
; row
++) {
1232 v
[row
] = values
[col
* rows
+ row
];
1240 * Called by ctx->Driver.UniformMatrix().
1243 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1244 GLenum matrixType
, GLint location
, GLsizei count
,
1245 GLboolean transpose
, const GLfloat
*values
)
1247 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1249 if (!shProg
|| !shProg
->LinkStatus
) {
1250 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1251 "glUniformMatrix(program not linked)");
1256 return; /* The standard specifies this as a no-op */
1258 if (location
< 0 || location
>= shProg
->Uniforms
->NumUniforms
) {
1259 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1262 if (values
== NULL
) {
1263 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1267 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1269 if (shProg
->VertexProgram
) {
1270 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1272 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1273 loc
, rows
, cols
, transpose
, values
);
1277 if (shProg
->FragmentProgram
) {
1278 GLint loc
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1280 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1281 loc
, rows
, cols
, transpose
, values
);
1288 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1290 struct gl_shader_program
*shProg
;
1291 shProg
= _mesa_lookup_shader_program(ctx
, program
);
1293 _mesa_error(ctx
, GL_INVALID_VALUE
, "glValidateProgram(program)");
1297 shProg
->Validated
= GL_TRUE
;
1299 /* From the GL spec:
1300 any two active samplers in the current program object are of
1301 different types, but refer to the same texture image unit,
1303 any active sampler in the current program object refers to a texture
1304 image unit where fixed-function fragment processing accesses a
1305 texture target that does not match the sampler type, or
1307 the sum of the number of active samplers in the program and the
1308 number of texture image units enabled for fixed-function fragment
1309 processing exceeds the combined limit on the total number of texture
1310 image units allowed.
1316 * Plug in Mesa's GLSL functions into the device driver function table.
1319 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
1321 driver
->AttachShader
= _mesa_attach_shader
;
1322 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
1323 driver
->CompileShader
= _mesa_compile_shader
;
1324 driver
->CreateProgram
= _mesa_create_program
;
1325 driver
->CreateShader
= _mesa_create_shader
;
1326 driver
->DeleteProgram2
= _mesa_delete_program2
;
1327 driver
->DeleteShader
= _mesa_delete_shader
;
1328 driver
->DetachShader
= _mesa_detach_shader
;
1329 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
1330 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
1331 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
1332 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
1333 driver
->GetHandle
= _mesa_get_handle
;
1334 driver
->GetProgramiv
= _mesa_get_programiv
;
1335 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
1336 driver
->GetShaderiv
= _mesa_get_shaderiv
;
1337 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
1338 driver
->GetShaderSource
= _mesa_get_shader_source
;
1339 driver
->GetUniformfv
= _mesa_get_uniformfv
;
1340 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
1341 driver
->IsProgram
= _mesa_is_program
;
1342 driver
->IsShader
= _mesa_is_shader
;
1343 driver
->LinkProgram
= _mesa_link_program
;
1344 driver
->ShaderSource
= _mesa_shader_source
;
1345 driver
->Uniform
= _mesa_uniform
;
1346 driver
->UniformMatrix
= _mesa_uniform_matrix
;
1347 driver
->UseProgram
= _mesa_use_program
;
1348 driver
->ValidateProgram
= _mesa_validate_program
;