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