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 "shader/program.h"
43 #include "shader/prog_parameter.h"
44 #include "shader/prog_statevars.h"
45 #include "shader/prog_uniform.h"
46 #include "shader/shader_api.h"
47 #include "shader/slang/slang_compile.h"
48 #include "shader/slang/slang_link.h"
49 #include "main/dispatch.h"
53 * Allocate a new gl_shader_program object, initialize it.
55 static struct gl_shader_program
*
56 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
58 struct gl_shader_program
*shProg
;
59 shProg
= CALLOC_STRUCT(gl_shader_program
);
61 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
64 shProg
->Attributes
= _mesa_new_parameter_list();
71 * Clear (free) the shader program state that gets produced by linking.
74 _mesa_clear_shader_program_data(GLcontext
*ctx
,
75 struct gl_shader_program
*shProg
)
77 _mesa_reference_vertprog(ctx
, &shProg
->VertexProgram
, NULL
);
78 _mesa_reference_fragprog(ctx
, &shProg
->FragmentProgram
, NULL
);
80 if (shProg
->Uniforms
) {
81 _mesa_free_uniform_list(shProg
->Uniforms
);
82 shProg
->Uniforms
= NULL
;
85 if (shProg
->Varying
) {
86 _mesa_free_parameter_list(shProg
->Varying
);
87 shProg
->Varying
= NULL
;
93 * Free all the data that hangs off a shader program object, but not the
97 _mesa_free_shader_program_data(GLcontext
*ctx
,
98 struct gl_shader_program
*shProg
)
102 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
104 _mesa_clear_shader_program_data(ctx
, shProg
);
106 if (shProg
->Attributes
) {
107 _mesa_free_parameter_list(shProg
->Attributes
);
108 shProg
->Attributes
= NULL
;
112 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
113 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
115 shProg
->NumShaders
= 0;
117 if (shProg
->Shaders
) {
118 free(shProg
->Shaders
);
119 shProg
->Shaders
= NULL
;
122 if (shProg
->InfoLog
) {
123 free(shProg
->InfoLog
);
124 shProg
->InfoLog
= NULL
;
130 * Free/delete a shader program object.
133 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
135 _mesa_free_shader_program_data(ctx
, shProg
);
142 * Set ptr to point to shProg.
143 * If ptr is pointing to another object, decrement its refcount (and delete
144 * if refcount hits zero).
145 * Then set ptr to point to shProg, incrementing its refcount.
147 /* XXX this could be static */
149 _mesa_reference_shader_program(GLcontext
*ctx
,
150 struct gl_shader_program
**ptr
,
151 struct gl_shader_program
*shProg
)
154 if (*ptr
== shProg
) {
159 /* Unreference the old shader program */
160 GLboolean deleteFlag
= GL_FALSE
;
161 struct gl_shader_program
*old
= *ptr
;
163 ASSERT(old
->RefCount
> 0);
166 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
167 (void *) old
, old
->Name
, old
->RefCount
);
169 deleteFlag
= (old
->RefCount
== 0);
172 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
173 _mesa_free_shader_program(ctx
, old
);
183 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
184 (void *) shProg
, shProg
->Name
, shProg
->RefCount
);
192 * Lookup a GLSL program object.
194 struct gl_shader_program
*
195 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
197 struct gl_shader_program
*shProg
;
199 shProg
= (struct gl_shader_program
*)
200 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
201 /* Note that both gl_shader and gl_shader_program objects are kept
202 * in the same hash table. Check the object's type to be sure it's
203 * what we're expecting.
205 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
215 * As above, but record an error if program is not found.
217 static struct gl_shader_program
*
218 _mesa_lookup_shader_program_err(GLcontext
*ctx
, GLuint name
,
222 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
226 struct gl_shader_program
*shProg
= (struct gl_shader_program
*)
227 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
229 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
232 if (shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
233 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
244 * Allocate a new gl_shader object, initialize it.
247 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
249 struct gl_shader
*shader
;
250 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
251 shader
= CALLOC_STRUCT(gl_shader
);
255 shader
->RefCount
= 1;
262 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
265 free((void *) sh
->Source
);
268 _mesa_reference_program(ctx
, &sh
->Program
, NULL
);
274 * Set ptr to point to sh.
275 * If ptr is pointing to another shader, decrement its refcount (and delete
276 * if refcount hits zero).
277 * Then set ptr to point to sh, incrementing its refcount.
279 /* XXX this could be static */
281 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
282 struct gl_shader
*sh
)
290 /* Unreference the old shader */
291 GLboolean deleteFlag
= GL_FALSE
;
292 struct gl_shader
*old
= *ptr
;
294 ASSERT(old
->RefCount
> 0);
296 /*printf("SHADER DECR %p (%d) to %d\n",
297 (void*) old, old->Name, old->RefCount);*/
298 deleteFlag
= (old
->RefCount
== 0);
301 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
302 _mesa_free_shader(ctx
, old
);
312 /*printf("SHADER INCR %p (%d) to %d\n",
313 (void*) sh, sh->Name, sh->RefCount);*/
320 * Lookup a GLSL shader object.
323 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
326 struct gl_shader
*sh
= (struct gl_shader
*)
327 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
328 /* Note that both gl_shader and gl_shader_program objects are kept
329 * in the same hash table. Check the object's type to be sure it's
330 * what we're expecting.
332 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
342 * As above, but record an error if shader is not found.
344 static struct gl_shader
*
345 _mesa_lookup_shader_err(GLcontext
*ctx
, GLuint name
, const char *caller
)
348 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
352 struct gl_shader
*sh
= (struct gl_shader
*)
353 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
355 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
358 if (sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
359 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
368 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
371 get_shader_flags(void)
373 GLbitfield flags
= 0x0;
374 const char *env
= _mesa_getenv("MESA_GLSL");
377 if (strstr(env
, "dump"))
379 if (strstr(env
, "log"))
381 if (strstr(env
, "nopvert"))
382 flags
|= GLSL_NOP_VERT
;
383 if (strstr(env
, "nopfrag"))
384 flags
|= GLSL_NOP_FRAG
;
385 if (strstr(env
, "nopt"))
386 flags
|= GLSL_NO_OPT
;
387 else if (strstr(env
, "opt"))
389 if (strstr(env
, "uniform"))
390 flags
|= GLSL_UNIFORMS
;
391 if (strstr(env
, "useprog"))
392 flags
|= GLSL_USE_PROG
;
400 * Initialize context's shader state.
403 _mesa_init_shader_state(GLcontext
* ctx
)
405 /* Device drivers may override these to control what kind of instructions
406 * are generated by the GLSL compiler.
408 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
409 ctx
->Shader
.EmitContReturn
= GL_TRUE
;
410 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;
411 ctx
->Shader
.EmitComments
= GL_FALSE
;
412 ctx
->Shader
.Flags
= get_shader_flags();
414 /* Default pragma settings */
415 ctx
->Shader
.DefaultPragmas
.IgnoreOptimize
= GL_FALSE
;
416 ctx
->Shader
.DefaultPragmas
.IgnoreDebug
= GL_FALSE
;
417 ctx
->Shader
.DefaultPragmas
.Optimize
= GL_TRUE
;
418 ctx
->Shader
.DefaultPragmas
.Debug
= GL_FALSE
;
423 * Free the per-context shader-related state.
426 _mesa_free_shader_state(GLcontext
*ctx
)
428 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
433 * Copy string from <src> to <dst>, up to maxLength characters, returning
434 * length of <dst> in <length>.
435 * \param src the strings source
436 * \param maxLength max chars to copy
437 * \param length returns number of chars copied
438 * \param dst the string destination
441 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
444 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
454 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
456 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
457 return shProg
? GL_TRUE
: GL_FALSE
;
462 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
464 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
465 return shader
? GL_TRUE
: GL_FALSE
;
470 * Called via ctx->Driver.AttachShader()
473 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
475 struct gl_shader_program
*shProg
;
476 struct gl_shader
*sh
;
479 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
483 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
488 n
= shProg
->NumShaders
;
489 for (i
= 0; i
< n
; i
++) {
490 if (shProg
->Shaders
[i
] == sh
) {
491 /* The shader is already attched to this program. The
492 * GL_ARB_shader_objects spec says:
494 * "The error INVALID_OPERATION is generated by AttachObjectARB
495 * if <obj> is already attached to <containerObj>."
497 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glAttachShader");
503 shProg
->Shaders
= (struct gl_shader
**)
504 _mesa_realloc(shProg
->Shaders
,
505 n
* sizeof(struct gl_shader
*),
506 (n
+ 1) * sizeof(struct gl_shader
*));
507 if (!shProg
->Shaders
) {
508 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
513 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
514 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
515 shProg
->NumShaders
++;
520 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
523 struct gl_shader_program
*shProg
524 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
530 if (!shProg
->LinkStatus
) {
531 _mesa_error(ctx
, GL_INVALID_OPERATION
,
532 "glGetAttribLocation(program not linked)");
539 if (shProg
->VertexProgram
) {
540 const struct gl_program_parameter_list
*attribs
=
541 shProg
->VertexProgram
->Base
.Attributes
;
543 GLint i
= _mesa_lookup_parameter_index(attribs
, -1, name
);
545 return attribs
->Parameters
[i
].StateIndexes
[0];
554 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
557 struct gl_shader_program
*shProg
;
558 const GLint size
= -1; /* unknown size */
560 GLenum datatype
= GL_FLOAT_VEC4
;
562 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
563 "glBindAttribLocation");
571 if (strncmp(name
, "gl_", 3) == 0) {
572 _mesa_error(ctx
, GL_INVALID_OPERATION
,
573 "glBindAttribLocation(illegal name)");
577 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
578 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
582 if (shProg
->LinkStatus
) {
583 /* get current index/location for the attribute */
584 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
590 /* this will replace the current value if it's already in the list */
591 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, datatype
, index
);
593 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
598 * Note that this attribute binding won't go into effect until
599 * glLinkProgram is called again.
605 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
607 struct gl_shader
*sh
;
610 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
613 case GL_FRAGMENT_SHADER
:
614 case GL_VERTEX_SHADER
:
615 sh
= _mesa_new_shader(ctx
, name
, type
);
618 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
622 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
629 _mesa_create_program(GLcontext
*ctx
)
632 struct gl_shader_program
*shProg
;
634 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
635 shProg
= _mesa_new_shader_program(ctx
, name
);
637 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
639 assert(shProg
->RefCount
== 1);
646 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
650 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
653 * NOTE: deleting shaders/programs works a bit differently than
654 * texture objects (and buffer objects, etc). Shader/program
655 * handles/IDs exist in the hash table until the object is really
656 * deleted (refcount==0). With texture objects, the handle/ID is
657 * removed from the hash table in glDeleteTextures() while the tex
658 * object itself might linger until its refcount goes to zero.
660 struct gl_shader_program
*shProg
;
662 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
666 shProg
->DeletePending
= GL_TRUE
;
668 /* effectively, decr shProg's refcount */
669 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
674 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
676 struct gl_shader
*sh
;
678 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
682 sh
->DeletePending
= GL_TRUE
;
684 /* effectively, decr sh's refcount */
685 _mesa_reference_shader(ctx
, &sh
, NULL
);
690 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
692 struct gl_shader_program
*shProg
;
696 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
700 n
= shProg
->NumShaders
;
702 for (i
= 0; i
< n
; i
++) {
703 if (shProg
->Shaders
[i
]->Name
== shader
) {
705 struct gl_shader
**newList
;
708 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
710 /* alloc new, smaller array */
711 newList
= (struct gl_shader
**)
712 malloc((n
- 1) * sizeof(struct gl_shader
*));
714 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
717 for (j
= 0; j
< i
; j
++) {
718 newList
[j
] = shProg
->Shaders
[j
];
721 newList
[j
++] = shProg
->Shaders
[i
];
722 free(shProg
->Shaders
);
724 shProg
->Shaders
= newList
;
725 shProg
->NumShaders
= n
- 1;
730 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
731 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
732 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
733 assert(shProg
->Shaders
[j
]->RefCount
> 0);
745 if (_mesa_is_shader(ctx
, shader
))
746 err
= GL_INVALID_OPERATION
;
747 else if (_mesa_is_program(ctx
, shader
))
748 err
= GL_INVALID_OPERATION
;
750 err
= GL_INVALID_VALUE
;
751 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
758 sizeof_glsl_type(GLenum type
)
767 case GL_SAMPLER_CUBE
:
768 case GL_SAMPLER_1D_SHADOW
:
769 case GL_SAMPLER_2D_SHADOW
:
770 case GL_SAMPLER_2D_RECT_ARB
:
771 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
772 case GL_SAMPLER_1D_ARRAY_EXT
:
773 case GL_SAMPLER_2D_ARRAY_EXT
:
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
:
853 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
854 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
863 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
864 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
865 GLenum
*type
, GLchar
*nameOut
)
867 const struct gl_program_parameter_list
*attribs
= NULL
;
868 struct gl_shader_program
*shProg
;
870 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
874 if (shProg
->VertexProgram
)
875 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
877 if (!attribs
|| index
>= attribs
->NumParameters
) {
878 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
882 copy_string(nameOut
, maxLength
, length
, attribs
->Parameters
[index
].Name
);
885 *size
= attribs
->Parameters
[index
].Size
886 / sizeof_glsl_type(attribs
->Parameters
[index
].DataType
);
889 *type
= attribs
->Parameters
[index
].DataType
;
893 static struct gl_program_parameter
*
894 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
896 const struct gl_program
*prog
= NULL
;
899 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
901 prog
= &shProg
->VertexProgram
->Base
;
904 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
906 prog
= &shProg
->FragmentProgram
->Base
;
910 if (!prog
|| progPos
< 0)
911 return NULL
; /* should never happen */
913 return &prog
->Parameters
->Parameters
[progPos
];
918 * Called via ctx->Driver.GetActiveUniform().
921 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
922 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
923 GLenum
*type
, GLchar
*nameOut
)
925 const struct gl_shader_program
*shProg
;
926 const struct gl_program
*prog
= NULL
;
927 const struct gl_program_parameter
*param
;
930 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
934 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
935 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
939 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
941 prog
= &shProg
->VertexProgram
->Base
;
944 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
946 prog
= &shProg
->FragmentProgram
->Base
;
950 if (!prog
|| progPos
< 0)
951 return; /* should never happen */
953 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
954 param
= &prog
->Parameters
->Parameters
[progPos
];
957 copy_string(nameOut
, maxLength
, length
, param
->Name
);
961 GLint typeSize
= sizeof_glsl_type(param
->DataType
);
962 if ((GLint
) param
->Size
> typeSize
) {
964 * Array elements are placed on vector[4] boundaries so they're
965 * a multiple of four floats. We round typeSize up to next multiple
966 * of four to get the right size below.
968 typeSize
= (typeSize
+ 3) & ~3;
970 /* Note that the returned size is in units of the <type>, not bytes */
971 *size
= param
->Size
/ typeSize
;
975 *type
= param
->DataType
;
981 * Called via ctx->Driver.GetAttachedShaders().
984 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
985 GLsizei
*count
, GLuint
*obj
)
987 struct gl_shader_program
*shProg
=
988 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
991 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
992 obj
[i
] = shProg
->Shaders
[i
]->Name
;
1001 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
1005 if (pname
== GL_PROGRAM_OBJECT_ARB
) {
1006 CALL_GetIntegerv(ctx
->Exec
, (GL_CURRENT_PROGRAM
, &handle
));
1008 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
1016 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
1017 GLenum pname
, GLint
*params
)
1019 const struct gl_program_parameter_list
*attribs
;
1020 struct gl_shader_program
*shProg
1021 = _mesa_lookup_shader_program(ctx
, program
);
1024 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
1028 if (shProg
->VertexProgram
)
1029 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
1034 case GL_DELETE_STATUS
:
1035 *params
= shProg
->DeletePending
;
1037 case GL_LINK_STATUS
:
1038 *params
= shProg
->LinkStatus
;
1040 case GL_VALIDATE_STATUS
:
1041 *params
= shProg
->Validated
;
1043 case GL_INFO_LOG_LENGTH
:
1044 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
1046 case GL_ATTACHED_SHADERS
:
1047 *params
= shProg
->NumShaders
;
1049 case GL_ACTIVE_ATTRIBUTES
:
1050 *params
= attribs
? attribs
->NumParameters
: 0;
1052 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
1053 *params
= _mesa_longest_parameter_name(attribs
, PROGRAM_INPUT
) + 1;
1055 case GL_ACTIVE_UNIFORMS
:
1056 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
1058 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
1059 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
1061 (*params
)++; /* add one for terminating zero */
1063 case GL_PROGRAM_BINARY_LENGTH_OES
:
1067 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
1074 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
1076 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
1083 case GL_SHADER_TYPE
:
1084 *params
= shader
->Type
;
1086 case GL_DELETE_STATUS
:
1087 *params
= shader
->DeletePending
;
1089 case GL_COMPILE_STATUS
:
1090 *params
= shader
->CompileStatus
;
1092 case GL_INFO_LOG_LENGTH
:
1093 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
1095 case GL_SHADER_SOURCE_LENGTH
:
1096 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
1099 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
1106 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
1107 GLsizei
*length
, GLchar
*infoLog
)
1109 struct gl_shader_program
*shProg
1110 = _mesa_lookup_shader_program(ctx
, program
);
1112 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
1115 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
1120 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
1121 GLsizei
*length
, GLchar
*infoLog
)
1123 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1125 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
1128 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
1133 * Called via ctx->Driver.GetShaderSource().
1136 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
1137 GLsizei
*length
, GLchar
*sourceOut
)
1139 struct gl_shader
*sh
;
1140 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
1144 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
1149 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1155 case GL_FLOAT_MAT2x3
:
1159 case GL_FLOAT_MAT2x4
:
1167 case GL_FLOAT_MAT3x2
:
1171 case GL_FLOAT_MAT3x4
:
1179 case GL_FLOAT_MAT4x2
:
1183 case GL_FLOAT_MAT4x3
:
1194 * Determine the number of rows and columns occupied by a uniform
1195 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1196 * the number of rows = 1 and cols = number of elements in the vector.
1199 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
1200 GLint
*rows
, GLint
*cols
)
1202 get_matrix_dims(p
->DataType
, rows
, cols
);
1203 if (*rows
== 0 && *cols
== 0) {
1204 /* not a matrix type, probably a float or vector */
1210 *rows
= p
->Size
/ 4 + 1;
1211 if (p
->Size
% 4 == 0)
1214 *cols
= p
->Size
% 4;
1221 * Helper for get_uniform[fi]v() functions.
1222 * Given a shader program name and uniform location, return a pointer
1223 * to the shader program and return the program parameter position.
1226 lookup_uniform_parameter(GLcontext
*ctx
, GLuint program
, GLint location
,
1227 struct gl_program
**progOut
, GLint
*paramPosOut
)
1229 struct gl_shader_program
*shProg
1230 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
1231 struct gl_program
*prog
= NULL
;
1234 /* if shProg is NULL, we'll have already recorded an error */
1237 if (!shProg
->Uniforms
||
1239 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1240 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1243 /* OK, find the gl_program and program parameter location */
1244 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1246 prog
= &shProg
->VertexProgram
->Base
;
1249 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1251 prog
= &shProg
->FragmentProgram
->Base
;
1258 *paramPosOut
= progPos
;
1263 * Called via ctx->Driver.GetUniformfv().
1266 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1269 struct gl_program
*prog
;
1272 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1275 const struct gl_program_parameter
*p
=
1276 &prog
->Parameters
->Parameters
[paramPos
];
1277 GLint rows
, cols
, i
, j
, k
;
1279 get_uniform_rows_cols(p
, &rows
, &cols
);
1282 for (i
= 0; i
< rows
; i
++) {
1283 for (j
= 0; j
< cols
; j
++ ) {
1284 params
[k
++] = prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1292 * Called via ctx->Driver.GetUniformiv().
1293 * \sa _mesa_get_uniformfv, only difference is a cast.
1296 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1299 struct gl_program
*prog
;
1302 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1305 const struct gl_program_parameter
*p
=
1306 &prog
->Parameters
->Parameters
[paramPos
];
1307 GLint rows
, cols
, i
, j
, k
;
1309 get_uniform_rows_cols(p
, &rows
, &cols
);
1312 for (i
= 0; i
< rows
; i
++) {
1313 for (j
= 0; j
< cols
; j
++ ) {
1314 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1322 * The value returned by GetUniformLocation actually encodes two things:
1323 * 1. the index into the prog->Uniforms[] array for the uniform
1324 * 2. an offset in the prog->ParameterValues[] array for specifying array
1325 * elements or structure fields.
1326 * This function merges those two values.
1329 merge_location_offset(GLint
*location
, GLint offset
)
1331 *location
= *location
| (offset
<< 16);
1336 * Seperate the uniform location and parameter offset. See above.
1339 split_location_offset(GLint
*location
, GLint
*offset
)
1341 *offset
= (*location
>> 16);
1342 *location
= *location
& 0xffff;
1347 * Called via ctx->Driver.GetUniformLocation().
1349 * The return value will encode two values, the uniform location and an
1350 * offset (used for arrays, structs).
1353 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1355 GLint offset
= 0, location
= -1;
1357 struct gl_shader_program
*shProg
=
1358 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1363 if (shProg
->LinkStatus
== GL_FALSE
) {
1364 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1368 /* XXX we should return -1 if the uniform was declared, but not
1372 /* XXX we need to be able to parse uniform names for structs and arrays
1379 /* handle 1-dimension arrays here... */
1380 char *c
= strchr(name
, '[');
1382 /* truncate name at [ */
1383 const GLint len
= c
- name
;
1384 GLchar
*newName
= malloc(len
+ 1);
1386 return -1; /* out of mem */
1387 memcpy(newName
, name
, len
);
1390 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
1391 if (location
>= 0) {
1392 const GLint element
= atoi(c
+ 1);
1394 /* get type of the uniform array element */
1395 struct gl_program_parameter
*p
;
1396 p
= get_uniform_parameter(shProg
, location
);
1399 get_matrix_dims(p
->DataType
, &rows
, &cols
);
1402 offset
= element
* rows
;
1412 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1415 if (location
>= 0) {
1416 merge_location_offset(&location
, offset
);
1425 * Called via ctx->Driver.ShaderSource()
1428 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1430 struct gl_shader
*sh
;
1432 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1436 /* free old shader source string and install new one */
1438 free((void *) sh
->Source
);
1440 sh
->Source
= source
;
1441 sh
->CompileStatus
= GL_FALSE
;
1443 sh
->SourceChecksum
= _mesa_str_checksum(sh
->Source
);
1449 * Called via ctx->Driver.CompileShader()
1452 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1454 struct gl_shader
*sh
;
1456 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1460 /* set default pragma state for shader */
1461 sh
->Pragmas
= ctx
->Shader
.DefaultPragmas
;
1463 /* this call will set the sh->CompileStatus field to indicate if
1464 * compilation was successful.
1466 (void) _slang_compile(ctx
, sh
);
1471 * Called via ctx->Driver.LinkProgram()
1474 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1476 struct gl_shader_program
*shProg
;
1478 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1482 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1484 _slang_link(ctx
, program
, shProg
);
1490 printf("Link %u shaders in program %u: %s\n",
1491 shProg
->NumShaders
, shProg
->Name
,
1492 shProg
->LinkStatus
? "Success" : "Failed");
1494 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1495 printf(" shader %u, type 0x%x\n",
1496 shProg
->Shaders
[i
]->Name
,
1497 shProg
->Shaders
[i
]->Type
);
1504 * Print basic shader info (for debug).
1507 print_shader_info(const struct gl_shader_program
*shProg
)
1511 printf("Mesa: glUseProgram(%u)\n", shProg
->Name
);
1512 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1514 switch (shProg
->Shaders
[i
]->Type
) {
1515 case GL_VERTEX_SHADER
:
1518 case GL_FRAGMENT_SHADER
:
1521 case GL_GEOMETRY_SHADER
:
1527 printf(" %s shader %u, checksum %u\n", s
,
1528 shProg
->Shaders
[i
]->Name
,
1529 shProg
->Shaders
[i
]->SourceChecksum
);
1531 if (shProg
->VertexProgram
)
1532 printf(" vert prog %u\n", shProg
->VertexProgram
->Base
.Id
);
1533 if (shProg
->FragmentProgram
)
1534 printf(" frag prog %u\n", shProg
->FragmentProgram
->Base
.Id
);
1539 * Called via ctx->Driver.UseProgram()
1542 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1544 struct gl_shader_program
*shProg
;
1546 if (ctx
->Shader
.CurrentProgram
&&
1547 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1553 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1557 if (!shProg
->LinkStatus
) {
1558 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1559 "glUseProgram(program %u not linked)", program
);
1564 if (ctx
->Shader
.Flags
& GLSL_USE_PROG
) {
1565 print_shader_info(shProg
);
1572 if (ctx
->Shader
.CurrentProgram
!= shProg
) {
1573 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
1574 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1581 * Update the vertex/fragment program's TexturesUsed array.
1583 * This needs to be called after glUniform(set sampler var) is called.
1584 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1585 * particular texture unit. We know the sampler's texture target
1586 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1587 * set by glUniform() calls.
1589 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1590 * information to update the prog->TexturesUsed[] values.
1591 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1592 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1593 * We'll use that info for state validation before rendering.
1596 _mesa_update_shader_textures_used(struct gl_program
*prog
)
1600 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1602 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1603 if (prog
->SamplersUsed
& (1 << s
)) {
1604 GLuint unit
= prog
->SamplerUnits
[s
];
1605 GLuint tgt
= prog
->SamplerTargets
[s
];
1606 assert(unit
< MAX_TEXTURE_IMAGE_UNITS
);
1607 assert(tgt
< NUM_TEXTURE_TARGETS
);
1608 prog
->TexturesUsed
[unit
] |= (1 << tgt
);
1615 * Check if the type given by userType is allowed to set a uniform of the
1616 * target type. Generally, equivalence is required, but setting Boolean
1617 * uniforms can be done with glUniformiv or glUniformfv.
1620 compatible_types(GLenum userType
, GLenum targetType
)
1622 if (userType
== targetType
)
1625 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1628 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1629 userType
== GL_INT_VEC2
))
1632 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1633 userType
== GL_INT_VEC3
))
1636 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1637 userType
== GL_INT_VEC4
))
1640 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1648 * Set the value of a program's uniform variable.
1649 * \param program the program whose uniform to update
1650 * \param index the index of the program parameter for the uniform
1651 * \param offset additional parameter slot offset (for arrays)
1652 * \param type the incoming datatype of 'values'
1653 * \param count the number of uniforms to set
1654 * \param elems number of elements per uniform (1, 2, 3 or 4)
1655 * \param values the new values, of datatype 'type'
1658 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
1659 GLint index
, GLint offset
,
1660 GLenum type
, GLsizei count
, GLint elems
,
1663 const struct gl_program_parameter
*param
=
1664 &program
->Parameters
->Parameters
[index
];
1666 assert(offset
>= 0);
1670 if (!compatible_types(type
, param
->DataType
)) {
1671 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1675 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
1676 /* out of bounds! */
1680 if (param
->Type
== PROGRAM_SAMPLER
) {
1681 /* This controls which texture unit which is used by a sampler */
1682 GLboolean changed
= GL_FALSE
;
1685 /* this should have been caught by the compatible_types() check */
1686 ASSERT(type
== GL_INT
);
1688 /* loop over number of samplers to change */
1689 for (i
= 0; i
< count
; i
++) {
1691 (GLuint
) program
->Parameters
->ParameterValues
[index
+ offset
+ i
][0];
1692 GLuint texUnit
= ((GLuint
*) values
)[i
];
1694 /* check that the sampler (tex unit index) is legal */
1695 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1696 _mesa_error(ctx
, GL_INVALID_VALUE
,
1697 "glUniform1(invalid sampler/tex unit index)");
1701 /* This maps a sampler to a texture unit: */
1702 if (sampler
< MAX_SAMPLERS
) {
1704 printf("Set program %p sampler %d '%s' to unit %u\n",
1705 program
, sampler
, param
->Name
, texUnit
);
1707 if (program
->SamplerUnits
[sampler
] != texUnit
) {
1708 program
->SamplerUnits
[sampler
] = texUnit
;
1715 /* When a sampler's value changes it usually requires rewriting
1716 * a GPU program's TEX instructions since there may not be a
1717 * sampler->texture lookup table. We signal this with the
1718 * ProgramStringNotify() callback.
1720 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
| _NEW_PROGRAM
);
1721 _mesa_update_shader_textures_used(program
);
1722 /* Do we need to care about the return value here?
1723 * This should not be the first time the driver was notified of
1726 (void) ctx
->Driver
.ProgramStringNotify(ctx
, program
->Target
, program
);
1730 /* ordinary uniform variable */
1731 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
1732 const GLboolean areIntValues
= is_integer_type(type
);
1733 const GLint slots
= (param
->Size
+ 3) / 4;
1734 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1737 if ((GLint
) param
->Size
> typeSize
) {
1739 /* we'll ignore extra data below */
1742 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1744 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1745 "glUniform(uniform is not an array)");
1750 /* loop over number of array elements */
1751 for (k
= 0; k
< count
; k
++) {
1752 GLfloat
*uniformVal
;
1754 if (offset
+ k
>= slots
) {
1755 /* Extra array data is ignored */
1759 /* uniformVal (the destination) is always float[4] */
1760 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
1763 /* convert user's ints to floats */
1764 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1765 for (i
= 0; i
< elems
; i
++) {
1766 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1770 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1771 for (i
= 0; i
< elems
; i
++) {
1772 uniformVal
[i
] = fValues
[i
];
1776 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1777 if (isUniformBool
) {
1778 for (i
= 0; i
< elems
; i
++) {
1779 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1788 * Called via ctx->Driver.Uniform().
1791 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1792 const GLvoid
*values
, GLenum type
)
1794 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1795 struct gl_uniform
*uniform
;
1796 GLint elems
, offset
;
1799 if (!shProg
|| !shProg
->LinkStatus
) {
1800 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1805 return; /* The standard specifies this as a no-op */
1807 if (location
< -1) {
1808 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1812 split_location_offset(&location
, &offset
);
1814 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1815 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1820 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1826 basicType
= GL_FLOAT
;
1834 basicType
= GL_FLOAT
;
1842 basicType
= GL_FLOAT
;
1850 basicType
= GL_FLOAT
;
1858 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1862 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1864 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1866 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
1868 printf("Mesa: set program %u uniform %s (loc %d) to: ",
1869 shProg
->Name
, uniform
->Name
, location
);
1870 if (basicType
== GL_INT
) {
1871 const GLint
*v
= (const GLint
*) values
;
1872 for (i
= 0; i
< count
* elems
; i
++) {
1873 printf("%d ", v
[i
]);
1877 const GLfloat
*v
= (const GLfloat
*) values
;
1878 for (i
= 0; i
< count
* elems
; i
++) {
1879 printf("%g ", v
[i
]);
1885 /* A uniform var may be used by both a vertex shader and a fragment
1886 * shader. We may need to update one or both shader's uniform here:
1888 if (shProg
->VertexProgram
) {
1889 /* convert uniform location to program parameter index */
1890 GLint index
= uniform
->VertPos
;
1892 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1893 index
, offset
, type
, count
, elems
, values
);
1897 if (shProg
->FragmentProgram
) {
1898 /* convert uniform location to program parameter index */
1899 GLint index
= uniform
->FragPos
;
1901 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1902 index
, offset
, type
, count
, elems
, values
);
1906 uniform
->Initialized
= GL_TRUE
;
1911 * Set a matrix-valued program parameter.
1914 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1915 GLuint index
, GLuint offset
,
1916 GLuint count
, GLuint rows
, GLuint cols
,
1917 GLboolean transpose
, const GLfloat
*values
)
1919 GLuint mat
, row
, col
;
1921 const struct gl_program_parameter
* param
= &program
->Parameters
->Parameters
[index
];
1922 const GLuint slots
= (param
->Size
+ 3) / 4;
1923 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1926 /* check that the number of rows, columns is correct */
1927 get_matrix_dims(param
->DataType
, &nr
, &nc
);
1928 if (rows
!= nr
|| cols
!= nc
) {
1929 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1930 "glUniformMatrix(matrix size mismatch)");
1934 if ((GLint
) param
->Size
<= typeSize
) {
1935 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1937 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1938 "glUniformMatrix(uniform is not an array)");
1944 * Note: the _columns_ of a matrix are stored in program registers, not
1945 * the rows. So, the loops below look a little funny.
1946 * XXX could optimize this a bit...
1949 /* loop over matrices */
1950 for (mat
= 0; mat
< count
; mat
++) {
1953 for (col
= 0; col
< cols
; col
++) {
1955 if (offset
>= slots
) {
1956 /* Ignore writes beyond the end of (the used part of) an array */
1959 v
= program
->Parameters
->ParameterValues
[index
+ offset
];
1960 for (row
= 0; row
< rows
; row
++) {
1962 v
[row
] = values
[src
+ row
* cols
+ col
];
1965 v
[row
] = values
[src
+ col
* rows
+ row
];
1972 src
+= rows
* cols
; /* next matrix */
1978 * Called by ctx->Driver.UniformMatrix().
1979 * Note: cols=2, rows=4 ==> array[2] of vec4
1982 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1983 GLint location
, GLsizei count
,
1984 GLboolean transpose
, const GLfloat
*values
)
1986 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1987 struct gl_uniform
*uniform
;
1990 if (!shProg
|| !shProg
->LinkStatus
) {
1991 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1992 "glUniformMatrix(program not linked)");
1997 return; /* The standard specifies this as a no-op */
1999 if (location
< -1) {
2000 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
2004 split_location_offset(&location
, &offset
);
2006 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
2007 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
2010 if (values
== NULL
) {
2011 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
2015 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
2017 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
2019 if (shProg
->VertexProgram
) {
2020 /* convert uniform location to program parameter index */
2021 GLint index
= uniform
->VertPos
;
2023 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
2025 count
, rows
, cols
, transpose
, values
);
2029 if (shProg
->FragmentProgram
) {
2030 /* convert uniform location to program parameter index */
2031 GLint index
= uniform
->FragPos
;
2033 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
2035 count
, rows
, cols
, transpose
, values
);
2039 uniform
->Initialized
= GL_TRUE
;
2044 * Validate a program's samplers.
2045 * Specifically, check that there aren't two samplers of different types
2046 * pointing to the same texture unit.
2047 * \return GL_TRUE if valid, GL_FALSE if invalid
2050 validate_samplers(GLcontext
*ctx
, const struct gl_program
*prog
, char *errMsg
)
2052 static const char *targetName
[] = {
2061 GLint targetUsed
[MAX_TEXTURE_IMAGE_UNITS
];
2062 GLbitfield samplersUsed
= prog
->SamplersUsed
;
2065 assert(Elements(targetName
) == NUM_TEXTURE_TARGETS
);
2067 if (samplersUsed
== 0x0)
2070 for (i
= 0; i
< Elements(targetUsed
); i
++)
2073 /* walk over bits which are set in 'samplers' */
2074 while (samplersUsed
) {
2076 gl_texture_index target
;
2077 GLint sampler
= _mesa_ffs(samplersUsed
) - 1;
2078 assert(sampler
>= 0);
2079 assert(sampler
< MAX_TEXTURE_IMAGE_UNITS
);
2080 unit
= prog
->SamplerUnits
[sampler
];
2081 target
= prog
->SamplerTargets
[sampler
];
2082 if (targetUsed
[unit
] != -1 && targetUsed
[unit
] != target
) {
2083 _mesa_snprintf(errMsg
, 100,
2084 "Texture unit %d is accessed both as %s and %s",
2085 unit
, targetName
[targetUsed
[unit
]], targetName
[target
]);
2088 targetUsed
[unit
] = target
;
2089 samplersUsed
^= (1 << sampler
);
2097 * Do validation of the given shader program.
2098 * \param errMsg returns error message if validation fails.
2099 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2102 _mesa_validate_shader_program(GLcontext
*ctx
,
2103 const struct gl_shader_program
*shProg
,
2106 const struct gl_vertex_program
*vp
= shProg
->VertexProgram
;
2107 const struct gl_fragment_program
*fp
= shProg
->FragmentProgram
;
2109 if (!shProg
->LinkStatus
) {
2113 /* From the GL spec, a program is invalid if any of these are true:
2115 any two active samplers in the current program object are of
2116 different types, but refer to the same texture image unit,
2118 any active sampler in the current program object refers to a texture
2119 image unit where fixed-function fragment processing accesses a
2120 texture target that does not match the sampler type, or
2122 the sum of the number of active samplers in the program and the
2123 number of texture image units enabled for fixed-function fragment
2124 processing exceeds the combined limit on the total number of texture
2125 image units allowed.
2130 * Check: any two active samplers in the current program object are of
2131 * different types, but refer to the same texture image unit,
2133 if (vp
&& !validate_samplers(ctx
, &vp
->Base
, errMsg
)) {
2136 if (fp
&& !validate_samplers(ctx
, &fp
->Base
, errMsg
)) {
2145 * Called via glValidateProgram()
2148 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
2150 struct gl_shader_program
*shProg
;
2153 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
2158 shProg
->Validated
= _mesa_validate_shader_program(ctx
, shProg
, errMsg
);
2159 if (!shProg
->Validated
) {
2160 /* update info log */
2161 if (shProg
->InfoLog
) {
2162 free(shProg
->InfoLog
);
2164 shProg
->InfoLog
= _mesa_strdup(errMsg
);
2170 * Plug in Mesa's GLSL functions into the device driver function table.
2173 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
2175 driver
->AttachShader
= _mesa_attach_shader
;
2176 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
2177 driver
->CompileShader
= _mesa_compile_shader
;
2178 driver
->CreateProgram
= _mesa_create_program
;
2179 driver
->CreateShader
= _mesa_create_shader
;
2180 driver
->DeleteProgram2
= _mesa_delete_program2
;
2181 driver
->DeleteShader
= _mesa_delete_shader
;
2182 driver
->DetachShader
= _mesa_detach_shader
;
2183 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
2184 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
2185 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
2186 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
2187 driver
->GetHandle
= _mesa_get_handle
;
2188 driver
->GetProgramiv
= _mesa_get_programiv
;
2189 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
2190 driver
->GetShaderiv
= _mesa_get_shaderiv
;
2191 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
2192 driver
->GetShaderSource
= _mesa_get_shader_source
;
2193 driver
->GetUniformfv
= _mesa_get_uniformfv
;
2194 driver
->GetUniformiv
= _mesa_get_uniformiv
;
2195 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
2196 driver
->IsProgram
= _mesa_is_program
;
2197 driver
->IsShader
= _mesa_is_shader
;
2198 driver
->LinkProgram
= _mesa_link_program
;
2199 driver
->ShaderSource
= _mesa_shader_source
;
2200 driver
->Uniform
= _mesa_uniform
;
2201 driver
->UniformMatrix
= _mesa_uniform_matrix
;
2202 driver
->UseProgram
= _mesa_use_program
;
2203 driver
->ValidateProgram
= _mesa_validate_program
;