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
.EmitContReturn
= GL_TRUE
;
406 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;
407 ctx
->Shader
.EmitComments
= GL_FALSE
;
408 ctx
->Shader
.Flags
= get_shader_flags();
410 /* Default pragma settings */
411 ctx
->Shader
.DefaultPragmas
.IgnoreOptimize
= GL_FALSE
;
412 ctx
->Shader
.DefaultPragmas
.IgnoreDebug
= GL_FALSE
;
413 ctx
->Shader
.DefaultPragmas
.Optimize
= GL_TRUE
;
414 ctx
->Shader
.DefaultPragmas
.Debug
= GL_FALSE
;
419 * Free the per-context shader-related state.
422 _mesa_free_shader_state(GLcontext
*ctx
)
424 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
429 * Copy string from <src> to <dst>, up to maxLength characters, returning
430 * length of <dst> in <length>.
431 * \param src the strings source
432 * \param maxLength max chars to copy
433 * \param length returns number of chars copied
434 * \param dst the string destination
437 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
440 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
450 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
452 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
453 return shProg
? GL_TRUE
: GL_FALSE
;
458 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
460 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
461 return shader
? GL_TRUE
: GL_FALSE
;
466 * Called via ctx->Driver.AttachShader()
469 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
471 struct gl_shader_program
*shProg
;
472 struct gl_shader
*sh
;
475 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
479 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
484 n
= shProg
->NumShaders
;
485 for (i
= 0; i
< n
; i
++) {
486 if (shProg
->Shaders
[i
] == sh
) {
487 /* The shader is already attched to this program. The
488 * GL_ARB_shader_objects spec says:
490 * "The error INVALID_OPERATION is generated by AttachObjectARB
491 * if <obj> is already attached to <containerObj>."
493 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glAttachShader");
499 shProg
->Shaders
= (struct gl_shader
**)
500 _mesa_realloc(shProg
->Shaders
,
501 n
* sizeof(struct gl_shader
*),
502 (n
+ 1) * sizeof(struct gl_shader
*));
503 if (!shProg
->Shaders
) {
504 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
509 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
510 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
511 shProg
->NumShaders
++;
516 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
519 struct gl_shader_program
*shProg
520 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
526 if (!shProg
->LinkStatus
) {
527 _mesa_error(ctx
, GL_INVALID_OPERATION
,
528 "glGetAttribLocation(program not linked)");
535 if (shProg
->VertexProgram
) {
536 const struct gl_program_parameter_list
*attribs
=
537 shProg
->VertexProgram
->Base
.Attributes
;
539 GLint i
= _mesa_lookup_parameter_index(attribs
, -1, name
);
541 return attribs
->Parameters
[i
].StateIndexes
[0];
550 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
553 struct gl_shader_program
*shProg
;
554 const GLint size
= -1; /* unknown size */
556 GLenum datatype
= GL_FLOAT_VEC4
;
558 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
559 "glBindAttribLocation");
567 if (strncmp(name
, "gl_", 3) == 0) {
568 _mesa_error(ctx
, GL_INVALID_OPERATION
,
569 "glBindAttribLocation(illegal name)");
573 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
574 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
578 if (shProg
->LinkStatus
) {
579 /* get current index/location for the attribute */
580 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
586 /* this will replace the current value if it's already in the list */
587 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, datatype
, index
);
589 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
594 * Note that this attribute binding won't go into effect until
595 * glLinkProgram is called again.
601 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
603 struct gl_shader
*sh
;
606 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
609 case GL_FRAGMENT_SHADER
:
610 case GL_VERTEX_SHADER
:
611 sh
= _mesa_new_shader(ctx
, name
, type
);
614 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
618 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
625 _mesa_create_program(GLcontext
*ctx
)
628 struct gl_shader_program
*shProg
;
630 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
631 shProg
= _mesa_new_shader_program(ctx
, name
);
633 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
635 assert(shProg
->RefCount
== 1);
642 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
646 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
649 * NOTE: deleting shaders/programs works a bit differently than
650 * texture objects (and buffer objects, etc). Shader/program
651 * handles/IDs exist in the hash table until the object is really
652 * deleted (refcount==0). With texture objects, the handle/ID is
653 * removed from the hash table in glDeleteTextures() while the tex
654 * object itself might linger until its refcount goes to zero.
656 struct gl_shader_program
*shProg
;
658 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
662 shProg
->DeletePending
= GL_TRUE
;
664 /* effectively, decr shProg's refcount */
665 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
670 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
672 struct gl_shader
*sh
;
674 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
678 sh
->DeletePending
= GL_TRUE
;
680 /* effectively, decr sh's refcount */
681 _mesa_reference_shader(ctx
, &sh
, NULL
);
686 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
688 struct gl_shader_program
*shProg
;
692 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
696 n
= shProg
->NumShaders
;
698 for (i
= 0; i
< n
; i
++) {
699 if (shProg
->Shaders
[i
]->Name
== shader
) {
701 struct gl_shader
**newList
;
704 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
706 /* alloc new, smaller array */
707 newList
= (struct gl_shader
**)
708 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
710 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
713 for (j
= 0; j
< i
; j
++) {
714 newList
[j
] = shProg
->Shaders
[j
];
717 newList
[j
++] = shProg
->Shaders
[i
];
718 _mesa_free(shProg
->Shaders
);
720 shProg
->Shaders
= newList
;
721 shProg
->NumShaders
= n
- 1;
726 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
727 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
728 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
729 assert(shProg
->Shaders
[j
]->RefCount
> 0);
741 if (_mesa_is_shader(ctx
, shader
))
742 err
= GL_INVALID_OPERATION
;
743 else if (_mesa_is_program(ctx
, shader
))
744 err
= GL_INVALID_OPERATION
;
746 err
= GL_INVALID_VALUE
;
747 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
754 sizeof_glsl_type(GLenum type
)
763 case GL_SAMPLER_CUBE
:
764 case GL_SAMPLER_1D_SHADOW
:
765 case GL_SAMPLER_2D_SHADOW
:
766 case GL_SAMPLER_2D_RECT_ARB
:
767 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
768 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
769 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
770 case GL_SAMPLER_CUBE_SHADOW_EXT
:
785 case GL_FLOAT_MAT2x3
:
786 case GL_FLOAT_MAT2x4
:
787 return 8; /* two float[4] vectors */
789 case GL_FLOAT_MAT3x2
:
790 case GL_FLOAT_MAT3x4
:
791 return 12; /* three float[4] vectors */
793 case GL_FLOAT_MAT4x2
:
794 case GL_FLOAT_MAT4x3
:
795 return 16; /* four float[4] vectors */
797 _mesa_problem(NULL
, "Invalid type in sizeof_glsl_type()");
804 is_boolean_type(GLenum type
)
819 is_integer_type(GLenum type
)
834 is_sampler_type(GLenum type
)
840 case GL_SAMPLER_CUBE
:
841 case GL_SAMPLER_1D_SHADOW
:
842 case GL_SAMPLER_2D_SHADOW
:
843 case GL_SAMPLER_2D_RECT_ARB
:
844 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
845 case GL_SAMPLER_1D_ARRAY_EXT
:
846 case GL_SAMPLER_2D_ARRAY_EXT
:
855 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
856 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
857 GLenum
*type
, GLchar
*nameOut
)
859 const struct gl_program_parameter_list
*attribs
= NULL
;
860 struct gl_shader_program
*shProg
;
862 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
866 if (shProg
->VertexProgram
)
867 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
869 if (!attribs
|| index
>= attribs
->NumParameters
) {
870 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
874 copy_string(nameOut
, maxLength
, length
, attribs
->Parameters
[index
].Name
);
877 *size
= attribs
->Parameters
[index
].Size
878 / sizeof_glsl_type(attribs
->Parameters
[index
].DataType
);
881 *type
= attribs
->Parameters
[index
].DataType
;
885 static struct gl_program_parameter
*
886 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
888 const struct gl_program
*prog
;
891 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
893 prog
= &shProg
->VertexProgram
->Base
;
896 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
898 prog
= &shProg
->FragmentProgram
->Base
;
902 if (!prog
|| progPos
< 0)
903 return NULL
; /* should never happen */
905 return &prog
->Parameters
->Parameters
[progPos
];
910 * Called via ctx->Driver.GetActiveUniform().
913 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
914 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
915 GLenum
*type
, GLchar
*nameOut
)
917 const struct gl_shader_program
*shProg
;
918 const struct gl_program
*prog
;
919 const struct gl_program_parameter
*param
;
922 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
926 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
927 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
931 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
933 prog
= &shProg
->VertexProgram
->Base
;
936 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
938 prog
= &shProg
->FragmentProgram
->Base
;
942 if (!prog
|| progPos
< 0)
943 return; /* should never happen */
945 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
946 param
= &prog
->Parameters
->Parameters
[progPos
];
949 copy_string(nameOut
, maxLength
, length
, param
->Name
);
953 GLint typeSize
= sizeof_glsl_type(param
->DataType
);
954 if (param
->Size
> typeSize
) {
956 * Array elements are placed on vector[4] boundaries so they're
957 * a multiple of four floats. We round typeSize up to next multiple
958 * of four to get the right size below.
960 typeSize
= (typeSize
+ 3) & ~3;
962 /* Note that the returned size is in units of the <type>, not bytes */
963 *size
= param
->Size
/ typeSize
;
967 *type
= param
->DataType
;
973 * Called via ctx->Driver.GetAttachedShaders().
976 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
977 GLsizei
*count
, GLuint
*obj
)
979 struct gl_shader_program
*shProg
=
980 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
983 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
984 obj
[i
] = shProg
->Shaders
[i
]->Name
;
993 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
997 if (pname
== GL_PROGRAM_OBJECT_ARB
) {
998 CALL_GetIntegerv(ctx
->Exec
, (GL_CURRENT_PROGRAM
, &handle
));
1000 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
1008 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
1009 GLenum pname
, GLint
*params
)
1011 const struct gl_program_parameter_list
*attribs
;
1012 struct gl_shader_program
*shProg
1013 = _mesa_lookup_shader_program(ctx
, program
);
1016 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
1020 if (shProg
->VertexProgram
)
1021 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
1026 case GL_DELETE_STATUS
:
1027 *params
= shProg
->DeletePending
;
1029 case GL_LINK_STATUS
:
1030 *params
= shProg
->LinkStatus
;
1032 case GL_VALIDATE_STATUS
:
1033 *params
= shProg
->Validated
;
1035 case GL_INFO_LOG_LENGTH
:
1036 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
1038 case GL_ATTACHED_SHADERS
:
1039 *params
= shProg
->NumShaders
;
1041 case GL_ACTIVE_ATTRIBUTES
:
1042 *params
= attribs
? attribs
->NumParameters
: 0;
1044 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
1045 *params
= _mesa_longest_parameter_name(attribs
, PROGRAM_INPUT
) + 1;
1047 case GL_ACTIVE_UNIFORMS
:
1048 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
1050 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
1051 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
1053 (*params
)++; /* add one for terminating zero */
1055 case GL_PROGRAM_BINARY_LENGTH_OES
:
1059 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
1066 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
1068 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
1075 case GL_SHADER_TYPE
:
1076 *params
= shader
->Type
;
1078 case GL_DELETE_STATUS
:
1079 *params
= shader
->DeletePending
;
1081 case GL_COMPILE_STATUS
:
1082 *params
= shader
->CompileStatus
;
1084 case GL_INFO_LOG_LENGTH
:
1085 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
1087 case GL_SHADER_SOURCE_LENGTH
:
1088 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
1091 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
1098 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
1099 GLsizei
*length
, GLchar
*infoLog
)
1101 struct gl_shader_program
*shProg
1102 = _mesa_lookup_shader_program(ctx
, program
);
1104 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
1107 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
1112 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
1113 GLsizei
*length
, GLchar
*infoLog
)
1115 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1117 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
1120 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
1125 * Called via ctx->Driver.GetShaderSource().
1128 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
1129 GLsizei
*length
, GLchar
*sourceOut
)
1131 struct gl_shader
*sh
;
1132 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
1136 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
1141 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1147 case GL_FLOAT_MAT2x3
:
1151 case GL_FLOAT_MAT2x4
:
1159 case GL_FLOAT_MAT3x2
:
1163 case GL_FLOAT_MAT3x4
:
1171 case GL_FLOAT_MAT4x2
:
1175 case GL_FLOAT_MAT4x3
:
1186 * Determine the number of rows and columns occupied by a uniform
1187 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1188 * the number of rows = 1 and cols = number of elements in the vector.
1191 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
1192 GLint
*rows
, GLint
*cols
)
1194 get_matrix_dims(p
->DataType
, rows
, cols
);
1195 if (*rows
== 0 && *cols
== 0) {
1196 /* not a matrix type, probably a float or vector */
1202 *rows
= p
->Size
/ 4 + 1;
1203 if (p
->Size
% 4 == 0)
1206 *cols
= p
->Size
% 4;
1213 * Helper for get_uniform[fi]v() functions.
1214 * Given a shader program name and uniform location, return a pointer
1215 * to the shader program and return the program parameter position.
1218 lookup_uniform_parameter(GLcontext
*ctx
, GLuint program
, GLint location
,
1219 struct gl_program
**progOut
, GLint
*paramPosOut
)
1221 struct gl_shader_program
*shProg
1222 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
1223 struct gl_program
*prog
= NULL
;
1226 /* if shProg is NULL, we'll have already recorded an error */
1229 if (!shProg
->Uniforms
||
1231 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1232 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1235 /* OK, find the gl_program and program parameter location */
1236 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1238 prog
= &shProg
->VertexProgram
->Base
;
1241 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1243 prog
= &shProg
->FragmentProgram
->Base
;
1250 *paramPosOut
= progPos
;
1255 * Called via ctx->Driver.GetUniformfv().
1258 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1261 struct gl_program
*prog
;
1264 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1267 const struct gl_program_parameter
*p
=
1268 &prog
->Parameters
->Parameters
[paramPos
];
1269 GLint rows
, cols
, i
, j
, k
;
1271 get_uniform_rows_cols(p
, &rows
, &cols
);
1274 for (i
= 0; i
< rows
; i
++) {
1275 for (j
= 0; j
< cols
; j
++ ) {
1276 params
[k
++] = prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1284 * Called via ctx->Driver.GetUniformiv().
1285 * \sa _mesa_get_uniformfv, only difference is a cast.
1288 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1291 struct gl_program
*prog
;
1294 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1297 const struct gl_program_parameter
*p
=
1298 &prog
->Parameters
->Parameters
[paramPos
];
1299 GLint rows
, cols
, i
, j
, k
;
1301 get_uniform_rows_cols(p
, &rows
, &cols
);
1304 for (i
= 0; i
< rows
; i
++) {
1305 for (j
= 0; j
< cols
; j
++ ) {
1306 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1314 * The value returned by GetUniformLocation actually encodes two things:
1315 * 1. the index into the prog->Uniforms[] array for the uniform
1316 * 2. an offset in the prog->ParameterValues[] array for specifying array
1317 * elements or structure fields.
1318 * This function merges those two values.
1321 merge_location_offset(GLint
*location
, GLint offset
)
1323 *location
= *location
| (offset
<< 16);
1328 * Seperate the uniform location and parameter offset. See above.
1331 split_location_offset(GLint
*location
, GLint
*offset
)
1333 *offset
= (*location
>> 16);
1334 *location
= *location
& 0xffff;
1339 * Called via ctx->Driver.GetUniformLocation().
1341 * The return value will encode two values, the uniform location and an
1342 * offset (used for arrays, structs).
1345 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1347 GLint offset
= 0, location
= -1;
1349 struct gl_shader_program
*shProg
=
1350 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1355 if (shProg
->LinkStatus
== GL_FALSE
) {
1356 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1360 /* XXX we should return -1 if the uniform was declared, but not
1364 /* XXX we need to be able to parse uniform names for structs and arrays
1371 /* handle 1-dimension arrays here... */
1372 char *c
= strchr(name
, '[');
1374 /* truncate name at [ */
1375 const GLint len
= c
- name
;
1376 GLchar
*newName
= _mesa_malloc(len
+ 1);
1378 return -1; /* out of mem */
1379 _mesa_memcpy(newName
, name
, len
);
1382 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
1383 if (location
>= 0) {
1384 const GLint element
= _mesa_atoi(c
+ 1);
1386 /* get type of the uniform array element */
1387 struct gl_program_parameter
*p
;
1388 p
= get_uniform_parameter(shProg
, location
);
1391 get_matrix_dims(p
->DataType
, &rows
, &cols
);
1394 offset
= element
* rows
;
1399 _mesa_free(newName
);
1404 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1407 if (location
>= 0) {
1408 merge_location_offset(&location
, offset
);
1417 * Called via ctx->Driver.ShaderSource()
1420 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1422 struct gl_shader
*sh
;
1424 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1428 /* free old shader source string and install new one */
1430 _mesa_free((void *) sh
->Source
);
1432 sh
->Source
= source
;
1433 sh
->CompileStatus
= GL_FALSE
;
1438 * Called via ctx->Driver.CompileShader()
1441 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1443 struct gl_shader
*sh
;
1445 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1449 /* set default pragma state for shader */
1450 sh
->Pragmas
= ctx
->Shader
.DefaultPragmas
;
1452 /* this call will set the sh->CompileStatus field to indicate if
1453 * compilation was successful.
1455 (void) _slang_compile(ctx
, sh
);
1460 * Called via ctx->Driver.LinkProgram()
1463 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1465 struct gl_shader_program
*shProg
;
1467 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1471 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1473 _slang_link(ctx
, program
, shProg
);
1478 * Called via ctx->Driver.UseProgram()
1481 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1483 struct gl_shader_program
*shProg
;
1485 if (ctx
->Shader
.CurrentProgram
&&
1486 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1491 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
1494 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1498 if (!shProg
->LinkStatus
) {
1499 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1500 "glUseProgram(program %u not linked)", program
);
1507 _mesa_printf("Use Shader %u\n", shProg
->Name
);
1508 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1509 _mesa_printf(" shader %u, type 0x%x\n",
1510 shProg
->Shaders
[i
]->Name
,
1511 shProg
->Shaders
[i
]->Type
);
1513 if (shProg
->VertexProgram
)
1514 printf(" vert prog %u\n", shProg
->VertexProgram
->Base
.Id
);
1515 if (shProg
->FragmentProgram
)
1516 printf(" frag prog %u\n", shProg
->FragmentProgram
->Base
.Id
);
1523 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1529 * Update the vertex/fragment program's TexturesUsed array.
1531 * This needs to be called after glUniform(set sampler var) is called.
1532 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1533 * particular texture unit. We know the sampler's texture target
1534 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1535 * set by glUniform() calls.
1537 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1538 * information to update the prog->TexturesUsed[] values.
1539 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1540 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1541 * We'll use that info for state validation before rendering.
1544 _mesa_update_shader_textures_used(struct gl_program
*prog
)
1548 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1550 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1551 if (prog
->SamplersUsed
& (1 << s
)) {
1552 GLuint u
= prog
->SamplerUnits
[s
];
1553 GLuint t
= prog
->SamplerTargets
[s
];
1554 assert(u
< MAX_TEXTURE_IMAGE_UNITS
);
1555 prog
->TexturesUsed
[u
] |= (1 << t
);
1562 * Check if the type given by userType is allowed to set a uniform of the
1563 * target type. Generally, equivalence is required, but setting Boolean
1564 * uniforms can be done with glUniformiv or glUniformfv.
1567 compatible_types(GLenum userType
, GLenum targetType
)
1569 if (userType
== targetType
)
1572 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1575 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1576 userType
== GL_INT_VEC2
))
1579 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1580 userType
== GL_INT_VEC3
))
1583 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1584 userType
== GL_INT_VEC4
))
1587 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1595 * Set the value of a program's uniform variable.
1596 * \param program the program whose uniform to update
1597 * \param index the index of the program parameter for the uniform
1598 * \param offset additional parameter slot offset (for arrays)
1599 * \param type the incoming datatype of 'values'
1600 * \param count the number of uniforms to set
1601 * \param elems number of elements per uniform (1, 2, 3 or 4)
1602 * \param values the new values, of datatype 'type'
1605 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
1606 GLint index
, GLint offset
,
1607 GLenum type
, GLsizei count
, GLint elems
,
1610 struct gl_program_parameter
*param
=
1611 &program
->Parameters
->Parameters
[index
];
1612 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
1613 const GLboolean areIntValues
= is_integer_type(type
);
1615 assert(offset
>= 0);
1619 if (!compatible_types(type
, param
->DataType
)) {
1620 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1624 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
1625 /* out of bounds! */
1629 if (param
->Type
== PROGRAM_SAMPLER
) {
1630 /* This controls which texture unit which is used by a sampler */
1631 GLuint texUnit
, sampler
;
1634 /* data type for setting samplers must be int */
1635 if (type
!= GL_INT
) {
1636 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1637 "glUniform(only glUniform1i can be used "
1638 "to set sampler uniforms)");
1642 /* XXX arrays of samplers haven't been tested much, but it's not a
1645 for (i
= 0; i
< count
; i
++) {
1646 sampler
= (GLuint
) program
->Parameters
->ParameterValues
[index
+ i
][0];
1647 texUnit
= ((GLuint
*) values
)[i
];
1649 /* check that the sampler (tex unit index) is legal */
1650 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1651 _mesa_error(ctx
, GL_INVALID_VALUE
,
1652 "glUniform1(invalid sampler/tex unit index)");
1656 /* This maps a sampler to a texture unit: */
1657 if (sampler
< MAX_SAMPLERS
) {
1658 program
->SamplerUnits
[sampler
] = texUnit
;
1662 _mesa_update_shader_textures_used(program
);
1664 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1667 /* ordinary uniform variable */
1669 const GLint slots
= (param
->Size
+ 3) / 4;
1670 const GLint typeSize
= sizeof_glsl_type(param
->DataType
);
1672 if (param
->Size
> typeSize
) {
1674 /* we'll ignore extra data below */
1677 /* non-array: count must be one */
1679 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1680 "glUniform(uniform is not an array)");
1685 /* loop over number of array elements */
1686 for (k
= 0; k
< count
; k
++) {
1687 GLfloat
*uniformVal
;
1689 if (offset
+ k
>= slots
) {
1690 /* Extra array data is ignored */
1694 /* uniformVal (the destination) is always float[4] */
1695 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
1698 /* convert user's ints to floats */
1699 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1700 for (i
= 0; i
< elems
; i
++) {
1701 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1705 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1706 for (i
= 0; i
< elems
; i
++) {
1707 uniformVal
[i
] = fValues
[i
];
1711 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1712 if (isUniformBool
) {
1713 for (i
= 0; i
< elems
; i
++) {
1714 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1723 * Called via ctx->Driver.Uniform().
1726 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1727 const GLvoid
*values
, GLenum type
)
1729 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1730 struct gl_uniform
*uniform
;
1731 GLint elems
, offset
;
1734 if (!shProg
|| !shProg
->LinkStatus
) {
1735 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1740 return; /* The standard specifies this as a no-op */
1742 if (location
< -1) {
1743 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1747 split_location_offset(&location
, &offset
);
1749 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1750 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1755 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1761 basicType
= GL_FLOAT
;
1769 basicType
= GL_FLOAT
;
1777 basicType
= GL_FLOAT
;
1785 basicType
= GL_FLOAT
;
1793 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1797 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1799 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1801 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
1803 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1804 shProg
->Name
, uniform
->Name
, location
);
1805 if (basicType
== GL_INT
) {
1806 const GLint
*v
= (const GLint
*) values
;
1807 for (i
= 0; i
< count
* elems
; i
++) {
1808 _mesa_printf("%d ", v
[i
]);
1812 const GLfloat
*v
= (const GLfloat
*) values
;
1813 for (i
= 0; i
< count
* elems
; i
++) {
1814 _mesa_printf("%g ", v
[i
]);
1820 /* A uniform var may be used by both a vertex shader and a fragment
1821 * shader. We may need to update one or both shader's uniform here:
1823 if (shProg
->VertexProgram
) {
1824 /* convert uniform location to program parameter index */
1825 GLint index
= uniform
->VertPos
;
1827 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1828 index
, offset
, type
, count
, elems
, values
);
1832 if (shProg
->FragmentProgram
) {
1833 /* convert uniform location to program parameter index */
1834 GLint index
= uniform
->FragPos
;
1836 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1837 index
, offset
, type
, count
, elems
, values
);
1841 uniform
->Initialized
= GL_TRUE
;
1846 * Set a matrix-valued program parameter.
1849 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1850 GLuint index
, GLuint offset
,
1851 GLuint count
, GLuint rows
, GLuint cols
,
1852 GLboolean transpose
, const GLfloat
*values
)
1854 GLuint mat
, row
, col
;
1855 GLuint dst
= index
+ offset
, src
= 0;
1858 /* check that the number of rows, columns is correct */
1859 get_matrix_dims(program
->Parameters
->Parameters
[index
].DataType
, &nr
, &nc
);
1860 if (rows
!= nr
|| cols
!= nc
) {
1861 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1862 "glUniformMatrix(matrix size mismatch)");
1866 if (index
+ offset
> program
->Parameters
->Size
) {
1867 /* out of bounds! */
1872 * Note: the _columns_ of a matrix are stored in program registers, not
1873 * the rows. So, the loops below look a little funny.
1874 * XXX could optimize this a bit...
1877 /* loop over matrices */
1878 for (mat
= 0; mat
< count
; mat
++) {
1881 for (col
= 0; col
< cols
; col
++) {
1882 GLfloat
*v
= program
->Parameters
->ParameterValues
[dst
];
1883 for (row
= 0; row
< rows
; row
++) {
1885 v
[row
] = values
[src
+ row
* cols
+ col
];
1888 v
[row
] = values
[src
+ col
* rows
+ row
];
1894 src
+= rows
* cols
; /* next matrix */
1900 * Called by ctx->Driver.UniformMatrix().
1901 * Note: cols=2, rows=4 ==> array[2] of vec4
1904 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
1905 GLint location
, GLsizei count
,
1906 GLboolean transpose
, const GLfloat
*values
)
1908 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1909 struct gl_uniform
*uniform
;
1912 if (!shProg
|| !shProg
->LinkStatus
) {
1913 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1914 "glUniformMatrix(program not linked)");
1919 return; /* The standard specifies this as a no-op */
1921 if (location
< -1) {
1922 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
1926 split_location_offset(&location
, &offset
);
1928 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1929 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
1932 if (values
== NULL
) {
1933 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
1937 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1939 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1941 if (shProg
->VertexProgram
) {
1942 /* convert uniform location to program parameter index */
1943 GLint index
= uniform
->VertPos
;
1945 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
1947 count
, rows
, cols
, transpose
, values
);
1951 if (shProg
->FragmentProgram
) {
1952 /* convert uniform location to program parameter index */
1953 GLint index
= uniform
->FragPos
;
1955 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
1957 count
, rows
, cols
, transpose
, values
);
1961 uniform
->Initialized
= GL_TRUE
;
1966 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
1968 struct gl_shader_program
*shProg
;
1970 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
1975 if (!shProg
->LinkStatus
) {
1976 shProg
->Validated
= GL_FALSE
;
1980 /* From the GL spec, a program is invalid if any of these are true:
1982 any two active samplers in the current program object are of
1983 different types, but refer to the same texture image unit,
1985 any active sampler in the current program object refers to a texture
1986 image unit where fixed-function fragment processing accesses a
1987 texture target that does not match the sampler type, or
1989 the sum of the number of active samplers in the program and the
1990 number of texture image units enabled for fixed-function fragment
1991 processing exceeds the combined limit on the total number of texture
1992 image units allowed.
1995 shProg
->Validated
= GL_TRUE
;
2000 * Plug in Mesa's GLSL functions into the device driver function table.
2003 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
2005 driver
->AttachShader
= _mesa_attach_shader
;
2006 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
2007 driver
->CompileShader
= _mesa_compile_shader
;
2008 driver
->CreateProgram
= _mesa_create_program
;
2009 driver
->CreateShader
= _mesa_create_shader
;
2010 driver
->DeleteProgram2
= _mesa_delete_program2
;
2011 driver
->DeleteShader
= _mesa_delete_shader
;
2012 driver
->DetachShader
= _mesa_detach_shader
;
2013 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
2014 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
2015 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
2016 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
2017 driver
->GetHandle
= _mesa_get_handle
;
2018 driver
->GetProgramiv
= _mesa_get_programiv
;
2019 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
2020 driver
->GetShaderiv
= _mesa_get_shaderiv
;
2021 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
2022 driver
->GetShaderSource
= _mesa_get_shader_source
;
2023 driver
->GetUniformfv
= _mesa_get_uniformfv
;
2024 driver
->GetUniformiv
= _mesa_get_uniformiv
;
2025 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
2026 driver
->IsProgram
= _mesa_is_program
;
2027 driver
->IsShader
= _mesa_is_shader
;
2028 driver
->LinkProgram
= _mesa_link_program
;
2029 driver
->ShaderSource
= _mesa_shader_source
;
2030 driver
->Uniform
= _mesa_uniform
;
2031 driver
->UniformMatrix
= _mesa_uniform_matrix
;
2032 driver
->UseProgram
= _mesa_use_program
;
2033 driver
->ValidateProgram
= _mesa_validate_program
;