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