2 * Mesa 3-D graphics library
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Implementation of GLSL-related API functions
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/hash.h"
42 #include "shader/program.h"
43 #include "shader/prog_parameter.h"
44 #include "shader/prog_statevars.h"
45 #include "shader/prog_uniform.h"
46 #include "shader/shader_api.h"
47 #include "shader/slang/slang_compile.h"
48 #include "shader/slang/slang_link.h"
49 #include "main/dispatch.h"
53 * Allocate a new gl_shader_program object, initialize it.
55 static struct gl_shader_program
*
56 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
58 struct gl_shader_program
*shProg
;
59 shProg
= CALLOC_STRUCT(gl_shader_program
);
61 shProg
->Type
= GL_SHADER_PROGRAM_MESA
;
64 shProg
->Attributes
= _mesa_new_parameter_list();
71 * Clear (free) the shader program state that gets produced by linking.
74 _mesa_clear_shader_program_data(GLcontext
*ctx
,
75 struct gl_shader_program
*shProg
)
77 _mesa_reference_vertprog(ctx
, &shProg
->VertexProgram
, NULL
);
78 _mesa_reference_fragprog(ctx
, &shProg
->FragmentProgram
, NULL
);
80 if (shProg
->Uniforms
) {
81 _mesa_free_uniform_list(shProg
->Uniforms
);
82 shProg
->Uniforms
= NULL
;
85 if (shProg
->Varying
) {
86 _mesa_free_parameter_list(shProg
->Varying
);
87 shProg
->Varying
= NULL
;
93 * Free all the data that hangs off a shader program object, but not the
97 _mesa_free_shader_program_data(GLcontext
*ctx
,
98 struct gl_shader_program
*shProg
)
102 assert(shProg
->Type
== GL_SHADER_PROGRAM_MESA
);
104 _mesa_clear_shader_program_data(ctx
, shProg
);
106 if (shProg
->Attributes
) {
107 _mesa_free_parameter_list(shProg
->Attributes
);
108 shProg
->Attributes
= NULL
;
112 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
113 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
115 shProg
->NumShaders
= 0;
117 if (shProg
->Shaders
) {
118 free(shProg
->Shaders
);
119 shProg
->Shaders
= NULL
;
122 if (shProg
->InfoLog
) {
123 free(shProg
->InfoLog
);
124 shProg
->InfoLog
= NULL
;
127 /* Transform feedback varying vars */
128 for (i
= 0; i
< shProg
->TransformFeedback
.NumVarying
; i
++) {
129 free(shProg
->TransformFeedback
.VaryingNames
[i
]);
131 free(shProg
->TransformFeedback
.VaryingNames
);
132 shProg
->TransformFeedback
.VaryingNames
= NULL
;
133 shProg
->TransformFeedback
.NumVarying
= 0;
138 * Free/delete a shader program object.
141 _mesa_free_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
143 _mesa_free_shader_program_data(ctx
, shProg
);
150 * Set ptr to point to shProg.
151 * If ptr is pointing to another object, decrement its refcount (and delete
152 * if refcount hits zero).
153 * Then set ptr to point to shProg, incrementing its refcount.
155 /* XXX this could be static */
157 _mesa_reference_shader_program(GLcontext
*ctx
,
158 struct gl_shader_program
**ptr
,
159 struct gl_shader_program
*shProg
)
162 if (*ptr
== shProg
) {
167 /* Unreference the old shader program */
168 GLboolean deleteFlag
= GL_FALSE
;
169 struct gl_shader_program
*old
= *ptr
;
171 ASSERT(old
->RefCount
> 0);
174 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
175 (void *) old
, old
->Name
, old
->RefCount
);
177 deleteFlag
= (old
->RefCount
== 0);
180 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
181 _mesa_free_shader_program(ctx
, old
);
191 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
192 (void *) shProg
, shProg
->Name
, shProg
->RefCount
);
200 * Lookup a GLSL program object.
202 struct gl_shader_program
*
203 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
205 struct gl_shader_program
*shProg
;
207 shProg
= (struct gl_shader_program
*)
208 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
209 /* Note that both gl_shader and gl_shader_program objects are kept
210 * in the same hash table. Check the object's type to be sure it's
211 * what we're expecting.
213 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
223 * As above, but record an error if program is not found.
225 static struct gl_shader_program
*
226 _mesa_lookup_shader_program_err(GLcontext
*ctx
, GLuint name
,
230 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
234 struct gl_shader_program
*shProg
= (struct gl_shader_program
*)
235 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
237 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
240 if (shProg
->Type
!= GL_SHADER_PROGRAM_MESA
) {
241 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
252 * Allocate a new gl_shader object, initialize it.
255 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
257 struct gl_shader
*shader
;
258 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
259 shader
= CALLOC_STRUCT(gl_shader
);
263 shader
->RefCount
= 1;
270 _mesa_free_shader(GLcontext
*ctx
, struct gl_shader
*sh
)
273 free((void *) sh
->Source
);
276 _mesa_reference_program(ctx
, &sh
->Program
, NULL
);
282 * Set ptr to point to sh.
283 * If ptr is pointing to another shader, decrement its refcount (and delete
284 * if refcount hits zero).
285 * Then set ptr to point to sh, incrementing its refcount.
287 /* XXX this could be static */
289 _mesa_reference_shader(GLcontext
*ctx
, struct gl_shader
**ptr
,
290 struct gl_shader
*sh
)
298 /* Unreference the old shader */
299 GLboolean deleteFlag
= GL_FALSE
;
300 struct gl_shader
*old
= *ptr
;
302 ASSERT(old
->RefCount
> 0);
304 /*printf("SHADER DECR %p (%d) to %d\n",
305 (void*) old, old->Name, old->RefCount);*/
306 deleteFlag
= (old
->RefCount
== 0);
309 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, old
->Name
);
310 _mesa_free_shader(ctx
, old
);
320 /*printf("SHADER INCR %p (%d) to %d\n",
321 (void*) sh, sh->Name, sh->RefCount);*/
328 * Lookup a GLSL shader object.
331 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
334 struct gl_shader
*sh
= (struct gl_shader
*)
335 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
336 /* Note that both gl_shader and gl_shader_program objects are kept
337 * in the same hash table. Check the object's type to be sure it's
338 * what we're expecting.
340 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
350 * As above, but record an error if shader is not found.
352 static struct gl_shader
*
353 _mesa_lookup_shader_err(GLcontext
*ctx
, GLuint name
, const char *caller
)
356 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
360 struct gl_shader
*sh
= (struct gl_shader
*)
361 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
363 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
366 if (sh
->Type
== GL_SHADER_PROGRAM_MESA
) {
367 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
376 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
379 get_shader_flags(void)
381 GLbitfield flags
= 0x0;
382 const char *env
= _mesa_getenv("MESA_GLSL");
385 if (strstr(env
, "dump"))
387 if (strstr(env
, "log"))
389 if (strstr(env
, "nopvert"))
390 flags
|= GLSL_NOP_VERT
;
391 if (strstr(env
, "nopfrag"))
392 flags
|= GLSL_NOP_FRAG
;
393 if (strstr(env
, "nopt"))
394 flags
|= GLSL_NO_OPT
;
395 else if (strstr(env
, "opt"))
397 if (strstr(env
, "uniform"))
398 flags
|= GLSL_UNIFORMS
;
399 if (strstr(env
, "useprog"))
400 flags
|= GLSL_USE_PROG
;
408 * Find the length of the longest transform feedback varying name
409 * which was specified with glTransformFeedbackVaryings().
412 longest_feedback_varying_name(const struct gl_shader_program
*shProg
)
416 for (i
= 0; i
< shProg
->TransformFeedback
.NumVarying
; i
++) {
417 GLint len
= strlen(shProg
->TransformFeedback
.VaryingNames
[i
]);
427 * Initialize context's shader state.
430 _mesa_init_shader_state(GLcontext
* ctx
)
432 /* Device drivers may override these to control what kind of instructions
433 * are generated by the GLSL compiler.
435 ctx
->Shader
.EmitHighLevelInstructions
= GL_TRUE
;
436 ctx
->Shader
.EmitContReturn
= GL_TRUE
;
437 ctx
->Shader
.EmitCondCodes
= GL_FALSE
;
438 ctx
->Shader
.EmitComments
= GL_FALSE
;
439 ctx
->Shader
.Flags
= get_shader_flags();
441 /* Default pragma settings */
442 ctx
->Shader
.DefaultPragmas
.IgnoreOptimize
= GL_FALSE
;
443 ctx
->Shader
.DefaultPragmas
.IgnoreDebug
= GL_FALSE
;
444 ctx
->Shader
.DefaultPragmas
.Optimize
= GL_TRUE
;
445 ctx
->Shader
.DefaultPragmas
.Debug
= GL_FALSE
;
450 * Free the per-context shader-related state.
453 _mesa_free_shader_state(GLcontext
*ctx
)
455 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, NULL
);
460 * Copy string from <src> to <dst>, up to maxLength characters, returning
461 * length of <dst> in <length>.
462 * \param src the strings source
463 * \param maxLength max chars to copy
464 * \param length returns number of chars copied
465 * \param dst the string destination
468 _mesa_copy_string(GLchar
*dst
, GLsizei maxLength
,
469 GLsizei
*length
, const GLchar
*src
)
472 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
482 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
484 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
485 return shProg
? GL_TRUE
: GL_FALSE
;
490 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
492 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
493 return shader
? GL_TRUE
: GL_FALSE
;
498 * Called via ctx->Driver.AttachShader()
501 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
503 struct gl_shader_program
*shProg
;
504 struct gl_shader
*sh
;
507 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
511 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
516 n
= shProg
->NumShaders
;
517 for (i
= 0; i
< n
; i
++) {
518 if (shProg
->Shaders
[i
] == sh
) {
519 /* The shader is already attched to this program. The
520 * GL_ARB_shader_objects spec says:
522 * "The error INVALID_OPERATION is generated by AttachObjectARB
523 * if <obj> is already attached to <containerObj>."
525 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glAttachShader");
531 shProg
->Shaders
= (struct gl_shader
**)
532 _mesa_realloc(shProg
->Shaders
,
533 n
* sizeof(struct gl_shader
*),
534 (n
+ 1) * sizeof(struct gl_shader
*));
535 if (!shProg
->Shaders
) {
536 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
541 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
542 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
543 shProg
->NumShaders
++;
548 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
551 struct gl_shader_program
*shProg
552 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttribLocation");
558 if (!shProg
->LinkStatus
) {
559 _mesa_error(ctx
, GL_INVALID_OPERATION
,
560 "glGetAttribLocation(program not linked)");
567 if (shProg
->VertexProgram
) {
568 const struct gl_program_parameter_list
*attribs
=
569 shProg
->VertexProgram
->Base
.Attributes
;
571 GLint i
= _mesa_lookup_parameter_index(attribs
, -1, name
);
573 return attribs
->Parameters
[i
].StateIndexes
[0];
582 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
585 struct gl_shader_program
*shProg
;
586 const GLint size
= -1; /* unknown size */
588 GLenum datatype
= GL_FLOAT_VEC4
;
590 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
591 "glBindAttribLocation");
599 if (strncmp(name
, "gl_", 3) == 0) {
600 _mesa_error(ctx
, GL_INVALID_OPERATION
,
601 "glBindAttribLocation(illegal name)");
605 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
606 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocation(index)");
610 if (shProg
->LinkStatus
) {
611 /* get current index/location for the attribute */
612 oldIndex
= _mesa_get_attrib_location(ctx
, program
, name
);
618 /* this will replace the current value if it's already in the list */
619 i
= _mesa_add_attribute(shProg
->Attributes
, name
, size
, datatype
, index
);
621 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindAttribLocation");
626 * Note that this attribute binding won't go into effect until
627 * glLinkProgram is called again.
633 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
635 struct gl_shader
*sh
;
638 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
641 case GL_FRAGMENT_SHADER
:
642 case GL_VERTEX_SHADER
:
643 sh
= _mesa_new_shader(ctx
, name
, type
);
646 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
650 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
657 _mesa_create_program(GLcontext
*ctx
)
660 struct gl_shader_program
*shProg
;
662 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
663 shProg
= _mesa_new_shader_program(ctx
, name
);
665 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
667 assert(shProg
->RefCount
== 1);
674 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
678 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
681 * NOTE: deleting shaders/programs works a bit differently than
682 * texture objects (and buffer objects, etc). Shader/program
683 * handles/IDs exist in the hash table until the object is really
684 * deleted (refcount==0). With texture objects, the handle/ID is
685 * removed from the hash table in glDeleteTextures() while the tex
686 * object itself might linger until its refcount goes to zero.
688 struct gl_shader_program
*shProg
;
690 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
694 shProg
->DeletePending
= GL_TRUE
;
696 /* effectively, decr shProg's refcount */
697 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
702 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
704 struct gl_shader
*sh
;
706 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
710 sh
->DeletePending
= GL_TRUE
;
712 /* effectively, decr sh's refcount */
713 _mesa_reference_shader(ctx
, &sh
, NULL
);
718 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
720 struct gl_shader_program
*shProg
;
724 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
728 n
= shProg
->NumShaders
;
730 for (i
= 0; i
< n
; i
++) {
731 if (shProg
->Shaders
[i
]->Name
== shader
) {
733 struct gl_shader
**newList
;
736 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
738 /* alloc new, smaller array */
739 newList
= (struct gl_shader
**)
740 malloc((n
- 1) * sizeof(struct gl_shader
*));
742 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
745 for (j
= 0; j
< i
; j
++) {
746 newList
[j
] = shProg
->Shaders
[j
];
749 newList
[j
++] = shProg
->Shaders
[i
];
750 free(shProg
->Shaders
);
752 shProg
->Shaders
= newList
;
753 shProg
->NumShaders
= n
- 1;
758 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
759 assert(shProg
->Shaders
[j
]->Type
== GL_VERTEX_SHADER
||
760 shProg
->Shaders
[j
]->Type
== GL_FRAGMENT_SHADER
);
761 assert(shProg
->Shaders
[j
]->RefCount
> 0);
773 if (_mesa_is_shader(ctx
, shader
))
774 err
= GL_INVALID_OPERATION
;
775 else if (_mesa_is_program(ctx
, shader
))
776 err
= GL_INVALID_OPERATION
;
778 err
= GL_INVALID_VALUE
;
779 _mesa_error(ctx
, err
, "glDetachProgram(shader)");
786 * Return the size of the given GLSL datatype, in floats (components).
789 _mesa_sizeof_glsl_type(GLenum type
)
798 case GL_SAMPLER_CUBE
:
799 case GL_SAMPLER_1D_SHADOW
:
800 case GL_SAMPLER_2D_SHADOW
:
801 case GL_SAMPLER_2D_RECT_ARB
:
802 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
803 case GL_SAMPLER_1D_ARRAY_EXT
:
804 case GL_SAMPLER_2D_ARRAY_EXT
:
805 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
806 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
807 case GL_SAMPLER_CUBE_SHADOW_EXT
:
822 case GL_FLOAT_MAT2x3
:
823 case GL_FLOAT_MAT2x4
:
824 return 8; /* two float[4] vectors */
826 case GL_FLOAT_MAT3x2
:
827 case GL_FLOAT_MAT3x4
:
828 return 12; /* three float[4] vectors */
830 case GL_FLOAT_MAT4x2
:
831 case GL_FLOAT_MAT4x3
:
832 return 16; /* four float[4] vectors */
834 _mesa_problem(NULL
, "Invalid type in _mesa_sizeof_glsl_type()");
841 is_boolean_type(GLenum type
)
856 is_integer_type(GLenum type
)
871 is_sampler_type(GLenum type
)
877 case GL_SAMPLER_CUBE
:
878 case GL_SAMPLER_1D_SHADOW
:
879 case GL_SAMPLER_2D_SHADOW
:
880 case GL_SAMPLER_2D_RECT_ARB
:
881 case GL_SAMPLER_2D_RECT_SHADOW_ARB
:
882 case GL_SAMPLER_1D_ARRAY_EXT
:
883 case GL_SAMPLER_2D_ARRAY_EXT
:
884 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT
:
885 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT
:
894 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
895 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
896 GLenum
*type
, GLchar
*nameOut
)
898 const struct gl_program_parameter_list
*attribs
= NULL
;
899 struct gl_shader_program
*shProg
;
901 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveAttrib");
905 if (shProg
->VertexProgram
)
906 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
908 if (!attribs
|| index
>= attribs
->NumParameters
) {
909 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveAttrib(index)");
913 _mesa_copy_string(nameOut
, maxLength
, length
,
914 attribs
->Parameters
[index
].Name
);
917 *size
= attribs
->Parameters
[index
].Size
918 / _mesa_sizeof_glsl_type(attribs
->Parameters
[index
].DataType
);
921 *type
= attribs
->Parameters
[index
].DataType
;
925 static struct gl_program_parameter
*
926 get_uniform_parameter(const struct gl_shader_program
*shProg
, GLuint index
)
928 const struct gl_program
*prog
= NULL
;
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 NULL
; /* should never happen */
945 return &prog
->Parameters
->Parameters
[progPos
];
950 * Called via ctx->Driver.GetActiveUniform().
953 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
954 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
955 GLenum
*type
, GLchar
*nameOut
)
957 const struct gl_shader_program
*shProg
;
958 const struct gl_program
*prog
= NULL
;
959 const struct gl_program_parameter
*param
;
962 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniform");
966 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumUniforms
) {
967 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
971 progPos
= shProg
->Uniforms
->Uniforms
[index
].VertPos
;
973 prog
= &shProg
->VertexProgram
->Base
;
976 progPos
= shProg
->Uniforms
->Uniforms
[index
].FragPos
;
978 prog
= &shProg
->FragmentProgram
->Base
;
982 if (!prog
|| progPos
< 0)
983 return; /* should never happen */
985 ASSERT(progPos
< prog
->Parameters
->NumParameters
);
986 param
= &prog
->Parameters
->Parameters
[progPos
];
989 _mesa_copy_string(nameOut
, maxLength
, length
, param
->Name
);
993 GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
994 if ((GLint
) param
->Size
> typeSize
) {
996 * Array elements are placed on vector[4] boundaries so they're
997 * a multiple of four floats. We round typeSize up to next multiple
998 * of four to get the right size below.
1000 typeSize
= (typeSize
+ 3) & ~3;
1002 /* Note that the returned size is in units of the <type>, not bytes */
1003 *size
= param
->Size
/ typeSize
;
1007 *type
= param
->DataType
;
1013 * Called via ctx->Driver.GetAttachedShaders().
1016 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
1017 GLsizei
*count
, GLuint
*obj
)
1019 struct gl_shader_program
*shProg
=
1020 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
1023 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
1024 obj
[i
] = shProg
->Shaders
[i
]->Name
;
1033 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
1037 if (pname
== GL_PROGRAM_OBJECT_ARB
) {
1038 CALL_GetIntegerv(ctx
->Exec
, (GL_CURRENT_PROGRAM
, &handle
));
1040 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
1048 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
1049 GLenum pname
, GLint
*params
)
1051 const struct gl_program_parameter_list
*attribs
;
1052 struct gl_shader_program
*shProg
1053 = _mesa_lookup_shader_program(ctx
, program
);
1056 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
1060 if (shProg
->VertexProgram
)
1061 attribs
= shProg
->VertexProgram
->Base
.Attributes
;
1066 case GL_DELETE_STATUS
:
1067 *params
= shProg
->DeletePending
;
1069 case GL_LINK_STATUS
:
1070 *params
= shProg
->LinkStatus
;
1072 case GL_VALIDATE_STATUS
:
1073 *params
= shProg
->Validated
;
1075 case GL_INFO_LOG_LENGTH
:
1076 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) + 1 : 0;
1078 case GL_ATTACHED_SHADERS
:
1079 *params
= shProg
->NumShaders
;
1081 case GL_ACTIVE_ATTRIBUTES
:
1082 *params
= attribs
? attribs
->NumParameters
: 0;
1084 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
1085 *params
= _mesa_longest_parameter_name(attribs
, PROGRAM_INPUT
) + 1;
1087 case GL_ACTIVE_UNIFORMS
:
1088 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumUniforms
: 0;
1090 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
1091 *params
= _mesa_longest_uniform_name(shProg
->Uniforms
);
1093 (*params
)++; /* add one for terminating zero */
1095 case GL_PROGRAM_BINARY_LENGTH_OES
:
1098 #if FEATURE_EXT_transform_feedback
1099 case GL_TRANSFORM_FEEDBACK_VARYINGS
:
1100 *params
= shProg
->TransformFeedback
.NumVarying
;
1102 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
:
1103 *params
= longest_feedback_varying_name(shProg
) + 1;
1105 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE
:
1106 *params
= shProg
->TransformFeedback
.BufferMode
;
1110 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
1117 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
1119 struct gl_shader
*shader
= _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
1126 case GL_SHADER_TYPE
:
1127 *params
= shader
->Type
;
1129 case GL_DELETE_STATUS
:
1130 *params
= shader
->DeletePending
;
1132 case GL_COMPILE_STATUS
:
1133 *params
= shader
->CompileStatus
;
1135 case GL_INFO_LOG_LENGTH
:
1136 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) + 1 : 0;
1138 case GL_SHADER_SOURCE_LENGTH
:
1139 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
1142 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
1149 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
1150 GLsizei
*length
, GLchar
*infoLog
)
1152 struct gl_shader_program
*shProg
1153 = _mesa_lookup_shader_program(ctx
, program
);
1155 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
1158 _mesa_copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
1163 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
1164 GLsizei
*length
, GLchar
*infoLog
)
1166 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
1168 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
1171 _mesa_copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
1176 * Called via ctx->Driver.GetShaderSource().
1179 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
1180 GLsizei
*length
, GLchar
*sourceOut
)
1182 struct gl_shader
*sh
;
1183 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
1187 _mesa_copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
1192 get_matrix_dims(GLenum type
, GLint
*rows
, GLint
*cols
)
1198 case GL_FLOAT_MAT2x3
:
1202 case GL_FLOAT_MAT2x4
:
1210 case GL_FLOAT_MAT3x2
:
1214 case GL_FLOAT_MAT3x4
:
1222 case GL_FLOAT_MAT4x2
:
1226 case GL_FLOAT_MAT4x3
:
1237 * Determine the number of rows and columns occupied by a uniform
1238 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1239 * the number of rows = 1 and cols = number of elements in the vector.
1242 get_uniform_rows_cols(const struct gl_program_parameter
*p
,
1243 GLint
*rows
, GLint
*cols
)
1245 get_matrix_dims(p
->DataType
, rows
, cols
);
1246 if (*rows
== 0 && *cols
== 0) {
1247 /* not a matrix type, probably a float or vector */
1253 *rows
= p
->Size
/ 4 + 1;
1254 if (p
->Size
% 4 == 0)
1257 *cols
= p
->Size
% 4;
1264 * Helper for get_uniform[fi]v() functions.
1265 * Given a shader program name and uniform location, return a pointer
1266 * to the shader program and return the program parameter position.
1269 lookup_uniform_parameter(GLcontext
*ctx
, GLuint program
, GLint location
,
1270 struct gl_program
**progOut
, GLint
*paramPosOut
)
1272 struct gl_shader_program
*shProg
1273 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniform[if]v");
1274 struct gl_program
*prog
= NULL
;
1277 /* if shProg is NULL, we'll have already recorded an error */
1280 if (!shProg
->Uniforms
||
1282 location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1283 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(location)");
1286 /* OK, find the gl_program and program parameter location */
1287 progPos
= shProg
->Uniforms
->Uniforms
[location
].VertPos
;
1289 prog
= &shProg
->VertexProgram
->Base
;
1292 progPos
= shProg
->Uniforms
->Uniforms
[location
].FragPos
;
1294 prog
= &shProg
->FragmentProgram
->Base
;
1301 *paramPosOut
= progPos
;
1306 * Called via ctx->Driver.GetUniformfv().
1309 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
1312 struct gl_program
*prog
;
1315 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1318 const struct gl_program_parameter
*p
=
1319 &prog
->Parameters
->Parameters
[paramPos
];
1320 GLint rows
, cols
, i
, j
, k
;
1322 get_uniform_rows_cols(p
, &rows
, &cols
);
1325 for (i
= 0; i
< rows
; i
++) {
1326 for (j
= 0; j
< cols
; j
++ ) {
1327 params
[k
++] = prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1335 * Called via ctx->Driver.GetUniformiv().
1336 * \sa _mesa_get_uniformfv, only difference is a cast.
1339 _mesa_get_uniformiv(GLcontext
*ctx
, GLuint program
, GLint location
,
1342 struct gl_program
*prog
;
1345 lookup_uniform_parameter(ctx
, program
, location
, &prog
, ¶mPos
);
1348 const struct gl_program_parameter
*p
=
1349 &prog
->Parameters
->Parameters
[paramPos
];
1350 GLint rows
, cols
, i
, j
, k
;
1352 get_uniform_rows_cols(p
, &rows
, &cols
);
1355 for (i
= 0; i
< rows
; i
++) {
1356 for (j
= 0; j
< cols
; j
++ ) {
1357 params
[k
++] = (GLint
) prog
->Parameters
->ParameterValues
[paramPos
+i
][j
];
1365 * The value returned by GetUniformLocation actually encodes two things:
1366 * 1. the index into the prog->Uniforms[] array for the uniform
1367 * 2. an offset in the prog->ParameterValues[] array for specifying array
1368 * elements or structure fields.
1369 * This function merges those two values.
1372 merge_location_offset(GLint
*location
, GLint offset
)
1374 *location
= *location
| (offset
<< 16);
1379 * Seperate the uniform location and parameter offset. See above.
1382 split_location_offset(GLint
*location
, GLint
*offset
)
1384 *offset
= (*location
>> 16);
1385 *location
= *location
& 0xffff;
1390 * Called via ctx->Driver.GetUniformLocation().
1392 * The return value will encode two values, the uniform location and an
1393 * offset (used for arrays, structs).
1396 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
1398 GLint offset
= 0, location
= -1;
1400 struct gl_shader_program
*shProg
=
1401 _mesa_lookup_shader_program_err(ctx
, program
, "glGetUniformLocation");
1406 if (shProg
->LinkStatus
== GL_FALSE
) {
1407 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
1411 /* XXX we should return -1 if the uniform was declared, but not
1415 /* XXX we need to be able to parse uniform names for structs and arrays
1422 /* handle 1-dimension arrays here... */
1423 char *c
= strchr(name
, '[');
1425 /* truncate name at [ */
1426 const GLint len
= c
- name
;
1427 GLchar
*newName
= malloc(len
+ 1);
1429 return -1; /* out of mem */
1430 memcpy(newName
, name
, len
);
1433 location
= _mesa_lookup_uniform(shProg
->Uniforms
, newName
);
1434 if (location
>= 0) {
1435 const GLint element
= atoi(c
+ 1);
1437 /* get type of the uniform array element */
1438 struct gl_program_parameter
*p
;
1439 p
= get_uniform_parameter(shProg
, location
);
1442 get_matrix_dims(p
->DataType
, &rows
, &cols
);
1445 offset
= element
* rows
;
1455 location
= _mesa_lookup_uniform(shProg
->Uniforms
, name
);
1458 if (location
>= 0) {
1459 merge_location_offset(&location
, offset
);
1468 * Called via ctx->Driver.ShaderSource()
1471 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
1473 struct gl_shader
*sh
;
1475 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glShaderSource");
1479 /* free old shader source string and install new one */
1481 free((void *) sh
->Source
);
1483 sh
->Source
= source
;
1484 sh
->CompileStatus
= GL_FALSE
;
1486 sh
->SourceChecksum
= _mesa_str_checksum(sh
->Source
);
1492 * Called via ctx->Driver.CompileShader()
1495 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
1497 struct gl_shader
*sh
;
1499 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glCompileShader");
1503 /* set default pragma state for shader */
1504 sh
->Pragmas
= ctx
->Shader
.DefaultPragmas
;
1506 /* this call will set the sh->CompileStatus field to indicate if
1507 * compilation was successful.
1509 (void) _slang_compile(ctx
, sh
);
1514 * Called via ctx->Driver.LinkProgram()
1517 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
1519 struct gl_shader_program
*shProg
;
1520 struct gl_transform_feedback_object
*obj
=
1521 ctx
->TransformFeedback
.CurrentObject
;
1523 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glLinkProgram");
1527 if (obj
->Active
&& shProg
== ctx
->Shader
.CurrentProgram
) {
1528 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1529 "glLinkProgram(transform feedback active");
1533 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
1535 _slang_link(ctx
, program
, shProg
);
1541 printf("Link %u shaders in program %u: %s\n",
1542 shProg
->NumShaders
, shProg
->Name
,
1543 shProg
->LinkStatus
? "Success" : "Failed");
1545 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1546 printf(" shader %u, type 0x%x\n",
1547 shProg
->Shaders
[i
]->Name
,
1548 shProg
->Shaders
[i
]->Type
);
1555 * Print basic shader info (for debug).
1558 print_shader_info(const struct gl_shader_program
*shProg
)
1562 printf("Mesa: glUseProgram(%u)\n", shProg
->Name
);
1563 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1565 switch (shProg
->Shaders
[i
]->Type
) {
1566 case GL_VERTEX_SHADER
:
1569 case GL_FRAGMENT_SHADER
:
1572 case GL_GEOMETRY_SHADER
:
1578 printf(" %s shader %u, checksum %u\n", s
,
1579 shProg
->Shaders
[i
]->Name
,
1580 shProg
->Shaders
[i
]->SourceChecksum
);
1582 if (shProg
->VertexProgram
)
1583 printf(" vert prog %u\n", shProg
->VertexProgram
->Base
.Id
);
1584 if (shProg
->FragmentProgram
)
1585 printf(" frag prog %u\n", shProg
->FragmentProgram
->Base
.Id
);
1590 * Called via ctx->Driver.UseProgram()
1593 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
1595 struct gl_shader_program
*shProg
;
1596 struct gl_transform_feedback_object
*obj
=
1597 ctx
->TransformFeedback
.CurrentObject
;
1600 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1601 "glUseProgram(transform feedback active)");
1605 if (ctx
->Shader
.CurrentProgram
&&
1606 ctx
->Shader
.CurrentProgram
->Name
== program
) {
1612 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1616 if (!shProg
->LinkStatus
) {
1617 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1618 "glUseProgram(program %u not linked)", program
);
1623 if (ctx
->Shader
.Flags
& GLSL_USE_PROG
) {
1624 print_shader_info(shProg
);
1631 if (ctx
->Shader
.CurrentProgram
!= shProg
) {
1632 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
1633 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.CurrentProgram
, shProg
);
1640 * Update the vertex/fragment program's TexturesUsed array.
1642 * This needs to be called after glUniform(set sampler var) is called.
1643 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1644 * particular texture unit. We know the sampler's texture target
1645 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1646 * set by glUniform() calls.
1648 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1649 * information to update the prog->TexturesUsed[] values.
1650 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1651 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1652 * We'll use that info for state validation before rendering.
1655 _mesa_update_shader_textures_used(struct gl_program
*prog
)
1659 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
1661 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
1662 if (prog
->SamplersUsed
& (1 << s
)) {
1663 GLuint unit
= prog
->SamplerUnits
[s
];
1664 GLuint tgt
= prog
->SamplerTargets
[s
];
1665 assert(unit
< MAX_TEXTURE_IMAGE_UNITS
);
1666 assert(tgt
< NUM_TEXTURE_TARGETS
);
1667 prog
->TexturesUsed
[unit
] |= (1 << tgt
);
1674 * Check if the type given by userType is allowed to set a uniform of the
1675 * target type. Generally, equivalence is required, but setting Boolean
1676 * uniforms can be done with glUniformiv or glUniformfv.
1679 compatible_types(GLenum userType
, GLenum targetType
)
1681 if (userType
== targetType
)
1684 if (targetType
== GL_BOOL
&& (userType
== GL_FLOAT
|| userType
== GL_INT
))
1687 if (targetType
== GL_BOOL_VEC2
&& (userType
== GL_FLOAT_VEC2
||
1688 userType
== GL_INT_VEC2
))
1691 if (targetType
== GL_BOOL_VEC3
&& (userType
== GL_FLOAT_VEC3
||
1692 userType
== GL_INT_VEC3
))
1695 if (targetType
== GL_BOOL_VEC4
&& (userType
== GL_FLOAT_VEC4
||
1696 userType
== GL_INT_VEC4
))
1699 if (is_sampler_type(targetType
) && userType
== GL_INT
)
1707 * Set the value of a program's uniform variable.
1708 * \param program the program whose uniform to update
1709 * \param index the index of the program parameter for the uniform
1710 * \param offset additional parameter slot offset (for arrays)
1711 * \param type the incoming datatype of 'values'
1712 * \param count the number of uniforms to set
1713 * \param elems number of elements per uniform (1, 2, 3 or 4)
1714 * \param values the new values, of datatype 'type'
1717 set_program_uniform(GLcontext
*ctx
, struct gl_program
*program
,
1718 GLint index
, GLint offset
,
1719 GLenum type
, GLsizei count
, GLint elems
,
1722 const struct gl_program_parameter
*param
=
1723 &program
->Parameters
->Parameters
[index
];
1725 assert(offset
>= 0);
1729 if (!compatible_types(type
, param
->DataType
)) {
1730 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(type mismatch)");
1734 if (index
+ offset
> (GLint
) program
->Parameters
->Size
) {
1735 /* out of bounds! */
1739 if (param
->Type
== PROGRAM_SAMPLER
) {
1740 /* This controls which texture unit which is used by a sampler */
1741 GLboolean changed
= GL_FALSE
;
1744 /* this should have been caught by the compatible_types() check */
1745 ASSERT(type
== GL_INT
);
1747 /* loop over number of samplers to change */
1748 for (i
= 0; i
< count
; i
++) {
1750 (GLuint
) program
->Parameters
->ParameterValues
[index
+ offset
+ i
][0];
1751 GLuint texUnit
= ((GLuint
*) values
)[i
];
1753 /* check that the sampler (tex unit index) is legal */
1754 if (texUnit
>= ctx
->Const
.MaxTextureImageUnits
) {
1755 _mesa_error(ctx
, GL_INVALID_VALUE
,
1756 "glUniform1(invalid sampler/tex unit index)");
1760 /* This maps a sampler to a texture unit: */
1761 if (sampler
< MAX_SAMPLERS
) {
1763 printf("Set program %p sampler %d '%s' to unit %u\n",
1764 program
, sampler
, param
->Name
, texUnit
);
1766 if (program
->SamplerUnits
[sampler
] != texUnit
) {
1767 program
->SamplerUnits
[sampler
] = texUnit
;
1774 /* When a sampler's value changes it usually requires rewriting
1775 * a GPU program's TEX instructions since there may not be a
1776 * sampler->texture lookup table. We signal this with the
1777 * ProgramStringNotify() callback.
1779 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
| _NEW_PROGRAM
);
1780 _mesa_update_shader_textures_used(program
);
1781 /* Do we need to care about the return value here?
1782 * This should not be the first time the driver was notified of
1785 (void) ctx
->Driver
.ProgramStringNotify(ctx
, program
->Target
, program
);
1789 /* ordinary uniform variable */
1790 const GLboolean isUniformBool
= is_boolean_type(param
->DataType
);
1791 const GLboolean areIntValues
= is_integer_type(type
);
1792 const GLint slots
= (param
->Size
+ 3) / 4;
1793 const GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
1796 if ((GLint
) param
->Size
> typeSize
) {
1798 /* we'll ignore extra data below */
1801 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1803 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1804 "glUniform(uniform is not an array)");
1809 /* loop over number of array elements */
1810 for (k
= 0; k
< count
; k
++) {
1811 GLfloat
*uniformVal
;
1813 if (offset
+ k
>= slots
) {
1814 /* Extra array data is ignored */
1818 /* uniformVal (the destination) is always float[4] */
1819 uniformVal
= program
->Parameters
->ParameterValues
[index
+ offset
+ k
];
1822 /* convert user's ints to floats */
1823 const GLint
*iValues
= ((const GLint
*) values
) + k
* elems
;
1824 for (i
= 0; i
< elems
; i
++) {
1825 uniformVal
[i
] = (GLfloat
) iValues
[i
];
1829 const GLfloat
*fValues
= ((const GLfloat
*) values
) + k
* elems
;
1830 for (i
= 0; i
< elems
; i
++) {
1831 uniformVal
[i
] = fValues
[i
];
1835 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1836 if (isUniformBool
) {
1837 for (i
= 0; i
< elems
; i
++) {
1838 uniformVal
[i
] = uniformVal
[i
] ? 1.0f
: 0.0f
;
1847 * Called via ctx->Driver.Uniform().
1850 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
1851 const GLvoid
*values
, GLenum type
)
1853 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
1854 struct gl_uniform
*uniform
;
1855 GLint elems
, offset
;
1858 if (!shProg
|| !shProg
->LinkStatus
) {
1859 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
1864 return; /* The standard specifies this as a no-op */
1866 if (location
< -1) {
1867 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(location)");
1871 split_location_offset(&location
, &offset
);
1873 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
1874 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(location)");
1879 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniform(count < 0)");
1885 basicType
= GL_FLOAT
;
1893 basicType
= GL_FLOAT
;
1901 basicType
= GL_FLOAT
;
1909 basicType
= GL_FLOAT
;
1917 _mesa_problem(ctx
, "Invalid type in _mesa_uniform");
1921 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
1923 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
1925 if (ctx
->Shader
.Flags
& GLSL_UNIFORMS
) {
1927 printf("Mesa: set program %u uniform %s (loc %d) to: ",
1928 shProg
->Name
, uniform
->Name
, location
);
1929 if (basicType
== GL_INT
) {
1930 const GLint
*v
= (const GLint
*) values
;
1931 for (i
= 0; i
< count
* elems
; i
++) {
1932 printf("%d ", v
[i
]);
1936 const GLfloat
*v
= (const GLfloat
*) values
;
1937 for (i
= 0; i
< count
* elems
; i
++) {
1938 printf("%g ", v
[i
]);
1944 /* A uniform var may be used by both a vertex shader and a fragment
1945 * shader. We may need to update one or both shader's uniform here:
1947 if (shProg
->VertexProgram
) {
1948 /* convert uniform location to program parameter index */
1949 GLint index
= uniform
->VertPos
;
1951 set_program_uniform(ctx
, &shProg
->VertexProgram
->Base
,
1952 index
, offset
, type
, count
, elems
, values
);
1956 if (shProg
->FragmentProgram
) {
1957 /* convert uniform location to program parameter index */
1958 GLint index
= uniform
->FragPos
;
1960 set_program_uniform(ctx
, &shProg
->FragmentProgram
->Base
,
1961 index
, offset
, type
, count
, elems
, values
);
1965 uniform
->Initialized
= GL_TRUE
;
1970 * Set a matrix-valued program parameter.
1973 set_program_uniform_matrix(GLcontext
*ctx
, struct gl_program
*program
,
1974 GLuint index
, GLuint offset
,
1975 GLuint count
, GLuint rows
, GLuint cols
,
1976 GLboolean transpose
, const GLfloat
*values
)
1978 GLuint mat
, row
, col
;
1980 const struct gl_program_parameter
* param
= &program
->Parameters
->Parameters
[index
];
1981 const GLuint slots
= (param
->Size
+ 3) / 4;
1982 const GLint typeSize
= _mesa_sizeof_glsl_type(param
->DataType
);
1985 /* check that the number of rows, columns is correct */
1986 get_matrix_dims(param
->DataType
, &nr
, &nc
);
1987 if (rows
!= nr
|| cols
!= nc
) {
1988 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1989 "glUniformMatrix(matrix size mismatch)");
1993 if ((GLint
) param
->Size
<= typeSize
) {
1994 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1996 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1997 "glUniformMatrix(uniform is not an array)");
2003 * Note: the _columns_ of a matrix are stored in program registers, not
2004 * the rows. So, the loops below look a little funny.
2005 * XXX could optimize this a bit...
2008 /* loop over matrices */
2009 for (mat
= 0; mat
< count
; mat
++) {
2012 for (col
= 0; col
< cols
; col
++) {
2014 if (offset
>= slots
) {
2015 /* Ignore writes beyond the end of (the used part of) an array */
2018 v
= program
->Parameters
->ParameterValues
[index
+ offset
];
2019 for (row
= 0; row
< rows
; row
++) {
2021 v
[row
] = values
[src
+ row
* cols
+ col
];
2024 v
[row
] = values
[src
+ col
* rows
+ row
];
2031 src
+= rows
* cols
; /* next matrix */
2037 * Called by ctx->Driver.UniformMatrix().
2038 * Note: cols=2, rows=4 ==> array[2] of vec4
2041 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
2042 GLint location
, GLsizei count
,
2043 GLboolean transpose
, const GLfloat
*values
)
2045 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
2046 struct gl_uniform
*uniform
;
2049 if (!shProg
|| !shProg
->LinkStatus
) {
2050 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2051 "glUniformMatrix(program not linked)");
2056 return; /* The standard specifies this as a no-op */
2058 if (location
< -1) {
2059 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformMatrix(location)");
2063 split_location_offset(&location
, &offset
);
2065 if (location
< 0 || location
>= (GLint
) shProg
->Uniforms
->NumUniforms
) {
2066 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix(location)");
2069 if (values
== NULL
) {
2070 _mesa_error(ctx
, GL_INVALID_VALUE
, "glUniformMatrix");
2074 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
2076 uniform
= &shProg
->Uniforms
->Uniforms
[location
];
2078 if (shProg
->VertexProgram
) {
2079 /* convert uniform location to program parameter index */
2080 GLint index
= uniform
->VertPos
;
2082 set_program_uniform_matrix(ctx
, &shProg
->VertexProgram
->Base
,
2084 count
, rows
, cols
, transpose
, values
);
2088 if (shProg
->FragmentProgram
) {
2089 /* convert uniform location to program parameter index */
2090 GLint index
= uniform
->FragPos
;
2092 set_program_uniform_matrix(ctx
, &shProg
->FragmentProgram
->Base
,
2094 count
, rows
, cols
, transpose
, values
);
2098 uniform
->Initialized
= GL_TRUE
;
2103 * Validate a program's samplers.
2104 * Specifically, check that there aren't two samplers of different types
2105 * pointing to the same texture unit.
2106 * \return GL_TRUE if valid, GL_FALSE if invalid
2109 validate_samplers(GLcontext
*ctx
, const struct gl_program
*prog
, char *errMsg
)
2111 static const char *targetName
[] = {
2120 GLint targetUsed
[MAX_TEXTURE_IMAGE_UNITS
];
2121 GLbitfield samplersUsed
= prog
->SamplersUsed
;
2124 assert(Elements(targetName
) == NUM_TEXTURE_TARGETS
);
2126 if (samplersUsed
== 0x0)
2129 for (i
= 0; i
< Elements(targetUsed
); i
++)
2132 /* walk over bits which are set in 'samplers' */
2133 while (samplersUsed
) {
2135 gl_texture_index target
;
2136 GLint sampler
= _mesa_ffs(samplersUsed
) - 1;
2137 assert(sampler
>= 0);
2138 assert(sampler
< MAX_TEXTURE_IMAGE_UNITS
);
2139 unit
= prog
->SamplerUnits
[sampler
];
2140 target
= prog
->SamplerTargets
[sampler
];
2141 if (targetUsed
[unit
] != -1 && targetUsed
[unit
] != target
) {
2142 _mesa_snprintf(errMsg
, 100,
2143 "Texture unit %d is accessed both as %s and %s",
2144 unit
, targetName
[targetUsed
[unit
]], targetName
[target
]);
2147 targetUsed
[unit
] = target
;
2148 samplersUsed
^= (1 << sampler
);
2156 * Do validation of the given shader program.
2157 * \param errMsg returns error message if validation fails.
2158 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2161 _mesa_validate_shader_program(GLcontext
*ctx
,
2162 const struct gl_shader_program
*shProg
,
2165 const struct gl_vertex_program
*vp
= shProg
->VertexProgram
;
2166 const struct gl_fragment_program
*fp
= shProg
->FragmentProgram
;
2168 if (!shProg
->LinkStatus
) {
2172 /* From the GL spec, a program is invalid if any of these are true:
2174 any two active samplers in the current program object are of
2175 different types, but refer to the same texture image unit,
2177 any active sampler in the current program object refers to a texture
2178 image unit where fixed-function fragment processing accesses a
2179 texture target that does not match the sampler type, or
2181 the sum of the number of active samplers in the program and the
2182 number of texture image units enabled for fixed-function fragment
2183 processing exceeds the combined limit on the total number of texture
2184 image units allowed.
2189 * Check: any two active samplers in the current program object are of
2190 * different types, but refer to the same texture image unit,
2192 if (vp
&& !validate_samplers(ctx
, &vp
->Base
, errMsg
)) {
2195 if (fp
&& !validate_samplers(ctx
, &fp
->Base
, errMsg
)) {
2204 * Called via glValidateProgram()
2207 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
2209 struct gl_shader_program
*shProg
;
2212 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
2217 shProg
->Validated
= _mesa_validate_shader_program(ctx
, shProg
, errMsg
);
2218 if (!shProg
->Validated
) {
2219 /* update info log */
2220 if (shProg
->InfoLog
) {
2221 free(shProg
->InfoLog
);
2223 shProg
->InfoLog
= _mesa_strdup(errMsg
);
2229 * Plug in Mesa's GLSL functions into the device driver function table.
2232 _mesa_init_glsl_driver_functions(struct dd_function_table
*driver
)
2234 driver
->AttachShader
= _mesa_attach_shader
;
2235 driver
->BindAttribLocation
= _mesa_bind_attrib_location
;
2236 driver
->CompileShader
= _mesa_compile_shader
;
2237 driver
->CreateProgram
= _mesa_create_program
;
2238 driver
->CreateShader
= _mesa_create_shader
;
2239 driver
->DeleteProgram2
= _mesa_delete_program2
;
2240 driver
->DeleteShader
= _mesa_delete_shader
;
2241 driver
->DetachShader
= _mesa_detach_shader
;
2242 driver
->GetActiveAttrib
= _mesa_get_active_attrib
;
2243 driver
->GetActiveUniform
= _mesa_get_active_uniform
;
2244 driver
->GetAttachedShaders
= _mesa_get_attached_shaders
;
2245 driver
->GetAttribLocation
= _mesa_get_attrib_location
;
2246 driver
->GetHandle
= _mesa_get_handle
;
2247 driver
->GetProgramiv
= _mesa_get_programiv
;
2248 driver
->GetProgramInfoLog
= _mesa_get_program_info_log
;
2249 driver
->GetShaderiv
= _mesa_get_shaderiv
;
2250 driver
->GetShaderInfoLog
= _mesa_get_shader_info_log
;
2251 driver
->GetShaderSource
= _mesa_get_shader_source
;
2252 driver
->GetUniformfv
= _mesa_get_uniformfv
;
2253 driver
->GetUniformiv
= _mesa_get_uniformiv
;
2254 driver
->GetUniformLocation
= _mesa_get_uniform_location
;
2255 driver
->IsProgram
= _mesa_is_program
;
2256 driver
->IsShader
= _mesa_is_shader
;
2257 driver
->LinkProgram
= _mesa_link_program
;
2258 driver
->ShaderSource
= _mesa_shader_source
;
2259 driver
->Uniform
= _mesa_uniform
;
2260 driver
->UniformMatrix
= _mesa_uniform_matrix
;
2261 driver
->UseProgram
= _mesa_use_program
;
2262 driver
->ValidateProgram
= _mesa_validate_program
;