2 * Mesa 3-D graphics library
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Implementation of GLSL-related API functions
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/hash.h"
42 #include "main/macros.h"
43 #include "shader/program.h"
44 #include "shader/prog_parameter.h"
45 #include "shader/prog_print.h"
46 #include "shader/prog_statevars.h"
47 #include "shader/prog_uniform.h"
48 #include "shader/shader_api.h"
49 #include "shader/slang/slang_compile.h"
50 #include "shader/slang/slang_link.h"
51 #include "glapi/dispatch.h"
55 * Allocate a new gl_shader_program object, initialize it.
57 static struct gl_shader_program
*
58 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
60 struct gl_shader_program
*shProg
;
61 shProg
= CALLOC_STRUCT(gl_shader_program
);
63 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
66 shProg
->Attributes
= _mesa_new_parameter_list();
73 * Clear (free) the shader program state that gets produced by linking.
76 _mesa_clear_shader_program_data(GLcontext
*ctx
,
77 struct gl_shader_program
*shProg
)
79 _mesa_reference_vertprog(ctx
, &shProg
->VertexProgram
, NULL
);
80 _mesa_reference_fragprog(ctx
, &shProg
->FragmentProgram
, NULL
);
82 if (shProg
->Uniforms
) {
83 _mesa_free_uniform_list(shProg
->Uniforms
);
84 shProg
->Uniforms
= NULL
;
87 if (shProg
->Varying
) {
88 _mesa_free_parameter_list(shProg
->Varying
);
89 shProg
->Varying
= NULL
;
95 * Free all the data that hangs off a shader program object, but not the
99 _mesa_free_shader_program_data(GLcontext
*ctx
,
100 struct gl_shader_program
*shProg
)
104 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
106 _mesa_clear_shader_program_data(ctx
, shProg
);
108 if (shProg
->Attributes
) {
109 _mesa_free_parameter_list(shProg
->Attributes
);
110 shProg
->Attributes
= NULL
;
114 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
115 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
117 shProg
->NumShaders
= 0;
119 if (shProg
->Shaders
) {
120 _mesa_free(shProg
->Shaders
);
121 shProg
->Shaders
= NULL
;
124 if (shProg
->InfoLog
) {
125 _mesa_free(shProg
->InfoLog
);
126 shProg
->InfoLog
= NULL
;
132 * Free/delete a shader program object.
135 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
137 _mesa_free_shader_program_data(ctx
, shProg
);
144 * Set ptr to point to shProg.
145 * If ptr is pointing to another object, decrement its refcount (and delete
146 * if refcount hits zero).
147 * Then set ptr to point to shProg, incrementing its refcount.
149 /* XXX this could be static */
151 _mesa_reference_shader_program(GLcontext
*ctx
,
152 struct gl_shader_program
**ptr
,
153 struct gl_shader_program
*shProg
)
156 if (*ptr
== shProg
) {
161 /* Unreference the old shader program */
162 GLboolean deleteFlag
= GL_FALSE
;
163 struct gl_shader_program
*old
= *ptr
;
165 ASSERT(old
->RefCount
> 0);
168 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
169 (void *) old
, old
->Name
, old
->RefCount
);
171 deleteFlag
= (old
->RefCount
== 0);
174 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
175 _mesa_free_shader_program(ctx
, old
);
185 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
186 (void *) shProg
, shProg
->Name
, shProg
->RefCount
);
194 * Lookup a GLSL program object.
196 struct gl_shader_program
*
197 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
199 struct gl_shader_program
*shProg
;
201 shProg
= (struct gl_shader_program
*)
202 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
203 /* Note that both gl_shader and gl_shader_program objects are kept
204 * in the same hash table. Check the object's type to be sure it's
205 * what we're expecting.
207 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
217 * As above, but record an error if program is not found.
219 static struct gl_shader_program
*
220 _mesa_lookup_shader_program_err(GLcontext
*ctx
, GLuint name
,
224 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
228 struct gl_shader_program
*shProg
= (struct gl_shader_program
*)
229 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
231 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
234 if (shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
235 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
246 * Allocate a new gl_shader object, initialize it.
249 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
251 struct gl_shader
*shader
;
252 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
253 shader
= CALLOC_STRUCT(gl_shader
);
257 shader
->RefCount
= 1;
264 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
267 _mesa_free((void *) sh
->Source
);
269 _mesa_free(sh
->InfoLog
);
270 _mesa_reference_program(ctx
, &sh
->Program
, NULL
);
276 * Set ptr to point to sh.
277 * If ptr is pointing to another shader, decrement its refcount (and delete
278 * if refcount hits zero).
279 * Then set ptr to point to sh, incrementing its refcount.
281 /* XXX this could be static */
283 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
284 struct gl_shader
*sh
)
292 /* Unreference the old shader */
293 GLboolean deleteFlag
= GL_FALSE
;
294 struct gl_shader
*old
= *ptr
;
296 ASSERT(old
->RefCount
> 0);
298 /*printf("SHADER DECR %p (%d) to %d\n",
299 (void*) old, old->Name, old->RefCount);*/
300 deleteFlag
= (old
->RefCount
== 0);
303 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
304 _mesa_free_shader(ctx
, old
);
314 /*printf("SHADER INCR %p (%d) to %d\n",
315 (void*) sh, sh->Name, sh->RefCount);*/
322 * Lookup a GLSL shader object.
325 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
328 struct gl_shader
*sh
= (struct gl_shader
*)
329 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
330 /* Note that both gl_shader and gl_shader_program objects are kept
331 * in the same hash table. Check the object's type to be sure it's
332 * what we're expecting.
334 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
344 * As above, but record an error if shader is not found.
346 static struct gl_shader
*
347 _mesa_lookup_shader_err(GLcontext
*ctx
, GLuint name
, const char *caller
)
350 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
354 struct gl_shader
*sh
= (struct gl_shader
*)
355 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
357 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
360 if (sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
361 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
370 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
373 get_shader_flags(void)
375 GLbitfield flags
= 0x0;
376 const char *env
= _mesa_getenv("MESA_GLSL");
379 if (_mesa_strstr(env
, "dump"))
381 if (_mesa_strstr(env
, "log"))
383 if (_mesa_strstr(env
, "nopt"))
384 flags
|= GLSL_NO_OPT
;
385 else if (_mesa_strstr(env
, "opt"))
387 if (_mesa_strstr(env
, "uniform"))
388 flags
|= GLSL_UNIFORMS
;
396 * Initialize context's shader state.
399 _mesa_init_shader_state(GLcontext
* ctx
)
401 /* Device drivers may override these to control what kind of instructions
402 * are generated by the GLSL compiler.
404 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
405 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;
406 ctx
->Shader
.EmitComments
= GL_FALSE
;
407 ctx
->Shader
.Flags
= get_shader_flags();
409 /* Default pragma settings */
410 ctx
->Shader
.DefaultPragmas
.IgnoreOptimize
= GL_FALSE
;
411 ctx
->Shader
.DefaultPragmas
.IgnoreDebug
= GL_FALSE
;
412 ctx
->Shader
.DefaultPragmas
.Optimize
= GL_TRUE
;
413 ctx
->Shader
.DefaultPragmas
.Debug
= GL_FALSE
;
418 * Free the per-context shader-related state.
421 _mesa_free_shader_state(GLcontext
*ctx
)
423 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
428 * Copy string from <src> to <dst>, up to maxLength characters, returning
429 * length of <dst> in <length>.
430 * \param src the strings source
431 * \param maxLength max chars to copy
432 * \param length returns number of chars copied
433 * \param dst the string destination
436 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
439 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
449 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
451 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
452 return shProg
? GL_TRUE
: GL_FALSE
;
457 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
459 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
460 return shader
? GL_TRUE
: GL_FALSE
;
465 * Called via ctx->Driver.AttachShader()
468 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
470 struct gl_shader_program
*shProg
;
471 struct gl_shader
*sh
;
474 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
478 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
483 n
= shProg
->NumShaders
;
484 for (i
= 0; i
< n
; i
++) {
485 if (shProg
->Shaders
[i
] == sh
) {
486 /* The shader is already attched to this program. The
487 * GL_ARB_shader_objects spec says:
489 * "The error INVALID_OPERATION is generated by AttachObjectARB
490 * if <obj> is already attached to <containerObj>."
492 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glAttachShader");
498 shProg
->Shaders
= (struct gl_shader
**)
499 _mesa_realloc(shProg
->Shaders
,
500 n
* sizeof(struct gl_shader
*),
501 (n
+ 1) * sizeof(struct gl_shader
*));
502 if (!shProg
->Shaders
) {
503 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
508 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
509 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
510 shProg
->NumShaders
++;
515 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
518 struct gl_shader_program
*shProg
519 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
525 if (!shProg
->LinkStatus
) {
526 _mesa_error(ctx
, GL_INVALID_OPERATION
,
527 "glGetAttribLocation(program not linked)");
534 if (shProg
->VertexProgram
) {
535 const struct gl_program_parameter_list
*attribs
=
536 shProg
->VertexProgram
->Base
.Attributes
;
538 GLint i
= _mesa_lookup_parameter_index(attribs
, -1, name
);
540 return attribs
->Parameters
[i
].StateIndexes
[0];
549 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
552 struct gl_shader_program
*shProg
;
553 const GLint size
= -1; /* unknown size */
555 GLenum datatype
= GL_FLOAT_VEC4
;
557 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
558 "glBindAttribLocation");
566 if (strncmp(name
, "gl_", 3) == 0) {
567 _mesa_error(ctx
, GL_INVALID_OPERATION
,
568 "glBindAttribLocation(illegal name)");
572 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
573 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
577 if (shProg
->LinkStatus
) {
578 /* get current index/location for the attribute */
579 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
585 /* this will replace the current value if it's already in the list */
586 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, datatype
, index
);
588 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
593 * Note that this attribute binding won't go into effect until
594 * glLinkProgram is called again.
600 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
602 struct gl_shader
*sh
;
605 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
608 case GL_FRAGMENT_SHADER
:
609 case GL_VERTEX_SHADER
:
610 sh
= _mesa_new_shader(ctx
, name
, type
);
613 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
617 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
624 _mesa_create_program(GLcontext
*ctx
)
627 struct gl_shader_program
*shProg
;
629 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
630 shProg
= _mesa_new_shader_program(ctx
, name
);
632 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
634 assert(shProg
->RefCount
== 1);
641 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
645 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
648 * NOTE: deleting shaders/programs works a bit differently than
649 * texture objects (and buffer objects, etc). Shader/program
650 * handles/IDs exist in the hash table until the object is really
651 * deleted (refcount==0). With texture objects, the handle/ID is
652 * removed from the hash table in glDeleteTextures() while the tex
653 * object itself might linger until its refcount goes to zero.
655 struct gl_shader_program
*shProg
;
657 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
661 shProg
->DeletePending
= GL_TRUE
;
663 /* effectively, decr shProg's refcount */
664 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
669 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
671 struct gl_shader
*sh
;
673 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
677 sh
->DeletePending
= GL_TRUE
;
679 /* effectively, decr sh's refcount */
680 _mesa_reference_shader(ctx
, &sh
, NULL
);
685 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
687 struct gl_shader_program
*shProg
;
691 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
695 n
= shProg
->NumShaders
;
697 for (i
= 0; i
< n
; i
++) {
698 if (shProg
->Shaders
[i
]->Name
== shader
) {
700 struct gl_shader
**newList
;
703 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
705 /* alloc new, smaller array */
706 newList
= (struct gl_shader
**)
707 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
709 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
712 for (j
= 0; j
< i
; j
++) {
713 newList
[j
] = shProg
->Shaders
[j
];
716 newList
[j
++] = shProg
->Shaders
[i
];
717 _mesa_free(shProg
->Shaders
);
719 shProg
->Shaders
= newList
;
720 shProg
->NumShaders
= n
- 1;
725 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
726 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
727 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
728 assert(shProg
->Shaders
[j
]->RefCount
> 0);
740 if (_mesa_is_shader(ctx
, shader
))
741 err
= GL_INVALID_OPERATION
;
742 else if (_mesa_is_program(ctx
, shader
))
743 err
= GL_INVALID_OPERATION
;
745 err
= GL_INVALID_VALUE
;
746 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
753 sizeof_glsl_type(GLenum type
)
762 case GL_SAMPLER_CUBE
:
763 case GL_SAMPLER_1D_SHADOW
:
764 case GL_SAMPLER_2D_SHADOW
:
765 case GL_SAMPLER_2D_RECT_ARB
:
766 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
767 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
768 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
769 case GL_SAMPLER_CUBE_SHADOW_EXT
:
784 case GL_FLOAT_MAT2x3
:
785 case GL_FLOAT_MAT2x4
:
786 return 8; /* two float[4] vectors */
788 case GL_FLOAT_MAT3x2
:
789 case GL_FLOAT_MAT3x4
:
790 return 12; /* three float[4] vectors */
792 case GL_FLOAT_MAT4x2
:
793 case GL_FLOAT_MAT4x3
:
794 return 16; /* four float[4] vectors */
796 _mesa_problem(NULL
, "Invalid type in sizeof_glsl_type()");
803 is_boolean_type(GLenum type
)
818 is_integer_type(GLenum type
)
833 is_sampler_type(GLenum type
)
839 case GL_SAMPLER_CUBE
:
840 case GL_SAMPLER_1D_SHADOW
:
841 case GL_SAMPLER_2D_SHADOW
:
842 case GL_SAMPLER_2D_RECT_ARB
:
843 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
844 case GL_SAMPLER_1D_ARRAY_EXT
:
845 case GL_SAMPLER_2D_ARRAY_EXT
:
854 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
855 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
856 GLenum
*type
, GLchar
*nameOut
)
858 const struct gl_program_parameter_list
*attribs
= NULL
;
859 struct gl_shader_program
*shProg
;
861 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
865 if (shProg
->VertexProgram
)
866 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
868 if (!attribs
|| index
>= attribs
->NumParameters
) {
869 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
873 copy_string(nameOut
, maxLength
, length
, attribs
->Parameters
[index
].Name
);
876 *size
= attribs
->Parameters
[index
].Size
877 / sizeof_glsl_type(attribs
->Parameters
[index
].DataType
);
880 *type
= attribs
->Parameters
[index
].DataType
;
884 static struct gl_program_parameter
*
885 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
887 const struct gl_program
*prog
;
890 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
892 prog
= &shProg
->VertexProgram
->Base
;
895 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
897 prog
= &shProg
->FragmentProgram
->Base
;
901 if (!prog
|| progPos
< 0)
902 return NULL
; /* should never happen */
904 return &prog
->Parameters
->Parameters
[progPos
];
909 * Called via ctx->Driver.GetActiveUniform().
912 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
913 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
914 GLenum
*type
, GLchar
*nameOut
)
916 const struct gl_shader_program
*shProg
;
917 const struct gl_program
*prog
;
918 const struct gl_program_parameter
*param
;
921 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
925 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
926 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
930 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
932 prog
= &shProg
->VertexProgram
->Base
;
935 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
937 prog
= &shProg
->FragmentProgram
->Base
;
941 if (!prog
|| progPos
< 0)
942 return; /* should never happen */
944 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
945 param
= &prog
->Parameters
->Parameters
[progPos
];
948 copy_string(nameOut
, maxLength
, length
, param
->Name
);
952 GLint typeSize
= sizeof_glsl_type(param
->DataType
);
953 if (param
->Size
> typeSize
) {
955 * Array elements are placed on vector[4] boundaries so they're
956 * a multiple of four floats. We round typeSize up to next multiple
957 * of four to get the right size below.
959 typeSize
= (typeSize
+ 3) & ~3;
961 /* Note that the returned size is in units of the <type>, not bytes */
962 *size
= param
->Size
/ typeSize
;
966 *type
= param
->DataType
;
972 * Called via ctx->Driver.GetAttachedShaders().
975 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
976 GLsizei
*count
, GLuint
*obj
)
978 struct gl_shader_program
*shProg
=
979 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
982 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
983 obj
[i
] = shProg
->Shaders
[i
]->Name
;
992 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
996 if (pname
== GL_PROGRAM_OBJECT_ARB
) {
997 CALL_GetIntegerv(ctx
->Exec
, (GL_CURRENT_PROGRAM
, &handle
));
999 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
1007 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
1008 GLenum pname
, GLint
*params
)
1010 const struct gl_program_parameter_list
*attribs
;
1011 struct gl_shader_program
*shProg
1012 = _mesa_lookup_shader_program(ctx
, program
);
1015 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
1019 if (shProg
->VertexProgram
)
1020 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
1025 case GL_DELETE_STATUS
:
1026 *params
= shProg
->DeletePending
;
1028 case GL_LINK_STATUS
:
1029 *params
= shProg
->LinkStatus
;
1031 case GL_VALIDATE_STATUS
:
1032 *params
= shProg
->Validated
;
1034 case GL_INFO_LOG_LENGTH
:
1035 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
1037 case GL_ATTACHED_SHADERS
:
1038 *params
= shProg
->NumShaders
;
1040 case GL_ACTIVE_ATTRIBUTES
:
1041 *params
= attribs
? attribs
->NumParameters
: 0;
1043 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
1044 *params
= _mesa_longest_parameter_name(attribs
, PROGRAM_INPUT
) + 1;
1046 case GL_ACTIVE_UNIFORMS
:
1047 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
1049 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
1050 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
1052 (*params
)++; /* add one for terminating zero */
1054 case GL_PROGRAM_BINARY_LENGTH_OES
:
1058 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
1065 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
1067 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
1074 case GL_SHADER_TYPE
:
1075 *params
= shader
->Type
;
1077 case GL_DELETE_STATUS
:
1078 *params
= shader
->DeletePending
;
1080 case GL_COMPILE_STATUS
:
1081 *params
= shader
->CompileStatus
;
1083 case GL_INFO_LOG_LENGTH
:
1084 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
1086 case GL_SHADER_SOURCE_LENGTH
:
1087 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
1090 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
1097 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
1098 GLsizei
*length
, GLchar
*infoLog
)
1100 struct gl_shader_program
*shProg
1101 = _mesa_lookup_shader_program(ctx
, program
);
1103 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
1106 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
1111 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
1112 GLsizei
*length
, GLchar
*infoLog
)
1114 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1116 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
1119 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
1124 * Called via ctx->Driver.GetShaderSource().
1127 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
1128 GLsizei
*length
, GLchar
*sourceOut
)
1130 struct gl_shader
*sh
;
1131 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
1135 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
1140 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1146 case GL_FLOAT_MAT2x3
:
1150 case GL_FLOAT_MAT2x4
:
1158 case GL_FLOAT_MAT3x2
:
1162 case GL_FLOAT_MAT3x4
:
1170 case GL_FLOAT_MAT4x2
:
1174 case GL_FLOAT_MAT4x3
:
1185 * Determine the number of rows and columns occupied by a uniform
1186 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1187 * the number of rows = 1 and cols = number of elements in the vector.
1190 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
1191 GLint
*rows
, GLint
*cols
)
1193 get_matrix_dims(p
->DataType
, rows
, cols
);
1194 if (*rows
== 0 && *cols
== 0) {
1195 /* not a matrix type, probably a float or vector */
1201 *rows
= p
->Size
/ 4 + 1;
1202 if (p
->Size
% 4 == 0)
1205 *cols
= p
->Size
% 4;
1212 * Helper for get_uniform[fi]v() functions.
1213 * Given a shader program name and uniform location, return a pointer
1214 * to the shader program and return the program parameter position.
1217 lookup_uniform_parameter(GLcontext
*ctx
, GLuint program
, GLint location
,
1218 struct gl_program
**progOut
, GLint
*paramPosOut
)
1220 struct gl_shader_program
*shProg
1221 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
1222 struct gl_program
*prog
= NULL
;
1225 /* if shProg is NULL, we'll have already recorded an error */
1228 if (!shProg
->Uniforms
||
1230 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1231 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1234 /* OK, find the gl_program and program parameter location */
1235 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1237 prog
= &shProg
->VertexProgram
->Base
;
1240 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1242 prog
= &shProg
->FragmentProgram
->Base
;
1249 *paramPosOut
= progPos
;
1254 * Called via ctx->Driver.GetUniformfv().
1257 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1260 struct gl_program
*prog
;
1263 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1266 const struct gl_program_parameter
*p
=
1267 &prog
->Parameters
->Parameters
[paramPos
];
1268 GLint rows
, cols
, i
, j
, k
;
1270 get_uniform_rows_cols(p
, &rows
, &cols
);
1273 for (i
= 0; i
< rows
; i
++) {
1274 for (j
= 0; j
< cols
; j
++ ) {
1275 params
[k
++] = prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1283 * Called via ctx->Driver.GetUniformiv().
1284 * \sa _mesa_get_uniformfv, only difference is a cast.
1287 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1290 struct gl_program
*prog
;
1293 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1296 const struct gl_program_parameter
*p
=
1297 &prog
->Parameters
->Parameters
[paramPos
];
1298 GLint rows
, cols
, i
, j
, k
;
1300 get_uniform_rows_cols(p
, &rows
, &cols
);
1303 for (i
= 0; i
< rows
; i
++) {
1304 for (j
= 0; j
< cols
; j
++ ) {
1305 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1313 * The value returned by GetUniformLocation actually encodes two things:
1314 * 1. the index into the prog->Uniforms[] array for the uniform
1315 * 2. an offset in the prog->ParameterValues[] array for specifying array
1316 * elements or structure fields.
1317 * This function merges those two values.
1320 merge_location_offset(GLint
*location
, GLint offset
)
1322 *location
= *location
| (offset
<< 16);
1327 * Seperate the uniform location and parameter offset. See above.
1330 split_location_offset(GLint
*location
, GLint
*offset
)
1332 *offset
= (*location
>> 16);
1333 *location
= *location
& 0xffff;
1338 * Called via ctx->Driver.GetUniformLocation().
1340 * The return value will encode two values, the uniform location and an
1341 * offset (used for arrays, structs).
1344 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1346 GLint offset
= 0, location
= -1;
1348 struct gl_shader_program
*shProg
=
1349 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1354 if (shProg
->LinkStatus
== GL_FALSE
) {
1355 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1359 /* XXX we should return -1 if the uniform was declared, but not
1363 /* XXX we need to be able to parse uniform names for structs and arrays
1370 /* handle 1-dimension arrays here... */
1371 char *c
= strchr(name
, '[');
1373 /* truncate name at [ */
1374 const GLint len
= c
- name
;
1375 GLchar
*newName
= _mesa_malloc(len
+ 1);
1377 return -1; /* out of mem */
1378 _mesa_memcpy(newName
, name
, len
);
1381 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
1382 if (location
>= 0) {
1383 const GLint element
= _mesa_atoi(c
+ 1);
1385 /* get type of the uniform array element */
1386 struct gl_program_parameter
*p
;
1387 p
= get_uniform_parameter(shProg
, location
);
1390 get_matrix_dims(p
->DataType
, &rows
, &cols
);
1393 offset
= element
* rows
;
1398 _mesa_free(newName
);
1403 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1406 if (location
>= 0) {
1407 merge_location_offset(&location
, offset
);
1416 * Called via ctx->Driver.ShaderSource()
1419 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1421 struct gl_shader
*sh
;
1423 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1427 /* free old shader source string and install new one */
1429 _mesa_free((void *) sh
->Source
);
1431 sh
->Source
= source
;
1432 sh
->CompileStatus
= GL_FALSE
;
1437 * Called via ctx->Driver.CompileShader()
1440 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1442 struct gl_shader
*sh
;
1444 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1448 /* set default pragma state for shader */
1449 sh
->Pragmas
= ctx
->Shader
.DefaultPragmas
;
1451 /* this call will set the sh->CompileStatus field to indicate if
1452 * compilation was successful.
1454 (void) _slang_compile(ctx
, sh
);
1459 * Called via ctx->Driver.LinkProgram()
1462 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1464 struct gl_shader_program
*shProg
;
1466 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1470 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1472 _slang_link(ctx
, program
, shProg
);
1477 * Called via ctx->Driver.UseProgram()
1480 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1482 struct gl_shader_program
*shProg
;
1484 if (ctx
->Shader
.CurrentProgram
&&
1485 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1490 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
1493 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1497 if (!shProg
->LinkStatus
) {
1498 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1499 "glUseProgram(program %u not linked)", program
);
1506 _mesa_printf("Use Shader %u\n", shProg
->Name
);
1507 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1508 _mesa_printf(" shader %u, type 0x%x\n",
1509 shProg
->Shaders
[i
]->Name
,
1510 shProg
->Shaders
[i
]->Type
);
1512 if (shProg
->VertexProgram
)
1513 printf(" vert prog %u\n", shProg
->VertexProgram
->Base
.Id
);
1514 if (shProg
->FragmentProgram
)
1515 printf(" frag prog %u\n", shProg
->FragmentProgram
->Base
.Id
);
1522 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1528 * Update the vertex/fragment program's TexturesUsed array.
1530 * This needs to be called after glUniform(set sampler var) is called.
1531 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1532 * particular texture unit. We know the sampler's texture target
1533 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1534 * set by glUniform() calls.
1536 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1537 * information to update the prog->TexturesUsed[] values.
1538 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1539 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1540 * We'll use that info for state validation before rendering.
1543 _mesa_update_shader_textures_used(struct gl_program
*prog
)
1547 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1549 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1550 if (prog
->SamplersUsed
& (1 << s
)) {
1551 GLuint u
= prog
->SamplerUnits
[s
];
1552 GLuint t
= prog
->SamplerTargets
[s
];
1553 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1554 prog
->TexturesUsed
[u
] |= (1 << t
);
1561 * Check if the type given by userType is allowed to set a uniform of the
1562 * target type. Generally, equivalence is required, but setting Boolean
1563 * uniforms can be done with glUniformiv or glUniformfv.
1566 compatible_types(GLenum userType
, GLenum targetType
)
1568 if (userType
== targetType
)
1571 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1574 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1575 userType
== GL_INT_VEC2
))
1578 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1579 userType
== GL_INT_VEC3
))
1582 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1583 userType
== GL_INT_VEC4
))
1586 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1594 * Set the value of a program's uniform variable.
1595 * \param program the program whose uniform to update
1596 * \param index the index of the program parameter for the uniform
1597 * \param offset additional parameter slot offset (for arrays)
1598 * \param type the incoming datatype of 'values'
1599 * \param count the number of uniforms to set
1600 * \param elems number of elements per uniform (1, 2, 3 or 4)
1601 * \param values the new values, of datatype 'type'
1604 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
1605 GLint index
, GLint offset
,
1606 GLenum type
, GLsizei count
, GLint elems
,
1609 struct gl_program_parameter
*param
=
1610 &program
->Parameters
->Parameters
[index
];
1611 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
1612 const GLboolean areIntValues
= is_integer_type(type
);
1614 assert(offset
>= 0);
1618 if (!compatible_types(type
, param
->DataType
)) {
1619 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1623 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
1624 /* out of bounds! */
1628 if (param
->Type
== PROGRAM_SAMPLER
) {
1629 /* This controls which texture unit which is used by a sampler */
1630 GLuint texUnit
, sampler
;
1633 /* data type for setting samplers must be int */
1634 if (type
!= GL_INT
) {
1635 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1636 "glUniform(only glUniform1i can be used "
1637 "to set sampler uniforms)");
1641 /* XXX arrays of samplers haven't been tested much, but it's not a
1644 for (i
= 0; i
< count
; i
++) {
1645 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[index
+ i
][0];
1646 texUnit
= ((GLuint
*) values
)[i
];
1648 /* check that the sampler (tex unit index) is legal */
1649 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1650 _mesa_error(ctx
, GL_INVALID_VALUE
,
1651 "glUniform1(invalid sampler/tex unit index)");
1655 /* This maps a sampler to a texture unit: */
1656 if (sampler
< MAX_SAMPLERS
) {
1657 program
->SamplerUnits
[sampler
] = texUnit
;
1661 _mesa_update_shader_textures_used(program
);
1663 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1666 /* ordinary uniform variable */
1668 const GLint slots
= (param
->Size
+ 3) / 4;
1669 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1671 if (param
->Size
> typeSize
) {
1673 /* we'll ignore extra data below */
1676 /* non-array: count must be one */
1678 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1679 "glUniform(uniform is not an array)");
1684 /* loop over number of array elements */
1685 for (k
= 0; k
< count
; k
++) {
1686 GLfloat
*uniformVal
;
1688 if (offset
+ k
>= slots
) {
1689 /* Extra array data is ignored */
1693 /* uniformVal (the destination) is always float[4] */
1694 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
1697 /* convert user's ints to floats */
1698 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1699 for (i
= 0; i
< elems
; i
++) {
1700 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1704 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1705 for (i
= 0; i
< elems
; i
++) {
1706 uniformVal
[i
] = fValues
[i
];
1710 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1711 if (isUniformBool
) {
1712 for (i
= 0; i
< elems
; i
++) {
1713 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1722 * Called via ctx->Driver.Uniform().
1725 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1726 const GLvoid
*values
, GLenum type
)
1728 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1729 struct gl_uniform
*uniform
;
1730 GLint elems
, offset
;
1733 if (!shProg
|| !shProg
->LinkStatus
) {
1734 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1739 return; /* The standard specifies this as a no-op */
1741 if (location
< -1) {
1742 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1746 split_location_offset(&location
, &offset
);
1748 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1749 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1754 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1760 basicType
= GL_FLOAT
;
1768 basicType
= GL_FLOAT
;
1776 basicType
= GL_FLOAT
;
1784 basicType
= GL_FLOAT
;
1792 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1796 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1798 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1800 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
1802 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1803 shProg
->Name
, uniform
->Name
, location
);
1804 if (basicType
== GL_INT
) {
1805 const GLint
*v
= (const GLint
*) values
;
1806 for (i
= 0; i
< count
* elems
; i
++) {
1807 _mesa_printf("%d ", v
[i
]);
1811 const GLfloat
*v
= (const GLfloat
*) values
;
1812 for (i
= 0; i
< count
* elems
; i
++) {
1813 _mesa_printf("%g ", v
[i
]);
1819 /* A uniform var may be used by both a vertex shader and a fragment
1820 * shader. We may need to update one or both shader's uniform here:
1822 if (shProg
->VertexProgram
) {
1823 /* convert uniform location to program parameter index */
1824 GLint index
= uniform
->VertPos
;
1826 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1827 index
, offset
, type
, count
, elems
, values
);
1831 if (shProg
->FragmentProgram
) {
1832 /* convert uniform location to program parameter index */
1833 GLint index
= uniform
->FragPos
;
1835 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1836 index
, offset
, type
, count
, elems
, values
);
1840 uniform
->Initialized
= GL_TRUE
;
1845 * Set a matrix-valued program parameter.
1848 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1849 GLuint index
, GLuint offset
,
1850 GLuint count
, GLuint rows
, GLuint cols
,
1851 GLboolean transpose
, const GLfloat
*values
)
1853 GLuint mat
, row
, col
;
1854 GLuint dst
= index
+ offset
, src
= 0;
1857 /* check that the number of rows, columns is correct */
1858 get_matrix_dims(program
->Parameters
->Parameters
[index
].DataType
, &nr
, &nc
);
1859 if (rows
!= nr
|| cols
!= nc
) {
1860 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1861 "glUniformMatrix(matrix size mismatch)");
1865 if (index
+ offset
> program
->Parameters
->Size
) {
1866 /* out of bounds! */
1871 * Note: the _columns_ of a matrix are stored in program registers, not
1872 * the rows. So, the loops below look a little funny.
1873 * XXX could optimize this a bit...
1876 /* loop over matrices */
1877 for (mat
= 0; mat
< count
; mat
++) {
1880 for (col
= 0; col
< cols
; col
++) {
1881 GLfloat
*v
= program
->Parameters
->ParameterValues
[dst
];
1882 for (row
= 0; row
< rows
; row
++) {
1884 v
[row
] = values
[src
+ row
* cols
+ col
];
1887 v
[row
] = values
[src
+ col
* rows
+ row
];
1893 src
+= rows
* cols
; /* next matrix */
1899 * Called by ctx->Driver.UniformMatrix().
1900 * Note: cols=2, rows=4 ==> array[2] of vec4
1903 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1904 GLint location
, GLsizei count
,
1905 GLboolean transpose
, const GLfloat
*values
)
1907 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1908 struct gl_uniform
*uniform
;
1911 if (!shProg
|| !shProg
->LinkStatus
) {
1912 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1913 "glUniformMatrix(program not linked)");
1918 return; /* The standard specifies this as a no-op */
1920 if (location
< -1) {
1921 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
1925 split_location_offset(&location
, &offset
);
1927 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1928 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1931 if (values
== NULL
) {
1932 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1936 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1938 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1940 if (shProg
->VertexProgram
) {
1941 /* convert uniform location to program parameter index */
1942 GLint index
= uniform
->VertPos
;
1944 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1946 count
, rows
, cols
, transpose
, values
);
1950 if (shProg
->FragmentProgram
) {
1951 /* convert uniform location to program parameter index */
1952 GLint index
= uniform
->FragPos
;
1954 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1956 count
, rows
, cols
, transpose
, values
);
1960 uniform
->Initialized
= GL_TRUE
;
1965 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1967 struct gl_shader_program
*shProg
;
1969 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
1974 if (!shProg
->LinkStatus
) {
1975 shProg
->Validated
= GL_FALSE
;
1979 /* From the GL spec, a program is invalid if any of these are true:
1981 any two active samplers in the current program object are of
1982 different types, but refer to the same texture image unit,
1984 any active sampler in the current program object refers to a texture
1985 image unit where fixed-function fragment processing accesses a
1986 texture target that does not match the sampler type, or
1988 the sum of the number of active samplers in the program and the
1989 number of texture image units enabled for fixed-function fragment
1990 processing exceeds the combined limit on the total number of texture
1991 image units allowed.
1994 shProg
->Validated
= GL_TRUE
;
1999 * Plug in Mesa's GLSL functions into the device driver function table.
2002 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
2004 driver
->AttachShader
= _mesa_attach_shader
;
2005 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
2006 driver
->CompileShader
= _mesa_compile_shader
;
2007 driver
->CreateProgram
= _mesa_create_program
;
2008 driver
->CreateShader
= _mesa_create_shader
;
2009 driver
->DeleteProgram2
= _mesa_delete_program2
;
2010 driver
->DeleteShader
= _mesa_delete_shader
;
2011 driver
->DetachShader
= _mesa_detach_shader
;
2012 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
2013 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
2014 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
2015 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
2016 driver
->GetHandle
= _mesa_get_handle
;
2017 driver
->GetProgramiv
= _mesa_get_programiv
;
2018 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
2019 driver
->GetShaderiv
= _mesa_get_shaderiv
;
2020 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
2021 driver
->GetShaderSource
= _mesa_get_shader_source
;
2022 driver
->GetUniformfv
= _mesa_get_uniformfv
;
2023 driver
->GetUniformiv
= _mesa_get_uniformiv
;
2024 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
2025 driver
->IsProgram
= _mesa_is_program
;
2026 driver
->IsShader
= _mesa_is_shader
;
2027 driver
->LinkProgram
= _mesa_link_program
;
2028 driver
->ShaderSource
= _mesa_shader_source
;
2029 driver
->Uniform
= _mesa_uniform
;
2030 driver
->UniformMatrix
= _mesa_uniform_matrix
;
2031 driver
->UseProgram
= _mesa_use_program
;
2032 driver
->ValidateProgram
= _mesa_validate_program
;