glsl: Add assert to check input to strcmp.
[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 "shader/program.h"
43 #include "shader/prog_parameter.h"
44 #include "shader/prog_statevars.h"
45 #include "shader/prog_uniform.h"
46 #include "shader/shader_api.h"
47 #include "shader/slang/slang_compile.h"
48 #include "shader/slang/slang_link.h"
49 #include "main/dispatch.h"
50
51
52 /**
53 * Allocate a new gl_shader_program object, initialize it.
54 */
55 static struct gl_shader_program *
56 _mesa_new_shader_program(GLcontext *ctx, GLuint name)
57 {
58 struct gl_shader_program *shProg;
59 shProg = CALLOC_STRUCT(gl_shader_program);
60 if (shProg) {
61 shProg->Type = GL_SHADER_PROGRAM_MESA;
62 shProg->Name = name;
63 shProg->RefCount = 1;
64 shProg->Attributes = _mesa_new_parameter_list();
65 }
66 return shProg;
67 }
68
69
70 /**
71 * Clear (free) the shader program state that gets produced by linking.
72 */
73 void
74 _mesa_clear_shader_program_data(GLcontext *ctx,
75 struct gl_shader_program *shProg)
76 {
77 _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
78 _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
79
80 if (shProg->Uniforms) {
81 _mesa_free_uniform_list(shProg->Uniforms);
82 shProg->Uniforms = NULL;
83 }
84
85 if (shProg->Varying) {
86 _mesa_free_parameter_list(shProg->Varying);
87 shProg->Varying = NULL;
88 }
89 }
90
91
92 /**
93 * Free all the data that hangs off a shader program object, but not the
94 * object itself.
95 */
96 void
97 _mesa_free_shader_program_data(GLcontext *ctx,
98 struct gl_shader_program *shProg)
99 {
100 GLuint i;
101
102 assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
103
104 _mesa_clear_shader_program_data(ctx, shProg);
105
106 if (shProg->Attributes) {
107 _mesa_free_parameter_list(shProg->Attributes);
108 shProg->Attributes = NULL;
109 }
110
111 /* detach shaders */
112 for (i = 0; i < shProg->NumShaders; i++) {
113 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
114 }
115 shProg->NumShaders = 0;
116
117 if (shProg->Shaders) {
118 free(shProg->Shaders);
119 shProg->Shaders = NULL;
120 }
121
122 if (shProg->InfoLog) {
123 free(shProg->InfoLog);
124 shProg->InfoLog = NULL;
125 }
126 }
127
128
129 /**
130 * Free/delete a shader program object.
131 */
132 void
133 _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
134 {
135 _mesa_free_shader_program_data(ctx, shProg);
136
137 free(shProg);
138 }
139
140
141 /**
142 * Set ptr to point to shProg.
143 * If ptr is pointing to another object, decrement its refcount (and delete
144 * if refcount hits zero).
145 * Then set ptr to point to shProg, incrementing its refcount.
146 */
147 /* XXX this could be static */
148 void
149 _mesa_reference_shader_program(GLcontext *ctx,
150 struct gl_shader_program **ptr,
151 struct gl_shader_program *shProg)
152 {
153 assert(ptr);
154 if (*ptr == shProg) {
155 /* no-op */
156 return;
157 }
158 if (*ptr) {
159 /* Unreference the old shader program */
160 GLboolean deleteFlag = GL_FALSE;
161 struct gl_shader_program *old = *ptr;
162
163 ASSERT(old->RefCount > 0);
164 old->RefCount--;
165 #if 0
166 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
167 (void *) old, old->Name, old->RefCount);
168 #endif
169 deleteFlag = (old->RefCount == 0);
170
171 if (deleteFlag) {
172 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
173 _mesa_free_shader_program(ctx, old);
174 }
175
176 *ptr = NULL;
177 }
178 assert(!*ptr);
179
180 if (shProg) {
181 shProg->RefCount++;
182 #if 0
183 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
184 (void *) shProg, shProg->Name, shProg->RefCount);
185 #endif
186 *ptr = shProg;
187 }
188 }
189
190
191 /**
192 * Lookup a GLSL program object.
193 */
194 struct gl_shader_program *
195 _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
196 {
197 struct gl_shader_program *shProg;
198 if (name) {
199 shProg = (struct gl_shader_program *)
200 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
201 /* Note that both gl_shader and gl_shader_program objects are kept
202 * in the same hash table. Check the object's type to be sure it's
203 * what we're expecting.
204 */
205 if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
206 return NULL;
207 }
208 return shProg;
209 }
210 return NULL;
211 }
212
213
214 /**
215 * As above, but record an error if program is not found.
216 */
217 static struct gl_shader_program *
218 _mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
219 const char *caller)
220 {
221 if (!name) {
222 _mesa_error(ctx, GL_INVALID_VALUE, caller);
223 return NULL;
224 }
225 else {
226 struct gl_shader_program *shProg = (struct gl_shader_program *)
227 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
228 if (!shProg) {
229 _mesa_error(ctx, GL_INVALID_VALUE, caller);
230 return NULL;
231 }
232 if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
233 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
234 return NULL;
235 }
236 return shProg;
237 }
238 }
239
240
241
242
243 /**
244 * Allocate a new gl_shader object, initialize it.
245 */
246 struct gl_shader *
247 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
248 {
249 struct gl_shader *shader;
250 assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
251 shader = CALLOC_STRUCT(gl_shader);
252 if (shader) {
253 shader->Type = type;
254 shader->Name = name;
255 shader->RefCount = 1;
256 }
257 return shader;
258 }
259
260
261 void
262 _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
263 {
264 if (sh->Source)
265 free((void *) sh->Source);
266 if (sh->InfoLog)
267 free(sh->InfoLog);
268 _mesa_reference_program(ctx, &sh->Program, NULL);
269 free(sh);
270 }
271
272
273 /**
274 * Set ptr to point to sh.
275 * If ptr is pointing to another shader, decrement its refcount (and delete
276 * if refcount hits zero).
277 * Then set ptr to point to sh, incrementing its refcount.
278 */
279 /* XXX this could be static */
280 void
281 _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
282 struct gl_shader *sh)
283 {
284 assert(ptr);
285 if (*ptr == sh) {
286 /* no-op */
287 return;
288 }
289 if (*ptr) {
290 /* Unreference the old shader */
291 GLboolean deleteFlag = GL_FALSE;
292 struct gl_shader *old = *ptr;
293
294 ASSERT(old->RefCount > 0);
295 old->RefCount--;
296 /*printf("SHADER DECR %p (%d) to %d\n",
297 (void*) old, old->Name, old->RefCount);*/
298 deleteFlag = (old->RefCount == 0);
299
300 if (deleteFlag) {
301 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
302 _mesa_free_shader(ctx, old);
303 }
304
305 *ptr = NULL;
306 }
307 assert(!*ptr);
308
309 if (sh) {
310 /* reference new */
311 sh->RefCount++;
312 /*printf("SHADER INCR %p (%d) to %d\n",
313 (void*) sh, sh->Name, sh->RefCount);*/
314 *ptr = sh;
315 }
316 }
317
318
319 /**
320 * Lookup a GLSL shader object.
321 */
322 struct gl_shader *
323 _mesa_lookup_shader(GLcontext *ctx, GLuint name)
324 {
325 if (name) {
326 struct gl_shader *sh = (struct gl_shader *)
327 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
328 /* Note that both gl_shader and gl_shader_program objects are kept
329 * in the same hash table. Check the object's type to be sure it's
330 * what we're expecting.
331 */
332 if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
333 return NULL;
334 }
335 return sh;
336 }
337 return NULL;
338 }
339
340
341 /**
342 * As above, but record an error if shader is not found.
343 */
344 static struct gl_shader *
345 _mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
346 {
347 if (!name) {
348 _mesa_error(ctx, GL_INVALID_VALUE, caller);
349 return NULL;
350 }
351 else {
352 struct gl_shader *sh = (struct gl_shader *)
353 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
354 if (!sh) {
355 _mesa_error(ctx, GL_INVALID_VALUE, caller);
356 return NULL;
357 }
358 if (sh->Type == GL_SHADER_PROGRAM_MESA) {
359 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
360 return NULL;
361 }
362 return sh;
363 }
364 }
365
366
367 /**
368 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
369 */
370 static GLbitfield
371 get_shader_flags(void)
372 {
373 GLbitfield flags = 0x0;
374 const char *env = _mesa_getenv("MESA_GLSL");
375
376 if (env) {
377 if (strstr(env, "dump"))
378 flags |= GLSL_DUMP;
379 if (strstr(env, "log"))
380 flags |= GLSL_LOG;
381 if (strstr(env, "nopvert"))
382 flags |= GLSL_NOP_VERT;
383 if (strstr(env, "nopfrag"))
384 flags |= GLSL_NOP_FRAG;
385 if (strstr(env, "nopt"))
386 flags |= GLSL_NO_OPT;
387 else if (strstr(env, "opt"))
388 flags |= GLSL_OPT;
389 if (strstr(env, "uniform"))
390 flags |= GLSL_UNIFORMS;
391 if (strstr(env, "useprog"))
392 flags |= GLSL_USE_PROG;
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 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 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_EXT:
773 case GL_SAMPLER_2D_ARRAY_EXT:
774 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
775 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
776 case GL_SAMPLER_CUBE_SHADOW_EXT:
777 return 1;
778 case GL_FLOAT_VEC2:
779 case GL_INT_VEC2:
780 case GL_BOOL_VEC2:
781 return 2;
782 case GL_FLOAT_VEC3:
783 case GL_INT_VEC3:
784 case GL_BOOL_VEC3:
785 return 3;
786 case GL_FLOAT_VEC4:
787 case GL_INT_VEC4:
788 case GL_BOOL_VEC4:
789 return 4;
790 case GL_FLOAT_MAT2:
791 case GL_FLOAT_MAT2x3:
792 case GL_FLOAT_MAT2x4:
793 return 8; /* two float[4] vectors */
794 case GL_FLOAT_MAT3:
795 case GL_FLOAT_MAT3x2:
796 case GL_FLOAT_MAT3x4:
797 return 12; /* three float[4] vectors */
798 case GL_FLOAT_MAT4:
799 case GL_FLOAT_MAT4x2:
800 case GL_FLOAT_MAT4x3:
801 return 16; /* four float[4] vectors */
802 default:
803 _mesa_problem(NULL, "Invalid type in sizeof_glsl_type()");
804 return 1;
805 }
806 }
807
808
809 static GLboolean
810 is_boolean_type(GLenum type)
811 {
812 switch (type) {
813 case GL_BOOL:
814 case GL_BOOL_VEC2:
815 case GL_BOOL_VEC3:
816 case GL_BOOL_VEC4:
817 return GL_TRUE;
818 default:
819 return GL_FALSE;
820 }
821 }
822
823
824 static GLboolean
825 is_integer_type(GLenum type)
826 {
827 switch (type) {
828 case GL_INT:
829 case GL_INT_VEC2:
830 case GL_INT_VEC3:
831 case GL_INT_VEC4:
832 return GL_TRUE;
833 default:
834 return GL_FALSE;
835 }
836 }
837
838
839 static GLboolean
840 is_sampler_type(GLenum type)
841 {
842 switch (type) {
843 case GL_SAMPLER_1D:
844 case GL_SAMPLER_2D:
845 case GL_SAMPLER_3D:
846 case GL_SAMPLER_CUBE:
847 case GL_SAMPLER_1D_SHADOW:
848 case GL_SAMPLER_2D_SHADOW:
849 case GL_SAMPLER_2D_RECT_ARB:
850 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
851 case GL_SAMPLER_1D_ARRAY_EXT:
852 case GL_SAMPLER_2D_ARRAY_EXT:
853 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
854 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
855 return GL_TRUE;
856 default:
857 return GL_FALSE;
858 }
859 }
860
861
862 static void
863 _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
864 GLsizei maxLength, GLsizei *length, GLint *size,
865 GLenum *type, GLchar *nameOut)
866 {
867 const struct gl_program_parameter_list *attribs = NULL;
868 struct gl_shader_program *shProg;
869
870 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
871 if (!shProg)
872 return;
873
874 if (shProg->VertexProgram)
875 attribs = shProg->VertexProgram->Base.Attributes;
876
877 if (!attribs || index >= attribs->NumParameters) {
878 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
879 return;
880 }
881
882 copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name);
883
884 if (size)
885 *size = attribs->Parameters[index].Size
886 / sizeof_glsl_type(attribs->Parameters[index].DataType);
887
888 if (type)
889 *type = attribs->Parameters[index].DataType;
890 }
891
892
893 static struct gl_program_parameter *
894 get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
895 {
896 const struct gl_program *prog = NULL;
897 GLint progPos;
898
899 progPos = shProg->Uniforms->Uniforms[index].VertPos;
900 if (progPos >= 0) {
901 prog = &shProg->VertexProgram->Base;
902 }
903 else {
904 progPos = shProg->Uniforms->Uniforms[index].FragPos;
905 if (progPos >= 0) {
906 prog = &shProg->FragmentProgram->Base;
907 }
908 }
909
910 if (!prog || progPos < 0)
911 return NULL; /* should never happen */
912
913 return &prog->Parameters->Parameters[progPos];
914 }
915
916
917 /**
918 * Called via ctx->Driver.GetActiveUniform().
919 */
920 static void
921 _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
922 GLsizei maxLength, GLsizei *length, GLint *size,
923 GLenum *type, GLchar *nameOut)
924 {
925 const struct gl_shader_program *shProg;
926 const struct gl_program *prog = NULL;
927 const struct gl_program_parameter *param;
928 GLint progPos;
929
930 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
931 if (!shProg)
932 return;
933
934 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
935 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
936 return;
937 }
938
939 progPos = shProg->Uniforms->Uniforms[index].VertPos;
940 if (progPos >= 0) {
941 prog = &shProg->VertexProgram->Base;
942 }
943 else {
944 progPos = shProg->Uniforms->Uniforms[index].FragPos;
945 if (progPos >= 0) {
946 prog = &shProg->FragmentProgram->Base;
947 }
948 }
949
950 if (!prog || progPos < 0)
951 return; /* should never happen */
952
953 ASSERT(progPos < prog->Parameters->NumParameters);
954 param = &prog->Parameters->Parameters[progPos];
955
956 if (nameOut) {
957 copy_string(nameOut, maxLength, length, param->Name);
958 }
959
960 if (size) {
961 GLint typeSize = sizeof_glsl_type(param->DataType);
962 if ((GLint) param->Size > typeSize) {
963 /* This is an array.
964 * Array elements are placed on vector[4] boundaries so they're
965 * a multiple of four floats. We round typeSize up to next multiple
966 * of four to get the right size below.
967 */
968 typeSize = (typeSize + 3) & ~3;
969 }
970 /* Note that the returned size is in units of the <type>, not bytes */
971 *size = param->Size / typeSize;
972 }
973
974 if (type) {
975 *type = param->DataType;
976 }
977 }
978
979
980 /**
981 * Called via ctx->Driver.GetAttachedShaders().
982 */
983 static void
984 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
985 GLsizei *count, GLuint *obj)
986 {
987 struct gl_shader_program *shProg =
988 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
989 if (shProg) {
990 GLuint i;
991 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
992 obj[i] = shProg->Shaders[i]->Name;
993 }
994 if (count)
995 *count = i;
996 }
997 }
998
999
1000 static GLuint
1001 _mesa_get_handle(GLcontext *ctx, GLenum pname)
1002 {
1003 GLint handle = 0;
1004
1005 if (pname == GL_PROGRAM_OBJECT_ARB) {
1006 CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
1007 } else {
1008 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
1009 }
1010
1011 return handle;
1012 }
1013
1014
1015 static void
1016 _mesa_get_programiv(GLcontext *ctx, GLuint program,
1017 GLenum pname, GLint *params)
1018 {
1019 const struct gl_program_parameter_list *attribs;
1020 struct gl_shader_program *shProg
1021 = _mesa_lookup_shader_program(ctx, program);
1022
1023 if (!shProg) {
1024 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
1025 return;
1026 }
1027
1028 if (shProg->VertexProgram)
1029 attribs = shProg->VertexProgram->Base.Attributes;
1030 else
1031 attribs = NULL;
1032
1033 switch (pname) {
1034 case GL_DELETE_STATUS:
1035 *params = shProg->DeletePending;
1036 break;
1037 case GL_LINK_STATUS:
1038 *params = shProg->LinkStatus;
1039 break;
1040 case GL_VALIDATE_STATUS:
1041 *params = shProg->Validated;
1042 break;
1043 case GL_INFO_LOG_LENGTH:
1044 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
1045 break;
1046 case GL_ATTACHED_SHADERS:
1047 *params = shProg->NumShaders;
1048 break;
1049 case GL_ACTIVE_ATTRIBUTES:
1050 *params = attribs ? attribs->NumParameters : 0;
1051 break;
1052 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1053 *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
1054 break;
1055 case GL_ACTIVE_UNIFORMS:
1056 *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
1057 break;
1058 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1059 *params = _mesa_longest_uniform_name(shProg->Uniforms);
1060 if (*params > 0)
1061 (*params)++; /* add one for terminating zero */
1062 break;
1063 case GL_PROGRAM_BINARY_LENGTH_OES:
1064 *params = 0;
1065 break;
1066 default:
1067 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
1068 return;
1069 }
1070 }
1071
1072
1073 static void
1074 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
1075 {
1076 struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
1077
1078 if (!shader) {
1079 return;
1080 }
1081
1082 switch (pname) {
1083 case GL_SHADER_TYPE:
1084 *params = shader->Type;
1085 break;
1086 case GL_DELETE_STATUS:
1087 *params = shader->DeletePending;
1088 break;
1089 case GL_COMPILE_STATUS:
1090 *params = shader->CompileStatus;
1091 break;
1092 case GL_INFO_LOG_LENGTH:
1093 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
1094 break;
1095 case GL_SHADER_SOURCE_LENGTH:
1096 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1097 break;
1098 default:
1099 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1100 return;
1101 }
1102 }
1103
1104
1105 static void
1106 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
1107 GLsizei *length, GLchar *infoLog)
1108 {
1109 struct gl_shader_program *shProg
1110 = _mesa_lookup_shader_program(ctx, program);
1111 if (!shProg) {
1112 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
1113 return;
1114 }
1115 copy_string(infoLog, bufSize, length, shProg->InfoLog);
1116 }
1117
1118
1119 static void
1120 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
1121 GLsizei *length, GLchar *infoLog)
1122 {
1123 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
1124 if (!sh) {
1125 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
1126 return;
1127 }
1128 copy_string(infoLog, bufSize, length, sh->InfoLog);
1129 }
1130
1131
1132 /**
1133 * Called via ctx->Driver.GetShaderSource().
1134 */
1135 static void
1136 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
1137 GLsizei *length, GLchar *sourceOut)
1138 {
1139 struct gl_shader *sh;
1140 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1141 if (!sh) {
1142 return;
1143 }
1144 copy_string(sourceOut, maxLength, length, sh->Source);
1145 }
1146
1147
1148 static void
1149 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
1150 {
1151 switch (type) {
1152 case GL_FLOAT_MAT2:
1153 *rows = *cols = 2;
1154 break;
1155 case GL_FLOAT_MAT2x3:
1156 *rows = 3;
1157 *cols = 2;
1158 break;
1159 case GL_FLOAT_MAT2x4:
1160 *rows = 4;
1161 *cols = 2;
1162 break;
1163 case GL_FLOAT_MAT3:
1164 *rows = 3;
1165 *cols = 3;
1166 break;
1167 case GL_FLOAT_MAT3x2:
1168 *rows = 2;
1169 *cols = 3;
1170 break;
1171 case GL_FLOAT_MAT3x4:
1172 *rows = 4;
1173 *cols = 3;
1174 break;
1175 case GL_FLOAT_MAT4:
1176 *rows = 4;
1177 *cols = 4;
1178 break;
1179 case GL_FLOAT_MAT4x2:
1180 *rows = 2;
1181 *cols = 4;
1182 break;
1183 case GL_FLOAT_MAT4x3:
1184 *rows = 3;
1185 *cols = 4;
1186 break;
1187 default:
1188 *rows = *cols = 0;
1189 }
1190 }
1191
1192
1193 /**
1194 * Determine the number of rows and columns occupied by a uniform
1195 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1196 * the number of rows = 1 and cols = number of elements in the vector.
1197 */
1198 static void
1199 get_uniform_rows_cols(const struct gl_program_parameter *p,
1200 GLint *rows, GLint *cols)
1201 {
1202 get_matrix_dims(p->DataType, rows, cols);
1203 if (*rows == 0 && *cols == 0) {
1204 /* not a matrix type, probably a float or vector */
1205 if (p->Size <= 4) {
1206 *rows = 1;
1207 *cols = p->Size;
1208 }
1209 else {
1210 *rows = p->Size / 4 + 1;
1211 if (p->Size % 4 == 0)
1212 *cols = 4;
1213 else
1214 *cols = p->Size % 4;
1215 }
1216 }
1217 }
1218
1219
1220 /**
1221 * Helper for get_uniform[fi]v() functions.
1222 * Given a shader program name and uniform location, return a pointer
1223 * to the shader program and return the program parameter position.
1224 */
1225 static void
1226 lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
1227 struct gl_program **progOut, GLint *paramPosOut)
1228 {
1229 struct gl_shader_program *shProg
1230 = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
1231 struct gl_program *prog = NULL;
1232 GLint progPos = -1;
1233
1234 /* if shProg is NULL, we'll have already recorded an error */
1235
1236 if (shProg) {
1237 if (!shProg->Uniforms ||
1238 location < 0 ||
1239 location >= (GLint) shProg->Uniforms->NumUniforms) {
1240 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
1241 }
1242 else {
1243 /* OK, find the gl_program and program parameter location */
1244 progPos = shProg->Uniforms->Uniforms[location].VertPos;
1245 if (progPos >= 0) {
1246 prog = &shProg->VertexProgram->Base;
1247 }
1248 else {
1249 progPos = shProg->Uniforms->Uniforms[location].FragPos;
1250 if (progPos >= 0) {
1251 prog = &shProg->FragmentProgram->Base;
1252 }
1253 }
1254 }
1255 }
1256
1257 *progOut = prog;
1258 *paramPosOut = progPos;
1259 }
1260
1261
1262 /**
1263 * Called via ctx->Driver.GetUniformfv().
1264 */
1265 static void
1266 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1267 GLfloat *params)
1268 {
1269 struct gl_program *prog;
1270 GLint paramPos;
1271
1272 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
1273
1274 if (prog) {
1275 const struct gl_program_parameter *p =
1276 &prog->Parameters->Parameters[paramPos];
1277 GLint rows, cols, i, j, k;
1278
1279 get_uniform_rows_cols(p, &rows, &cols);
1280
1281 k = 0;
1282 for (i = 0; i < rows; i++) {
1283 for (j = 0; j < cols; j++ ) {
1284 params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
1285 }
1286 }
1287 }
1288 }
1289
1290
1291 /**
1292 * Called via ctx->Driver.GetUniformiv().
1293 * \sa _mesa_get_uniformfv, only difference is a cast.
1294 */
1295 static void
1296 _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
1297 GLint *params)
1298 {
1299 struct gl_program *prog;
1300 GLint paramPos;
1301
1302 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
1303
1304 if (prog) {
1305 const struct gl_program_parameter *p =
1306 &prog->Parameters->Parameters[paramPos];
1307 GLint rows, cols, i, j, k;
1308
1309 get_uniform_rows_cols(p, &rows, &cols);
1310
1311 k = 0;
1312 for (i = 0; i < rows; i++) {
1313 for (j = 0; j < cols; j++ ) {
1314 params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
1315 }
1316 }
1317 }
1318 }
1319
1320
1321 /**
1322 * The value returned by GetUniformLocation actually encodes two things:
1323 * 1. the index into the prog->Uniforms[] array for the uniform
1324 * 2. an offset in the prog->ParameterValues[] array for specifying array
1325 * elements or structure fields.
1326 * This function merges those two values.
1327 */
1328 static void
1329 merge_location_offset(GLint *location, GLint offset)
1330 {
1331 *location = *location | (offset << 16);
1332 }
1333
1334
1335 /**
1336 * Seperate the uniform location and parameter offset. See above.
1337 */
1338 static void
1339 split_location_offset(GLint *location, GLint *offset)
1340 {
1341 *offset = (*location >> 16);
1342 *location = *location & 0xffff;
1343 }
1344
1345
1346 /**
1347 * Called via ctx->Driver.GetUniformLocation().
1348 *
1349 * The return value will encode two values, the uniform location and an
1350 * offset (used for arrays, structs).
1351 */
1352 static GLint
1353 _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
1354 {
1355 GLint offset = 0, location = -1;
1356
1357 struct gl_shader_program *shProg =
1358 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
1359
1360 if (!shProg)
1361 return -1;
1362
1363 if (shProg->LinkStatus == GL_FALSE) {
1364 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1365 return -1;
1366 }
1367
1368 /* XXX we should return -1 if the uniform was declared, but not
1369 * actually used.
1370 */
1371
1372 /* XXX we need to be able to parse uniform names for structs and arrays
1373 * such as:
1374 * mymatrix[1]
1375 * mystruct.field1
1376 */
1377
1378 {
1379 /* handle 1-dimension arrays here... */
1380 char *c = strchr(name, '[');
1381 if (c) {
1382 /* truncate name at [ */
1383 const GLint len = c - name;
1384 GLchar *newName = malloc(len + 1);
1385 if (!newName)
1386 return -1; /* out of mem */
1387 memcpy(newName, name, len);
1388 newName[len] = 0;
1389
1390 location = _mesa_lookup_uniform(shProg->Uniforms, newName);
1391 if (location >= 0) {
1392 const GLint element = atoi(c + 1);
1393 if (element > 0) {
1394 /* get type of the uniform array element */
1395 struct gl_program_parameter *p;
1396 p = get_uniform_parameter(shProg, location);
1397 if (p) {
1398 GLint rows, cols;
1399 get_matrix_dims(p->DataType, &rows, &cols);
1400 if (rows < 1)
1401 rows = 1;
1402 offset = element * rows;
1403 }
1404 }
1405 }
1406
1407 free(newName);
1408 }
1409 }
1410
1411 if (location < 0) {
1412 location = _mesa_lookup_uniform(shProg->Uniforms, name);
1413 }
1414
1415 if (location >= 0) {
1416 merge_location_offset(&location, offset);
1417 }
1418
1419 return location;
1420 }
1421
1422
1423
1424 /**
1425 * Called via ctx->Driver.ShaderSource()
1426 */
1427 static void
1428 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1429 {
1430 struct gl_shader *sh;
1431
1432 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1433 if (!sh)
1434 return;
1435
1436 /* free old shader source string and install new one */
1437 if (sh->Source) {
1438 free((void *) sh->Source);
1439 }
1440 sh->Source = source;
1441 sh->CompileStatus = GL_FALSE;
1442 #ifdef DEBUG
1443 sh->SourceChecksum = _mesa_str_checksum(sh->Source);
1444 #endif
1445 }
1446
1447
1448 /**
1449 * Called via ctx->Driver.CompileShader()
1450 */
1451 static void
1452 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1453 {
1454 struct gl_shader *sh;
1455
1456 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1457 if (!sh)
1458 return;
1459
1460 /* set default pragma state for shader */
1461 sh->Pragmas = ctx->Shader.DefaultPragmas;
1462
1463 /* this call will set the sh->CompileStatus field to indicate if
1464 * compilation was successful.
1465 */
1466 (void) _slang_compile(ctx, sh);
1467 }
1468
1469
1470 /**
1471 * Called via ctx->Driver.LinkProgram()
1472 */
1473 static void
1474 _mesa_link_program(GLcontext *ctx, GLuint program)
1475 {
1476 struct gl_shader_program *shProg;
1477
1478 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1479 if (!shProg)
1480 return;
1481
1482 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1483
1484 _slang_link(ctx, program, shProg);
1485
1486 /* debug code */
1487 if (0) {
1488 GLuint i;
1489
1490 printf("Link %u shaders in program %u: %s\n",
1491 shProg->NumShaders, shProg->Name,
1492 shProg->LinkStatus ? "Success" : "Failed");
1493
1494 for (i = 0; i < shProg->NumShaders; i++) {
1495 printf(" shader %u, type 0x%x\n",
1496 shProg->Shaders[i]->Name,
1497 shProg->Shaders[i]->Type);
1498 }
1499 }
1500 }
1501
1502
1503 /**
1504 * Print basic shader info (for debug).
1505 */
1506 static void
1507 print_shader_info(const struct gl_shader_program *shProg)
1508 {
1509 GLuint i;
1510
1511 printf("Mesa: glUseProgram(%u)\n", shProg->Name);
1512 for (i = 0; i < shProg->NumShaders; i++) {
1513 const char *s;
1514 switch (shProg->Shaders[i]->Type) {
1515 case GL_VERTEX_SHADER:
1516 s = "vertex";
1517 break;
1518 case GL_FRAGMENT_SHADER:
1519 s = "fragment";
1520 break;
1521 case GL_GEOMETRY_SHADER:
1522 s = "geometry";
1523 break;
1524 default:
1525 s = "";
1526 }
1527 printf(" %s shader %u, checksum %u\n", s,
1528 shProg->Shaders[i]->Name,
1529 shProg->Shaders[i]->SourceChecksum);
1530 }
1531 if (shProg->VertexProgram)
1532 printf(" vert prog %u\n", shProg->VertexProgram->Base.Id);
1533 if (shProg->FragmentProgram)
1534 printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id);
1535 }
1536
1537
1538 /**
1539 * Called via ctx->Driver.UseProgram()
1540 */
1541 void
1542 _mesa_use_program(GLcontext *ctx, GLuint program)
1543 {
1544 struct gl_shader_program *shProg;
1545
1546 if (ctx->Shader.CurrentProgram &&
1547 ctx->Shader.CurrentProgram->Name == program) {
1548 /* no-op */
1549 return;
1550 }
1551
1552 if (program) {
1553 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1554 if (!shProg) {
1555 return;
1556 }
1557 if (!shProg->LinkStatus) {
1558 _mesa_error(ctx, GL_INVALID_OPERATION,
1559 "glUseProgram(program %u not linked)", program);
1560 return;
1561 }
1562
1563 /* debug code */
1564 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1565 print_shader_info(shProg);
1566 }
1567 }
1568 else {
1569 shProg = NULL;
1570 }
1571
1572 if (ctx->Shader.CurrentProgram != shProg) {
1573 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1574 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1575 }
1576 }
1577
1578
1579
1580 /**
1581 * Update the vertex/fragment program's TexturesUsed array.
1582 *
1583 * This needs to be called after glUniform(set sampler var) is called.
1584 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1585 * particular texture unit. We know the sampler's texture target
1586 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1587 * set by glUniform() calls.
1588 *
1589 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1590 * information to update the prog->TexturesUsed[] values.
1591 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1592 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1593 * We'll use that info for state validation before rendering.
1594 */
1595 void
1596 _mesa_update_shader_textures_used(struct gl_program *prog)
1597 {
1598 GLuint s;
1599
1600 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1601
1602 for (s = 0; s < MAX_SAMPLERS; s++) {
1603 if (prog->SamplersUsed & (1 << s)) {
1604 GLuint unit = prog->SamplerUnits[s];
1605 GLuint tgt = prog->SamplerTargets[s];
1606 assert(unit < MAX_TEXTURE_IMAGE_UNITS);
1607 assert(tgt < NUM_TEXTURE_TARGETS);
1608 prog->TexturesUsed[unit] |= (1 << tgt);
1609 }
1610 }
1611 }
1612
1613
1614 /**
1615 * Check if the type given by userType is allowed to set a uniform of the
1616 * target type. Generally, equivalence is required, but setting Boolean
1617 * uniforms can be done with glUniformiv or glUniformfv.
1618 */
1619 static GLboolean
1620 compatible_types(GLenum userType, GLenum targetType)
1621 {
1622 if (userType == targetType)
1623 return GL_TRUE;
1624
1625 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1626 return GL_TRUE;
1627
1628 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1629 userType == GL_INT_VEC2))
1630 return GL_TRUE;
1631
1632 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1633 userType == GL_INT_VEC3))
1634 return GL_TRUE;
1635
1636 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1637 userType == GL_INT_VEC4))
1638 return GL_TRUE;
1639
1640 if (is_sampler_type(targetType) && userType == GL_INT)
1641 return GL_TRUE;
1642
1643 return GL_FALSE;
1644 }
1645
1646
1647 /**
1648 * Set the value of a program's uniform variable.
1649 * \param program the program whose uniform to update
1650 * \param index the index of the program parameter for the uniform
1651 * \param offset additional parameter slot offset (for arrays)
1652 * \param type the incoming datatype of 'values'
1653 * \param count the number of uniforms to set
1654 * \param elems number of elements per uniform (1, 2, 3 or 4)
1655 * \param values the new values, of datatype 'type'
1656 */
1657 static void
1658 set_program_uniform(GLcontext *ctx, struct gl_program *program,
1659 GLint index, GLint offset,
1660 GLenum type, GLsizei count, GLint elems,
1661 const void *values)
1662 {
1663 const struct gl_program_parameter *param =
1664 &program->Parameters->Parameters[index];
1665
1666 assert(offset >= 0);
1667 assert(elems >= 1);
1668 assert(elems <= 4);
1669
1670 if (!compatible_types(type, param->DataType)) {
1671 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1672 return;
1673 }
1674
1675 if (index + offset > (GLint) program->Parameters->Size) {
1676 /* out of bounds! */
1677 return;
1678 }
1679
1680 if (param->Type == PROGRAM_SAMPLER) {
1681 /* This controls which texture unit which is used by a sampler */
1682 GLboolean changed = GL_FALSE;
1683 GLint i;
1684
1685 /* this should have been caught by the compatible_types() check */
1686 ASSERT(type == GL_INT);
1687
1688 /* loop over number of samplers to change */
1689 for (i = 0; i < count; i++) {
1690 GLuint sampler =
1691 (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
1692 GLuint texUnit = ((GLuint *) values)[i];
1693
1694 /* check that the sampler (tex unit index) is legal */
1695 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1696 _mesa_error(ctx, GL_INVALID_VALUE,
1697 "glUniform1(invalid sampler/tex unit index)");
1698 return;
1699 }
1700
1701 /* This maps a sampler to a texture unit: */
1702 if (sampler < MAX_SAMPLERS) {
1703 #if 0
1704 printf("Set program %p sampler %d '%s' to unit %u\n",
1705 program, sampler, param->Name, texUnit);
1706 #endif
1707 if (program->SamplerUnits[sampler] != texUnit) {
1708 program->SamplerUnits[sampler] = texUnit;
1709 changed = GL_TRUE;
1710 }
1711 }
1712 }
1713
1714 if (changed) {
1715 /* When a sampler's value changes it usually requires rewriting
1716 * a GPU program's TEX instructions since there may not be a
1717 * sampler->texture lookup table. We signal this with the
1718 * ProgramStringNotify() callback.
1719 */
1720 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
1721 _mesa_update_shader_textures_used(program);
1722 /* Do we need to care about the return value here?
1723 * This should not be the first time the driver was notified of
1724 * this program.
1725 */
1726 (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
1727 }
1728 }
1729 else {
1730 /* ordinary uniform variable */
1731 const GLboolean isUniformBool = is_boolean_type(param->DataType);
1732 const GLboolean areIntValues = is_integer_type(type);
1733 const GLint slots = (param->Size + 3) / 4;
1734 const GLint typeSize = sizeof_glsl_type(param->DataType);
1735 GLsizei k, i;
1736
1737 if ((GLint) param->Size > typeSize) {
1738 /* an array */
1739 /* we'll ignore extra data below */
1740 }
1741 else {
1742 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1743 if (count > 1) {
1744 _mesa_error(ctx, GL_INVALID_OPERATION,
1745 "glUniform(uniform is not an array)");
1746 return;
1747 }
1748 }
1749
1750 /* loop over number of array elements */
1751 for (k = 0; k < count; k++) {
1752 GLfloat *uniformVal;
1753
1754 if (offset + k >= slots) {
1755 /* Extra array data is ignored */
1756 break;
1757 }
1758
1759 /* uniformVal (the destination) is always float[4] */
1760 uniformVal = program->Parameters->ParameterValues[index + offset + k];
1761
1762 if (areIntValues) {
1763 /* convert user's ints to floats */
1764 const GLint *iValues = ((const GLint *) values) + k * elems;
1765 for (i = 0; i < elems; i++) {
1766 uniformVal[i] = (GLfloat) iValues[i];
1767 }
1768 }
1769 else {
1770 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1771 for (i = 0; i < elems; i++) {
1772 uniformVal[i] = fValues[i];
1773 }
1774 }
1775
1776 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1777 if (isUniformBool) {
1778 for (i = 0; i < elems; i++) {
1779 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1780 }
1781 }
1782 }
1783 }
1784 }
1785
1786
1787 /**
1788 * Called via ctx->Driver.Uniform().
1789 */
1790 static void
1791 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1792 const GLvoid *values, GLenum type)
1793 {
1794 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1795 struct gl_uniform *uniform;
1796 GLint elems, offset;
1797 GLenum basicType;
1798
1799 if (!shProg || !shProg->LinkStatus) {
1800 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1801 return;
1802 }
1803
1804 if (location == -1)
1805 return; /* The standard specifies this as a no-op */
1806
1807 if (location < -1) {
1808 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)");
1809 return;
1810 }
1811
1812 split_location_offset(&location, &offset);
1813
1814 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1815 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1816 return;
1817 }
1818
1819 if (count < 0) {
1820 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1821 return;
1822 }
1823
1824 switch (type) {
1825 case GL_FLOAT:
1826 basicType = GL_FLOAT;
1827 elems = 1;
1828 break;
1829 case GL_INT:
1830 basicType = GL_INT;
1831 elems = 1;
1832 break;
1833 case GL_FLOAT_VEC2:
1834 basicType = GL_FLOAT;
1835 elems = 2;
1836 break;
1837 case GL_INT_VEC2:
1838 basicType = GL_INT;
1839 elems = 2;
1840 break;
1841 case GL_FLOAT_VEC3:
1842 basicType = GL_FLOAT;
1843 elems = 3;
1844 break;
1845 case GL_INT_VEC3:
1846 basicType = GL_INT;
1847 elems = 3;
1848 break;
1849 case GL_FLOAT_VEC4:
1850 basicType = GL_FLOAT;
1851 elems = 4;
1852 break;
1853 case GL_INT_VEC4:
1854 basicType = GL_INT;
1855 elems = 4;
1856 break;
1857 default:
1858 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1859 return;
1860 }
1861
1862 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1863
1864 uniform = &shProg->Uniforms->Uniforms[location];
1865
1866 if (ctx->Shader.Flags & GLSL_UNIFORMS) {
1867 GLint i;
1868 printf("Mesa: set program %u uniform %s (loc %d) to: ",
1869 shProg->Name, uniform->Name, location);
1870 if (basicType == GL_INT) {
1871 const GLint *v = (const GLint *) values;
1872 for (i = 0; i < count * elems; i++) {
1873 printf("%d ", v[i]);
1874 }
1875 }
1876 else {
1877 const GLfloat *v = (const GLfloat *) values;
1878 for (i = 0; i < count * elems; i++) {
1879 printf("%g ", v[i]);
1880 }
1881 }
1882 printf("\n");
1883 }
1884
1885 /* A uniform var may be used by both a vertex shader and a fragment
1886 * shader. We may need to update one or both shader's uniform here:
1887 */
1888 if (shProg->VertexProgram) {
1889 /* convert uniform location to program parameter index */
1890 GLint index = uniform->VertPos;
1891 if (index >= 0) {
1892 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1893 index, offset, type, count, elems, values);
1894 }
1895 }
1896
1897 if (shProg->FragmentProgram) {
1898 /* convert uniform location to program parameter index */
1899 GLint index = uniform->FragPos;
1900 if (index >= 0) {
1901 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1902 index, offset, type, count, elems, values);
1903 }
1904 }
1905
1906 uniform->Initialized = GL_TRUE;
1907 }
1908
1909
1910 /**
1911 * Set a matrix-valued program parameter.
1912 */
1913 static void
1914 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1915 GLuint index, GLuint offset,
1916 GLuint count, GLuint rows, GLuint cols,
1917 GLboolean transpose, const GLfloat *values)
1918 {
1919 GLuint mat, row, col;
1920 GLuint src = 0;
1921 const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
1922 const GLuint slots = (param->Size + 3) / 4;
1923 const GLint typeSize = sizeof_glsl_type(param->DataType);
1924 GLint nr, nc;
1925
1926 /* check that the number of rows, columns is correct */
1927 get_matrix_dims(param->DataType, &nr, &nc);
1928 if (rows != nr || cols != nc) {
1929 _mesa_error(ctx, GL_INVALID_OPERATION,
1930 "glUniformMatrix(matrix size mismatch)");
1931 return;
1932 }
1933
1934 if ((GLint) param->Size <= typeSize) {
1935 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1936 if (count > 1) {
1937 _mesa_error(ctx, GL_INVALID_OPERATION,
1938 "glUniformMatrix(uniform is not an array)");
1939 return;
1940 }
1941 }
1942
1943 /*
1944 * Note: the _columns_ of a matrix are stored in program registers, not
1945 * the rows. So, the loops below look a little funny.
1946 * XXX could optimize this a bit...
1947 */
1948
1949 /* loop over matrices */
1950 for (mat = 0; mat < count; mat++) {
1951
1952 /* each matrix: */
1953 for (col = 0; col < cols; col++) {
1954 GLfloat *v;
1955 if (offset >= slots) {
1956 /* Ignore writes beyond the end of (the used part of) an array */
1957 return;
1958 }
1959 v = program->Parameters->ParameterValues[index + offset];
1960 for (row = 0; row < rows; row++) {
1961 if (transpose) {
1962 v[row] = values[src + row * cols + col];
1963 }
1964 else {
1965 v[row] = values[src + col * rows + row];
1966 }
1967 }
1968
1969 offset++;
1970 }
1971
1972 src += rows * cols; /* next matrix */
1973 }
1974 }
1975
1976
1977 /**
1978 * Called by ctx->Driver.UniformMatrix().
1979 * Note: cols=2, rows=4 ==> array[2] of vec4
1980 */
1981 static void
1982 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1983 GLint location, GLsizei count,
1984 GLboolean transpose, const GLfloat *values)
1985 {
1986 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1987 struct gl_uniform *uniform;
1988 GLint offset;
1989
1990 if (!shProg || !shProg->LinkStatus) {
1991 _mesa_error(ctx, GL_INVALID_OPERATION,
1992 "glUniformMatrix(program not linked)");
1993 return;
1994 }
1995
1996 if (location == -1)
1997 return; /* The standard specifies this as a no-op */
1998
1999 if (location < -1) {
2000 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
2001 return;
2002 }
2003
2004 split_location_offset(&location, &offset);
2005
2006 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
2007 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
2008 return;
2009 }
2010 if (values == NULL) {
2011 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
2012 return;
2013 }
2014
2015 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
2016
2017 uniform = &shProg->Uniforms->Uniforms[location];
2018
2019 if (shProg->VertexProgram) {
2020 /* convert uniform location to program parameter index */
2021 GLint index = uniform->VertPos;
2022 if (index >= 0) {
2023 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
2024 index, offset,
2025 count, rows, cols, transpose, values);
2026 }
2027 }
2028
2029 if (shProg->FragmentProgram) {
2030 /* convert uniform location to program parameter index */
2031 GLint index = uniform->FragPos;
2032 if (index >= 0) {
2033 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
2034 index, offset,
2035 count, rows, cols, transpose, values);
2036 }
2037 }
2038
2039 uniform->Initialized = GL_TRUE;
2040 }
2041
2042
2043 /**
2044 * Validate a program's samplers.
2045 * Specifically, check that there aren't two samplers of different types
2046 * pointing to the same texture unit.
2047 * \return GL_TRUE if valid, GL_FALSE if invalid
2048 */
2049 static GLboolean
2050 validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
2051 {
2052 static const char *targetName[] = {
2053 "TEXTURE_2D_ARRAY",
2054 "TEXTURE_1D_ARRAY",
2055 "TEXTURE_CUBE",
2056 "TEXTURE_3D",
2057 "TEXTURE_RECT",
2058 "TEXTURE_2D",
2059 "TEXTURE_1D",
2060 };
2061 GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
2062 GLbitfield samplersUsed = prog->SamplersUsed;
2063 GLuint i;
2064
2065 assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
2066
2067 if (samplersUsed == 0x0)
2068 return GL_TRUE;
2069
2070 for (i = 0; i < Elements(targetUsed); i++)
2071 targetUsed[i] = -1;
2072
2073 /* walk over bits which are set in 'samplers' */
2074 while (samplersUsed) {
2075 GLuint unit;
2076 gl_texture_index target;
2077 GLint sampler = _mesa_ffs(samplersUsed) - 1;
2078 assert(sampler >= 0);
2079 assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
2080 unit = prog->SamplerUnits[sampler];
2081 target = prog->SamplerTargets[sampler];
2082 if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
2083 _mesa_snprintf(errMsg, 100,
2084 "Texture unit %d is accessed both as %s and %s",
2085 unit, targetName[targetUsed[unit]], targetName[target]);
2086 return GL_FALSE;
2087 }
2088 targetUsed[unit] = target;
2089 samplersUsed ^= (1 << sampler);
2090 }
2091
2092 return GL_TRUE;
2093 }
2094
2095
2096 /**
2097 * Do validation of the given shader program.
2098 * \param errMsg returns error message if validation fails.
2099 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2100 */
2101 GLboolean
2102 _mesa_validate_shader_program(GLcontext *ctx,
2103 const struct gl_shader_program *shProg,
2104 char *errMsg)
2105 {
2106 const struct gl_vertex_program *vp = shProg->VertexProgram;
2107 const struct gl_fragment_program *fp = shProg->FragmentProgram;
2108
2109 if (!shProg->LinkStatus) {
2110 return GL_FALSE;
2111 }
2112
2113 /* From the GL spec, a program is invalid if any of these are true:
2114
2115 any two active samplers in the current program object are of
2116 different types, but refer to the same texture image unit,
2117
2118 any active sampler in the current program object refers to a texture
2119 image unit where fixed-function fragment processing accesses a
2120 texture target that does not match the sampler type, or
2121
2122 the sum of the number of active samplers in the program and the
2123 number of texture image units enabled for fixed-function fragment
2124 processing exceeds the combined limit on the total number of texture
2125 image units allowed.
2126 */
2127
2128
2129 /*
2130 * Check: any two active samplers in the current program object are of
2131 * different types, but refer to the same texture image unit,
2132 */
2133 if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
2134 return GL_FALSE;
2135 }
2136 if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
2137 return GL_FALSE;
2138 }
2139
2140 return GL_TRUE;
2141 }
2142
2143
2144 /**
2145 * Called via glValidateProgram()
2146 */
2147 static void
2148 _mesa_validate_program(GLcontext *ctx, GLuint program)
2149 {
2150 struct gl_shader_program *shProg;
2151 char errMsg[100];
2152
2153 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
2154 if (!shProg) {
2155 return;
2156 }
2157
2158 shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
2159 if (!shProg->Validated) {
2160 /* update info log */
2161 if (shProg->InfoLog) {
2162 free(shProg->InfoLog);
2163 }
2164 shProg->InfoLog = _mesa_strdup(errMsg);
2165 }
2166 }
2167
2168
2169 /**
2170 * Plug in Mesa's GLSL functions into the device driver function table.
2171 */
2172 void
2173 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
2174 {
2175 driver->AttachShader = _mesa_attach_shader;
2176 driver->BindAttribLocation = _mesa_bind_attrib_location;
2177 driver->CompileShader = _mesa_compile_shader;
2178 driver->CreateProgram = _mesa_create_program;
2179 driver->CreateShader = _mesa_create_shader;
2180 driver->DeleteProgram2 = _mesa_delete_program2;
2181 driver->DeleteShader = _mesa_delete_shader;
2182 driver->DetachShader = _mesa_detach_shader;
2183 driver->GetActiveAttrib = _mesa_get_active_attrib;
2184 driver->GetActiveUniform = _mesa_get_active_uniform;
2185 driver->GetAttachedShaders = _mesa_get_attached_shaders;
2186 driver->GetAttribLocation = _mesa_get_attrib_location;
2187 driver->GetHandle = _mesa_get_handle;
2188 driver->GetProgramiv = _mesa_get_programiv;
2189 driver->GetProgramInfoLog = _mesa_get_program_info_log;
2190 driver->GetShaderiv = _mesa_get_shaderiv;
2191 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
2192 driver->GetShaderSource = _mesa_get_shader_source;
2193 driver->GetUniformfv = _mesa_get_uniformfv;
2194 driver->GetUniformiv = _mesa_get_uniformiv;
2195 driver->GetUniformLocation = _mesa_get_uniform_location;
2196 driver->IsProgram = _mesa_is_program;
2197 driver->IsShader = _mesa_is_shader;
2198 driver->LinkProgram = _mesa_link_program;
2199 driver->ShaderSource = _mesa_shader_source;
2200 driver->Uniform = _mesa_uniform;
2201 driver->UniformMatrix = _mesa_uniform_matrix;
2202 driver->UseProgram = _mesa_use_program;
2203 driver->ValidateProgram = _mesa_validate_program;
2204 }