2 * Mesa 3-D graphics library
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Implementation of GLSL-related API functions
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/hash.h"
42 #include "main/macros.h"
43 #include "shader/program.h"
44 #include "shader/prog_parameter.h"
45 #include "shader/prog_print.h"
46 #include "shader/prog_statevars.h"
47 #include "shader/prog_uniform.h"
48 #include "shader/shader_api.h"
49 #include "shader/slang/slang_compile.h"
50 #include "shader/slang/slang_link.h"
51 #include "glapi/dispatch.h"
55 * Allocate a new gl_shader_program object, initialize it.
57 static struct gl_shader_program
*
58 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
60 struct gl_shader_program
*shProg
;
61 shProg
= CALLOC_STRUCT(gl_shader_program
);
63 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
66 shProg
->Attributes
= _mesa_new_parameter_list();
73 * Clear (free) the shader program state that gets produced by linking.
76 _mesa_clear_shader_program_data(GLcontext
*ctx
,
77 struct gl_shader_program
*shProg
)
79 _mesa_reference_vertprog(ctx
, &shProg
->VertexProgram
, NULL
);
80 _mesa_reference_fragprog(ctx
, &shProg
->FragmentProgram
, NULL
);
82 if (shProg
->Uniforms
) {
83 _mesa_free_uniform_list(shProg
->Uniforms
);
84 shProg
->Uniforms
= NULL
;
87 if (shProg
->Varying
) {
88 _mesa_free_parameter_list(shProg
->Varying
);
89 shProg
->Varying
= NULL
;
95 * Free all the data that hangs off a shader program object, but not the
99 _mesa_free_shader_program_data(GLcontext
*ctx
,
100 struct gl_shader_program
*shProg
)
104 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
106 _mesa_clear_shader_program_data(ctx
, shProg
);
108 if (shProg
->Attributes
) {
109 _mesa_free_parameter_list(shProg
->Attributes
);
110 shProg
->Attributes
= NULL
;
114 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
115 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
117 shProg
->NumShaders
= 0;
119 if (shProg
->Shaders
) {
120 _mesa_free(shProg
->Shaders
);
121 shProg
->Shaders
= NULL
;
124 if (shProg
->InfoLog
) {
125 _mesa_free(shProg
->InfoLog
);
126 shProg
->InfoLog
= NULL
;
132 * Free/delete a shader program object.
135 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
137 _mesa_free_shader_program_data(ctx
, shProg
);
144 * Set ptr to point to shProg.
145 * If ptr is pointing to another object, decrement its refcount (and delete
146 * if refcount hits zero).
147 * Then set ptr to point to shProg, incrementing its refcount.
149 /* XXX this could be static */
151 _mesa_reference_shader_program(GLcontext
*ctx
,
152 struct gl_shader_program
**ptr
,
153 struct gl_shader_program
*shProg
)
156 if (*ptr
== shProg
) {
161 /* Unreference the old shader program */
162 GLboolean deleteFlag
= GL_FALSE
;
163 struct gl_shader_program
*old
= *ptr
;
165 ASSERT(old
->RefCount
> 0);
168 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
169 (void *) old
, old
->Name
, old
->RefCount
);
171 deleteFlag
= (old
->RefCount
== 0);
174 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
175 _mesa_free_shader_program(ctx
, old
);
185 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
186 (void *) shProg
, shProg
->Name
, shProg
->RefCount
);
194 * Lookup a GLSL program object.
196 struct gl_shader_program
*
197 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
199 struct gl_shader_program
*shProg
;
201 shProg
= (struct gl_shader_program
*)
202 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
203 /* Note that both gl_shader and gl_shader_program objects are kept
204 * in the same hash table. Check the object's type to be sure it's
205 * what we're expecting.
207 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
217 * As above, but record an error if program is not found.
219 static struct gl_shader_program
*
220 _mesa_lookup_shader_program_err(GLcontext
*ctx
, GLuint name
,
224 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
228 struct gl_shader_program
*shProg
= (struct gl_shader_program
*)
229 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
231 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
234 if (shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
235 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
246 * Allocate a new gl_shader object, initialize it.
249 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
251 struct gl_shader
*shader
;
252 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
253 shader
= CALLOC_STRUCT(gl_shader
);
257 shader
->RefCount
= 1;
264 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
267 _mesa_free((void *) sh
->Source
);
269 _mesa_free(sh
->InfoLog
);
270 _mesa_reference_program(ctx
, &sh
->Program
, NULL
);
276 * Set ptr to point to sh.
277 * If ptr is pointing to another shader, decrement its refcount (and delete
278 * if refcount hits zero).
279 * Then set ptr to point to sh, incrementing its refcount.
281 /* XXX this could be static */
283 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
284 struct gl_shader
*sh
)
292 /* Unreference the old shader */
293 GLboolean deleteFlag
= GL_FALSE
;
294 struct gl_shader
*old
= *ptr
;
296 ASSERT(old
->RefCount
> 0);
298 /*printf("SHADER DECR %p (%d) to %d\n",
299 (void*) old, old->Name, old->RefCount);*/
300 deleteFlag
= (old
->RefCount
== 0);
303 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
304 _mesa_free_shader(ctx
, old
);
314 /*printf("SHADER INCR %p (%d) to %d\n",
315 (void*) sh, sh->Name, sh->RefCount);*/
322 * Lookup a GLSL shader object.
325 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
328 struct gl_shader
*sh
= (struct gl_shader
*)
329 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
330 /* Note that both gl_shader and gl_shader_program objects are kept
331 * in the same hash table. Check the object's type to be sure it's
332 * what we're expecting.
334 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
344 * As above, but record an error if shader is not found.
346 static struct gl_shader
*
347 _mesa_lookup_shader_err(GLcontext
*ctx
, GLuint name
, const char *caller
)
350 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
354 struct gl_shader
*sh
= (struct gl_shader
*)
355 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
357 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
360 if (sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
361 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
370 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
373 get_shader_flags(void)
375 GLbitfield flags
= 0x0;
376 const char *env
= _mesa_getenv("MESA_GLSL");
379 if (_mesa_strstr(env
, "dump"))
381 if (_mesa_strstr(env
, "log"))
383 if (_mesa_strstr(env
, "nopvert"))
384 flags
|= GLSL_NOP_VERT
;
385 if (_mesa_strstr(env
, "nopfrag"))
386 flags
|= GLSL_NOP_FRAG
;
387 if (_mesa_strstr(env
, "nopt"))
388 flags
|= GLSL_NO_OPT
;
389 else if (_mesa_strstr(env
, "opt"))
391 if (_mesa_strstr(env
, "uniform"))
392 flags
|= GLSL_UNIFORMS
;
393 if (_mesa_strstr(env
, "useprog"))
394 flags
|= GLSL_USE_PROG
;
402 * Initialize context's shader state.
405 _mesa_init_shader_state(GLcontext
* ctx
)
407 /* Device drivers may override these to control what kind of instructions
408 * are generated by the GLSL compiler.
410 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
411 ctx
->Shader
.EmitContReturn
= GL_TRUE
;
412 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;
413 ctx
->Shader
.EmitComments
= GL_FALSE
;
414 ctx
->Shader
.Flags
= get_shader_flags();
416 /* Default pragma settings */
417 ctx
->Shader
.DefaultPragmas
.IgnoreOptimize
= GL_FALSE
;
418 ctx
->Shader
.DefaultPragmas
.IgnoreDebug
= GL_FALSE
;
419 ctx
->Shader
.DefaultPragmas
.Optimize
= GL_TRUE
;
420 ctx
->Shader
.DefaultPragmas
.Debug
= GL_FALSE
;
425 * Free the per-context shader-related state.
428 _mesa_free_shader_state(GLcontext
*ctx
)
430 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
435 * Copy string from <src> to <dst>, up to maxLength characters, returning
436 * length of <dst> in <length>.
437 * \param src the strings source
438 * \param maxLength max chars to copy
439 * \param length returns number of chars copied
440 * \param dst the string destination
443 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
446 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
456 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
458 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
459 return shProg
? GL_TRUE
: GL_FALSE
;
464 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
466 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
467 return shader
? GL_TRUE
: GL_FALSE
;
472 * Called via ctx->Driver.AttachShader()
475 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
477 struct gl_shader_program
*shProg
;
478 struct gl_shader
*sh
;
481 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
485 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
490 n
= shProg
->NumShaders
;
491 for (i
= 0; i
< n
; i
++) {
492 if (shProg
->Shaders
[i
] == sh
) {
493 /* The shader is already attched to this program. The
494 * GL_ARB_shader_objects spec says:
496 * "The error INVALID_OPERATION is generated by AttachObjectARB
497 * if <obj> is already attached to <containerObj>."
499 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glAttachShader");
505 shProg
->Shaders
= (struct gl_shader
**)
506 _mesa_realloc(shProg
->Shaders
,
507 n
* sizeof(struct gl_shader
*),
508 (n
+ 1) * sizeof(struct gl_shader
*));
509 if (!shProg
->Shaders
) {
510 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
515 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
516 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
517 shProg
->NumShaders
++;
522 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
525 struct gl_shader_program
*shProg
526 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
532 if (!shProg
->LinkStatus
) {
533 _mesa_error(ctx
, GL_INVALID_OPERATION
,
534 "glGetAttribLocation(program not linked)");
541 if (shProg
->VertexProgram
) {
542 const struct gl_program_parameter_list
*attribs
=
543 shProg
->VertexProgram
->Base
.Attributes
;
545 GLint i
= _mesa_lookup_parameter_index(attribs
, -1, name
);
547 return attribs
->Parameters
[i
].StateIndexes
[0];
556 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
559 struct gl_shader_program
*shProg
;
560 const GLint size
= -1; /* unknown size */
562 GLenum datatype
= GL_FLOAT_VEC4
;
564 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
565 "glBindAttribLocation");
573 if (strncmp(name
, "gl_", 3) == 0) {
574 _mesa_error(ctx
, GL_INVALID_OPERATION
,
575 "glBindAttribLocation(illegal name)");
579 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
580 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
584 if (shProg
->LinkStatus
) {
585 /* get current index/location for the attribute */
586 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
592 /* this will replace the current value if it's already in the list */
593 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, datatype
, index
);
595 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
600 * Note that this attribute binding won't go into effect until
601 * glLinkProgram is called again.
607 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
609 struct gl_shader
*sh
;
612 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
615 case GL_FRAGMENT_SHADER
:
616 case GL_VERTEX_SHADER
:
617 sh
= _mesa_new_shader(ctx
, name
, type
);
620 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
624 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
631 _mesa_create_program(GLcontext
*ctx
)
634 struct gl_shader_program
*shProg
;
636 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
637 shProg
= _mesa_new_shader_program(ctx
, name
);
639 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
641 assert(shProg
->RefCount
== 1);
648 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
652 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
655 * NOTE: deleting shaders/programs works a bit differently than
656 * texture objects (and buffer objects, etc). Shader/program
657 * handles/IDs exist in the hash table until the object is really
658 * deleted (refcount==0). With texture objects, the handle/ID is
659 * removed from the hash table in glDeleteTextures() while the tex
660 * object itself might linger until its refcount goes to zero.
662 struct gl_shader_program
*shProg
;
664 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
668 shProg
->DeletePending
= GL_TRUE
;
670 /* effectively, decr shProg's refcount */
671 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
676 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
678 struct gl_shader
*sh
;
680 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
684 sh
->DeletePending
= GL_TRUE
;
686 /* effectively, decr sh's refcount */
687 _mesa_reference_shader(ctx
, &sh
, NULL
);
692 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
694 struct gl_shader_program
*shProg
;
698 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
702 n
= shProg
->NumShaders
;
704 for (i
= 0; i
< n
; i
++) {
705 if (shProg
->Shaders
[i
]->Name
== shader
) {
707 struct gl_shader
**newList
;
710 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
712 /* alloc new, smaller array */
713 newList
= (struct gl_shader
**)
714 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
716 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
719 for (j
= 0; j
< i
; j
++) {
720 newList
[j
] = shProg
->Shaders
[j
];
723 newList
[j
++] = shProg
->Shaders
[i
];
724 _mesa_free(shProg
->Shaders
);
726 shProg
->Shaders
= newList
;
727 shProg
->NumShaders
= n
- 1;
732 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
733 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
734 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
735 assert(shProg
->Shaders
[j
]->RefCount
> 0);
747 if (_mesa_is_shader(ctx
, shader
))
748 err
= GL_INVALID_OPERATION
;
749 else if (_mesa_is_program(ctx
, shader
))
750 err
= GL_INVALID_OPERATION
;
752 err
= GL_INVALID_VALUE
;
753 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
760 sizeof_glsl_type(GLenum type
)
769 case GL_SAMPLER_CUBE
:
770 case GL_SAMPLER_1D_SHADOW
:
771 case GL_SAMPLER_2D_SHADOW
:
772 case GL_SAMPLER_2D_RECT_ARB
:
773 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
774 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
775 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
776 case GL_SAMPLER_CUBE_SHADOW_EXT
:
791 case GL_FLOAT_MAT2x3
:
792 case GL_FLOAT_MAT2x4
:
793 return 8; /* two float[4] vectors */
795 case GL_FLOAT_MAT3x2
:
796 case GL_FLOAT_MAT3x4
:
797 return 12; /* three float[4] vectors */
799 case GL_FLOAT_MAT4x2
:
800 case GL_FLOAT_MAT4x3
:
801 return 16; /* four float[4] vectors */
803 _mesa_problem(NULL
, "Invalid type in sizeof_glsl_type()");
810 is_boolean_type(GLenum type
)
825 is_integer_type(GLenum type
)
840 is_sampler_type(GLenum type
)
846 case GL_SAMPLER_CUBE
:
847 case GL_SAMPLER_1D_SHADOW
:
848 case GL_SAMPLER_2D_SHADOW
:
849 case GL_SAMPLER_2D_RECT_ARB
:
850 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
851 case GL_SAMPLER_1D_ARRAY_EXT
:
852 case GL_SAMPLER_2D_ARRAY_EXT
:
861 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
862 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
863 GLenum
*type
, GLchar
*nameOut
)
865 const struct gl_program_parameter_list
*attribs
= NULL
;
866 struct gl_shader_program
*shProg
;
868 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
872 if (shProg
->VertexProgram
)
873 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
875 if (!attribs
|| index
>= attribs
->NumParameters
) {
876 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
880 copy_string(nameOut
, maxLength
, length
, attribs
->Parameters
[index
].Name
);
883 *size
= attribs
->Parameters
[index
].Size
884 / sizeof_glsl_type(attribs
->Parameters
[index
].DataType
);
887 *type
= attribs
->Parameters
[index
].DataType
;
891 static struct gl_program_parameter
*
892 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
894 const struct gl_program
*prog
= NULL
;
897 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
899 prog
= &shProg
->VertexProgram
->Base
;
902 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
904 prog
= &shProg
->FragmentProgram
->Base
;
908 if (!prog
|| progPos
< 0)
909 return NULL
; /* should never happen */
911 return &prog
->Parameters
->Parameters
[progPos
];
916 * Called via ctx->Driver.GetActiveUniform().
919 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
920 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
921 GLenum
*type
, GLchar
*nameOut
)
923 const struct gl_shader_program
*shProg
;
924 const struct gl_program
*prog
= NULL
;
925 const struct gl_program_parameter
*param
;
928 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
932 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
933 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
937 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
939 prog
= &shProg
->VertexProgram
->Base
;
942 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
944 prog
= &shProg
->FragmentProgram
->Base
;
948 if (!prog
|| progPos
< 0)
949 return; /* should never happen */
951 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
952 param
= &prog
->Parameters
->Parameters
[progPos
];
955 copy_string(nameOut
, maxLength
, length
, param
->Name
);
959 GLint typeSize
= sizeof_glsl_type(param
->DataType
);
960 if (param
->Size
> typeSize
) {
962 * Array elements are placed on vector[4] boundaries so they're
963 * a multiple of four floats. We round typeSize up to next multiple
964 * of four to get the right size below.
966 typeSize
= (typeSize
+ 3) & ~3;
968 /* Note that the returned size is in units of the <type>, not bytes */
969 *size
= param
->Size
/ typeSize
;
973 *type
= param
->DataType
;
979 * Called via ctx->Driver.GetAttachedShaders().
982 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
983 GLsizei
*count
, GLuint
*obj
)
985 struct gl_shader_program
*shProg
=
986 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
989 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
990 obj
[i
] = shProg
->Shaders
[i
]->Name
;
999 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
1003 if (pname
== GL_PROGRAM_OBJECT_ARB
) {
1004 CALL_GetIntegerv(ctx
->Exec
, (GL_CURRENT_PROGRAM
, &handle
));
1006 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
1014 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
1015 GLenum pname
, GLint
*params
)
1017 const struct gl_program_parameter_list
*attribs
;
1018 struct gl_shader_program
*shProg
1019 = _mesa_lookup_shader_program(ctx
, program
);
1022 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
1026 if (shProg
->VertexProgram
)
1027 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
1032 case GL_DELETE_STATUS
:
1033 *params
= shProg
->DeletePending
;
1035 case GL_LINK_STATUS
:
1036 *params
= shProg
->LinkStatus
;
1038 case GL_VALIDATE_STATUS
:
1039 *params
= shProg
->Validated
;
1041 case GL_INFO_LOG_LENGTH
:
1042 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
1044 case GL_ATTACHED_SHADERS
:
1045 *params
= shProg
->NumShaders
;
1047 case GL_ACTIVE_ATTRIBUTES
:
1048 *params
= attribs
? attribs
->NumParameters
: 0;
1050 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
1051 *params
= _mesa_longest_parameter_name(attribs
, PROGRAM_INPUT
) + 1;
1053 case GL_ACTIVE_UNIFORMS
:
1054 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
1056 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
1057 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
1059 (*params
)++; /* add one for terminating zero */
1061 case GL_PROGRAM_BINARY_LENGTH_OES
:
1065 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
1072 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
1074 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
1081 case GL_SHADER_TYPE
:
1082 *params
= shader
->Type
;
1084 case GL_DELETE_STATUS
:
1085 *params
= shader
->DeletePending
;
1087 case GL_COMPILE_STATUS
:
1088 *params
= shader
->CompileStatus
;
1090 case GL_INFO_LOG_LENGTH
:
1091 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
1093 case GL_SHADER_SOURCE_LENGTH
:
1094 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
1097 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
1104 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
1105 GLsizei
*length
, GLchar
*infoLog
)
1107 struct gl_shader_program
*shProg
1108 = _mesa_lookup_shader_program(ctx
, program
);
1110 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
1113 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
1118 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
1119 GLsizei
*length
, GLchar
*infoLog
)
1121 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1123 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
1126 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
1131 * Called via ctx->Driver.GetShaderSource().
1134 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
1135 GLsizei
*length
, GLchar
*sourceOut
)
1137 struct gl_shader
*sh
;
1138 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
1142 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
1147 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1153 case GL_FLOAT_MAT2x3
:
1157 case GL_FLOAT_MAT2x4
:
1165 case GL_FLOAT_MAT3x2
:
1169 case GL_FLOAT_MAT3x4
:
1177 case GL_FLOAT_MAT4x2
:
1181 case GL_FLOAT_MAT4x3
:
1192 * Determine the number of rows and columns occupied by a uniform
1193 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1194 * the number of rows = 1 and cols = number of elements in the vector.
1197 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
1198 GLint
*rows
, GLint
*cols
)
1200 get_matrix_dims(p
->DataType
, rows
, cols
);
1201 if (*rows
== 0 && *cols
== 0) {
1202 /* not a matrix type, probably a float or vector */
1208 *rows
= p
->Size
/ 4 + 1;
1209 if (p
->Size
% 4 == 0)
1212 *cols
= p
->Size
% 4;
1219 * Helper for get_uniform[fi]v() functions.
1220 * Given a shader program name and uniform location, return a pointer
1221 * to the shader program and return the program parameter position.
1224 lookup_uniform_parameter(GLcontext
*ctx
, GLuint program
, GLint location
,
1225 struct gl_program
**progOut
, GLint
*paramPosOut
)
1227 struct gl_shader_program
*shProg
1228 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
1229 struct gl_program
*prog
= NULL
;
1232 /* if shProg is NULL, we'll have already recorded an error */
1235 if (!shProg
->Uniforms
||
1237 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1238 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1241 /* OK, find the gl_program and program parameter location */
1242 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1244 prog
= &shProg
->VertexProgram
->Base
;
1247 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1249 prog
= &shProg
->FragmentProgram
->Base
;
1256 *paramPosOut
= progPos
;
1261 * Called via ctx->Driver.GetUniformfv().
1264 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1267 struct gl_program
*prog
;
1270 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1273 const struct gl_program_parameter
*p
=
1274 &prog
->Parameters
->Parameters
[paramPos
];
1275 GLint rows
, cols
, i
, j
, k
;
1277 get_uniform_rows_cols(p
, &rows
, &cols
);
1280 for (i
= 0; i
< rows
; i
++) {
1281 for (j
= 0; j
< cols
; j
++ ) {
1282 params
[k
++] = prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1290 * Called via ctx->Driver.GetUniformiv().
1291 * \sa _mesa_get_uniformfv, only difference is a cast.
1294 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1297 struct gl_program
*prog
;
1300 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1303 const struct gl_program_parameter
*p
=
1304 &prog
->Parameters
->Parameters
[paramPos
];
1305 GLint rows
, cols
, i
, j
, k
;
1307 get_uniform_rows_cols(p
, &rows
, &cols
);
1310 for (i
= 0; i
< rows
; i
++) {
1311 for (j
= 0; j
< cols
; j
++ ) {
1312 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1320 * The value returned by GetUniformLocation actually encodes two things:
1321 * 1. the index into the prog->Uniforms[] array for the uniform
1322 * 2. an offset in the prog->ParameterValues[] array for specifying array
1323 * elements or structure fields.
1324 * This function merges those two values.
1327 merge_location_offset(GLint
*location
, GLint offset
)
1329 *location
= *location
| (offset
<< 16);
1334 * Seperate the uniform location and parameter offset. See above.
1337 split_location_offset(GLint
*location
, GLint
*offset
)
1339 *offset
= (*location
>> 16);
1340 *location
= *location
& 0xffff;
1345 * Called via ctx->Driver.GetUniformLocation().
1347 * The return value will encode two values, the uniform location and an
1348 * offset (used for arrays, structs).
1351 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1353 GLint offset
= 0, location
= -1;
1355 struct gl_shader_program
*shProg
=
1356 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1361 if (shProg
->LinkStatus
== GL_FALSE
) {
1362 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1366 /* XXX we should return -1 if the uniform was declared, but not
1370 /* XXX we need to be able to parse uniform names for structs and arrays
1377 /* handle 1-dimension arrays here... */
1378 char *c
= strchr(name
, '[');
1380 /* truncate name at [ */
1381 const GLint len
= c
- name
;
1382 GLchar
*newName
= _mesa_malloc(len
+ 1);
1384 return -1; /* out of mem */
1385 _mesa_memcpy(newName
, name
, len
);
1388 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
1389 if (location
>= 0) {
1390 const GLint element
= _mesa_atoi(c
+ 1);
1392 /* get type of the uniform array element */
1393 struct gl_program_parameter
*p
;
1394 p
= get_uniform_parameter(shProg
, location
);
1397 get_matrix_dims(p
->DataType
, &rows
, &cols
);
1400 offset
= element
* rows
;
1405 _mesa_free(newName
);
1410 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1413 if (location
>= 0) {
1414 merge_location_offset(&location
, offset
);
1423 * Called via ctx->Driver.ShaderSource()
1426 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1428 struct gl_shader
*sh
;
1430 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1434 /* free old shader source string and install new one */
1436 _mesa_free((void *) sh
->Source
);
1438 sh
->Source
= source
;
1439 sh
->CompileStatus
= GL_FALSE
;
1441 sh
->SourceChecksum
= _mesa_str_checksum(sh
->Source
);
1447 * Called via ctx->Driver.CompileShader()
1450 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1452 struct gl_shader
*sh
;
1454 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1458 /* set default pragma state for shader */
1459 sh
->Pragmas
= ctx
->Shader
.DefaultPragmas
;
1461 /* this call will set the sh->CompileStatus field to indicate if
1462 * compilation was successful.
1464 (void) _slang_compile(ctx
, sh
);
1469 * Called via ctx->Driver.LinkProgram()
1472 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1474 struct gl_shader_program
*shProg
;
1476 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1480 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1482 _slang_link(ctx
, program
, shProg
);
1488 _mesa_printf("Link %u shaders in program %u: %s\n",
1489 shProg
->NumShaders
, shProg
->Name
,
1490 shProg
->LinkStatus
? "Success" : "Failed");
1492 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1493 _mesa_printf(" shader %u, type 0x%x\n",
1494 shProg
->Shaders
[i
]->Name
,
1495 shProg
->Shaders
[i
]->Type
);
1502 * Print basic shader info (for debug).
1505 print_shader_info(const struct gl_shader_program
*shProg
)
1509 _mesa_printf("Mesa: glUseProgram(%u)\n", shProg
->Name
);
1510 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1512 switch (shProg
->Shaders
[i
]->Type
) {
1513 case GL_VERTEX_SHADER
:
1516 case GL_FRAGMENT_SHADER
:
1519 case GL_GEOMETRY_SHADER
:
1525 _mesa_printf(" %s shader %u, checksum %u\n", s
,
1526 shProg
->Shaders
[i
]->Name
,
1527 shProg
->Shaders
[i
]->SourceChecksum
);
1529 if (shProg
->VertexProgram
)
1530 _mesa_printf(" vert prog %u\n", shProg
->VertexProgram
->Base
.Id
);
1531 if (shProg
->FragmentProgram
)
1532 _mesa_printf(" frag prog %u\n", shProg
->FragmentProgram
->Base
.Id
);
1537 * Called via ctx->Driver.UseProgram()
1540 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1542 struct gl_shader_program
*shProg
;
1544 if (ctx
->Shader
.CurrentProgram
&&
1545 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1551 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1555 if (!shProg
->LinkStatus
) {
1556 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1557 "glUseProgram(program %u not linked)", program
);
1562 if (ctx
->Shader
.Flags
& GLSL_USE_PROG
) {
1563 print_shader_info(shProg
);
1570 if (ctx
->Shader
.CurrentProgram
!= shProg
) {
1571 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
1572 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1579 * Update the vertex/fragment program's TexturesUsed array.
1581 * This needs to be called after glUniform(set sampler var) is called.
1582 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1583 * particular texture unit. We know the sampler's texture target
1584 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1585 * set by glUniform() calls.
1587 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1588 * information to update the prog->TexturesUsed[] values.
1589 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1590 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1591 * We'll use that info for state validation before rendering.
1594 _mesa_update_shader_textures_used(struct gl_program
*prog
)
1598 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1600 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1601 if (prog
->SamplersUsed
& (1 << s
)) {
1602 GLuint unit
= prog
->SamplerUnits
[s
];
1603 GLuint tgt
= prog
->SamplerTargets
[s
];
1604 assert(unit
< MAX_TEXTURE_IMAGE_UNITS
);
1605 assert(tgt
< NUM_TEXTURE_TARGETS
);
1606 prog
->TexturesUsed
[unit
] |= (1 << tgt
);
1613 * Check if the type given by userType is allowed to set a uniform of the
1614 * target type. Generally, equivalence is required, but setting Boolean
1615 * uniforms can be done with glUniformiv or glUniformfv.
1618 compatible_types(GLenum userType
, GLenum targetType
)
1620 if (userType
== targetType
)
1623 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1626 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1627 userType
== GL_INT_VEC2
))
1630 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1631 userType
== GL_INT_VEC3
))
1634 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1635 userType
== GL_INT_VEC4
))
1638 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1646 * Set the value of a program's uniform variable.
1647 * \param program the program whose uniform to update
1648 * \param index the index of the program parameter for the uniform
1649 * \param offset additional parameter slot offset (for arrays)
1650 * \param type the incoming datatype of 'values'
1651 * \param count the number of uniforms to set
1652 * \param elems number of elements per uniform (1, 2, 3 or 4)
1653 * \param values the new values, of datatype 'type'
1656 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
1657 GLint index
, GLint offset
,
1658 GLenum type
, GLsizei count
, GLint elems
,
1661 const struct gl_program_parameter
*param
=
1662 &program
->Parameters
->Parameters
[index
];
1664 assert(offset
>= 0);
1668 if (!compatible_types(type
, param
->DataType
)) {
1669 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1673 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
1674 /* out of bounds! */
1678 if (param
->Type
== PROGRAM_SAMPLER
) {
1679 /* This controls which texture unit which is used by a sampler */
1680 GLboolean changed
= GL_FALSE
;
1683 /* this should have been caught by the compatible_types() check */
1684 ASSERT(type
== GL_INT
);
1686 /* loop over number of samplers to change */
1687 for (i
= 0; i
< count
; i
++) {
1689 (GLuint
) program
->Parameters
->ParameterValues
[index
+ offset
+ i
][0];
1690 GLuint texUnit
= ((GLuint
*) values
)[i
];
1692 /* check that the sampler (tex unit index) is legal */
1693 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1694 _mesa_error(ctx
, GL_INVALID_VALUE
,
1695 "glUniform1(invalid sampler/tex unit index)");
1699 /* This maps a sampler to a texture unit: */
1700 if (sampler
< MAX_SAMPLERS
) {
1702 _mesa_printf("Set program %p sampler %d '%s' to unit %u\n",
1703 program
, sampler
, param
->Name
, texUnit
);
1705 if (program
->SamplerUnits
[sampler
] != texUnit
) {
1706 program
->SamplerUnits
[sampler
] = texUnit
;
1713 /* When a sampler's value changes it usually requires rewriting
1714 * a GPU program's TEX instructions since there may not be a
1715 * sampler->texture lookup table. We signal this with the
1716 * ProgramStringNotify() callback.
1718 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
| _NEW_PROGRAM
);
1719 _mesa_update_shader_textures_used(program
);
1720 ctx
->Driver
.ProgramStringNotify(ctx
, program
->Target
, program
);
1724 /* ordinary uniform variable */
1725 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
1726 const GLboolean areIntValues
= is_integer_type(type
);
1727 const GLint slots
= (param
->Size
+ 3) / 4;
1728 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1731 if (param
->Size
> typeSize
) {
1733 /* we'll ignore extra data below */
1736 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1738 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1739 "glUniform(uniform is not an array)");
1744 /* loop over number of array elements */
1745 for (k
= 0; k
< count
; k
++) {
1746 GLfloat
*uniformVal
;
1748 if (offset
+ k
>= slots
) {
1749 /* Extra array data is ignored */
1753 /* uniformVal (the destination) is always float[4] */
1754 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
1757 /* convert user's ints to floats */
1758 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1759 for (i
= 0; i
< elems
; i
++) {
1760 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1764 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1765 for (i
= 0; i
< elems
; i
++) {
1766 uniformVal
[i
] = fValues
[i
];
1770 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1771 if (isUniformBool
) {
1772 for (i
= 0; i
< elems
; i
++) {
1773 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1782 * Called via ctx->Driver.Uniform().
1785 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1786 const GLvoid
*values
, GLenum type
)
1788 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1789 struct gl_uniform
*uniform
;
1790 GLint elems
, offset
;
1793 if (!shProg
|| !shProg
->LinkStatus
) {
1794 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1799 return; /* The standard specifies this as a no-op */
1801 if (location
< -1) {
1802 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1806 split_location_offset(&location
, &offset
);
1808 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1809 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1814 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1820 basicType
= GL_FLOAT
;
1828 basicType
= GL_FLOAT
;
1836 basicType
= GL_FLOAT
;
1844 basicType
= GL_FLOAT
;
1852 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1856 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1858 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1860 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
1862 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1863 shProg
->Name
, uniform
->Name
, location
);
1864 if (basicType
== GL_INT
) {
1865 const GLint
*v
= (const GLint
*) values
;
1866 for (i
= 0; i
< count
* elems
; i
++) {
1867 _mesa_printf("%d ", v
[i
]);
1871 const GLfloat
*v
= (const GLfloat
*) values
;
1872 for (i
= 0; i
< count
* elems
; i
++) {
1873 _mesa_printf("%g ", v
[i
]);
1879 /* A uniform var may be used by both a vertex shader and a fragment
1880 * shader. We may need to update one or both shader's uniform here:
1882 if (shProg
->VertexProgram
) {
1883 /* convert uniform location to program parameter index */
1884 GLint index
= uniform
->VertPos
;
1886 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1887 index
, offset
, type
, count
, elems
, values
);
1891 if (shProg
->FragmentProgram
) {
1892 /* convert uniform location to program parameter index */
1893 GLint index
= uniform
->FragPos
;
1895 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1896 index
, offset
, type
, count
, elems
, values
);
1900 uniform
->Initialized
= GL_TRUE
;
1905 * Set a matrix-valued program parameter.
1908 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1909 GLuint index
, GLuint offset
,
1910 GLuint count
, GLuint rows
, GLuint cols
,
1911 GLboolean transpose
, const GLfloat
*values
)
1913 GLuint mat
, row
, col
;
1915 const struct gl_program_parameter
* param
= &program
->Parameters
->Parameters
[index
];
1916 const GLint slots
= (param
->Size
+ 3) / 4;
1917 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1920 /* check that the number of rows, columns is correct */
1921 get_matrix_dims(param
->DataType
, &nr
, &nc
);
1922 if (rows
!= nr
|| cols
!= nc
) {
1923 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1924 "glUniformMatrix(matrix size mismatch)");
1928 if (param
->Size
<= typeSize
) {
1929 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1931 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1932 "glUniformMatrix(uniform is not an array)");
1938 * Note: the _columns_ of a matrix are stored in program registers, not
1939 * the rows. So, the loops below look a little funny.
1940 * XXX could optimize this a bit...
1943 /* loop over matrices */
1944 for (mat
= 0; mat
< count
; mat
++) {
1947 for (col
= 0; col
< cols
; col
++) {
1949 if (offset
>= slots
) {
1950 /* Ignore writes beyond the end of (the used part of) an array */
1953 v
= program
->Parameters
->ParameterValues
[index
+ offset
];
1954 for (row
= 0; row
< rows
; row
++) {
1956 v
[row
] = values
[src
+ row
* cols
+ col
];
1959 v
[row
] = values
[src
+ col
* rows
+ row
];
1966 src
+= rows
* cols
; /* next matrix */
1972 * Called by ctx->Driver.UniformMatrix().
1973 * Note: cols=2, rows=4 ==> array[2] of vec4
1976 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1977 GLint location
, GLsizei count
,
1978 GLboolean transpose
, const GLfloat
*values
)
1980 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1981 struct gl_uniform
*uniform
;
1984 if (!shProg
|| !shProg
->LinkStatus
) {
1985 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1986 "glUniformMatrix(program not linked)");
1991 return; /* The standard specifies this as a no-op */
1993 if (location
< -1) {
1994 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
1998 split_location_offset(&location
, &offset
);
2000 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
2001 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
2004 if (values
== NULL
) {
2005 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
2009 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
2011 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
2013 if (shProg
->VertexProgram
) {
2014 /* convert uniform location to program parameter index */
2015 GLint index
= uniform
->VertPos
;
2017 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
2019 count
, rows
, cols
, transpose
, values
);
2023 if (shProg
->FragmentProgram
) {
2024 /* convert uniform location to program parameter index */
2025 GLint index
= uniform
->FragPos
;
2027 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
2029 count
, rows
, cols
, transpose
, values
);
2033 uniform
->Initialized
= GL_TRUE
;
2038 * Validate a program's samplers.
2039 * Specifically, check that there aren't two samplers of different types
2040 * pointing to the same texture unit.
2041 * \return GL_TRUE if valid, GL_FALSE if invalid
2044 validate_samplers(GLcontext
*ctx
, const struct gl_program
*prog
, char *errMsg
)
2046 static const char *targetName
[] = {
2055 GLint targetUsed
[MAX_TEXTURE_IMAGE_UNITS
];
2056 GLbitfield samplersUsed
= prog
->SamplersUsed
;
2059 assert(Elements(targetName
) == NUM_TEXTURE_TARGETS
);
2061 if (samplersUsed
== 0x0)
2064 for (i
= 0; i
< Elements(targetUsed
); i
++)
2067 /* walk over bits which are set in 'samplers' */
2068 while (samplersUsed
) {
2070 gl_texture_index target
;
2071 GLint sampler
= _mesa_ffs(samplersUsed
) - 1;
2072 assert(sampler
>= 0);
2073 assert(sampler
< MAX_TEXTURE_IMAGE_UNITS
);
2074 unit
= prog
->SamplerUnits
[sampler
];
2075 target
= prog
->SamplerTargets
[sampler
];
2076 if (targetUsed
[unit
] != -1 && targetUsed
[unit
] != target
) {
2077 _mesa_snprintf(errMsg
, 100,
2078 "Texture unit %d is accessed both as %s and %s",
2079 unit
, targetName
[targetUsed
[unit
]], targetName
[target
]);
2082 targetUsed
[unit
] = target
;
2083 samplersUsed
^= (1 << sampler
);
2091 * Do validation of the given shader program.
2092 * \param errMsg returns error message if validation fails.
2093 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2096 _mesa_validate_shader_program(GLcontext
*ctx
,
2097 const struct gl_shader_program
*shProg
,
2100 const struct gl_vertex_program
*vp
= shProg
->VertexProgram
;
2101 const struct gl_fragment_program
*fp
= shProg
->FragmentProgram
;
2103 if (!shProg
->LinkStatus
) {
2107 /* From the GL spec, a program is invalid if any of these are true:
2109 any two active samplers in the current program object are of
2110 different types, but refer to the same texture image unit,
2112 any active sampler in the current program object refers to a texture
2113 image unit where fixed-function fragment processing accesses a
2114 texture target that does not match the sampler type, or
2116 the sum of the number of active samplers in the program and the
2117 number of texture image units enabled for fixed-function fragment
2118 processing exceeds the combined limit on the total number of texture
2119 image units allowed.
2124 * Check: any two active samplers in the current program object are of
2125 * different types, but refer to the same texture image unit,
2127 if (vp
&& !validate_samplers(ctx
, &vp
->Base
, errMsg
)) {
2130 if (fp
&& !validate_samplers(ctx
, &fp
->Base
, errMsg
)) {
2139 * Called via glValidateProgram()
2142 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
2144 struct gl_shader_program
*shProg
;
2147 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
2152 shProg
->Validated
= _mesa_validate_shader_program(ctx
, shProg
, errMsg
);
2153 if (!shProg
->Validated
) {
2154 /* update info log */
2155 if (shProg
->InfoLog
) {
2156 _mesa_free(shProg
->InfoLog
);
2158 shProg
->InfoLog
= _mesa_strdup(errMsg
);
2164 * Plug in Mesa's GLSL functions into the device driver function table.
2167 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
2169 driver
->AttachShader
= _mesa_attach_shader
;
2170 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
2171 driver
->CompileShader
= _mesa_compile_shader
;
2172 driver
->CreateProgram
= _mesa_create_program
;
2173 driver
->CreateShader
= _mesa_create_shader
;
2174 driver
->DeleteProgram2
= _mesa_delete_program2
;
2175 driver
->DeleteShader
= _mesa_delete_shader
;
2176 driver
->DetachShader
= _mesa_detach_shader
;
2177 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
2178 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
2179 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
2180 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
2181 driver
->GetHandle
= _mesa_get_handle
;
2182 driver
->GetProgramiv
= _mesa_get_programiv
;
2183 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
2184 driver
->GetShaderiv
= _mesa_get_shaderiv
;
2185 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
2186 driver
->GetShaderSource
= _mesa_get_shader_source
;
2187 driver
->GetUniformfv
= _mesa_get_uniformfv
;
2188 driver
->GetUniformiv
= _mesa_get_uniformiv
;
2189 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
2190 driver
->IsProgram
= _mesa_is_program
;
2191 driver
->IsShader
= _mesa_is_shader
;
2192 driver
->LinkProgram
= _mesa_link_program
;
2193 driver
->ShaderSource
= _mesa_shader_source
;
2194 driver
->Uniform
= _mesa_uniform
;
2195 driver
->UniformMatrix
= _mesa_uniform_matrix
;
2196 driver
->UseProgram
= _mesa_use_program
;
2197 driver
->ValidateProgram
= _mesa_validate_program
;