mesa: move #define for GL_PROGRAM_BINARY_LENGTH_OES
[mesa.git] / src / mesa / shader / shader_api.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
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.
24 */
25
26 /**
27 * \file shader_api.c
28 * Implementation of GLSL-related API functions
29 * \author Brian Paul
30 */
31
32 /**
33 * XXX things to do:
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
36 */
37
38
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"
52
53
54 /**
55 * Allocate a new gl_shader_program object, initialize it.
56 */
57 static struct gl_shader_program *
58 _mesa_new_shader_program(GLcontext *ctx, GLuint name)
59 {
60 struct gl_shader_program *shProg;
61 shProg = CALLOC_STRUCT(gl_shader_program);
62 if (shProg) {
63 shProg->Type = GL_SHADER_PROGRAM_MESA;
64 shProg->Name = name;
65 shProg->RefCount = 1;
66 shProg->Attributes = _mesa_new_parameter_list();
67 }
68 return shProg;
69 }
70
71
72 /**
73 * Clear (free) the shader program state that gets produced by linking.
74 */
75 void
76 _mesa_clear_shader_program_data(GLcontext *ctx,
77 struct gl_shader_program *shProg)
78 {
79 _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
80 _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
81
82 if (shProg->Uniforms) {
83 _mesa_free_uniform_list(shProg->Uniforms);
84 shProg->Uniforms = NULL;
85 }
86
87 if (shProg->Varying) {
88 _mesa_free_parameter_list(shProg->Varying);
89 shProg->Varying = NULL;
90 }
91 }
92
93
94 /**
95 * Free all the data that hangs off a shader program object, but not the
96 * object itself.
97 */
98 void
99 _mesa_free_shader_program_data(GLcontext *ctx,
100 struct gl_shader_program *shProg)
101 {
102 GLuint i;
103
104 assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
105
106 _mesa_clear_shader_program_data(ctx, shProg);
107
108 if (shProg->Attributes) {
109 _mesa_free_parameter_list(shProg->Attributes);
110 shProg->Attributes = NULL;
111 }
112
113 /* detach shaders */
114 for (i = 0; i < shProg->NumShaders; i++) {
115 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
116 }
117 shProg->NumShaders = 0;
118
119 if (shProg->Shaders) {
120 _mesa_free(shProg->Shaders);
121 shProg->Shaders = NULL;
122 }
123
124 if (shProg->InfoLog) {
125 _mesa_free(shProg->InfoLog);
126 shProg->InfoLog = NULL;
127 }
128 }
129
130
131 /**
132 * Free/delete a shader program object.
133 */
134 void
135 _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
136 {
137 _mesa_free_shader_program_data(ctx, shProg);
138
139 _mesa_free(shProg);
140 }
141
142
143 /**
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.
148 */
149 /* XXX this could be static */
150 void
151 _mesa_reference_shader_program(GLcontext *ctx,
152 struct gl_shader_program **ptr,
153 struct gl_shader_program *shProg)
154 {
155 assert(ptr);
156 if (*ptr == shProg) {
157 /* no-op */
158 return;
159 }
160 if (*ptr) {
161 /* Unreference the old shader program */
162 GLboolean deleteFlag = GL_FALSE;
163 struct gl_shader_program *old = *ptr;
164
165 ASSERT(old->RefCount > 0);
166 old->RefCount--;
167 #if 0
168 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
169 (void *) old, old->Name, old->RefCount);
170 #endif
171 deleteFlag = (old->RefCount == 0);
172
173 if (deleteFlag) {
174 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
175 _mesa_free_shader_program(ctx, old);
176 }
177
178 *ptr = NULL;
179 }
180 assert(!*ptr);
181
182 if (shProg) {
183 shProg->RefCount++;
184 #if 0
185 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
186 (void *) shProg, shProg->Name, shProg->RefCount);
187 #endif
188 *ptr = shProg;
189 }
190 }
191
192
193 /**
194 * Lookup a GLSL program object.
195 */
196 struct gl_shader_program *
197 _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
198 {
199 struct gl_shader_program *shProg;
200 if (name) {
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.
206 */
207 if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
208 return NULL;
209 }
210 return shProg;
211 }
212 return NULL;
213 }
214
215
216 /**
217 * As above, but record an error if program is not found.
218 */
219 static struct gl_shader_program *
220 _mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
221 const char *caller)
222 {
223 if (!name) {
224 _mesa_error(ctx, GL_INVALID_VALUE, caller);
225 return NULL;
226 }
227 else {
228 struct gl_shader_program *shProg = (struct gl_shader_program *)
229 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
230 if (!shProg) {
231 _mesa_error(ctx, GL_INVALID_VALUE, caller);
232 return NULL;
233 }
234 if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
235 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
236 return NULL;
237 }
238 return shProg;
239 }
240 }
241
242
243
244
245 /**
246 * Allocate a new gl_shader object, initialize it.
247 */
248 struct gl_shader *
249 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
250 {
251 struct gl_shader *shader;
252 assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
253 shader = CALLOC_STRUCT(gl_shader);
254 if (shader) {
255 shader->Type = type;
256 shader->Name = name;
257 shader->RefCount = 1;
258 }
259 return shader;
260 }
261
262
263 void
264 _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
265 {
266 if (sh->Source)
267 _mesa_free((void *) sh->Source);
268 if (sh->InfoLog)
269 _mesa_free(sh->InfoLog);
270 _mesa_reference_program(ctx, &sh->Program, NULL);
271 _mesa_free(sh);
272 }
273
274
275 /**
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.
280 */
281 /* XXX this could be static */
282 void
283 _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
284 struct gl_shader *sh)
285 {
286 assert(ptr);
287 if (*ptr == sh) {
288 /* no-op */
289 return;
290 }
291 if (*ptr) {
292 /* Unreference the old shader */
293 GLboolean deleteFlag = GL_FALSE;
294 struct gl_shader *old = *ptr;
295
296 ASSERT(old->RefCount > 0);
297 old->RefCount--;
298 /*printf("SHADER DECR %p (%d) to %d\n",
299 (void*) old, old->Name, old->RefCount);*/
300 deleteFlag = (old->RefCount == 0);
301
302 if (deleteFlag) {
303 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
304 _mesa_free_shader(ctx, old);
305 }
306
307 *ptr = NULL;
308 }
309 assert(!*ptr);
310
311 if (sh) {
312 /* reference new */
313 sh->RefCount++;
314 /*printf("SHADER INCR %p (%d) to %d\n",
315 (void*) sh, sh->Name, sh->RefCount);*/
316 *ptr = sh;
317 }
318 }
319
320
321 /**
322 * Lookup a GLSL shader object.
323 */
324 struct gl_shader *
325 _mesa_lookup_shader(GLcontext *ctx, GLuint name)
326 {
327 if (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.
333 */
334 if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
335 return NULL;
336 }
337 return sh;
338 }
339 return NULL;
340 }
341
342
343 /**
344 * As above, but record an error if shader is not found.
345 */
346 static struct gl_shader *
347 _mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
348 {
349 if (!name) {
350 _mesa_error(ctx, GL_INVALID_VALUE, caller);
351 return NULL;
352 }
353 else {
354 struct gl_shader *sh = (struct gl_shader *)
355 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
356 if (!sh) {
357 _mesa_error(ctx, GL_INVALID_VALUE, caller);
358 return NULL;
359 }
360 if (sh->Type == GL_SHADER_PROGRAM_MESA) {
361 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
362 return NULL;
363 }
364 return sh;
365 }
366 }
367
368
369 /**
370 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
371 */
372 static GLbitfield
373 get_shader_flags(void)
374 {
375 GLbitfield flags = 0x0;
376 const char *env = _mesa_getenv("MESA_GLSL");
377
378 if (env) {
379 if (_mesa_strstr(env, "dump"))
380 flags |= GLSL_DUMP;
381 if (_mesa_strstr(env, "log"))
382 flags |= GLSL_LOG;
383 if (_mesa_strstr(env, "nopt"))
384 flags |= GLSL_NO_OPT;
385 else if (_mesa_strstr(env, "opt"))
386 flags |= GLSL_OPT;
387 if (_mesa_strstr(env, "uniform"))
388 flags |= GLSL_UNIFORMS;
389 }
390
391 return flags;
392 }
393
394
395 /**
396 * Initialize context's shader state.
397 */
398 void
399 _mesa_init_shader_state(GLcontext * ctx)
400 {
401 /* Device drivers may override these to control what kind of instructions
402 * are generated by the GLSL compiler.
403 */
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();
408
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;
414 }
415
416
417 /**
418 * Free the per-context shader-related state.
419 */
420 void
421 _mesa_free_shader_state(GLcontext *ctx)
422 {
423 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
424 }
425
426
427 /**
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
434 */
435 static void
436 copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src)
437 {
438 GLsizei len;
439 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
440 dst[len] = src[len];
441 if (maxLength > 0)
442 dst[len] = 0;
443 if (length)
444 *length = len;
445 }
446
447
448 static GLboolean
449 _mesa_is_program(GLcontext *ctx, GLuint name)
450 {
451 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
452 return shProg ? GL_TRUE : GL_FALSE;
453 }
454
455
456 static GLboolean
457 _mesa_is_shader(GLcontext *ctx, GLuint name)
458 {
459 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
460 return shader ? GL_TRUE : GL_FALSE;
461 }
462
463
464 /**
465 * Called via ctx->Driver.AttachShader()
466 */
467 static void
468 _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
469 {
470 struct gl_shader_program *shProg;
471 struct gl_shader *sh;
472 GLuint i, n;
473
474 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
475 if (!shProg)
476 return;
477
478 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
479 if (!sh) {
480 return;
481 }
482
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:
488 *
489 * "The error INVALID_OPERATION is generated by AttachObjectARB
490 * if <obj> is already attached to <containerObj>."
491 */
492 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
493 return;
494 }
495 }
496
497 /* grow list */
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");
504 return;
505 }
506
507 /* append */
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++;
511 }
512
513
514 static GLint
515 _mesa_get_attrib_location(GLcontext *ctx, GLuint program,
516 const GLchar *name)
517 {
518 struct gl_shader_program *shProg
519 = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
520
521 if (!shProg) {
522 return -1;
523 }
524
525 if (!shProg->LinkStatus) {
526 _mesa_error(ctx, GL_INVALID_OPERATION,
527 "glGetAttribLocation(program not linked)");
528 return -1;
529 }
530
531 if (!name)
532 return -1;
533
534 if (shProg->VertexProgram) {
535 const struct gl_program_parameter_list *attribs =
536 shProg->VertexProgram->Base.Attributes;
537 if (attribs) {
538 GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
539 if (i >= 0) {
540 return attribs->Parameters[i].StateIndexes[0];
541 }
542 }
543 }
544 return -1;
545 }
546
547
548 static void
549 _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
550 const GLchar *name)
551 {
552 struct gl_shader_program *shProg;
553 const GLint size = -1; /* unknown size */
554 GLint i, oldIndex;
555 GLenum datatype = GL_FLOAT_VEC4;
556
557 shProg = _mesa_lookup_shader_program_err(ctx, program,
558 "glBindAttribLocation");
559 if (!shProg) {
560 return;
561 }
562
563 if (!name)
564 return;
565
566 if (strncmp(name, "gl_", 3) == 0) {
567 _mesa_error(ctx, GL_INVALID_OPERATION,
568 "glBindAttribLocation(illegal name)");
569 return;
570 }
571
572 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
573 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
574 return;
575 }
576
577 if (shProg->LinkStatus) {
578 /* get current index/location for the attribute */
579 oldIndex = _mesa_get_attrib_location(ctx, program, name);
580 }
581 else {
582 oldIndex = -1;
583 }
584
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);
587 if (i < 0) {
588 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
589 return;
590 }
591
592 /*
593 * Note that this attribute binding won't go into effect until
594 * glLinkProgram is called again.
595 */
596 }
597
598
599 static GLuint
600 _mesa_create_shader(GLcontext *ctx, GLenum type)
601 {
602 struct gl_shader *sh;
603 GLuint name;
604
605 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
606
607 switch (type) {
608 case GL_FRAGMENT_SHADER:
609 case GL_VERTEX_SHADER:
610 sh = _mesa_new_shader(ctx, name, type);
611 break;
612 default:
613 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
614 return 0;
615 }
616
617 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
618
619 return name;
620 }
621
622
623 static GLuint
624 _mesa_create_program(GLcontext *ctx)
625 {
626 GLuint name;
627 struct gl_shader_program *shProg;
628
629 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
630 shProg = _mesa_new_shader_program(ctx, name);
631
632 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
633
634 assert(shProg->RefCount == 1);
635
636 return name;
637 }
638
639
640 /**
641 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
642 * DeleteProgramARB.
643 */
644 static void
645 _mesa_delete_program2(GLcontext *ctx, GLuint name)
646 {
647 /*
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.
654 */
655 struct gl_shader_program *shProg;
656
657 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
658 if (!shProg)
659 return;
660
661 shProg->DeletePending = GL_TRUE;
662
663 /* effectively, decr shProg's refcount */
664 _mesa_reference_shader_program(ctx, &shProg, NULL);
665 }
666
667
668 static void
669 _mesa_delete_shader(GLcontext *ctx, GLuint shader)
670 {
671 struct gl_shader *sh;
672
673 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
674 if (!sh)
675 return;
676
677 sh->DeletePending = GL_TRUE;
678
679 /* effectively, decr sh's refcount */
680 _mesa_reference_shader(ctx, &sh, NULL);
681 }
682
683
684 static void
685 _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
686 {
687 struct gl_shader_program *shProg;
688 GLuint n;
689 GLuint i, j;
690
691 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
692 if (!shProg)
693 return;
694
695 n = shProg->NumShaders;
696
697 for (i = 0; i < n; i++) {
698 if (shProg->Shaders[i]->Name == shader) {
699 /* found it */
700 struct gl_shader **newList;
701
702 /* release */
703 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
704
705 /* alloc new, smaller array */
706 newList = (struct gl_shader **)
707 _mesa_malloc((n - 1) * sizeof(struct gl_shader *));
708 if (!newList) {
709 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
710 return;
711 }
712 for (j = 0; j < i; j++) {
713 newList[j] = shProg->Shaders[j];
714 }
715 while (++i < n)
716 newList[j++] = shProg->Shaders[i];
717 _mesa_free(shProg->Shaders);
718
719 shProg->Shaders = newList;
720 shProg->NumShaders = n - 1;
721
722 #ifdef DEBUG
723 /* sanity check */
724 {
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);
729 }
730 }
731 #endif
732
733 return;
734 }
735 }
736
737 /* not found */
738 {
739 GLenum err;
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;
744 else
745 err = GL_INVALID_VALUE;
746 _mesa_error(ctx, err, "glDetachProgram(shader)");
747 return;
748 }
749 }
750
751
752 static GLint
753 sizeof_glsl_type(GLenum type)
754 {
755 switch (type) {
756 case GL_FLOAT:
757 case GL_INT:
758 case GL_BOOL:
759 case GL_SAMPLER_1D:
760 case GL_SAMPLER_2D:
761 case GL_SAMPLER_3D:
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:
770 return 1;
771 case GL_FLOAT_VEC2:
772 case GL_INT_VEC2:
773 case GL_BOOL_VEC2:
774 return 2;
775 case GL_FLOAT_VEC3:
776 case GL_INT_VEC3:
777 case GL_BOOL_VEC3:
778 return 3;
779 case GL_FLOAT_VEC4:
780 case GL_INT_VEC4:
781 case GL_BOOL_VEC4:
782 return 4;
783 case GL_FLOAT_MAT2:
784 case GL_FLOAT_MAT2x3:
785 case GL_FLOAT_MAT2x4:
786 return 8; /* two float[4] vectors */
787 case GL_FLOAT_MAT3:
788 case GL_FLOAT_MAT3x2:
789 case GL_FLOAT_MAT3x4:
790 return 12; /* three float[4] vectors */
791 case GL_FLOAT_MAT4:
792 case GL_FLOAT_MAT4x2:
793 case GL_FLOAT_MAT4x3:
794 return 16; /* four float[4] vectors */
795 default:
796 _mesa_problem(NULL, "Invalid type in sizeof_glsl_type()");
797 return 1;
798 }
799 }
800
801
802 static GLboolean
803 is_boolean_type(GLenum type)
804 {
805 switch (type) {
806 case GL_BOOL:
807 case GL_BOOL_VEC2:
808 case GL_BOOL_VEC3:
809 case GL_BOOL_VEC4:
810 return GL_TRUE;
811 default:
812 return GL_FALSE;
813 }
814 }
815
816
817 static GLboolean
818 is_integer_type(GLenum type)
819 {
820 switch (type) {
821 case GL_INT:
822 case GL_INT_VEC2:
823 case GL_INT_VEC3:
824 case GL_INT_VEC4:
825 return GL_TRUE;
826 default:
827 return GL_FALSE;
828 }
829 }
830
831
832 static GLboolean
833 is_sampler_type(GLenum type)
834 {
835 switch (type) {
836 case GL_SAMPLER_1D:
837 case GL_SAMPLER_2D:
838 case GL_SAMPLER_3D:
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:
846 return GL_TRUE;
847 default:
848 return GL_FALSE;
849 }
850 }
851
852
853 static void
854 _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
855 GLsizei maxLength, GLsizei *length, GLint *size,
856 GLenum *type, GLchar *nameOut)
857 {
858 const struct gl_program_parameter_list *attribs = NULL;
859 struct gl_shader_program *shProg;
860
861 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
862 if (!shProg)
863 return;
864
865 if (shProg->VertexProgram)
866 attribs = shProg->VertexProgram->Base.Attributes;
867
868 if (!attribs || index >= attribs->NumParameters) {
869 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
870 return;
871 }
872
873 copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name);
874
875 if (size)
876 *size = attribs->Parameters[index].Size
877 / sizeof_glsl_type(attribs->Parameters[index].DataType);
878
879 if (type)
880 *type = attribs->Parameters[index].DataType;
881 }
882
883
884 static struct gl_program_parameter *
885 get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
886 {
887 const struct gl_program *prog;
888 GLint progPos;
889
890 progPos = shProg->Uniforms->Uniforms[index].VertPos;
891 if (progPos >= 0) {
892 prog = &shProg->VertexProgram->Base;
893 }
894 else {
895 progPos = shProg->Uniforms->Uniforms[index].FragPos;
896 if (progPos >= 0) {
897 prog = &shProg->FragmentProgram->Base;
898 }
899 }
900
901 if (!prog || progPos < 0)
902 return NULL; /* should never happen */
903
904 return &prog->Parameters->Parameters[progPos];
905 }
906
907
908 /**
909 * Called via ctx->Driver.GetActiveUniform().
910 */
911 static void
912 _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
913 GLsizei maxLength, GLsizei *length, GLint *size,
914 GLenum *type, GLchar *nameOut)
915 {
916 const struct gl_shader_program *shProg;
917 const struct gl_program *prog;
918 const struct gl_program_parameter *param;
919 GLint progPos;
920
921 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
922 if (!shProg)
923 return;
924
925 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
926 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
927 return;
928 }
929
930 progPos = shProg->Uniforms->Uniforms[index].VertPos;
931 if (progPos >= 0) {
932 prog = &shProg->VertexProgram->Base;
933 }
934 else {
935 progPos = shProg->Uniforms->Uniforms[index].FragPos;
936 if (progPos >= 0) {
937 prog = &shProg->FragmentProgram->Base;
938 }
939 }
940
941 if (!prog || progPos < 0)
942 return; /* should never happen */
943
944 ASSERT(progPos < prog->Parameters->NumParameters);
945 param = &prog->Parameters->Parameters[progPos];
946
947 if (nameOut) {
948 copy_string(nameOut, maxLength, length, param->Name);
949 }
950
951 if (size) {
952 GLint typeSize = sizeof_glsl_type(param->DataType);
953 if (param->Size > typeSize) {
954 /* This is an array.
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.
958 */
959 typeSize = (typeSize + 3) & ~3;
960 }
961 /* Note that the returned size is in units of the <type>, not bytes */
962 *size = param->Size / typeSize;
963 }
964
965 if (type) {
966 *type = param->DataType;
967 }
968 }
969
970
971 /**
972 * Called via ctx->Driver.GetAttachedShaders().
973 */
974 static void
975 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
976 GLsizei *count, GLuint *obj)
977 {
978 struct gl_shader_program *shProg =
979 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
980 if (shProg) {
981 GLuint i;
982 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
983 obj[i] = shProg->Shaders[i]->Name;
984 }
985 if (count)
986 *count = i;
987 }
988 }
989
990
991 static GLuint
992 _mesa_get_handle(GLcontext *ctx, GLenum pname)
993 {
994 GLint handle = 0;
995
996 if (pname == GL_PROGRAM_OBJECT_ARB) {
997 CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
998 } else {
999 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
1000 }
1001
1002 return handle;
1003 }
1004
1005
1006 static void
1007 _mesa_get_programiv(GLcontext *ctx, GLuint program,
1008 GLenum pname, GLint *params)
1009 {
1010 const struct gl_program_parameter_list *attribs;
1011 struct gl_shader_program *shProg
1012 = _mesa_lookup_shader_program(ctx, program);
1013
1014 if (!shProg) {
1015 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
1016 return;
1017 }
1018
1019 if (shProg->VertexProgram)
1020 attribs = shProg->VertexProgram->Base.Attributes;
1021 else
1022 attribs = NULL;
1023
1024 switch (pname) {
1025 case GL_DELETE_STATUS:
1026 *params = shProg->DeletePending;
1027 break;
1028 case GL_LINK_STATUS:
1029 *params = shProg->LinkStatus;
1030 break;
1031 case GL_VALIDATE_STATUS:
1032 *params = shProg->Validated;
1033 break;
1034 case GL_INFO_LOG_LENGTH:
1035 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
1036 break;
1037 case GL_ATTACHED_SHADERS:
1038 *params = shProg->NumShaders;
1039 break;
1040 case GL_ACTIVE_ATTRIBUTES:
1041 *params = attribs ? attribs->NumParameters : 0;
1042 break;
1043 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1044 *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
1045 break;
1046 case GL_ACTIVE_UNIFORMS:
1047 *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
1048 break;
1049 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1050 *params = _mesa_longest_uniform_name(shProg->Uniforms);
1051 if (*params > 0)
1052 (*params)++; /* add one for terminating zero */
1053 break;
1054 case GL_PROGRAM_BINARY_LENGTH_OES:
1055 *params = 0;
1056 break;
1057 default:
1058 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
1059 return;
1060 }
1061 }
1062
1063
1064 static void
1065 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
1066 {
1067 struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
1068
1069 if (!shader) {
1070 return;
1071 }
1072
1073 switch (pname) {
1074 case GL_SHADER_TYPE:
1075 *params = shader->Type;
1076 break;
1077 case GL_DELETE_STATUS:
1078 *params = shader->DeletePending;
1079 break;
1080 case GL_COMPILE_STATUS:
1081 *params = shader->CompileStatus;
1082 break;
1083 case GL_INFO_LOG_LENGTH:
1084 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
1085 break;
1086 case GL_SHADER_SOURCE_LENGTH:
1087 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1088 break;
1089 default:
1090 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1091 return;
1092 }
1093 }
1094
1095
1096 static void
1097 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
1098 GLsizei *length, GLchar *infoLog)
1099 {
1100 struct gl_shader_program *shProg
1101 = _mesa_lookup_shader_program(ctx, program);
1102 if (!shProg) {
1103 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
1104 return;
1105 }
1106 copy_string(infoLog, bufSize, length, shProg->InfoLog);
1107 }
1108
1109
1110 static void
1111 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
1112 GLsizei *length, GLchar *infoLog)
1113 {
1114 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
1115 if (!sh) {
1116 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
1117 return;
1118 }
1119 copy_string(infoLog, bufSize, length, sh->InfoLog);
1120 }
1121
1122
1123 /**
1124 * Called via ctx->Driver.GetShaderSource().
1125 */
1126 static void
1127 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
1128 GLsizei *length, GLchar *sourceOut)
1129 {
1130 struct gl_shader *sh;
1131 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1132 if (!sh) {
1133 return;
1134 }
1135 copy_string(sourceOut, maxLength, length, sh->Source);
1136 }
1137
1138
1139 static void
1140 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
1141 {
1142 switch (type) {
1143 case GL_FLOAT_MAT2:
1144 *rows = *cols = 2;
1145 break;
1146 case GL_FLOAT_MAT2x3:
1147 *rows = 3;
1148 *cols = 2;
1149 break;
1150 case GL_FLOAT_MAT2x4:
1151 *rows = 4;
1152 *cols = 2;
1153 break;
1154 case GL_FLOAT_MAT3:
1155 *rows = 3;
1156 *cols = 3;
1157 break;
1158 case GL_FLOAT_MAT3x2:
1159 *rows = 2;
1160 *cols = 3;
1161 break;
1162 case GL_FLOAT_MAT3x4:
1163 *rows = 4;
1164 *cols = 3;
1165 break;
1166 case GL_FLOAT_MAT4:
1167 *rows = 4;
1168 *cols = 4;
1169 break;
1170 case GL_FLOAT_MAT4x2:
1171 *rows = 2;
1172 *cols = 4;
1173 break;
1174 case GL_FLOAT_MAT4x3:
1175 *rows = 3;
1176 *cols = 4;
1177 break;
1178 default:
1179 *rows = *cols = 0;
1180 }
1181 }
1182
1183
1184 /**
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.
1188 */
1189 static void
1190 get_uniform_rows_cols(const struct gl_program_parameter *p,
1191 GLint *rows, GLint *cols)
1192 {
1193 get_matrix_dims(p->DataType, rows, cols);
1194 if (*rows == 0 && *cols == 0) {
1195 /* not a matrix type, probably a float or vector */
1196 if (p->Size <= 4) {
1197 *rows = 1;
1198 *cols = p->Size;
1199 }
1200 else {
1201 *rows = p->Size / 4 + 1;
1202 if (p->Size % 4 == 0)
1203 *cols = 4;
1204 else
1205 *cols = p->Size % 4;
1206 }
1207 }
1208 }
1209
1210
1211 /**
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.
1215 */
1216 static void
1217 lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
1218 struct gl_program **progOut, GLint *paramPosOut)
1219 {
1220 struct gl_shader_program *shProg
1221 = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
1222 struct gl_program *prog = NULL;
1223 GLint progPos = -1;
1224
1225 /* if shProg is NULL, we'll have already recorded an error */
1226
1227 if (shProg) {
1228 if (!shProg->Uniforms ||
1229 location < 0 ||
1230 location >= (GLint) shProg->Uniforms->NumUniforms) {
1231 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
1232 }
1233 else {
1234 /* OK, find the gl_program and program parameter location */
1235 progPos = shProg->Uniforms->Uniforms[location].VertPos;
1236 if (progPos >= 0) {
1237 prog = &shProg->VertexProgram->Base;
1238 }
1239 else {
1240 progPos = shProg->Uniforms->Uniforms[location].FragPos;
1241 if (progPos >= 0) {
1242 prog = &shProg->FragmentProgram->Base;
1243 }
1244 }
1245 }
1246 }
1247
1248 *progOut = prog;
1249 *paramPosOut = progPos;
1250 }
1251
1252
1253 /**
1254 * Called via ctx->Driver.GetUniformfv().
1255 */
1256 static void
1257 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1258 GLfloat *params)
1259 {
1260 struct gl_program *prog;
1261 GLint paramPos;
1262
1263 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
1264
1265 if (prog) {
1266 const struct gl_program_parameter *p =
1267 &prog->Parameters->Parameters[paramPos];
1268 GLint rows, cols, i, j, k;
1269
1270 get_uniform_rows_cols(p, &rows, &cols);
1271
1272 k = 0;
1273 for (i = 0; i < rows; i++) {
1274 for (j = 0; j < cols; j++ ) {
1275 params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
1276 }
1277 }
1278 }
1279 }
1280
1281
1282 /**
1283 * Called via ctx->Driver.GetUniformiv().
1284 * \sa _mesa_get_uniformfv, only difference is a cast.
1285 */
1286 static void
1287 _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
1288 GLint *params)
1289 {
1290 struct gl_program *prog;
1291 GLint paramPos;
1292
1293 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
1294
1295 if (prog) {
1296 const struct gl_program_parameter *p =
1297 &prog->Parameters->Parameters[paramPos];
1298 GLint rows, cols, i, j, k;
1299
1300 get_uniform_rows_cols(p, &rows, &cols);
1301
1302 k = 0;
1303 for (i = 0; i < rows; i++) {
1304 for (j = 0; j < cols; j++ ) {
1305 params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
1306 }
1307 }
1308 }
1309 }
1310
1311
1312 /**
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.
1318 */
1319 static void
1320 merge_location_offset(GLint *location, GLint offset)
1321 {
1322 *location = *location | (offset << 16);
1323 }
1324
1325
1326 /**
1327 * Seperate the uniform location and parameter offset. See above.
1328 */
1329 static void
1330 split_location_offset(GLint *location, GLint *offset)
1331 {
1332 *offset = (*location >> 16);
1333 *location = *location & 0xffff;
1334 }
1335
1336
1337 /**
1338 * Called via ctx->Driver.GetUniformLocation().
1339 *
1340 * The return value will encode two values, the uniform location and an
1341 * offset (used for arrays, structs).
1342 */
1343 static GLint
1344 _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
1345 {
1346 GLint offset = 0, location = -1;
1347
1348 struct gl_shader_program *shProg =
1349 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
1350
1351 if (!shProg)
1352 return -1;
1353
1354 if (shProg->LinkStatus == GL_FALSE) {
1355 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1356 return -1;
1357 }
1358
1359 /* XXX we should return -1 if the uniform was declared, but not
1360 * actually used.
1361 */
1362
1363 /* XXX we need to be able to parse uniform names for structs and arrays
1364 * such as:
1365 * mymatrix[1]
1366 * mystruct.field1
1367 */
1368
1369 {
1370 /* handle 1-dimension arrays here... */
1371 char *c = strchr(name, '[');
1372 if (c) {
1373 /* truncate name at [ */
1374 const GLint len = c - name;
1375 GLchar *newName = _mesa_malloc(len + 1);
1376 if (!newName)
1377 return -1; /* out of mem */
1378 _mesa_memcpy(newName, name, len);
1379 newName[len] = 0;
1380
1381 location = _mesa_lookup_uniform(shProg->Uniforms, newName);
1382 if (location >= 0) {
1383 const GLint element = _mesa_atoi(c + 1);
1384 if (element > 0) {
1385 /* get type of the uniform array element */
1386 struct gl_program_parameter *p;
1387 p = get_uniform_parameter(shProg, location);
1388 if (p) {
1389 GLint rows, cols;
1390 get_matrix_dims(p->DataType, &rows, &cols);
1391 if (rows < 1)
1392 rows = 1;
1393 offset = element * rows;
1394 }
1395 }
1396 }
1397
1398 _mesa_free(newName);
1399 }
1400 }
1401
1402 if (location < 0) {
1403 location = _mesa_lookup_uniform(shProg->Uniforms, name);
1404 }
1405
1406 if (location >= 0) {
1407 merge_location_offset(&location, offset);
1408 }
1409
1410 return location;
1411 }
1412
1413
1414
1415 /**
1416 * Called via ctx->Driver.ShaderSource()
1417 */
1418 static void
1419 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1420 {
1421 struct gl_shader *sh;
1422
1423 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1424 if (!sh)
1425 return;
1426
1427 /* free old shader source string and install new one */
1428 if (sh->Source) {
1429 _mesa_free((void *) sh->Source);
1430 }
1431 sh->Source = source;
1432 sh->CompileStatus = GL_FALSE;
1433 }
1434
1435
1436 /**
1437 * Called via ctx->Driver.CompileShader()
1438 */
1439 static void
1440 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1441 {
1442 struct gl_shader *sh;
1443
1444 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1445 if (!sh)
1446 return;
1447
1448 /* set default pragma state for shader */
1449 sh->Pragmas = ctx->Shader.DefaultPragmas;
1450
1451 /* this call will set the sh->CompileStatus field to indicate if
1452 * compilation was successful.
1453 */
1454 (void) _slang_compile(ctx, sh);
1455 }
1456
1457
1458 /**
1459 * Called via ctx->Driver.LinkProgram()
1460 */
1461 static void
1462 _mesa_link_program(GLcontext *ctx, GLuint program)
1463 {
1464 struct gl_shader_program *shProg;
1465
1466 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1467 if (!shProg)
1468 return;
1469
1470 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1471
1472 _slang_link(ctx, program, shProg);
1473 }
1474
1475
1476 /**
1477 * Called via ctx->Driver.UseProgram()
1478 */
1479 void
1480 _mesa_use_program(GLcontext *ctx, GLuint program)
1481 {
1482 struct gl_shader_program *shProg;
1483
1484 if (ctx->Shader.CurrentProgram &&
1485 ctx->Shader.CurrentProgram->Name == program) {
1486 /* no-op */
1487 return;
1488 }
1489
1490 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1491
1492 if (program) {
1493 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1494 if (!shProg) {
1495 return;
1496 }
1497 if (!shProg->LinkStatus) {
1498 _mesa_error(ctx, GL_INVALID_OPERATION,
1499 "glUseProgram(program %u not linked)", program);
1500 return;
1501 }
1502
1503 /* debug code */
1504 if (0) {
1505 GLuint i;
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);
1511 }
1512 }
1513 }
1514 else {
1515 shProg = NULL;
1516 }
1517
1518 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1519 }
1520
1521
1522
1523 /**
1524 * Update the vertex/fragment program's TexturesUsed array.
1525 *
1526 * This needs to be called after glUniform(set sampler var) is called.
1527 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1528 * particular texture unit. We know the sampler's texture target
1529 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1530 * set by glUniform() calls.
1531 *
1532 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1533 * information to update the prog->TexturesUsed[] values.
1534 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1535 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1536 * We'll use that info for state validation before rendering.
1537 */
1538 void
1539 _mesa_update_shader_textures_used(struct gl_program *prog)
1540 {
1541 GLuint s;
1542
1543 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1544
1545 for (s = 0; s < MAX_SAMPLERS; s++) {
1546 if (prog->SamplersUsed & (1 << s)) {
1547 GLuint u = prog->SamplerUnits[s];
1548 GLuint t = prog->SamplerTargets[s];
1549 assert(u < MAX_TEXTURE_IMAGE_UNITS);
1550 prog->TexturesUsed[u] |= (1 << t);
1551 }
1552 }
1553 }
1554
1555
1556 /**
1557 * Check if the type given by userType is allowed to set a uniform of the
1558 * target type. Generally, equivalence is required, but setting Boolean
1559 * uniforms can be done with glUniformiv or glUniformfv.
1560 */
1561 static GLboolean
1562 compatible_types(GLenum userType, GLenum targetType)
1563 {
1564 if (userType == targetType)
1565 return GL_TRUE;
1566
1567 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1568 return GL_TRUE;
1569
1570 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1571 userType == GL_INT_VEC2))
1572 return GL_TRUE;
1573
1574 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1575 userType == GL_INT_VEC3))
1576 return GL_TRUE;
1577
1578 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1579 userType == GL_INT_VEC4))
1580 return GL_TRUE;
1581
1582 if (is_sampler_type(targetType) && userType == GL_INT)
1583 return GL_TRUE;
1584
1585 return GL_FALSE;
1586 }
1587
1588
1589 /**
1590 * Set the value of a program's uniform variable.
1591 * \param program the program whose uniform to update
1592 * \param index the index of the program parameter for the uniform
1593 * \param offset additional parameter slot offset (for arrays)
1594 * \param type the incoming datatype of 'values'
1595 * \param count the number of uniforms to set
1596 * \param elems number of elements per uniform (1, 2, 3 or 4)
1597 * \param values the new values, of datatype 'type'
1598 */
1599 static void
1600 set_program_uniform(GLcontext *ctx, struct gl_program *program,
1601 GLint index, GLint offset,
1602 GLenum type, GLsizei count, GLint elems,
1603 const void *values)
1604 {
1605 struct gl_program_parameter *param =
1606 &program->Parameters->Parameters[index];
1607 const GLboolean isUniformBool = is_boolean_type(param->DataType);
1608 const GLboolean areIntValues = is_integer_type(type);
1609
1610 assert(offset >= 0);
1611 assert(elems >= 1);
1612 assert(elems <= 4);
1613
1614 if (!compatible_types(type, param->DataType)) {
1615 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1616 return;
1617 }
1618
1619 if (index + offset > (GLint) program->Parameters->Size) {
1620 /* out of bounds! */
1621 return;
1622 }
1623
1624 if (param->Type == PROGRAM_SAMPLER) {
1625 /* This controls which texture unit which is used by a sampler */
1626 GLuint texUnit, sampler;
1627 GLint i;
1628
1629 /* data type for setting samplers must be int */
1630 if (type != GL_INT) {
1631 _mesa_error(ctx, GL_INVALID_OPERATION,
1632 "glUniform(only glUniform1i can be used "
1633 "to set sampler uniforms)");
1634 return;
1635 }
1636
1637 /* XXX arrays of samplers haven't been tested much, but it's not a
1638 * common thing...
1639 */
1640 for (i = 0; i < count; i++) {
1641 sampler = (GLuint) program->Parameters->ParameterValues[index + i][0];
1642 texUnit = ((GLuint *) values)[i];
1643
1644 /* check that the sampler (tex unit index) is legal */
1645 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1646 _mesa_error(ctx, GL_INVALID_VALUE,
1647 "glUniform1(invalid sampler/tex unit index)");
1648 return;
1649 }
1650
1651 /* This maps a sampler to a texture unit: */
1652 if (sampler < MAX_SAMPLERS) {
1653 program->SamplerUnits[sampler] = texUnit;
1654 }
1655 }
1656
1657 _mesa_update_shader_textures_used(program);
1658
1659 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1660 }
1661 else {
1662 /* ordinary uniform variable */
1663 GLsizei k, i;
1664 const GLint slots = (param->Size + 3) / 4;
1665 const GLint typeSize = sizeof_glsl_type(param->DataType);
1666
1667 if (param->Size > typeSize) {
1668 /* an array */
1669 /* we'll ignore extra data below */
1670 }
1671 else {
1672 /* non-array: count must be one */
1673 if (count != 1) {
1674 _mesa_error(ctx, GL_INVALID_OPERATION,
1675 "glUniform(uniform is not an array)");
1676 return;
1677 }
1678 }
1679
1680 /* loop over number of array elements */
1681 for (k = 0; k < count; k++) {
1682 GLfloat *uniformVal;
1683
1684 if (offset + k >= slots) {
1685 /* Extra array data is ignored */
1686 break;
1687 }
1688
1689 /* uniformVal (the destination) is always float[4] */
1690 uniformVal = program->Parameters->ParameterValues[index + offset + k];
1691
1692 if (areIntValues) {
1693 /* convert user's ints to floats */
1694 const GLint *iValues = ((const GLint *) values) + k * elems;
1695 for (i = 0; i < elems; i++) {
1696 uniformVal[i] = (GLfloat) iValues[i];
1697 }
1698 }
1699 else {
1700 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1701 for (i = 0; i < elems; i++) {
1702 uniformVal[i] = fValues[i];
1703 }
1704 }
1705
1706 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1707 if (isUniformBool) {
1708 for (i = 0; i < elems; i++) {
1709 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1710 }
1711 }
1712 }
1713 }
1714 }
1715
1716
1717 /**
1718 * Called via ctx->Driver.Uniform().
1719 */
1720 static void
1721 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1722 const GLvoid *values, GLenum type)
1723 {
1724 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1725 struct gl_uniform *uniform;
1726 GLint elems, offset;
1727 GLenum basicType;
1728
1729 if (!shProg || !shProg->LinkStatus) {
1730 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1731 return;
1732 }
1733
1734 if (location == -1)
1735 return; /* The standard specifies this as a no-op */
1736
1737 if (location < -1) {
1738 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)");
1739 return;
1740 }
1741
1742 split_location_offset(&location, &offset);
1743
1744 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1745 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1746 return;
1747 }
1748
1749 if (count < 0) {
1750 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1751 return;
1752 }
1753
1754 switch (type) {
1755 case GL_FLOAT:
1756 basicType = GL_FLOAT;
1757 elems = 1;
1758 break;
1759 case GL_INT:
1760 basicType = GL_INT;
1761 elems = 1;
1762 break;
1763 case GL_FLOAT_VEC2:
1764 basicType = GL_FLOAT;
1765 elems = 2;
1766 break;
1767 case GL_INT_VEC2:
1768 basicType = GL_INT;
1769 elems = 2;
1770 break;
1771 case GL_FLOAT_VEC3:
1772 basicType = GL_FLOAT;
1773 elems = 3;
1774 break;
1775 case GL_INT_VEC3:
1776 basicType = GL_INT;
1777 elems = 3;
1778 break;
1779 case GL_FLOAT_VEC4:
1780 basicType = GL_FLOAT;
1781 elems = 4;
1782 break;
1783 case GL_INT_VEC4:
1784 basicType = GL_INT;
1785 elems = 4;
1786 break;
1787 default:
1788 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1789 return;
1790 }
1791
1792 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1793
1794 uniform = &shProg->Uniforms->Uniforms[location];
1795
1796 if (ctx->Shader.Flags & GLSL_UNIFORMS) {
1797 GLint i;
1798 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1799 shProg->Name, uniform->Name, location);
1800 if (basicType == GL_INT) {
1801 const GLint *v = (const GLint *) values;
1802 for (i = 0; i < count * elems; i++) {
1803 _mesa_printf("%d ", v[i]);
1804 }
1805 }
1806 else {
1807 const GLfloat *v = (const GLfloat *) values;
1808 for (i = 0; i < count * elems; i++) {
1809 _mesa_printf("%g ", v[i]);
1810 }
1811 }
1812 _mesa_printf("\n");
1813 }
1814
1815 /* A uniform var may be used by both a vertex shader and a fragment
1816 * shader. We may need to update one or both shader's uniform here:
1817 */
1818 if (shProg->VertexProgram) {
1819 /* convert uniform location to program parameter index */
1820 GLint index = uniform->VertPos;
1821 if (index >= 0) {
1822 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1823 index, offset, type, count, elems, values);
1824 }
1825 }
1826
1827 if (shProg->FragmentProgram) {
1828 /* convert uniform location to program parameter index */
1829 GLint index = uniform->FragPos;
1830 if (index >= 0) {
1831 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1832 index, offset, type, count, elems, values);
1833 }
1834 }
1835
1836 uniform->Initialized = GL_TRUE;
1837 }
1838
1839
1840 /**
1841 * Set a matrix-valued program parameter.
1842 */
1843 static void
1844 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1845 GLuint index, GLuint offset,
1846 GLuint count, GLuint rows, GLuint cols,
1847 GLboolean transpose, const GLfloat *values)
1848 {
1849 GLuint mat, row, col;
1850 GLuint dst = index + offset, src = 0;
1851 GLint nr, nc;
1852
1853 /* check that the number of rows, columns is correct */
1854 get_matrix_dims(program->Parameters->Parameters[index].DataType, &nr, &nc);
1855 if (rows != nr || cols != nc) {
1856 _mesa_error(ctx, GL_INVALID_OPERATION,
1857 "glUniformMatrix(matrix size mismatch)");
1858 return;
1859 }
1860
1861 if (index + offset > program->Parameters->Size) {
1862 /* out of bounds! */
1863 return;
1864 }
1865
1866 /*
1867 * Note: the _columns_ of a matrix are stored in program registers, not
1868 * the rows. So, the loops below look a little funny.
1869 * XXX could optimize this a bit...
1870 */
1871
1872 /* loop over matrices */
1873 for (mat = 0; mat < count; mat++) {
1874
1875 /* each matrix: */
1876 for (col = 0; col < cols; col++) {
1877 GLfloat *v = program->Parameters->ParameterValues[dst];
1878 for (row = 0; row < rows; row++) {
1879 if (transpose) {
1880 v[row] = values[src + row * cols + col];
1881 }
1882 else {
1883 v[row] = values[src + col * rows + row];
1884 }
1885 }
1886 dst++;
1887 }
1888
1889 src += rows * cols; /* next matrix */
1890 }
1891 }
1892
1893
1894 /**
1895 * Called by ctx->Driver.UniformMatrix().
1896 * Note: cols=2, rows=4 ==> array[2] of vec4
1897 */
1898 static void
1899 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1900 GLenum matrixType, GLint location, GLsizei count,
1901 GLboolean transpose, const GLfloat *values)
1902 {
1903 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1904 struct gl_uniform *uniform;
1905 GLint offset;
1906
1907 if (!shProg || !shProg->LinkStatus) {
1908 _mesa_error(ctx, GL_INVALID_OPERATION,
1909 "glUniformMatrix(program not linked)");
1910 return;
1911 }
1912
1913 if (location == -1)
1914 return; /* The standard specifies this as a no-op */
1915
1916 if (location < -1) {
1917 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
1918 return;
1919 }
1920
1921 split_location_offset(&location, &offset);
1922
1923 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1924 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
1925 return;
1926 }
1927 if (values == NULL) {
1928 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
1929 return;
1930 }
1931
1932 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1933
1934 uniform = &shProg->Uniforms->Uniforms[location];
1935
1936 if (shProg->VertexProgram) {
1937 /* convert uniform location to program parameter index */
1938 GLint index = uniform->VertPos;
1939 if (index >= 0) {
1940 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
1941 index, offset,
1942 count, rows, cols, transpose, values);
1943 }
1944 }
1945
1946 if (shProg->FragmentProgram) {
1947 /* convert uniform location to program parameter index */
1948 GLint index = uniform->FragPos;
1949 if (index >= 0) {
1950 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
1951 index, offset,
1952 count, rows, cols, transpose, values);
1953 }
1954 }
1955
1956 uniform->Initialized = GL_TRUE;
1957 }
1958
1959
1960 static void
1961 _mesa_validate_program(GLcontext *ctx, GLuint program)
1962 {
1963 struct gl_shader_program *shProg;
1964
1965 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1966 if (!shProg) {
1967 return;
1968 }
1969
1970 if (!shProg->LinkStatus) {
1971 shProg->Validated = GL_FALSE;
1972 return;
1973 }
1974
1975 /* From the GL spec, a program is invalid if any of these are true:
1976
1977 any two active samplers in the current program object are of
1978 different types, but refer to the same texture image unit,
1979
1980 any active sampler in the current program object refers to a texture
1981 image unit where fixed-function fragment processing accesses a
1982 texture target that does not match the sampler type, or
1983
1984 the sum of the number of active samplers in the program and the
1985 number of texture image units enabled for fixed-function fragment
1986 processing exceeds the combined limit on the total number of texture
1987 image units allowed.
1988 */
1989
1990 shProg->Validated = GL_TRUE;
1991 }
1992
1993
1994 /**
1995 * Plug in Mesa's GLSL functions into the device driver function table.
1996 */
1997 void
1998 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
1999 {
2000 driver->AttachShader = _mesa_attach_shader;
2001 driver->BindAttribLocation = _mesa_bind_attrib_location;
2002 driver->CompileShader = _mesa_compile_shader;
2003 driver->CreateProgram = _mesa_create_program;
2004 driver->CreateShader = _mesa_create_shader;
2005 driver->DeleteProgram2 = _mesa_delete_program2;
2006 driver->DeleteShader = _mesa_delete_shader;
2007 driver->DetachShader = _mesa_detach_shader;
2008 driver->GetActiveAttrib = _mesa_get_active_attrib;
2009 driver->GetActiveUniform = _mesa_get_active_uniform;
2010 driver->GetAttachedShaders = _mesa_get_attached_shaders;
2011 driver->GetAttribLocation = _mesa_get_attrib_location;
2012 driver->GetHandle = _mesa_get_handle;
2013 driver->GetProgramiv = _mesa_get_programiv;
2014 driver->GetProgramInfoLog = _mesa_get_program_info_log;
2015 driver->GetShaderiv = _mesa_get_shaderiv;
2016 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
2017 driver->GetShaderSource = _mesa_get_shader_source;
2018 driver->GetUniformfv = _mesa_get_uniformfv;
2019 driver->GetUniformiv = _mesa_get_uniformiv;
2020 driver->GetUniformLocation = _mesa_get_uniform_location;
2021 driver->IsProgram = _mesa_is_program;
2022 driver->IsShader = _mesa_is_shader;
2023 driver->LinkProgram = _mesa_link_program;
2024 driver->ShaderSource = _mesa_shader_source;
2025 driver->Uniform = _mesa_uniform;
2026 driver->UniformMatrix = _mesa_uniform_matrix;
2027 driver->UseProgram = _mesa_use_program;
2028 driver->ValidateProgram = _mesa_validate_program;
2029 }