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 "glapi/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 _mesa_free(shProg
->Shaders
);
119 shProg
->Shaders
= NULL
;
122 if (shProg
->InfoLog
) {
123 _mesa_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 _mesa_free((void *) sh
->Source
);
267 _mesa_free(sh
->InfoLog
);
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 (_mesa_strstr(env
, "dump"))
379 if (_mesa_strstr(env
, "log"))
381 if (_mesa_strstr(env
, "nopvert"))
382 flags
|= GLSL_NOP_VERT
;
383 if (_mesa_strstr(env
, "nopfrag"))
384 flags
|= GLSL_NOP_FRAG
;
385 if (_mesa_strstr(env
, "nopt"))
386 flags
|= GLSL_NO_OPT
;
387 else if (_mesa_strstr(env
, "opt"))
389 if (_mesa_strstr(env
, "uniform"))
390 flags
|= GLSL_UNIFORMS
;
391 if (_mesa_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 _mesa_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 _mesa_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_SHADOW_EXT
:
773 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
774 case GL_SAMPLER_CUBE_SHADOW_EXT
:
789 case GL_FLOAT_MAT2x3
:
790 case GL_FLOAT_MAT2x4
:
791 return 8; /* two float[4] vectors */
793 case GL_FLOAT_MAT3x2
:
794 case GL_FLOAT_MAT3x4
:
795 return 12; /* three float[4] vectors */
797 case GL_FLOAT_MAT4x2
:
798 case GL_FLOAT_MAT4x3
:
799 return 16; /* four float[4] vectors */
801 _mesa_problem(NULL
, "Invalid type in sizeof_glsl_type()");
808 is_boolean_type(GLenum type
)
823 is_integer_type(GLenum type
)
838 is_sampler_type(GLenum type
)
844 case GL_SAMPLER_CUBE
:
845 case GL_SAMPLER_1D_SHADOW
:
846 case GL_SAMPLER_2D_SHADOW
:
847 case GL_SAMPLER_2D_RECT_ARB
:
848 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
849 case GL_SAMPLER_1D_ARRAY_EXT
:
850 case GL_SAMPLER_2D_ARRAY_EXT
:
859 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
860 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
861 GLenum
*type
, GLchar
*nameOut
)
863 const struct gl_program_parameter_list
*attribs
= NULL
;
864 struct gl_shader_program
*shProg
;
866 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
870 if (shProg
->VertexProgram
)
871 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
873 if (!attribs
|| index
>= attribs
->NumParameters
) {
874 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
878 copy_string(nameOut
, maxLength
, length
, attribs
->Parameters
[index
].Name
);
881 *size
= attribs
->Parameters
[index
].Size
882 / sizeof_glsl_type(attribs
->Parameters
[index
].DataType
);
885 *type
= attribs
->Parameters
[index
].DataType
;
889 static struct gl_program_parameter
*
890 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
892 const struct gl_program
*prog
= NULL
;
895 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
897 prog
= &shProg
->VertexProgram
->Base
;
900 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
902 prog
= &shProg
->FragmentProgram
->Base
;
906 if (!prog
|| progPos
< 0)
907 return NULL
; /* should never happen */
909 return &prog
->Parameters
->Parameters
[progPos
];
914 * Called via ctx->Driver.GetActiveUniform().
917 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
918 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
919 GLenum
*type
, GLchar
*nameOut
)
921 const struct gl_shader_program
*shProg
;
922 const struct gl_program
*prog
= NULL
;
923 const struct gl_program_parameter
*param
;
926 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
930 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
931 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
935 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
937 prog
= &shProg
->VertexProgram
->Base
;
940 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
942 prog
= &shProg
->FragmentProgram
->Base
;
946 if (!prog
|| progPos
< 0)
947 return; /* should never happen */
949 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
950 param
= &prog
->Parameters
->Parameters
[progPos
];
953 copy_string(nameOut
, maxLength
, length
, param
->Name
);
957 GLint typeSize
= sizeof_glsl_type(param
->DataType
);
958 if (param
->Size
> typeSize
) {
960 * Array elements are placed on vector[4] boundaries so they're
961 * a multiple of four floats. We round typeSize up to next multiple
962 * of four to get the right size below.
964 typeSize
= (typeSize
+ 3) & ~3;
966 /* Note that the returned size is in units of the <type>, not bytes */
967 *size
= param
->Size
/ typeSize
;
971 *type
= param
->DataType
;
977 * Called via ctx->Driver.GetAttachedShaders().
980 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
981 GLsizei
*count
, GLuint
*obj
)
983 struct gl_shader_program
*shProg
=
984 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
987 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
988 obj
[i
] = shProg
->Shaders
[i
]->Name
;
997 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
1001 if (pname
== GL_PROGRAM_OBJECT_ARB
) {
1002 CALL_GetIntegerv(ctx
->Exec
, (GL_CURRENT_PROGRAM
, &handle
));
1004 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
1012 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
1013 GLenum pname
, GLint
*params
)
1015 const struct gl_program_parameter_list
*attribs
;
1016 struct gl_shader_program
*shProg
1017 = _mesa_lookup_shader_program(ctx
, program
);
1020 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
1024 if (shProg
->VertexProgram
)
1025 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
1030 case GL_DELETE_STATUS
:
1031 *params
= shProg
->DeletePending
;
1033 case GL_LINK_STATUS
:
1034 *params
= shProg
->LinkStatus
;
1036 case GL_VALIDATE_STATUS
:
1037 *params
= shProg
->Validated
;
1039 case GL_INFO_LOG_LENGTH
:
1040 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
1042 case GL_ATTACHED_SHADERS
:
1043 *params
= shProg
->NumShaders
;
1045 case GL_ACTIVE_ATTRIBUTES
:
1046 *params
= attribs
? attribs
->NumParameters
: 0;
1048 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
1049 *params
= _mesa_longest_parameter_name(attribs
, PROGRAM_INPUT
) + 1;
1051 case GL_ACTIVE_UNIFORMS
:
1052 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
1054 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
1055 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
1057 (*params
)++; /* add one for terminating zero */
1059 case GL_PROGRAM_BINARY_LENGTH_OES
:
1063 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
1070 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
1072 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
1079 case GL_SHADER_TYPE
:
1080 *params
= shader
->Type
;
1082 case GL_DELETE_STATUS
:
1083 *params
= shader
->DeletePending
;
1085 case GL_COMPILE_STATUS
:
1086 *params
= shader
->CompileStatus
;
1088 case GL_INFO_LOG_LENGTH
:
1089 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
1091 case GL_SHADER_SOURCE_LENGTH
:
1092 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
1095 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
1102 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
1103 GLsizei
*length
, GLchar
*infoLog
)
1105 struct gl_shader_program
*shProg
1106 = _mesa_lookup_shader_program(ctx
, program
);
1108 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
1111 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
1116 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
1117 GLsizei
*length
, GLchar
*infoLog
)
1119 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1121 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
1124 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
1129 * Called via ctx->Driver.GetShaderSource().
1132 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
1133 GLsizei
*length
, GLchar
*sourceOut
)
1135 struct gl_shader
*sh
;
1136 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
1140 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
1145 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1151 case GL_FLOAT_MAT2x3
:
1155 case GL_FLOAT_MAT2x4
:
1163 case GL_FLOAT_MAT3x2
:
1167 case GL_FLOAT_MAT3x4
:
1175 case GL_FLOAT_MAT4x2
:
1179 case GL_FLOAT_MAT4x3
:
1190 * Determine the number of rows and columns occupied by a uniform
1191 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1192 * the number of rows = 1 and cols = number of elements in the vector.
1195 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
1196 GLint
*rows
, GLint
*cols
)
1198 get_matrix_dims(p
->DataType
, rows
, cols
);
1199 if (*rows
== 0 && *cols
== 0) {
1200 /* not a matrix type, probably a float or vector */
1206 *rows
= p
->Size
/ 4 + 1;
1207 if (p
->Size
% 4 == 0)
1210 *cols
= p
->Size
% 4;
1217 * Helper for get_uniform[fi]v() functions.
1218 * Given a shader program name and uniform location, return a pointer
1219 * to the shader program and return the program parameter position.
1222 lookup_uniform_parameter(GLcontext
*ctx
, GLuint program
, GLint location
,
1223 struct gl_program
**progOut
, GLint
*paramPosOut
)
1225 struct gl_shader_program
*shProg
1226 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
1227 struct gl_program
*prog
= NULL
;
1230 /* if shProg is NULL, we'll have already recorded an error */
1233 if (!shProg
->Uniforms
||
1235 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1236 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1239 /* OK, find the gl_program and program parameter location */
1240 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1242 prog
= &shProg
->VertexProgram
->Base
;
1245 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1247 prog
= &shProg
->FragmentProgram
->Base
;
1254 *paramPosOut
= progPos
;
1259 * Called via ctx->Driver.GetUniformfv().
1262 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1265 struct gl_program
*prog
;
1268 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1271 const struct gl_program_parameter
*p
=
1272 &prog
->Parameters
->Parameters
[paramPos
];
1273 GLint rows
, cols
, i
, j
, k
;
1275 get_uniform_rows_cols(p
, &rows
, &cols
);
1278 for (i
= 0; i
< rows
; i
++) {
1279 for (j
= 0; j
< cols
; j
++ ) {
1280 params
[k
++] = prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1288 * Called via ctx->Driver.GetUniformiv().
1289 * \sa _mesa_get_uniformfv, only difference is a cast.
1292 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1295 struct gl_program
*prog
;
1298 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1301 const struct gl_program_parameter
*p
=
1302 &prog
->Parameters
->Parameters
[paramPos
];
1303 GLint rows
, cols
, i
, j
, k
;
1305 get_uniform_rows_cols(p
, &rows
, &cols
);
1308 for (i
= 0; i
< rows
; i
++) {
1309 for (j
= 0; j
< cols
; j
++ ) {
1310 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1318 * The value returned by GetUniformLocation actually encodes two things:
1319 * 1. the index into the prog->Uniforms[] array for the uniform
1320 * 2. an offset in the prog->ParameterValues[] array for specifying array
1321 * elements or structure fields.
1322 * This function merges those two values.
1325 merge_location_offset(GLint
*location
, GLint offset
)
1327 *location
= *location
| (offset
<< 16);
1332 * Seperate the uniform location and parameter offset. See above.
1335 split_location_offset(GLint
*location
, GLint
*offset
)
1337 *offset
= (*location
>> 16);
1338 *location
= *location
& 0xffff;
1343 * Called via ctx->Driver.GetUniformLocation().
1345 * The return value will encode two values, the uniform location and an
1346 * offset (used for arrays, structs).
1349 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1351 GLint offset
= 0, location
= -1;
1353 struct gl_shader_program
*shProg
=
1354 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1359 if (shProg
->LinkStatus
== GL_FALSE
) {
1360 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1364 /* XXX we should return -1 if the uniform was declared, but not
1368 /* XXX we need to be able to parse uniform names for structs and arrays
1375 /* handle 1-dimension arrays here... */
1376 char *c
= strchr(name
, '[');
1378 /* truncate name at [ */
1379 const GLint len
= c
- name
;
1380 GLchar
*newName
= _mesa_malloc(len
+ 1);
1382 return -1; /* out of mem */
1383 _mesa_memcpy(newName
, name
, len
);
1386 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
1387 if (location
>= 0) {
1388 const GLint element
= _mesa_atoi(c
+ 1);
1390 /* get type of the uniform array element */
1391 struct gl_program_parameter
*p
;
1392 p
= get_uniform_parameter(shProg
, location
);
1395 get_matrix_dims(p
->DataType
, &rows
, &cols
);
1398 offset
= element
* rows
;
1403 _mesa_free(newName
);
1408 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1411 if (location
>= 0) {
1412 merge_location_offset(&location
, offset
);
1421 * Called via ctx->Driver.ShaderSource()
1424 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1426 struct gl_shader
*sh
;
1428 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1432 /* free old shader source string and install new one */
1434 _mesa_free((void *) sh
->Source
);
1436 sh
->Source
= source
;
1437 sh
->CompileStatus
= GL_FALSE
;
1439 sh
->SourceChecksum
= _mesa_str_checksum(sh
->Source
);
1445 * Called via ctx->Driver.CompileShader()
1448 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1450 struct gl_shader
*sh
;
1452 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1456 /* set default pragma state for shader */
1457 sh
->Pragmas
= ctx
->Shader
.DefaultPragmas
;
1459 /* this call will set the sh->CompileStatus field to indicate if
1460 * compilation was successful.
1462 (void) _slang_compile(ctx
, sh
);
1467 * Called via ctx->Driver.LinkProgram()
1470 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1472 struct gl_shader_program
*shProg
;
1474 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1478 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1480 _slang_link(ctx
, program
, shProg
);
1486 _mesa_printf("Link %u shaders in program %u: %s\n",
1487 shProg
->NumShaders
, shProg
->Name
,
1488 shProg
->LinkStatus
? "Success" : "Failed");
1490 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1491 _mesa_printf(" shader %u, type 0x%x\n",
1492 shProg
->Shaders
[i
]->Name
,
1493 shProg
->Shaders
[i
]->Type
);
1500 * Print basic shader info (for debug).
1503 print_shader_info(const struct gl_shader_program
*shProg
)
1507 _mesa_printf("Mesa: glUseProgram(%u)\n", shProg
->Name
);
1508 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1510 switch (shProg
->Shaders
[i
]->Type
) {
1511 case GL_VERTEX_SHADER
:
1514 case GL_FRAGMENT_SHADER
:
1517 case GL_GEOMETRY_SHADER
:
1523 _mesa_printf(" %s shader %u, checksum %u\n", s
,
1524 shProg
->Shaders
[i
]->Name
,
1525 shProg
->Shaders
[i
]->SourceChecksum
);
1527 if (shProg
->VertexProgram
)
1528 _mesa_printf(" vert prog %u\n", shProg
->VertexProgram
->Base
.Id
);
1529 if (shProg
->FragmentProgram
)
1530 _mesa_printf(" frag prog %u\n", shProg
->FragmentProgram
->Base
.Id
);
1535 * Called via ctx->Driver.UseProgram()
1538 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1540 struct gl_shader_program
*shProg
;
1542 if (ctx
->Shader
.CurrentProgram
&&
1543 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1549 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1553 if (!shProg
->LinkStatus
) {
1554 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1555 "glUseProgram(program %u not linked)", program
);
1560 if (ctx
->Shader
.Flags
& GLSL_USE_PROG
) {
1561 print_shader_info(shProg
);
1568 if (ctx
->Shader
.CurrentProgram
!= shProg
) {
1569 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
1570 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1577 * Update the vertex/fragment program's TexturesUsed array.
1579 * This needs to be called after glUniform(set sampler var) is called.
1580 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1581 * particular texture unit. We know the sampler's texture target
1582 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1583 * set by glUniform() calls.
1585 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1586 * information to update the prog->TexturesUsed[] values.
1587 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1588 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1589 * We'll use that info for state validation before rendering.
1592 _mesa_update_shader_textures_used(struct gl_program
*prog
)
1596 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1598 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1599 if (prog
->SamplersUsed
& (1 << s
)) {
1600 GLuint unit
= prog
->SamplerUnits
[s
];
1601 GLuint tgt
= prog
->SamplerTargets
[s
];
1602 assert(unit
< MAX_TEXTURE_IMAGE_UNITS
);
1603 assert(tgt
< NUM_TEXTURE_TARGETS
);
1604 prog
->TexturesUsed
[unit
] |= (1 << tgt
);
1611 * Check if the type given by userType is allowed to set a uniform of the
1612 * target type. Generally, equivalence is required, but setting Boolean
1613 * uniforms can be done with glUniformiv or glUniformfv.
1616 compatible_types(GLenum userType
, GLenum targetType
)
1618 if (userType
== targetType
)
1621 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1624 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1625 userType
== GL_INT_VEC2
))
1628 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1629 userType
== GL_INT_VEC3
))
1632 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1633 userType
== GL_INT_VEC4
))
1636 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1644 * Set the value of a program's uniform variable.
1645 * \param program the program whose uniform to update
1646 * \param index the index of the program parameter for the uniform
1647 * \param offset additional parameter slot offset (for arrays)
1648 * \param type the incoming datatype of 'values'
1649 * \param count the number of uniforms to set
1650 * \param elems number of elements per uniform (1, 2, 3 or 4)
1651 * \param values the new values, of datatype 'type'
1654 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
1655 GLint index
, GLint offset
,
1656 GLenum type
, GLsizei count
, GLint elems
,
1659 const struct gl_program_parameter
*param
=
1660 &program
->Parameters
->Parameters
[index
];
1662 assert(offset
>= 0);
1666 if (!compatible_types(type
, param
->DataType
)) {
1667 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1671 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
1672 /* out of bounds! */
1676 if (param
->Type
== PROGRAM_SAMPLER
) {
1677 /* This controls which texture unit which is used by a sampler */
1678 GLboolean changed
= GL_FALSE
;
1681 /* this should have been caught by the compatible_types() check */
1682 ASSERT(type
== GL_INT
);
1684 /* loop over number of samplers to change */
1685 for (i
= 0; i
< count
; i
++) {
1687 (GLuint
) program
->Parameters
->ParameterValues
[index
+ offset
+ i
][0];
1688 GLuint texUnit
= ((GLuint
*) values
)[i
];
1690 /* check that the sampler (tex unit index) is legal */
1691 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1692 _mesa_error(ctx
, GL_INVALID_VALUE
,
1693 "glUniform1(invalid sampler/tex unit index)");
1697 /* This maps a sampler to a texture unit: */
1698 if (sampler
< MAX_SAMPLERS
) {
1700 _mesa_printf("Set program %p sampler %d '%s' to unit %u\n",
1701 program
, sampler
, param
->Name
, texUnit
);
1703 if (program
->SamplerUnits
[sampler
] != texUnit
) {
1704 program
->SamplerUnits
[sampler
] = texUnit
;
1711 /* When a sampler's value changes it usually requires rewriting
1712 * a GPU program's TEX instructions since there may not be a
1713 * sampler->texture lookup table. We signal this with the
1714 * ProgramStringNotify() callback.
1716 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
| _NEW_PROGRAM
);
1717 _mesa_update_shader_textures_used(program
);
1718 ctx
->Driver
.ProgramStringNotify(ctx
, program
->Target
, program
);
1722 /* ordinary uniform variable */
1723 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
1724 const GLboolean areIntValues
= is_integer_type(type
);
1725 const GLint slots
= (param
->Size
+ 3) / 4;
1726 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1729 if (param
->Size
> typeSize
) {
1731 /* we'll ignore extra data below */
1734 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1736 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1737 "glUniform(uniform is not an array)");
1742 /* loop over number of array elements */
1743 for (k
= 0; k
< count
; k
++) {
1744 GLfloat
*uniformVal
;
1746 if (offset
+ k
>= slots
) {
1747 /* Extra array data is ignored */
1751 /* uniformVal (the destination) is always float[4] */
1752 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
1755 /* convert user's ints to floats */
1756 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1757 for (i
= 0; i
< elems
; i
++) {
1758 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1762 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1763 for (i
= 0; i
< elems
; i
++) {
1764 uniformVal
[i
] = fValues
[i
];
1768 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1769 if (isUniformBool
) {
1770 for (i
= 0; i
< elems
; i
++) {
1771 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1780 * Called via ctx->Driver.Uniform().
1783 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1784 const GLvoid
*values
, GLenum type
)
1786 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1787 struct gl_uniform
*uniform
;
1788 GLint elems
, offset
;
1791 if (!shProg
|| !shProg
->LinkStatus
) {
1792 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1797 return; /* The standard specifies this as a no-op */
1799 if (location
< -1) {
1800 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1804 split_location_offset(&location
, &offset
);
1806 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1807 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1812 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1818 basicType
= GL_FLOAT
;
1826 basicType
= GL_FLOAT
;
1834 basicType
= GL_FLOAT
;
1842 basicType
= GL_FLOAT
;
1850 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1854 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1856 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1858 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
1860 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1861 shProg
->Name
, uniform
->Name
, location
);
1862 if (basicType
== GL_INT
) {
1863 const GLint
*v
= (const GLint
*) values
;
1864 for (i
= 0; i
< count
* elems
; i
++) {
1865 _mesa_printf("%d ", v
[i
]);
1869 const GLfloat
*v
= (const GLfloat
*) values
;
1870 for (i
= 0; i
< count
* elems
; i
++) {
1871 _mesa_printf("%g ", v
[i
]);
1877 /* A uniform var may be used by both a vertex shader and a fragment
1878 * shader. We may need to update one or both shader's uniform here:
1880 if (shProg
->VertexProgram
) {
1881 /* convert uniform location to program parameter index */
1882 GLint index
= uniform
->VertPos
;
1884 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1885 index
, offset
, type
, count
, elems
, values
);
1889 if (shProg
->FragmentProgram
) {
1890 /* convert uniform location to program parameter index */
1891 GLint index
= uniform
->FragPos
;
1893 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1894 index
, offset
, type
, count
, elems
, values
);
1898 uniform
->Initialized
= GL_TRUE
;
1903 * Set a matrix-valued program parameter.
1906 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1907 GLuint index
, GLuint offset
,
1908 GLuint count
, GLuint rows
, GLuint cols
,
1909 GLboolean transpose
, const GLfloat
*values
)
1911 GLuint mat
, row
, col
;
1913 const struct gl_program_parameter
* param
= &program
->Parameters
->Parameters
[index
];
1914 const GLint slots
= (param
->Size
+ 3) / 4;
1915 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1918 /* check that the number of rows, columns is correct */
1919 get_matrix_dims(param
->DataType
, &nr
, &nc
);
1920 if (rows
!= nr
|| cols
!= nc
) {
1921 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1922 "glUniformMatrix(matrix size mismatch)");
1926 if (param
->Size
<= typeSize
) {
1927 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1929 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1930 "glUniformMatrix(uniform is not an array)");
1936 * Note: the _columns_ of a matrix are stored in program registers, not
1937 * the rows. So, the loops below look a little funny.
1938 * XXX could optimize this a bit...
1941 /* loop over matrices */
1942 for (mat
= 0; mat
< count
; mat
++) {
1945 for (col
= 0; col
< cols
; col
++) {
1947 if (offset
>= slots
) {
1948 /* Ignore writes beyond the end of (the used part of) an array */
1951 v
= program
->Parameters
->ParameterValues
[index
+ offset
];
1952 for (row
= 0; row
< rows
; row
++) {
1954 v
[row
] = values
[src
+ row
* cols
+ col
];
1957 v
[row
] = values
[src
+ col
* rows
+ row
];
1964 src
+= rows
* cols
; /* next matrix */
1970 * Called by ctx->Driver.UniformMatrix().
1971 * Note: cols=2, rows=4 ==> array[2] of vec4
1974 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1975 GLint location
, GLsizei count
,
1976 GLboolean transpose
, const GLfloat
*values
)
1978 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1979 struct gl_uniform
*uniform
;
1982 if (!shProg
|| !shProg
->LinkStatus
) {
1983 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1984 "glUniformMatrix(program not linked)");
1989 return; /* The standard specifies this as a no-op */
1991 if (location
< -1) {
1992 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
1996 split_location_offset(&location
, &offset
);
1998 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1999 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
2002 if (values
== NULL
) {
2003 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
2007 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
2009 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
2011 if (shProg
->VertexProgram
) {
2012 /* convert uniform location to program parameter index */
2013 GLint index
= uniform
->VertPos
;
2015 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
2017 count
, rows
, cols
, transpose
, values
);
2021 if (shProg
->FragmentProgram
) {
2022 /* convert uniform location to program parameter index */
2023 GLint index
= uniform
->FragPos
;
2025 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
2027 count
, rows
, cols
, transpose
, values
);
2031 uniform
->Initialized
= GL_TRUE
;
2036 * Validate a program's samplers.
2037 * Specifically, check that there aren't two samplers of different types
2038 * pointing to the same texture unit.
2039 * \return GL_TRUE if valid, GL_FALSE if invalid
2042 validate_samplers(GLcontext
*ctx
, const struct gl_program
*prog
, char *errMsg
)
2044 static const char *targetName
[] = {
2053 GLint targetUsed
[MAX_TEXTURE_IMAGE_UNITS
];
2054 GLbitfield samplersUsed
= prog
->SamplersUsed
;
2057 assert(Elements(targetName
) == NUM_TEXTURE_TARGETS
);
2059 if (samplersUsed
== 0x0)
2062 for (i
= 0; i
< Elements(targetUsed
); i
++)
2065 /* walk over bits which are set in 'samplers' */
2066 while (samplersUsed
) {
2068 gl_texture_index target
;
2069 GLint sampler
= _mesa_ffs(samplersUsed
) - 1;
2070 assert(sampler
>= 0);
2071 assert(sampler
< MAX_TEXTURE_IMAGE_UNITS
);
2072 unit
= prog
->SamplerUnits
[sampler
];
2073 target
= prog
->SamplerTargets
[sampler
];
2074 if (targetUsed
[unit
] != -1 && targetUsed
[unit
] != target
) {
2075 _mesa_snprintf(errMsg
, 100,
2076 "Texture unit %d is accessed both as %s and %s",
2077 unit
, targetName
[targetUsed
[unit
]], targetName
[target
]);
2080 targetUsed
[unit
] = target
;
2081 samplersUsed
^= (1 << sampler
);
2089 * Do validation of the given shader program.
2090 * \param errMsg returns error message if validation fails.
2091 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2094 _mesa_validate_shader_program(GLcontext
*ctx
,
2095 const struct gl_shader_program
*shProg
,
2098 const struct gl_vertex_program
*vp
= shProg
->VertexProgram
;
2099 const struct gl_fragment_program
*fp
= shProg
->FragmentProgram
;
2101 if (!shProg
->LinkStatus
) {
2105 /* From the GL spec, a program is invalid if any of these are true:
2107 any two active samplers in the current program object are of
2108 different types, but refer to the same texture image unit,
2110 any active sampler in the current program object refers to a texture
2111 image unit where fixed-function fragment processing accesses a
2112 texture target that does not match the sampler type, or
2114 the sum of the number of active samplers in the program and the
2115 number of texture image units enabled for fixed-function fragment
2116 processing exceeds the combined limit on the total number of texture
2117 image units allowed.
2122 * Check: any two active samplers in the current program object are of
2123 * different types, but refer to the same texture image unit,
2125 if (vp
&& !validate_samplers(ctx
, &vp
->Base
, errMsg
)) {
2128 if (fp
&& !validate_samplers(ctx
, &fp
->Base
, errMsg
)) {
2137 * Called via glValidateProgram()
2140 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
2142 struct gl_shader_program
*shProg
;
2145 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
2150 shProg
->Validated
= _mesa_validate_shader_program(ctx
, shProg
, errMsg
);
2151 if (!shProg
->Validated
) {
2152 /* update info log */
2153 if (shProg
->InfoLog
) {
2154 _mesa_free(shProg
->InfoLog
);
2156 shProg
->InfoLog
= _mesa_strdup(errMsg
);
2162 * Plug in Mesa's GLSL functions into the device driver function table.
2165 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
2167 driver
->AttachShader
= _mesa_attach_shader
;
2168 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
2169 driver
->CompileShader
= _mesa_compile_shader
;
2170 driver
->CreateProgram
= _mesa_create_program
;
2171 driver
->CreateShader
= _mesa_create_shader
;
2172 driver
->DeleteProgram2
= _mesa_delete_program2
;
2173 driver
->DeleteShader
= _mesa_delete_shader
;
2174 driver
->DetachShader
= _mesa_detach_shader
;
2175 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
2176 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
2177 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
2178 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
2179 driver
->GetHandle
= _mesa_get_handle
;
2180 driver
->GetProgramiv
= _mesa_get_programiv
;
2181 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
2182 driver
->GetShaderiv
= _mesa_get_shaderiv
;
2183 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
2184 driver
->GetShaderSource
= _mesa_get_shader_source
;
2185 driver
->GetUniformfv
= _mesa_get_uniformfv
;
2186 driver
->GetUniformiv
= _mesa_get_uniformiv
;
2187 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
2188 driver
->IsProgram
= _mesa_is_program
;
2189 driver
->IsShader
= _mesa_is_shader
;
2190 driver
->LinkProgram
= _mesa_link_program
;
2191 driver
->ShaderSource
= _mesa_shader_source
;
2192 driver
->Uniform
= _mesa_uniform
;
2193 driver
->UniformMatrix
= _mesa_uniform_matrix
;
2194 driver
->UseProgram
= _mesa_use_program
;
2195 driver
->ValidateProgram
= _mesa_validate_program
;