Merge commit 'origin/gallium-master-merge'
[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;/*GL_TRUE;*/ /* XXX probably want 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 GLint progPos;
896
897 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
898 if (!shProg)
899 return;
900
901 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
902 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
903 return;
904 }
905
906 progPos = shProg->Uniforms->Uniforms[index].VertPos;
907 if (progPos >= 0) {
908 prog = &shProg->VertexProgram->Base;
909 }
910 else {
911 progPos = shProg->Uniforms->Uniforms[index].FragPos;
912 if (progPos >= 0) {
913 prog = &shProg->FragmentProgram->Base;
914 }
915 }
916
917 if (!prog || progPos < 0)
918 return; /* should never happen */
919
920 if (nameOut)
921 copy_string(nameOut, maxLength, length,
922 prog->Parameters->Parameters[progPos].Name);
923 if (size)
924 *size = prog->Parameters->Parameters[progPos].Size
925 / sizeof_glsl_type(prog->Parameters->Parameters[progPos].DataType);
926 if (type)
927 *type = prog->Parameters->Parameters[progPos].DataType;
928 }
929
930
931 /**
932 * Called via ctx->Driver.GetAttachedShaders().
933 */
934 static void
935 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
936 GLsizei *count, GLuint *obj)
937 {
938 struct gl_shader_program *shProg =
939 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
940 if (shProg) {
941 GLuint i;
942 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
943 obj[i] = shProg->Shaders[i]->Name;
944 }
945 if (count)
946 *count = i;
947 }
948 }
949
950
951 static GLuint
952 _mesa_get_handle(GLcontext *ctx, GLenum pname)
953 {
954 GLint handle = 0;
955
956 if (pname == GL_PROGRAM_OBJECT_ARB) {
957 CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
958 } else {
959 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
960 }
961
962 return handle;
963 }
964
965
966 static void
967 _mesa_get_programiv(GLcontext *ctx, GLuint program,
968 GLenum pname, GLint *params)
969 {
970 const struct gl_program_parameter_list *attribs;
971 struct gl_shader_program *shProg
972 = _mesa_lookup_shader_program(ctx, program);
973
974 if (!shProg) {
975 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
976 return;
977 }
978
979 if (shProg->VertexProgram)
980 attribs = shProg->VertexProgram->Base.Attributes;
981 else
982 attribs = NULL;
983
984 switch (pname) {
985 case GL_DELETE_STATUS:
986 *params = shProg->DeletePending;
987 break;
988 case GL_LINK_STATUS:
989 *params = shProg->LinkStatus;
990 break;
991 case GL_VALIDATE_STATUS:
992 *params = shProg->Validated;
993 break;
994 case GL_INFO_LOG_LENGTH:
995 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
996 break;
997 case GL_ATTACHED_SHADERS:
998 *params = shProg->NumShaders;
999 break;
1000 case GL_ACTIVE_ATTRIBUTES:
1001 *params = attribs ? attribs->NumParameters : 0;
1002 break;
1003 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1004 *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
1005 break;
1006 case GL_ACTIVE_UNIFORMS:
1007 *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
1008 break;
1009 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1010 *params = _mesa_longest_uniform_name(shProg->Uniforms);
1011 if (*params > 0)
1012 (*params)++; /* add one for terminating zero */
1013 break;
1014 case GL_PROGRAM_BINARY_LENGTH_OES:
1015 *params = 0;
1016 break;
1017 default:
1018 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
1019 return;
1020 }
1021 }
1022
1023
1024 static void
1025 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
1026 {
1027 struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
1028
1029 if (!shader) {
1030 return;
1031 }
1032
1033 switch (pname) {
1034 case GL_SHADER_TYPE:
1035 *params = shader->Type;
1036 break;
1037 case GL_DELETE_STATUS:
1038 *params = shader->DeletePending;
1039 break;
1040 case GL_COMPILE_STATUS:
1041 *params = shader->CompileStatus;
1042 break;
1043 case GL_INFO_LOG_LENGTH:
1044 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
1045 break;
1046 case GL_SHADER_SOURCE_LENGTH:
1047 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1048 break;
1049 default:
1050 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1051 return;
1052 }
1053 }
1054
1055
1056 static void
1057 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
1058 GLsizei *length, GLchar *infoLog)
1059 {
1060 struct gl_shader_program *shProg
1061 = _mesa_lookup_shader_program(ctx, program);
1062 if (!shProg) {
1063 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
1064 return;
1065 }
1066 copy_string(infoLog, bufSize, length, shProg->InfoLog);
1067 }
1068
1069
1070 static void
1071 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
1072 GLsizei *length, GLchar *infoLog)
1073 {
1074 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
1075 if (!sh) {
1076 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
1077 return;
1078 }
1079 copy_string(infoLog, bufSize, length, sh->InfoLog);
1080 }
1081
1082
1083 /**
1084 * Called via ctx->Driver.GetShaderSource().
1085 */
1086 static void
1087 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
1088 GLsizei *length, GLchar *sourceOut)
1089 {
1090 struct gl_shader *sh;
1091 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1092 if (!sh) {
1093 return;
1094 }
1095 copy_string(sourceOut, maxLength, length, sh->Source);
1096 }
1097
1098
1099 static void
1100 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
1101 {
1102 switch (type) {
1103 case GL_FLOAT_MAT2:
1104 *rows = *cols = 2;
1105 break;
1106 case GL_FLOAT_MAT2x3:
1107 *rows = 3;
1108 *cols = 2;
1109 break;
1110 case GL_FLOAT_MAT2x4:
1111 *rows = 4;
1112 *cols = 2;
1113 break;
1114 case GL_FLOAT_MAT3:
1115 *rows = 3;
1116 *cols = 3;
1117 break;
1118 case GL_FLOAT_MAT3x2:
1119 *rows = 2;
1120 *cols = 3;
1121 break;
1122 case GL_FLOAT_MAT3x4:
1123 *rows = 4;
1124 *cols = 3;
1125 break;
1126 case GL_FLOAT_MAT4:
1127 *rows = 4;
1128 *cols = 4;
1129 break;
1130 case GL_FLOAT_MAT4x2:
1131 *rows = 2;
1132 *cols = 4;
1133 break;
1134 case GL_FLOAT_MAT4x3:
1135 *rows = 3;
1136 *cols = 4;
1137 break;
1138 default:
1139 *rows = *cols = 0;
1140 }
1141 }
1142
1143
1144 /**
1145 * Determine the number of rows and columns occupied by a uniform
1146 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1147 * the number of rows = 1 and cols = number of elements in the vector.
1148 */
1149 static void
1150 get_uniform_rows_cols(const struct gl_program_parameter *p,
1151 GLint *rows, GLint *cols)
1152 {
1153 get_matrix_dims(p->DataType, rows, cols);
1154 if (*rows == 0 && *cols == 0) {
1155 /* not a matrix type, probably a float or vector */
1156 if (p->Size <= 4) {
1157 *rows = 1;
1158 *cols = p->Size;
1159 }
1160 else {
1161 *rows = p->Size / 4 + 1;
1162 if (p->Size % 4 == 0)
1163 *cols = 4;
1164 else
1165 *cols = p->Size % 4;
1166 }
1167 }
1168 }
1169
1170
1171 #define MAX_UNIFORM_ELEMENTS 16
1172
1173 /**
1174 * Helper for GetUniformfv(), GetUniformiv()
1175 * Returns number of elements written to 'params' output.
1176 */
1177 static GLuint
1178 get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1179 GLfloat *params)
1180 {
1181 struct gl_shader_program *shProg
1182 = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
1183 if (shProg) {
1184 if (shProg->Uniforms &&
1185 location >= 0 && location < (GLint) shProg->Uniforms->NumUniforms) {
1186 GLint progPos;
1187 const struct gl_program *prog = NULL;
1188
1189 progPos = shProg->Uniforms->Uniforms[location].VertPos;
1190 if (progPos >= 0) {
1191 prog = &shProg->VertexProgram->Base;
1192 }
1193 else {
1194 progPos = shProg->Uniforms->Uniforms[location].FragPos;
1195 if (progPos >= 0) {
1196 prog = &shProg->FragmentProgram->Base;
1197 }
1198 }
1199
1200 ASSERT(prog);
1201 if (prog) {
1202 const struct gl_program_parameter *p =
1203 &prog->Parameters->Parameters[progPos];
1204 GLint rows, cols, i, j, k;
1205
1206 /* See uniformiv() below */
1207 assert(p->Size <= MAX_UNIFORM_ELEMENTS);
1208
1209 get_uniform_rows_cols(p, &rows, &cols);
1210
1211 k = 0;
1212 for (i = 0; i < rows; i++) {
1213 for (j = 0; j < cols; j++ ) {
1214 params[k++] = prog->Parameters->ParameterValues[progPos+i][j];
1215 }
1216 }
1217
1218 return p->Size;
1219 }
1220 }
1221 else {
1222 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
1223 }
1224 }
1225 return 0;
1226 }
1227
1228
1229 /**
1230 * Called via ctx->Driver.GetUniformfv().
1231 */
1232 static void
1233 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1234 GLfloat *params)
1235 {
1236 (void) get_uniformfv(ctx, program, location, params);
1237 }
1238
1239
1240 /**
1241 * Called via ctx->Driver.GetUniformiv().
1242 */
1243 static void
1244 _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
1245 GLint *params)
1246 {
1247 GLfloat fparams[MAX_UNIFORM_ELEMENTS];
1248 GLuint n = get_uniformfv(ctx, program, location, fparams);
1249 GLuint i;
1250 assert(n <= MAX_UNIFORM_ELEMENTS);
1251 for (i = 0; i < n; i++) {
1252 params[i] = (GLint) fparams[i];
1253 }
1254 }
1255
1256
1257 /**
1258 * The value returned by GetUniformLocation actually encodes two things:
1259 * 1. the index into the prog->Uniforms[] array for the uniform
1260 * 2. an offset in the prog->ParameterValues[] array for specifying array
1261 * elements or structure fields.
1262 * This function merges those two values.
1263 */
1264 static void
1265 merge_location_offset(GLint *location, GLint offset)
1266 {
1267 *location = *location | (offset << 16);
1268 }
1269
1270
1271 /**
1272 * Seperate the uniform location and parameter offset. See above.
1273 */
1274 static void
1275 split_location_offset(GLint *location, GLint *offset)
1276 {
1277 *offset = (*location >> 16);
1278 *location = *location & 0xffff;
1279 }
1280
1281
1282 /**
1283 * Called via ctx->Driver.GetUniformLocation().
1284 *
1285 * The return value will encode two values, the uniform location and an
1286 * offset (used for arrays, structs).
1287 */
1288 static GLint
1289 _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
1290 {
1291 GLint offset = 0, location = -1;
1292
1293 struct gl_shader_program *shProg =
1294 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
1295
1296 if (!shProg)
1297 return -1;
1298
1299 if (shProg->LinkStatus == GL_FALSE) {
1300 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1301 return -1;
1302 }
1303
1304 /* XXX we should return -1 if the uniform was declared, but not
1305 * actually used.
1306 */
1307
1308 /* XXX we need to be able to parse uniform names for structs and arrays
1309 * such as:
1310 * mymatrix[1]
1311 * mystruct.field1
1312 */
1313
1314 {
1315 /* handle 1-dimension arrays here... */
1316 char *c = strchr(name, '[');
1317 if (c) {
1318 /* truncate name at [ */
1319 const GLint len = c - name;
1320 GLchar *newName = _mesa_malloc(len + 1);
1321 if (!newName)
1322 return -1; /* out of mem */
1323 _mesa_memcpy(newName, name, len);
1324 newName[len] = 0;
1325
1326 location = _mesa_lookup_uniform(shProg->Uniforms, newName);
1327 if (location >= 0) {
1328 const GLint element = _mesa_atoi(c + 1);
1329 if (element > 0) {
1330 /* get type of the uniform array element */
1331 struct gl_program_parameter *p;
1332 p = get_uniform_parameter(shProg, location);
1333 if (p) {
1334 GLint rows, cols;
1335 get_matrix_dims(p->DataType, &rows, &cols);
1336 if (rows < 1)
1337 rows = 1;
1338 offset = element * rows;
1339 }
1340 }
1341 }
1342
1343 _mesa_free(newName);
1344 }
1345 }
1346
1347 if (location < 0) {
1348 location = _mesa_lookup_uniform(shProg->Uniforms, name);
1349 }
1350
1351 if (location >= 0) {
1352 merge_location_offset(&location, offset);
1353 }
1354
1355 return location;
1356 }
1357
1358
1359
1360 /**
1361 * Called via ctx->Driver.ShaderSource()
1362 */
1363 static void
1364 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1365 {
1366 struct gl_shader *sh;
1367
1368 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1369 if (!sh)
1370 return;
1371
1372 /* free old shader source string and install new one */
1373 if (sh->Source) {
1374 _mesa_free((void *) sh->Source);
1375 }
1376 sh->Source = source;
1377 sh->CompileStatus = GL_FALSE;
1378 }
1379
1380
1381 /**
1382 * Called via ctx->Driver.CompileShader()
1383 */
1384 static void
1385 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1386 {
1387 struct gl_shader *sh;
1388
1389 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1390 if (!sh)
1391 return;
1392
1393 /* this call will set the sh->CompileStatus field to indicate if
1394 * compilation was successful.
1395 */
1396 (void) _slang_compile(ctx, sh);
1397 }
1398
1399
1400 /**
1401 * Called via ctx->Driver.LinkProgram()
1402 */
1403 static void
1404 _mesa_link_program(GLcontext *ctx, GLuint program)
1405 {
1406 struct gl_shader_program *shProg;
1407
1408 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1409 if (!shProg)
1410 return;
1411
1412 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1413
1414 _slang_link(ctx, program, shProg);
1415 }
1416
1417
1418 /**
1419 * Called via ctx->Driver.UseProgram()
1420 */
1421 void
1422 _mesa_use_program(GLcontext *ctx, GLuint program)
1423 {
1424 struct gl_shader_program *shProg;
1425
1426 if (ctx->Shader.CurrentProgram &&
1427 ctx->Shader.CurrentProgram->Name == program) {
1428 /* no-op */
1429 return;
1430 }
1431
1432 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1433
1434 if (program) {
1435 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1436 if (!shProg) {
1437 return;
1438 }
1439 if (!shProg->LinkStatus) {
1440 _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgram");
1441 return;
1442 }
1443 }
1444 else {
1445 shProg = NULL;
1446 }
1447
1448 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1449 }
1450
1451
1452
1453 /**
1454 * Update the vertex/fragment program's TexturesUsed array.
1455 *
1456 * This needs to be called after glUniform(set sampler var) is called.
1457 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1458 * particular texture unit. We know the sampler's texture target
1459 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1460 * set by glUniform() calls.
1461 *
1462 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1463 * information to update the prog->TexturesUsed[] values.
1464 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1465 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1466 * We'll use that info for state validation before rendering.
1467 */
1468 void
1469 _mesa_update_shader_textures_used(struct gl_program *prog)
1470 {
1471 GLuint s;
1472
1473 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1474
1475 for (s = 0; s < MAX_SAMPLERS; s++) {
1476 if (prog->SamplersUsed & (1 << s)) {
1477 GLuint u = prog->SamplerUnits[s];
1478 GLuint t = prog->SamplerTargets[s];
1479 assert(u < MAX_TEXTURE_IMAGE_UNITS);
1480 prog->TexturesUsed[u] |= (1 << t);
1481 }
1482 }
1483 }
1484
1485
1486 static GLboolean
1487 is_sampler_type(GLenum type)
1488 {
1489 switch (type) {
1490 case GL_SAMPLER_1D:
1491 case GL_SAMPLER_2D:
1492 case GL_SAMPLER_3D:
1493 case GL_SAMPLER_CUBE:
1494 case GL_SAMPLER_1D_SHADOW:
1495 case GL_SAMPLER_2D_SHADOW:
1496 case GL_SAMPLER_2D_RECT_ARB:
1497 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
1498 case GL_SAMPLER_1D_ARRAY_EXT:
1499 case GL_SAMPLER_2D_ARRAY_EXT:
1500 return GL_TRUE;
1501 default:
1502 return GL_FALSE;
1503 }
1504 }
1505
1506
1507 /**
1508 * Check if the type given by userType is allowed to set a uniform of the
1509 * target type. Generally, equivalence is required, but setting Boolean
1510 * uniforms can be done with glUniformiv or glUniformfv.
1511 */
1512 static GLboolean
1513 compatible_types(GLenum userType, GLenum targetType)
1514 {
1515 if (userType == targetType)
1516 return GL_TRUE;
1517
1518 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1519 return GL_TRUE;
1520
1521 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1522 userType == GL_INT_VEC2))
1523 return GL_TRUE;
1524
1525 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1526 userType == GL_INT_VEC3))
1527 return GL_TRUE;
1528
1529 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1530 userType == GL_INT_VEC4))
1531 return GL_TRUE;
1532
1533 if (is_sampler_type(targetType) && userType == GL_INT)
1534 return GL_TRUE;
1535
1536 return GL_FALSE;
1537 }
1538
1539
1540 /**
1541 * Set the value of a program's uniform variable.
1542 * \param program the program whose uniform to update
1543 * \param index the index of the program parameter for the uniform
1544 * \param offset additional parameter slot offset (for arrays)
1545 * \param type the datatype of the uniform
1546 * \param count the number of uniforms to set
1547 * \param elems number of elements per uniform
1548 * \param values the new values
1549 */
1550 static void
1551 set_program_uniform(GLcontext *ctx, struct gl_program *program,
1552 GLint index, GLint offset,
1553 GLenum type, GLsizei count, GLint elems,
1554 const void *values)
1555 {
1556 struct gl_program_parameter *param =
1557 &program->Parameters->Parameters[index];
1558
1559 assert(offset >= 0);
1560
1561 if (!compatible_types(type, param->DataType)) {
1562 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1563 return;
1564 }
1565
1566 if (index + offset > (GLint) program->Parameters->Size) {
1567 /* out of bounds! */
1568 return;
1569 }
1570
1571 if (param->Type == PROGRAM_SAMPLER) {
1572 /* This controls which texture unit which is used by a sampler */
1573 GLuint texUnit, sampler;
1574
1575 /* data type for setting samplers must be int */
1576 if (type != GL_INT || count != 1) {
1577 _mesa_error(ctx, GL_INVALID_OPERATION,
1578 "glUniform(only glUniform1i can be used "
1579 "to set sampler uniforms)");
1580 return;
1581 }
1582
1583 sampler = (GLuint) program->Parameters->ParameterValues[index][0];
1584 texUnit = ((GLuint *) values)[0];
1585
1586 /* check that the sampler (tex unit index) is legal */
1587 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1588 _mesa_error(ctx, GL_INVALID_VALUE,
1589 "glUniform1(invalid sampler/tex unit index)");
1590 return;
1591 }
1592
1593 /* This maps a sampler to a texture unit: */
1594 program->SamplerUnits[sampler] = texUnit;
1595 _mesa_update_shader_textures_used(program);
1596
1597 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1598 }
1599 else {
1600 /* ordinary uniform variable */
1601 GLsizei k, i;
1602 GLint slots = (param->Size + 3) / 4;
1603
1604 if (count * elems > (GLint) param->Size) {
1605 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)");
1606 return;
1607 }
1608
1609 if (count > slots)
1610 count = slots;
1611
1612 for (k = 0; k < count; k++) {
1613 GLfloat *uniformVal =
1614 program->Parameters->ParameterValues[index + offset + k];
1615 if (is_integer_type(type)) {
1616 const GLint *iValues = ((const GLint *) values) + k * elems;
1617 for (i = 0; i < elems; i++) {
1618 uniformVal[i] = (GLfloat) iValues[i];
1619 }
1620 }
1621 else {
1622 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1623 for (i = 0; i < elems; i++) {
1624 uniformVal[i] = fValues[i];
1625 }
1626 }
1627
1628 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1629 if (is_boolean_type(param->DataType)) {
1630 for (i = 0; i < elems; i++) {
1631 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1632 }
1633 }
1634 }
1635 }
1636 }
1637
1638
1639 /**
1640 * Called via ctx->Driver.Uniform().
1641 */
1642 static void
1643 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1644 const GLvoid *values, GLenum type)
1645 {
1646 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1647 struct gl_uniform *uniform;
1648 GLint elems, offset;
1649 GLenum basicType;
1650
1651 if (!shProg || !shProg->LinkStatus) {
1652 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1653 return;
1654 }
1655
1656 if (location == -1)
1657 return; /* The standard specifies this as a no-op */
1658
1659 split_location_offset(&location, &offset);
1660
1661 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1662 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1663 return;
1664 }
1665
1666 if (count < 0) {
1667 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1668 return;
1669 }
1670
1671 switch (type) {
1672 case GL_FLOAT:
1673 basicType = GL_FLOAT;
1674 elems = 1;
1675 break;
1676 case GL_INT:
1677 basicType = GL_INT;
1678 elems = 1;
1679 break;
1680 case GL_FLOAT_VEC2:
1681 basicType = GL_FLOAT;
1682 elems = 2;
1683 break;
1684 case GL_INT_VEC2:
1685 basicType = GL_INT;
1686 elems = 2;
1687 break;
1688 case GL_FLOAT_VEC3:
1689 basicType = GL_FLOAT;
1690 elems = 3;
1691 break;
1692 case GL_INT_VEC3:
1693 basicType = GL_INT;
1694 elems = 3;
1695 break;
1696 case GL_FLOAT_VEC4:
1697 basicType = GL_FLOAT;
1698 elems = 4;
1699 break;
1700 case GL_INT_VEC4:
1701 basicType = GL_INT;
1702 elems = 4;
1703 break;
1704 default:
1705 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1706 return;
1707 }
1708
1709 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1710
1711 uniform = &shProg->Uniforms->Uniforms[location];
1712
1713 if (ctx->Shader.Flags & GLSL_UNIFORMS) {
1714 GLint i;
1715 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1716 shProg->Name, uniform->Name, location);
1717 if (basicType == GL_INT) {
1718 const GLint *v = (const GLint *) values;
1719 for (i = 0; i < count * elems; i++) {
1720 _mesa_printf("%d ", v[i]);
1721 }
1722 }
1723 else {
1724 const GLfloat *v = (const GLfloat *) values;
1725 for (i = 0; i < count * elems; i++) {
1726 _mesa_printf("%g ", v[i]);
1727 }
1728 }
1729 _mesa_printf("\n");
1730 }
1731
1732 /* A uniform var may be used by both a vertex shader and a fragment
1733 * shader. We may need to update one or both shader's uniform here:
1734 */
1735 if (shProg->VertexProgram) {
1736 /* convert uniform location to program parameter index */
1737 GLint index = uniform->VertPos;
1738 if (index >= 0) {
1739 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1740 index, offset, type, count, elems, values);
1741 }
1742 }
1743
1744 if (shProg->FragmentProgram) {
1745 /* convert uniform location to program parameter index */
1746 GLint index = uniform->FragPos;
1747 if (index >= 0) {
1748 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1749 index, offset, type, count, elems, values);
1750 }
1751 }
1752
1753 uniform->Initialized = GL_TRUE;
1754 }
1755
1756
1757 /**
1758 * Set a matrix-valued program parameter.
1759 */
1760 static void
1761 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1762 GLuint index, GLuint offset,
1763 GLuint count, GLuint rows, GLuint cols,
1764 GLboolean transpose, const GLfloat *values)
1765 {
1766 GLuint mat, row, col;
1767 GLuint dst = index + offset, src = 0;
1768 GLint nr, nc;
1769
1770 /* check that the number of rows, columns is correct */
1771 get_matrix_dims(program->Parameters->Parameters[index].DataType, &nr, &nc);
1772 if (rows != nr || cols != nc) {
1773 _mesa_error(ctx, GL_INVALID_OPERATION,
1774 "glUniformMatrix(matrix size mismatch)");
1775 return;
1776 }
1777
1778 if (index + offset > program->Parameters->Size) {
1779 /* out of bounds! */
1780 return;
1781 }
1782
1783 /*
1784 * Note: the _columns_ of a matrix are stored in program registers, not
1785 * the rows. So, the loops below look a little funny.
1786 * XXX could optimize this a bit...
1787 */
1788
1789 /* loop over matrices */
1790 for (mat = 0; mat < count; mat++) {
1791
1792 /* each matrix: */
1793 for (col = 0; col < cols; col++) {
1794 GLfloat *v = program->Parameters->ParameterValues[dst];
1795 for (row = 0; row < rows; row++) {
1796 if (transpose) {
1797 v[row] = values[src + row * cols + col];
1798 }
1799 else {
1800 v[row] = values[src + col * rows + row];
1801 }
1802 }
1803 dst++;
1804 }
1805
1806 src += rows * cols; /* next matrix */
1807 }
1808 }
1809
1810
1811 /**
1812 * Called by ctx->Driver.UniformMatrix().
1813 * Note: cols=2, rows=4 ==> array[2] of vec4
1814 */
1815 static void
1816 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1817 GLenum matrixType, GLint location, GLsizei count,
1818 GLboolean transpose, const GLfloat *values)
1819 {
1820 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1821 struct gl_uniform *uniform;
1822 GLint offset;
1823
1824 if (!shProg || !shProg->LinkStatus) {
1825 _mesa_error(ctx, GL_INVALID_OPERATION,
1826 "glUniformMatrix(program not linked)");
1827 return;
1828 }
1829
1830 if (location == -1)
1831 return; /* The standard specifies this as a no-op */
1832
1833 split_location_offset(&location, &offset);
1834
1835 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1836 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
1837 return;
1838 }
1839 if (values == NULL) {
1840 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
1841 return;
1842 }
1843
1844 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1845
1846 uniform = &shProg->Uniforms->Uniforms[location];
1847
1848 if (shProg->VertexProgram) {
1849 /* convert uniform location to program parameter index */
1850 GLint index = uniform->VertPos;
1851 if (index >= 0) {
1852 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
1853 index, offset,
1854 count, rows, cols, transpose, values);
1855 }
1856 }
1857
1858 if (shProg->FragmentProgram) {
1859 /* convert uniform location to program parameter index */
1860 GLint index = uniform->FragPos;
1861 if (index >= 0) {
1862 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
1863 index, offset,
1864 count, rows, cols, transpose, values);
1865 }
1866 }
1867
1868 uniform->Initialized = GL_TRUE;
1869 }
1870
1871
1872 static void
1873 _mesa_validate_program(GLcontext *ctx, GLuint program)
1874 {
1875 struct gl_shader_program *shProg;
1876
1877 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1878 if (!shProg) {
1879 return;
1880 }
1881
1882 if (!shProg->LinkStatus) {
1883 shProg->Validated = GL_FALSE;
1884 return;
1885 }
1886
1887 /* From the GL spec, a program is invalid if any of these are true:
1888
1889 any two active samplers in the current program object are of
1890 different types, but refer to the same texture image unit,
1891
1892 any active sampler in the current program object refers to a texture
1893 image unit where fixed-function fragment processing accesses a
1894 texture target that does not match the sampler type, or
1895
1896 the sum of the number of active samplers in the program and the
1897 number of texture image units enabled for fixed-function fragment
1898 processing exceeds the combined limit on the total number of texture
1899 image units allowed.
1900 */
1901
1902 shProg->Validated = GL_TRUE;
1903 }
1904
1905
1906 /**
1907 * Plug in Mesa's GLSL functions into the device driver function table.
1908 */
1909 void
1910 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
1911 {
1912 driver->AttachShader = _mesa_attach_shader;
1913 driver->BindAttribLocation = _mesa_bind_attrib_location;
1914 driver->CompileShader = _mesa_compile_shader;
1915 driver->CreateProgram = _mesa_create_program;
1916 driver->CreateShader = _mesa_create_shader;
1917 driver->DeleteProgram2 = _mesa_delete_program2;
1918 driver->DeleteShader = _mesa_delete_shader;
1919 driver->DetachShader = _mesa_detach_shader;
1920 driver->GetActiveAttrib = _mesa_get_active_attrib;
1921 driver->GetActiveUniform = _mesa_get_active_uniform;
1922 driver->GetAttachedShaders = _mesa_get_attached_shaders;
1923 driver->GetAttribLocation = _mesa_get_attrib_location;
1924 driver->GetHandle = _mesa_get_handle;
1925 driver->GetProgramiv = _mesa_get_programiv;
1926 driver->GetProgramInfoLog = _mesa_get_program_info_log;
1927 driver->GetShaderiv = _mesa_get_shaderiv;
1928 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
1929 driver->GetShaderSource = _mesa_get_shader_source;
1930 driver->GetUniformfv = _mesa_get_uniformfv;
1931 driver->GetUniformiv = _mesa_get_uniformiv;
1932 driver->GetUniformLocation = _mesa_get_uniform_location;
1933 driver->IsProgram = _mesa_is_program;
1934 driver->IsShader = _mesa_is_shader;
1935 driver->LinkProgram = _mesa_link_program;
1936 driver->ShaderSource = _mesa_shader_source;
1937 driver->Uniform = _mesa_uniform;
1938 driver->UniformMatrix = _mesa_uniform_matrix;
1939 driver->UseProgram = _mesa_use_program;
1940 driver->ValidateProgram = _mesa_validate_program;
1941 }