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