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