Merge commit 'origin/master' into gallium-0.2
[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 /**
375 * Initialize context's shader state.
376 */
377 void
378 _mesa_init_shader_state(GLcontext * ctx)
379 {
380 /* Device drivers may override these to control what kind of instructions
381 * are generated by the GLSL compiler.
382 */
383 ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
384 ctx->Shader.EmitCondCodes = GL_FALSE;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
385 ctx->Shader.EmitComments = GL_FALSE;
386 }
387
388
389 /**
390 * Free the per-context shader-related state.
391 */
392 void
393 _mesa_free_shader_state(GLcontext *ctx)
394 {
395 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
396 }
397
398
399 /**
400 * Copy string from <src> to <dst>, up to maxLength characters, returning
401 * length of <dst> in <length>.
402 * \param src the strings source
403 * \param maxLength max chars to copy
404 * \param length returns number of chars copied
405 * \param dst the string destination
406 */
407 static void
408 copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src)
409 {
410 GLsizei len;
411 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
412 dst[len] = src[len];
413 if (maxLength > 0)
414 dst[len] = 0;
415 if (length)
416 *length = len;
417 }
418
419
420 static GLboolean
421 _mesa_is_program(GLcontext *ctx, GLuint name)
422 {
423 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
424 return shProg ? GL_TRUE : GL_FALSE;
425 }
426
427
428 static GLboolean
429 _mesa_is_shader(GLcontext *ctx, GLuint name)
430 {
431 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
432 return shader ? GL_TRUE : GL_FALSE;
433 }
434
435
436 /**
437 * Called via ctx->Driver.AttachShader()
438 */
439 static void
440 _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
441 {
442 struct gl_shader_program *shProg;
443 struct gl_shader *sh;
444 GLuint i, n;
445
446 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
447 if (!shProg)
448 return;
449
450 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
451 if (!sh) {
452 return;
453 }
454
455 n = shProg->NumShaders;
456 for (i = 0; i < n; i++) {
457 if (shProg->Shaders[i] == sh) {
458 /* The shader is already attched to this program. The
459 * GL_ARB_shader_objects spec says:
460 *
461 * "The error INVALID_OPERATION is generated by AttachObjectARB
462 * if <obj> is already attached to <containerObj>."
463 */
464 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
465 return;
466 }
467 }
468
469 /* grow list */
470 shProg->Shaders = (struct gl_shader **)
471 _mesa_realloc(shProg->Shaders,
472 n * sizeof(struct gl_shader *),
473 (n + 1) * sizeof(struct gl_shader *));
474 if (!shProg->Shaders) {
475 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
476 return;
477 }
478
479 /* append */
480 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
481 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
482 shProg->NumShaders++;
483 }
484
485
486 static GLint
487 _mesa_get_attrib_location(GLcontext *ctx, GLuint program,
488 const GLchar *name)
489 {
490 struct gl_shader_program *shProg
491 = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
492
493 if (!shProg) {
494 return -1;
495 }
496
497 if (!shProg->LinkStatus) {
498 _mesa_error(ctx, GL_INVALID_OPERATION,
499 "glGetAttribLocation(program not linked)");
500 return -1;
501 }
502
503 if (!name)
504 return -1;
505
506 if (shProg->VertexProgram) {
507 const struct gl_program_parameter_list *attribs =
508 shProg->VertexProgram->Base.Attributes;
509 if (attribs) {
510 GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
511 if (i >= 0) {
512 return attribs->Parameters[i].StateIndexes[0];
513 }
514 }
515 }
516 return -1;
517 }
518
519
520 static void
521 _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
522 const GLchar *name)
523 {
524 struct gl_shader_program *shProg;
525 const GLint size = -1; /* unknown size */
526 GLint i, oldIndex;
527 GLenum datatype = GL_FLOAT_VEC4;
528
529 shProg = _mesa_lookup_shader_program_err(ctx, program,
530 "glBindAttribLocation");
531 if (!shProg) {
532 return;
533 }
534
535 if (!name)
536 return;
537
538 if (strncmp(name, "gl_", 3) == 0) {
539 _mesa_error(ctx, GL_INVALID_OPERATION,
540 "glBindAttribLocation(illegal name)");
541 return;
542 }
543
544 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
545 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
546 return;
547 }
548
549 if (shProg->LinkStatus) {
550 /* get current index/location for the attribute */
551 oldIndex = _mesa_get_attrib_location(ctx, program, name);
552 }
553 else {
554 oldIndex = -1;
555 }
556
557 /* this will replace the current value if it's already in the list */
558 i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
559 if (i < 0) {
560 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
561 return;
562 }
563
564 /*
565 * Note that this attribute binding won't go into effect until
566 * glLinkProgram is called again.
567 */
568 }
569
570
571 static GLuint
572 _mesa_create_shader(GLcontext *ctx, GLenum type)
573 {
574 struct gl_shader *sh;
575 GLuint name;
576
577 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
578
579 switch (type) {
580 case GL_FRAGMENT_SHADER:
581 case GL_VERTEX_SHADER:
582 sh = _mesa_new_shader(ctx, name, type);
583 break;
584 default:
585 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
586 return 0;
587 }
588
589 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
590
591 return name;
592 }
593
594
595 static GLuint
596 _mesa_create_program(GLcontext *ctx)
597 {
598 GLuint name;
599 struct gl_shader_program *shProg;
600
601 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
602 shProg = _mesa_new_shader_program(ctx, name);
603
604 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
605
606 assert(shProg->RefCount == 1);
607
608 return name;
609 }
610
611
612 /**
613 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
614 * DeleteProgramARB.
615 */
616 static void
617 _mesa_delete_program2(GLcontext *ctx, GLuint name)
618 {
619 /*
620 * NOTE: deleting shaders/programs works a bit differently than
621 * texture objects (and buffer objects, etc). Shader/program
622 * handles/IDs exist in the hash table until the object is really
623 * deleted (refcount==0). With texture objects, the handle/ID is
624 * removed from the hash table in glDeleteTextures() while the tex
625 * object itself might linger until its refcount goes to zero.
626 */
627 struct gl_shader_program *shProg;
628
629 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
630 if (!shProg)
631 return;
632
633 shProg->DeletePending = GL_TRUE;
634
635 /* effectively, decr shProg's refcount */
636 _mesa_reference_shader_program(ctx, &shProg, NULL);
637 }
638
639
640 static void
641 _mesa_delete_shader(GLcontext *ctx, GLuint shader)
642 {
643 struct gl_shader *sh;
644
645 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
646 if (!sh)
647 return;
648
649 sh->DeletePending = GL_TRUE;
650
651 /* effectively, decr sh's refcount */
652 _mesa_reference_shader(ctx, &sh, NULL);
653 }
654
655
656 static void
657 _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
658 {
659 struct gl_shader_program *shProg;
660 GLuint n;
661 GLuint i, j;
662
663 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
664 if (!shProg)
665 return;
666
667 n = shProg->NumShaders;
668
669 for (i = 0; i < n; i++) {
670 if (shProg->Shaders[i]->Name == shader) {
671 /* found it */
672 struct gl_shader **newList;
673
674 /* release */
675 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
676
677 /* alloc new, smaller array */
678 newList = (struct gl_shader **)
679 _mesa_malloc((n - 1) * sizeof(struct gl_shader *));
680 if (!newList) {
681 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
682 return;
683 }
684 for (j = 0; j < i; j++) {
685 newList[j] = shProg->Shaders[j];
686 }
687 while (++i < n)
688 newList[j++] = shProg->Shaders[i];
689 _mesa_free(shProg->Shaders);
690
691 shProg->Shaders = newList;
692 shProg->NumShaders = n - 1;
693
694 #ifdef DEBUG
695 /* sanity check */
696 {
697 for (j = 0; j < shProg->NumShaders; j++) {
698 assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
699 shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
700 assert(shProg->Shaders[j]->RefCount > 0);
701 }
702 }
703 #endif
704
705 return;
706 }
707 }
708
709 /* not found */
710 {
711 GLenum err;
712 if (_mesa_is_shader(ctx, shader))
713 err = GL_INVALID_OPERATION;
714 else if (_mesa_is_program(ctx, shader))
715 err = GL_INVALID_OPERATION;
716 else
717 err = GL_INVALID_VALUE;
718 _mesa_error(ctx, err, "glDetachProgram(shader)");
719 return;
720 }
721 }
722
723
724 static GLint
725 sizeof_glsl_type(GLenum type)
726 {
727 switch (type) {
728 case GL_FLOAT:
729 case GL_INT:
730 case GL_BOOL:
731 case GL_SAMPLER_1D:
732 case GL_SAMPLER_2D:
733 case GL_SAMPLER_3D:
734 case GL_SAMPLER_CUBE:
735 case GL_SAMPLER_1D_SHADOW:
736 case GL_SAMPLER_2D_SHADOW:
737 case GL_SAMPLER_2D_RECT_ARB:
738 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
739 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
740 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
741 case GL_SAMPLER_CUBE_SHADOW_EXT:
742 return 1;
743 case GL_FLOAT_VEC2:
744 case GL_INT_VEC2:
745 case GL_BOOL_VEC2:
746 return 2;
747 case GL_FLOAT_VEC3:
748 case GL_INT_VEC3:
749 case GL_BOOL_VEC3:
750 return 3;
751 case GL_FLOAT_VEC4:
752 case GL_INT_VEC4:
753 case GL_BOOL_VEC4:
754 return 4;
755 case GL_FLOAT_MAT2:
756 case GL_FLOAT_MAT2x3:
757 case GL_FLOAT_MAT2x4:
758 return 8; /* two float[4] vectors */
759 case GL_FLOAT_MAT3:
760 case GL_FLOAT_MAT3x2:
761 case GL_FLOAT_MAT3x4:
762 return 12; /* three float[4] vectors */
763 case GL_FLOAT_MAT4:
764 case GL_FLOAT_MAT4x2:
765 case GL_FLOAT_MAT4x3:
766 return 16; /* four float[4] vectors */
767 default:
768 _mesa_problem(NULL, "Invalid type in sizeof_glsl_type()");
769 return 1;
770 }
771 }
772
773
774 static GLboolean
775 is_boolean_type(GLenum type)
776 {
777 switch (type) {
778 case GL_BOOL:
779 case GL_BOOL_VEC2:
780 case GL_BOOL_VEC3:
781 case GL_BOOL_VEC4:
782 return GL_TRUE;
783 default:
784 return GL_FALSE;
785 }
786 }
787
788
789 static GLboolean
790 is_integer_type(GLenum type)
791 {
792 switch (type) {
793 case GL_INT:
794 case GL_INT_VEC2:
795 case GL_INT_VEC3:
796 case GL_INT_VEC4:
797 return GL_TRUE;
798 default:
799 return GL_FALSE;
800 }
801 }
802
803
804 static void
805 _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
806 GLsizei maxLength, GLsizei *length, GLint *size,
807 GLenum *type, GLchar *nameOut)
808 {
809 const struct gl_program_parameter_list *attribs = NULL;
810 struct gl_shader_program *shProg;
811
812 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
813 if (!shProg)
814 return;
815
816 if (shProg->VertexProgram)
817 attribs = shProg->VertexProgram->Base.Attributes;
818
819 if (!attribs || index >= attribs->NumParameters) {
820 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
821 return;
822 }
823
824 copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name);
825
826 if (size)
827 *size = attribs->Parameters[index].Size
828 / sizeof_glsl_type(attribs->Parameters[index].DataType);
829
830 if (type)
831 *type = attribs->Parameters[index].DataType;
832 }
833
834
835 static struct gl_program_parameter *
836 get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
837 {
838 const struct gl_program *prog;
839 GLint progPos;
840
841 progPos = shProg->Uniforms->Uniforms[index].VertPos;
842 if (progPos >= 0) {
843 prog = &shProg->VertexProgram->Base;
844 }
845 else {
846 progPos = shProg->Uniforms->Uniforms[index].FragPos;
847 if (progPos >= 0) {
848 prog = &shProg->FragmentProgram->Base;
849 }
850 }
851
852 if (!prog || progPos < 0)
853 return NULL; /* should never happen */
854
855 return &prog->Parameters->Parameters[progPos];
856 }
857
858
859 /**
860 * Called via ctx->Driver.GetActiveUniform().
861 */
862 static void
863 _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
864 GLsizei maxLength, GLsizei *length, GLint *size,
865 GLenum *type, GLchar *nameOut)
866 {
867 const struct gl_shader_program *shProg;
868 const struct gl_program *prog;
869 GLint progPos;
870
871 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
872 if (!shProg)
873 return;
874
875 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
876 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
877 return;
878 }
879
880 progPos = shProg->Uniforms->Uniforms[index].VertPos;
881 if (progPos >= 0) {
882 prog = &shProg->VertexProgram->Base;
883 }
884 else {
885 progPos = shProg->Uniforms->Uniforms[index].FragPos;
886 if (progPos >= 0) {
887 prog = &shProg->FragmentProgram->Base;
888 }
889 }
890
891 if (!prog || progPos < 0)
892 return; /* should never happen */
893
894 if (nameOut)
895 copy_string(nameOut, maxLength, length,
896 prog->Parameters->Parameters[progPos].Name);
897 if (size)
898 *size = prog->Parameters->Parameters[progPos].Size
899 / sizeof_glsl_type(prog->Parameters->Parameters[progPos].DataType);
900 if (type)
901 *type = prog->Parameters->Parameters[progPos].DataType;
902 }
903
904
905 /**
906 * Called via ctx->Driver.GetAttachedShaders().
907 */
908 static void
909 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
910 GLsizei *count, GLuint *obj)
911 {
912 struct gl_shader_program *shProg =
913 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
914 if (shProg) {
915 GLuint i;
916 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
917 obj[i] = shProg->Shaders[i]->Name;
918 }
919 if (count)
920 *count = i;
921 }
922 }
923
924
925 static GLuint
926 _mesa_get_handle(GLcontext *ctx, GLenum pname)
927 {
928 GLint handle = 0;
929
930 if (pname == GL_PROGRAM_OBJECT_ARB) {
931 CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
932 } else {
933 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
934 }
935
936 return handle;
937 }
938
939
940 static void
941 _mesa_get_programiv(GLcontext *ctx, GLuint program,
942 GLenum pname, GLint *params)
943 {
944 const struct gl_program_parameter_list *attribs;
945 struct gl_shader_program *shProg
946 = _mesa_lookup_shader_program(ctx, program);
947
948 if (!shProg) {
949 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
950 return;
951 }
952
953 if (shProg->VertexProgram)
954 attribs = shProg->VertexProgram->Base.Attributes;
955 else
956 attribs = NULL;
957
958 switch (pname) {
959 case GL_DELETE_STATUS:
960 *params = shProg->DeletePending;
961 break;
962 case GL_LINK_STATUS:
963 *params = shProg->LinkStatus;
964 break;
965 case GL_VALIDATE_STATUS:
966 *params = shProg->Validated;
967 break;
968 case GL_INFO_LOG_LENGTH:
969 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
970 break;
971 case GL_ATTACHED_SHADERS:
972 *params = shProg->NumShaders;
973 break;
974 case GL_ACTIVE_ATTRIBUTES:
975 *params = attribs ? attribs->NumParameters : 0;
976 break;
977 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
978 *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
979 break;
980 case GL_ACTIVE_UNIFORMS:
981 *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
982 break;
983 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
984 *params = _mesa_longest_uniform_name(shProg->Uniforms);
985 if (*params > 0)
986 (*params)++; /* add one for terminating zero */
987 break;
988 case GL_PROGRAM_BINARY_LENGTH_OES:
989 *params = 0;
990 break;
991 default:
992 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
993 return;
994 }
995 }
996
997
998 static void
999 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
1000 {
1001 struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
1002
1003 if (!shader) {
1004 return;
1005 }
1006
1007 switch (pname) {
1008 case GL_SHADER_TYPE:
1009 *params = shader->Type;
1010 break;
1011 case GL_DELETE_STATUS:
1012 *params = shader->DeletePending;
1013 break;
1014 case GL_COMPILE_STATUS:
1015 *params = shader->CompileStatus;
1016 break;
1017 case GL_INFO_LOG_LENGTH:
1018 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
1019 break;
1020 case GL_SHADER_SOURCE_LENGTH:
1021 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1022 break;
1023 default:
1024 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1025 return;
1026 }
1027 }
1028
1029
1030 static void
1031 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
1032 GLsizei *length, GLchar *infoLog)
1033 {
1034 struct gl_shader_program *shProg
1035 = _mesa_lookup_shader_program(ctx, program);
1036 if (!shProg) {
1037 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
1038 return;
1039 }
1040 copy_string(infoLog, bufSize, length, shProg->InfoLog);
1041 }
1042
1043
1044 static void
1045 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
1046 GLsizei *length, GLchar *infoLog)
1047 {
1048 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
1049 if (!sh) {
1050 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
1051 return;
1052 }
1053 copy_string(infoLog, bufSize, length, sh->InfoLog);
1054 }
1055
1056
1057 /**
1058 * Called via ctx->Driver.GetShaderSource().
1059 */
1060 static void
1061 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
1062 GLsizei *length, GLchar *sourceOut)
1063 {
1064 struct gl_shader *sh;
1065 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1066 if (!sh) {
1067 return;
1068 }
1069 copy_string(sourceOut, maxLength, length, sh->Source);
1070 }
1071
1072
1073 static void
1074 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
1075 {
1076 switch (type) {
1077 case GL_FLOAT_MAT2:
1078 *rows = *cols = 2;
1079 break;
1080 case GL_FLOAT_MAT2x3:
1081 *rows = 3;
1082 *cols = 2;
1083 break;
1084 case GL_FLOAT_MAT2x4:
1085 *rows = 4;
1086 *cols = 2;
1087 break;
1088 case GL_FLOAT_MAT3:
1089 *rows = 3;
1090 *cols = 3;
1091 break;
1092 case GL_FLOAT_MAT3x2:
1093 *rows = 2;
1094 *cols = 3;
1095 break;
1096 case GL_FLOAT_MAT3x4:
1097 *rows = 4;
1098 *cols = 3;
1099 break;
1100 case GL_FLOAT_MAT4:
1101 *rows = 4;
1102 *cols = 4;
1103 break;
1104 case GL_FLOAT_MAT4x2:
1105 *rows = 2;
1106 *cols = 4;
1107 break;
1108 case GL_FLOAT_MAT4x3:
1109 *rows = 3;
1110 *cols = 4;
1111 break;
1112 default:
1113 *rows = *cols = 0;
1114 }
1115 }
1116
1117
1118 /**
1119 * Determine the number of rows and columns occupied by a uniform
1120 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1121 * the number of rows = 1 and cols = number of elements in the vector.
1122 */
1123 static void
1124 get_uniform_rows_cols(const struct gl_program_parameter *p,
1125 GLint *rows, GLint *cols)
1126 {
1127 get_matrix_dims(p->DataType, rows, cols);
1128 if (*rows == 0 && *cols == 0) {
1129 /* not a matrix type, probably a float or vector */
1130 if (p->Size <= 4) {
1131 *rows = 1;
1132 *cols = p->Size;
1133 }
1134 else {
1135 *rows = p->Size / 4 + 1;
1136 if (p->Size % 4 == 0)
1137 *cols = 4;
1138 else
1139 *cols = p->Size % 4;
1140 }
1141 }
1142 }
1143
1144
1145 #define MAX_UNIFORM_ELEMENTS 16
1146
1147 /**
1148 * Helper for GetUniformfv(), GetUniformiv()
1149 * Returns number of elements written to 'params' output.
1150 */
1151 static GLuint
1152 get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1153 GLfloat *params)
1154 {
1155 struct gl_shader_program *shProg
1156 = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
1157 if (shProg) {
1158 if (shProg->Uniforms &&
1159 location >= 0 && location < (GLint) shProg->Uniforms->NumUniforms) {
1160 GLint progPos;
1161 const struct gl_program *prog = NULL;
1162
1163 progPos = shProg->Uniforms->Uniforms[location].VertPos;
1164 if (progPos >= 0) {
1165 prog = &shProg->VertexProgram->Base;
1166 }
1167 else {
1168 progPos = shProg->Uniforms->Uniforms[location].FragPos;
1169 if (progPos >= 0) {
1170 prog = &shProg->FragmentProgram->Base;
1171 }
1172 }
1173
1174 ASSERT(prog);
1175 if (prog) {
1176 const struct gl_program_parameter *p =
1177 &prog->Parameters->Parameters[progPos];
1178 GLint rows, cols, i, j, k;
1179
1180 /* See uniformiv() below */
1181 assert(p->Size <= MAX_UNIFORM_ELEMENTS);
1182
1183 get_uniform_rows_cols(p, &rows, &cols);
1184
1185 k = 0;
1186 for (i = 0; i < rows; i++) {
1187 for (j = 0; j < cols; j++ ) {
1188 params[k++] = prog->Parameters->ParameterValues[progPos+i][j];
1189 }
1190 }
1191
1192 return p->Size;
1193 }
1194 }
1195 else {
1196 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
1197 }
1198 }
1199 return 0;
1200 }
1201
1202
1203 /**
1204 * Called via ctx->Driver.GetUniformfv().
1205 */
1206 static void
1207 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1208 GLfloat *params)
1209 {
1210 (void) get_uniformfv(ctx, program, location, params);
1211 }
1212
1213
1214 /**
1215 * Called via ctx->Driver.GetUniformiv().
1216 */
1217 static void
1218 _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
1219 GLint *params)
1220 {
1221 GLfloat fparams[MAX_UNIFORM_ELEMENTS];
1222 GLuint n = get_uniformfv(ctx, program, location, fparams);
1223 GLuint i;
1224 assert(n <= MAX_UNIFORM_ELEMENTS);
1225 for (i = 0; i < n; i++) {
1226 params[i] = (GLint) fparams[i];
1227 }
1228 }
1229
1230
1231 /**
1232 * The value returned by GetUniformLocation actually encodes two things:
1233 * 1. the index into the prog->Uniforms[] array for the uniform
1234 * 2. an offset in the prog->ParameterValues[] array for specifying array
1235 * elements or structure fields.
1236 * This function merges those two values.
1237 */
1238 static void
1239 merge_location_offset(GLint *location, GLint offset)
1240 {
1241 *location = *location | (offset << 16);
1242 }
1243
1244
1245 /**
1246 * Seperate the uniform location and parameter offset. See above.
1247 */
1248 static void
1249 split_location_offset(GLint *location, GLint *offset)
1250 {
1251 *offset = (*location >> 16);
1252 *location = *location & 0xffff;
1253 }
1254
1255
1256 /**
1257 * Called via ctx->Driver.GetUniformLocation().
1258 *
1259 * The return value will encode two values, the uniform location and an
1260 * offset (used for arrays, structs).
1261 */
1262 static GLint
1263 _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
1264 {
1265 GLint offset = 0, location = -1;
1266
1267 struct gl_shader_program *shProg =
1268 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
1269
1270 if (!shProg)
1271 return -1;
1272
1273 if (shProg->LinkStatus == GL_FALSE) {
1274 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1275 return -1;
1276 }
1277
1278 /* XXX we should return -1 if the uniform was declared, but not
1279 * actually used.
1280 */
1281
1282 /* XXX we need to be able to parse uniform names for structs and arrays
1283 * such as:
1284 * mymatrix[1]
1285 * mystruct.field1
1286 */
1287
1288 {
1289 /* handle 1-dimension arrays here... */
1290 char *c = strchr(name, '[');
1291 if (c) {
1292 /* truncate name at [ */
1293 const GLint len = c - name;
1294 GLchar *newName = _mesa_malloc(len + 1);
1295 if (!newName)
1296 return -1; /* out of mem */
1297 _mesa_memcpy(newName, name, len);
1298 newName[len] = 0;
1299
1300 location = _mesa_lookup_uniform(shProg->Uniforms, newName);
1301 if (location >= 0) {
1302 const GLint element = _mesa_atoi(c + 1);
1303 if (element > 0) {
1304 /* get type of the uniform array element */
1305 struct gl_program_parameter *p;
1306 p = get_uniform_parameter(shProg, location);
1307 if (p) {
1308 GLint rows, cols;
1309 get_matrix_dims(p->DataType, &rows, &cols);
1310 if (rows < 1)
1311 rows = 1;
1312 offset = element * rows;
1313 }
1314 }
1315 }
1316
1317 _mesa_free(newName);
1318 }
1319 }
1320
1321 if (location < 0) {
1322 location = _mesa_lookup_uniform(shProg->Uniforms, name);
1323 }
1324
1325 if (location >= 0) {
1326 merge_location_offset(&location, offset);
1327 }
1328
1329 return location;
1330 }
1331
1332
1333
1334 /**
1335 * Called via ctx->Driver.ShaderSource()
1336 */
1337 static void
1338 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1339 {
1340 struct gl_shader *sh;
1341
1342 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1343 if (!sh)
1344 return;
1345
1346 /* free old shader source string and install new one */
1347 if (sh->Source) {
1348 _mesa_free((void *) sh->Source);
1349 }
1350 sh->Source = source;
1351 sh->CompileStatus = GL_FALSE;
1352 }
1353
1354
1355 /**
1356 * Called via ctx->Driver.CompileShader()
1357 */
1358 static void
1359 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1360 {
1361 struct gl_shader *sh;
1362
1363 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1364 if (!sh)
1365 return;
1366
1367 sh->CompileStatus = _slang_compile(ctx, sh);
1368 }
1369
1370
1371 /**
1372 * Called via ctx->Driver.LinkProgram()
1373 */
1374 static void
1375 _mesa_link_program(GLcontext *ctx, GLuint program)
1376 {
1377 struct gl_shader_program *shProg;
1378
1379 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1380 if (!shProg)
1381 return;
1382
1383 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1384
1385 _slang_link(ctx, program, shProg);
1386 }
1387
1388
1389 /**
1390 * Called via ctx->Driver.UseProgram()
1391 */
1392 void
1393 _mesa_use_program(GLcontext *ctx, GLuint program)
1394 {
1395 struct gl_shader_program *shProg;
1396
1397 if (ctx->Shader.CurrentProgram &&
1398 ctx->Shader.CurrentProgram->Name == program) {
1399 /* no-op */
1400 return;
1401 }
1402
1403 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1404
1405 if (program) {
1406 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1407 if (!shProg) {
1408 return;
1409 }
1410 if (!shProg->LinkStatus) {
1411 _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgram");
1412 return;
1413 }
1414 }
1415 else {
1416 shProg = NULL;
1417 }
1418
1419 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1420 }
1421
1422
1423
1424 /**
1425 * Update the vertex/fragment program's TexturesUsed array.
1426 *
1427 * This needs to be called after glUniform(set sampler var) is called.
1428 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1429 * particular texture unit. We know the sampler's texture target
1430 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1431 * set by glUniform() calls.
1432 *
1433 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1434 * information to update the prog->TexturesUsed[] values.
1435 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1436 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1437 * We'll use that info for state validation before rendering.
1438 */
1439 void
1440 _mesa_update_shader_textures_used(struct gl_program *prog)
1441 {
1442 GLuint s;
1443
1444 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1445
1446 for (s = 0; s < MAX_SAMPLERS; s++) {
1447 if (prog->SamplersUsed & (1 << s)) {
1448 GLuint u = prog->SamplerUnits[s];
1449 GLuint t = prog->SamplerTargets[s];
1450 assert(u < MAX_TEXTURE_IMAGE_UNITS);
1451 prog->TexturesUsed[u] |= (1 << t);
1452 }
1453 }
1454 }
1455
1456
1457 static GLboolean
1458 is_sampler_type(GLenum type)
1459 {
1460 switch (type) {
1461 case GL_SAMPLER_1D:
1462 case GL_SAMPLER_2D:
1463 case GL_SAMPLER_3D:
1464 case GL_SAMPLER_CUBE:
1465 case GL_SAMPLER_1D_SHADOW:
1466 case GL_SAMPLER_2D_SHADOW:
1467 case GL_SAMPLER_2D_RECT_ARB:
1468 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
1469 case GL_SAMPLER_1D_ARRAY_EXT:
1470 case GL_SAMPLER_2D_ARRAY_EXT:
1471 return GL_TRUE;
1472 default:
1473 return GL_FALSE;
1474 }
1475 }
1476
1477
1478 /**
1479 * Check if the type given by userType is allowed to set a uniform of the
1480 * target type. Generally, equivalence is required, but setting Boolean
1481 * uniforms can be done with glUniformiv or glUniformfv.
1482 */
1483 static GLboolean
1484 compatible_types(GLenum userType, GLenum targetType)
1485 {
1486 if (userType == targetType)
1487 return GL_TRUE;
1488
1489 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1490 return GL_TRUE;
1491
1492 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1493 userType == GL_INT_VEC2))
1494 return GL_TRUE;
1495
1496 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1497 userType == GL_INT_VEC3))
1498 return GL_TRUE;
1499
1500 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1501 userType == GL_INT_VEC4))
1502 return GL_TRUE;
1503
1504 if (is_sampler_type(targetType) && userType == GL_INT)
1505 return GL_TRUE;
1506
1507 return GL_FALSE;
1508 }
1509
1510
1511 /**
1512 * Set the value of a program's uniform variable.
1513 * \param program the program whose uniform to update
1514 * \param index the index of the program parameter for the uniform
1515 * \param offset additional parameter slot offset (for arrays)
1516 * \param type the datatype of the uniform
1517 * \param count the number of uniforms to set
1518 * \param elems number of elements per uniform
1519 * \param values the new values
1520 */
1521 static void
1522 set_program_uniform(GLcontext *ctx, struct gl_program *program,
1523 GLint index, GLint offset,
1524 GLenum type, GLsizei count, GLint elems,
1525 const void *values)
1526 {
1527 struct gl_program_parameter *param =
1528 &program->Parameters->Parameters[index];
1529
1530 assert(offset >= 0);
1531
1532 if (!compatible_types(type, param->DataType)) {
1533 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1534 return;
1535 }
1536
1537 if (index + offset > (GLint) program->Parameters->Size) {
1538 /* out of bounds! */
1539 return;
1540 }
1541
1542 if (param->Type == PROGRAM_SAMPLER) {
1543 /* This controls which texture unit which is used by a sampler */
1544 GLuint texUnit, sampler;
1545
1546 /* data type for setting samplers must be int */
1547 if (type != GL_INT || count != 1) {
1548 _mesa_error(ctx, GL_INVALID_OPERATION,
1549 "glUniform(only glUniform1i can be used "
1550 "to set sampler uniforms)");
1551 return;
1552 }
1553
1554 sampler = (GLuint) program->Parameters->ParameterValues[index][0];
1555 texUnit = ((GLuint *) values)[0];
1556
1557 /* check that the sampler (tex unit index) is legal */
1558 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1559 _mesa_error(ctx, GL_INVALID_VALUE,
1560 "glUniform1(invalid sampler/tex unit index)");
1561 return;
1562 }
1563
1564 /* This maps a sampler to a texture unit: */
1565 program->SamplerUnits[sampler] = texUnit;
1566 _mesa_update_shader_textures_used(program);
1567
1568 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1569 }
1570 else {
1571 /* ordinary uniform variable */
1572 GLsizei k, i;
1573 GLint slots = (param->Size + 3) / 4;
1574
1575 if (count * elems > (GLint) param->Size) {
1576 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)");
1577 return;
1578 }
1579
1580 if (count > slots)
1581 count = slots;
1582
1583 for (k = 0; k < count; k++) {
1584 GLfloat *uniformVal =
1585 program->Parameters->ParameterValues[index + offset + k];
1586 if (is_integer_type(type)) {
1587 const GLint *iValues = ((const GLint *) values) + k * elems;
1588 for (i = 0; i < elems; i++) {
1589 uniformVal[i] = (GLfloat) iValues[i];
1590 }
1591 }
1592 else {
1593 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1594 for (i = 0; i < elems; i++) {
1595 uniformVal[i] = fValues[i];
1596 }
1597 }
1598
1599 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1600 if (is_boolean_type(param->DataType)) {
1601 for (i = 0; i < elems; i++) {
1602 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1603 }
1604 }
1605 }
1606 }
1607 }
1608
1609
1610 /**
1611 * Called via ctx->Driver.Uniform().
1612 */
1613 static void
1614 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1615 const GLvoid *values, GLenum type)
1616 {
1617 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1618 struct gl_uniform *uniform;
1619 GLint elems, offset;
1620
1621 if (!shProg || !shProg->LinkStatus) {
1622 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1623 return;
1624 }
1625
1626 if (location == -1)
1627 return; /* The standard specifies this as a no-op */
1628
1629 split_location_offset(&location, &offset);
1630
1631 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1632 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1633 return;
1634 }
1635
1636 if (count < 0) {
1637 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1638 return;
1639 }
1640
1641 switch (type) {
1642 case GL_FLOAT:
1643 case GL_INT:
1644 elems = 1;
1645 break;
1646 case GL_FLOAT_VEC2:
1647 case GL_INT_VEC2:
1648 elems = 2;
1649 break;
1650 case GL_FLOAT_VEC3:
1651 case GL_INT_VEC3:
1652 elems = 3;
1653 break;
1654 case GL_FLOAT_VEC4:
1655 case GL_INT_VEC4:
1656 elems = 4;
1657 break;
1658 default:
1659 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1660 return;
1661 }
1662
1663 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1664
1665 uniform = &shProg->Uniforms->Uniforms[location];
1666
1667 /* A uniform var may be used by both a vertex shader and a fragment
1668 * shader. We may need to update one or both shader's uniform here:
1669 */
1670 if (shProg->VertexProgram) {
1671 /* convert uniform location to program parameter index */
1672 GLint index = uniform->VertPos;
1673 if (index >= 0) {
1674 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1675 index, offset, type, count, elems, values);
1676 }
1677 }
1678
1679 if (shProg->FragmentProgram) {
1680 /* convert uniform location to program parameter index */
1681 GLint index = uniform->FragPos;
1682 if (index >= 0) {
1683 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1684 index, offset, type, count, elems, values);
1685 }
1686 }
1687
1688 uniform->Initialized = GL_TRUE;
1689 }
1690
1691
1692 /**
1693 * Set a matrix-valued program parameter.
1694 */
1695 static void
1696 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1697 GLuint index, GLuint offset,
1698 GLuint count, GLuint rows, GLuint cols,
1699 GLboolean transpose, const GLfloat *values)
1700 {
1701 GLuint mat, row, col;
1702 GLuint dst = index + offset, src = 0;
1703 GLint nr, nc;
1704
1705 /* check that the number of rows, columns is correct */
1706 get_matrix_dims(program->Parameters->Parameters[index].DataType, &nr, &nc);
1707 if (rows != nr || cols != nc) {
1708 _mesa_error(ctx, GL_INVALID_OPERATION,
1709 "glUniformMatrix(matrix size mismatch)");
1710 return;
1711 }
1712
1713 if (index + offset > program->Parameters->Size) {
1714 /* out of bounds! */
1715 return;
1716 }
1717
1718 /*
1719 * Note: the _columns_ of a matrix are stored in program registers, not
1720 * the rows. So, the loops below look a little funny.
1721 * XXX could optimize this a bit...
1722 */
1723
1724 /* loop over matrices */
1725 for (mat = 0; mat < count; mat++) {
1726
1727 /* each matrix: */
1728 for (col = 0; col < cols; col++) {
1729 GLfloat *v = program->Parameters->ParameterValues[dst];
1730 for (row = 0; row < rows; row++) {
1731 if (transpose) {
1732 v[row] = values[src + row * cols + col];
1733 }
1734 else {
1735 v[row] = values[src + col * rows + row];
1736 }
1737 }
1738 dst++;
1739 }
1740
1741 src += rows * cols; /* next matrix */
1742 }
1743 }
1744
1745
1746 /**
1747 * Called by ctx->Driver.UniformMatrix().
1748 * Note: cols=2, rows=4 ==> array[2] of vec4
1749 */
1750 static void
1751 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1752 GLenum matrixType, GLint location, GLsizei count,
1753 GLboolean transpose, const GLfloat *values)
1754 {
1755 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1756 struct gl_uniform *uniform;
1757 GLint offset;
1758
1759 if (!shProg || !shProg->LinkStatus) {
1760 _mesa_error(ctx, GL_INVALID_OPERATION,
1761 "glUniformMatrix(program not linked)");
1762 return;
1763 }
1764
1765 if (location == -1)
1766 return; /* The standard specifies this as a no-op */
1767
1768 split_location_offset(&location, &offset);
1769
1770 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1771 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
1772 return;
1773 }
1774 if (values == NULL) {
1775 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
1776 return;
1777 }
1778
1779 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1780
1781 uniform = &shProg->Uniforms->Uniforms[location];
1782
1783 if (shProg->VertexProgram) {
1784 /* convert uniform location to program parameter index */
1785 GLint index = uniform->VertPos;
1786 if (index >= 0) {
1787 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
1788 index, offset,
1789 count, rows, cols, transpose, values);
1790 }
1791 }
1792
1793 if (shProg->FragmentProgram) {
1794 /* convert uniform location to program parameter index */
1795 GLint index = uniform->FragPos;
1796 if (index >= 0) {
1797 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
1798 index, offset,
1799 count, rows, cols, transpose, values);
1800 }
1801 }
1802
1803 uniform->Initialized = GL_TRUE;
1804 }
1805
1806
1807 static void
1808 _mesa_validate_program(GLcontext *ctx, GLuint program)
1809 {
1810 struct gl_shader_program *shProg;
1811
1812 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1813 if (!shProg) {
1814 return;
1815 }
1816
1817 if (!shProg->LinkStatus) {
1818 shProg->Validated = GL_FALSE;
1819 return;
1820 }
1821
1822 /* From the GL spec, a program is invalid if any of these are true:
1823
1824 any two active samplers in the current program object are of
1825 different types, but refer to the same texture image unit,
1826
1827 any active sampler in the current program object refers to a texture
1828 image unit where fixed-function fragment processing accesses a
1829 texture target that does not match the sampler type, or
1830
1831 the sum of the number of active samplers in the program and the
1832 number of texture image units enabled for fixed-function fragment
1833 processing exceeds the combined limit on the total number of texture
1834 image units allowed.
1835 */
1836
1837 shProg->Validated = GL_TRUE;
1838 }
1839
1840
1841 /**
1842 * Plug in Mesa's GLSL functions into the device driver function table.
1843 */
1844 void
1845 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
1846 {
1847 driver->AttachShader = _mesa_attach_shader;
1848 driver->BindAttribLocation = _mesa_bind_attrib_location;
1849 driver->CompileShader = _mesa_compile_shader;
1850 driver->CreateProgram = _mesa_create_program;
1851 driver->CreateShader = _mesa_create_shader;
1852 driver->DeleteProgram2 = _mesa_delete_program2;
1853 driver->DeleteShader = _mesa_delete_shader;
1854 driver->DetachShader = _mesa_detach_shader;
1855 driver->GetActiveAttrib = _mesa_get_active_attrib;
1856 driver->GetActiveUniform = _mesa_get_active_uniform;
1857 driver->GetAttachedShaders = _mesa_get_attached_shaders;
1858 driver->GetAttribLocation = _mesa_get_attrib_location;
1859 driver->GetHandle = _mesa_get_handle;
1860 driver->GetProgramiv = _mesa_get_programiv;
1861 driver->GetProgramInfoLog = _mesa_get_program_info_log;
1862 driver->GetShaderiv = _mesa_get_shaderiv;
1863 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
1864 driver->GetShaderSource = _mesa_get_shader_source;
1865 driver->GetUniformfv = _mesa_get_uniformfv;
1866 driver->GetUniformiv = _mesa_get_uniformiv;
1867 driver->GetUniformLocation = _mesa_get_uniform_location;
1868 driver->IsProgram = _mesa_is_program;
1869 driver->IsShader = _mesa_is_shader;
1870 driver->LinkProgram = _mesa_link_program;
1871 driver->ShaderSource = _mesa_shader_source;
1872 driver->Uniform = _mesa_uniform;
1873 driver->UniformMatrix = _mesa_uniform_matrix;
1874 driver->UseProgram = _mesa_use_program;
1875 driver->ValidateProgram = _mesa_validate_program;
1876 }