mesa: fix double->float assignment warnings, int/uint comparison warnings
[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 "glapi/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 _mesa_free(shProg->Shaders);
119 shProg->Shaders = NULL;
120 }
121
122 if (shProg->InfoLog) {
123 _mesa_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 _mesa_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 _mesa_free((void *) sh->Source);
266 if (sh->InfoLog)
267 _mesa_free(sh->InfoLog);
268 _mesa_reference_program(ctx, &sh->Program, NULL);
269 _mesa_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 (_mesa_strstr(env, "dump"))
378 flags |= GLSL_DUMP;
379 if (_mesa_strstr(env, "log"))
380 flags |= GLSL_LOG;
381 if (_mesa_strstr(env, "nopvert"))
382 flags |= GLSL_NOP_VERT;
383 if (_mesa_strstr(env, "nopfrag"))
384 flags |= GLSL_NOP_FRAG;
385 if (_mesa_strstr(env, "nopt"))
386 flags |= GLSL_NO_OPT;
387 else if (_mesa_strstr(env, "opt"))
388 flags |= GLSL_OPT;
389 if (_mesa_strstr(env, "uniform"))
390 flags |= GLSL_UNIFORMS;
391 if (_mesa_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 _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 ((GLint) 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 * Print basic shader info (for debug).
1501 */
1502 static void
1503 print_shader_info(const struct gl_shader_program *shProg)
1504 {
1505 GLuint i;
1506
1507 _mesa_printf("Mesa: glUseProgram(%u)\n", shProg->Name);
1508 for (i = 0; i < shProg->NumShaders; i++) {
1509 const char *s;
1510 switch (shProg->Shaders[i]->Type) {
1511 case GL_VERTEX_SHADER:
1512 s = "vertex";
1513 break;
1514 case GL_FRAGMENT_SHADER:
1515 s = "fragment";
1516 break;
1517 case GL_GEOMETRY_SHADER:
1518 s = "geometry";
1519 break;
1520 default:
1521 s = "";
1522 }
1523 _mesa_printf(" %s shader %u, checksum %u\n", s,
1524 shProg->Shaders[i]->Name,
1525 shProg->Shaders[i]->SourceChecksum);
1526 }
1527 if (shProg->VertexProgram)
1528 _mesa_printf(" vert prog %u\n", shProg->VertexProgram->Base.Id);
1529 if (shProg->FragmentProgram)
1530 _mesa_printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id);
1531 }
1532
1533
1534 /**
1535 * Called via ctx->Driver.UseProgram()
1536 */
1537 void
1538 _mesa_use_program(GLcontext *ctx, GLuint program)
1539 {
1540 struct gl_shader_program *shProg;
1541
1542 if (ctx->Shader.CurrentProgram &&
1543 ctx->Shader.CurrentProgram->Name == program) {
1544 /* no-op */
1545 return;
1546 }
1547
1548 if (program) {
1549 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1550 if (!shProg) {
1551 return;
1552 }
1553 if (!shProg->LinkStatus) {
1554 _mesa_error(ctx, GL_INVALID_OPERATION,
1555 "glUseProgram(program %u not linked)", program);
1556 return;
1557 }
1558
1559 /* debug code */
1560 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1561 print_shader_info(shProg);
1562 }
1563 }
1564 else {
1565 shProg = NULL;
1566 }
1567
1568 if (ctx->Shader.CurrentProgram != shProg) {
1569 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1570 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1571 }
1572 }
1573
1574
1575
1576 /**
1577 * Update the vertex/fragment program's TexturesUsed array.
1578 *
1579 * This needs to be called after glUniform(set sampler var) is called.
1580 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1581 * particular texture unit. We know the sampler's texture target
1582 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1583 * set by glUniform() calls.
1584 *
1585 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1586 * information to update the prog->TexturesUsed[] values.
1587 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1588 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1589 * We'll use that info for state validation before rendering.
1590 */
1591 void
1592 _mesa_update_shader_textures_used(struct gl_program *prog)
1593 {
1594 GLuint s;
1595
1596 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1597
1598 for (s = 0; s < MAX_SAMPLERS; s++) {
1599 if (prog->SamplersUsed & (1 << s)) {
1600 GLuint unit = prog->SamplerUnits[s];
1601 GLuint tgt = prog->SamplerTargets[s];
1602 assert(unit < MAX_TEXTURE_IMAGE_UNITS);
1603 assert(tgt < NUM_TEXTURE_TARGETS);
1604 prog->TexturesUsed[unit] |= (1 << tgt);
1605 }
1606 }
1607 }
1608
1609
1610 /**
1611 * Check if the type given by userType is allowed to set a uniform of the
1612 * target type. Generally, equivalence is required, but setting Boolean
1613 * uniforms can be done with glUniformiv or glUniformfv.
1614 */
1615 static GLboolean
1616 compatible_types(GLenum userType, GLenum targetType)
1617 {
1618 if (userType == targetType)
1619 return GL_TRUE;
1620
1621 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1622 return GL_TRUE;
1623
1624 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1625 userType == GL_INT_VEC2))
1626 return GL_TRUE;
1627
1628 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1629 userType == GL_INT_VEC3))
1630 return GL_TRUE;
1631
1632 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1633 userType == GL_INT_VEC4))
1634 return GL_TRUE;
1635
1636 if (is_sampler_type(targetType) && userType == GL_INT)
1637 return GL_TRUE;
1638
1639 return GL_FALSE;
1640 }
1641
1642
1643 /**
1644 * Set the value of a program's uniform variable.
1645 * \param program the program whose uniform to update
1646 * \param index the index of the program parameter for the uniform
1647 * \param offset additional parameter slot offset (for arrays)
1648 * \param type the incoming datatype of 'values'
1649 * \param count the number of uniforms to set
1650 * \param elems number of elements per uniform (1, 2, 3 or 4)
1651 * \param values the new values, of datatype 'type'
1652 */
1653 static void
1654 set_program_uniform(GLcontext *ctx, struct gl_program *program,
1655 GLint index, GLint offset,
1656 GLenum type, GLsizei count, GLint elems,
1657 const void *values)
1658 {
1659 const struct gl_program_parameter *param =
1660 &program->Parameters->Parameters[index];
1661
1662 assert(offset >= 0);
1663 assert(elems >= 1);
1664 assert(elems <= 4);
1665
1666 if (!compatible_types(type, param->DataType)) {
1667 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1668 return;
1669 }
1670
1671 if (index + offset > (GLint) program->Parameters->Size) {
1672 /* out of bounds! */
1673 return;
1674 }
1675
1676 if (param->Type == PROGRAM_SAMPLER) {
1677 /* This controls which texture unit which is used by a sampler */
1678 GLboolean changed = GL_FALSE;
1679 GLint i;
1680
1681 /* this should have been caught by the compatible_types() check */
1682 ASSERT(type == GL_INT);
1683
1684 /* loop over number of samplers to change */
1685 for (i = 0; i < count; i++) {
1686 GLuint sampler =
1687 (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
1688 GLuint texUnit = ((GLuint *) values)[i];
1689
1690 /* check that the sampler (tex unit index) is legal */
1691 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1692 _mesa_error(ctx, GL_INVALID_VALUE,
1693 "glUniform1(invalid sampler/tex unit index)");
1694 return;
1695 }
1696
1697 /* This maps a sampler to a texture unit: */
1698 if (sampler < MAX_SAMPLERS) {
1699 #if 0
1700 _mesa_printf("Set program %p sampler %d '%s' to unit %u\n",
1701 program, sampler, param->Name, texUnit);
1702 #endif
1703 if (program->SamplerUnits[sampler] != texUnit) {
1704 program->SamplerUnits[sampler] = texUnit;
1705 changed = GL_TRUE;
1706 }
1707 }
1708 }
1709
1710 if (changed) {
1711 /* When a sampler's value changes it usually requires rewriting
1712 * a GPU program's TEX instructions since there may not be a
1713 * sampler->texture lookup table. We signal this with the
1714 * ProgramStringNotify() callback.
1715 */
1716 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
1717 _mesa_update_shader_textures_used(program);
1718 ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
1719 }
1720 }
1721 else {
1722 /* ordinary uniform variable */
1723 const GLboolean isUniformBool = is_boolean_type(param->DataType);
1724 const GLboolean areIntValues = is_integer_type(type);
1725 const GLint slots = (param->Size + 3) / 4;
1726 const GLint typeSize = sizeof_glsl_type(param->DataType);
1727 GLsizei k, i;
1728
1729 if ((GLint) param->Size > typeSize) {
1730 /* an array */
1731 /* we'll ignore extra data below */
1732 }
1733 else {
1734 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1735 if (count > 1) {
1736 _mesa_error(ctx, GL_INVALID_OPERATION,
1737 "glUniform(uniform is not an array)");
1738 return;
1739 }
1740 }
1741
1742 /* loop over number of array elements */
1743 for (k = 0; k < count; k++) {
1744 GLfloat *uniformVal;
1745
1746 if (offset + k >= slots) {
1747 /* Extra array data is ignored */
1748 break;
1749 }
1750
1751 /* uniformVal (the destination) is always float[4] */
1752 uniformVal = program->Parameters->ParameterValues[index + offset + k];
1753
1754 if (areIntValues) {
1755 /* convert user's ints to floats */
1756 const GLint *iValues = ((const GLint *) values) + k * elems;
1757 for (i = 0; i < elems; i++) {
1758 uniformVal[i] = (GLfloat) iValues[i];
1759 }
1760 }
1761 else {
1762 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1763 for (i = 0; i < elems; i++) {
1764 uniformVal[i] = fValues[i];
1765 }
1766 }
1767
1768 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1769 if (isUniformBool) {
1770 for (i = 0; i < elems; i++) {
1771 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1772 }
1773 }
1774 }
1775 }
1776 }
1777
1778
1779 /**
1780 * Called via ctx->Driver.Uniform().
1781 */
1782 static void
1783 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1784 const GLvoid *values, GLenum type)
1785 {
1786 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1787 struct gl_uniform *uniform;
1788 GLint elems, offset;
1789 GLenum basicType;
1790
1791 if (!shProg || !shProg->LinkStatus) {
1792 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1793 return;
1794 }
1795
1796 if (location == -1)
1797 return; /* The standard specifies this as a no-op */
1798
1799 if (location < -1) {
1800 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)");
1801 return;
1802 }
1803
1804 split_location_offset(&location, &offset);
1805
1806 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1807 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1808 return;
1809 }
1810
1811 if (count < 0) {
1812 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1813 return;
1814 }
1815
1816 switch (type) {
1817 case GL_FLOAT:
1818 basicType = GL_FLOAT;
1819 elems = 1;
1820 break;
1821 case GL_INT:
1822 basicType = GL_INT;
1823 elems = 1;
1824 break;
1825 case GL_FLOAT_VEC2:
1826 basicType = GL_FLOAT;
1827 elems = 2;
1828 break;
1829 case GL_INT_VEC2:
1830 basicType = GL_INT;
1831 elems = 2;
1832 break;
1833 case GL_FLOAT_VEC3:
1834 basicType = GL_FLOAT;
1835 elems = 3;
1836 break;
1837 case GL_INT_VEC3:
1838 basicType = GL_INT;
1839 elems = 3;
1840 break;
1841 case GL_FLOAT_VEC4:
1842 basicType = GL_FLOAT;
1843 elems = 4;
1844 break;
1845 case GL_INT_VEC4:
1846 basicType = GL_INT;
1847 elems = 4;
1848 break;
1849 default:
1850 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1851 return;
1852 }
1853
1854 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1855
1856 uniform = &shProg->Uniforms->Uniforms[location];
1857
1858 if (ctx->Shader.Flags & GLSL_UNIFORMS) {
1859 GLint i;
1860 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1861 shProg->Name, uniform->Name, location);
1862 if (basicType == GL_INT) {
1863 const GLint *v = (const GLint *) values;
1864 for (i = 0; i < count * elems; i++) {
1865 _mesa_printf("%d ", v[i]);
1866 }
1867 }
1868 else {
1869 const GLfloat *v = (const GLfloat *) values;
1870 for (i = 0; i < count * elems; i++) {
1871 _mesa_printf("%g ", v[i]);
1872 }
1873 }
1874 _mesa_printf("\n");
1875 }
1876
1877 /* A uniform var may be used by both a vertex shader and a fragment
1878 * shader. We may need to update one or both shader's uniform here:
1879 */
1880 if (shProg->VertexProgram) {
1881 /* convert uniform location to program parameter index */
1882 GLint index = uniform->VertPos;
1883 if (index >= 0) {
1884 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1885 index, offset, type, count, elems, values);
1886 }
1887 }
1888
1889 if (shProg->FragmentProgram) {
1890 /* convert uniform location to program parameter index */
1891 GLint index = uniform->FragPos;
1892 if (index >= 0) {
1893 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1894 index, offset, type, count, elems, values);
1895 }
1896 }
1897
1898 uniform->Initialized = GL_TRUE;
1899 }
1900
1901
1902 /**
1903 * Set a matrix-valued program parameter.
1904 */
1905 static void
1906 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1907 GLuint index, GLuint offset,
1908 GLuint count, GLuint rows, GLuint cols,
1909 GLboolean transpose, const GLfloat *values)
1910 {
1911 GLuint mat, row, col;
1912 GLuint src = 0;
1913 const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
1914 const GLuint slots = (param->Size + 3) / 4;
1915 const GLint typeSize = sizeof_glsl_type(param->DataType);
1916 GLint nr, nc;
1917
1918 /* check that the number of rows, columns is correct */
1919 get_matrix_dims(param->DataType, &nr, &nc);
1920 if (rows != nr || cols != nc) {
1921 _mesa_error(ctx, GL_INVALID_OPERATION,
1922 "glUniformMatrix(matrix size mismatch)");
1923 return;
1924 }
1925
1926 if ((GLint) param->Size <= typeSize) {
1927 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1928 if (count > 1) {
1929 _mesa_error(ctx, GL_INVALID_OPERATION,
1930 "glUniformMatrix(uniform is not an array)");
1931 return;
1932 }
1933 }
1934
1935 /*
1936 * Note: the _columns_ of a matrix are stored in program registers, not
1937 * the rows. So, the loops below look a little funny.
1938 * XXX could optimize this a bit...
1939 */
1940
1941 /* loop over matrices */
1942 for (mat = 0; mat < count; mat++) {
1943
1944 /* each matrix: */
1945 for (col = 0; col < cols; col++) {
1946 GLfloat *v;
1947 if (offset >= slots) {
1948 /* Ignore writes beyond the end of (the used part of) an array */
1949 return;
1950 }
1951 v = program->Parameters->ParameterValues[index + offset];
1952 for (row = 0; row < rows; row++) {
1953 if (transpose) {
1954 v[row] = values[src + row * cols + col];
1955 }
1956 else {
1957 v[row] = values[src + col * rows + row];
1958 }
1959 }
1960
1961 offset++;
1962 }
1963
1964 src += rows * cols; /* next matrix */
1965 }
1966 }
1967
1968
1969 /**
1970 * Called by ctx->Driver.UniformMatrix().
1971 * Note: cols=2, rows=4 ==> array[2] of vec4
1972 */
1973 static void
1974 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1975 GLint location, GLsizei count,
1976 GLboolean transpose, const GLfloat *values)
1977 {
1978 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1979 struct gl_uniform *uniform;
1980 GLint offset;
1981
1982 if (!shProg || !shProg->LinkStatus) {
1983 _mesa_error(ctx, GL_INVALID_OPERATION,
1984 "glUniformMatrix(program not linked)");
1985 return;
1986 }
1987
1988 if (location == -1)
1989 return; /* The standard specifies this as a no-op */
1990
1991 if (location < -1) {
1992 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
1993 return;
1994 }
1995
1996 split_location_offset(&location, &offset);
1997
1998 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1999 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
2000 return;
2001 }
2002 if (values == NULL) {
2003 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
2004 return;
2005 }
2006
2007 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
2008
2009 uniform = &shProg->Uniforms->Uniforms[location];
2010
2011 if (shProg->VertexProgram) {
2012 /* convert uniform location to program parameter index */
2013 GLint index = uniform->VertPos;
2014 if (index >= 0) {
2015 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
2016 index, offset,
2017 count, rows, cols, transpose, values);
2018 }
2019 }
2020
2021 if (shProg->FragmentProgram) {
2022 /* convert uniform location to program parameter index */
2023 GLint index = uniform->FragPos;
2024 if (index >= 0) {
2025 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
2026 index, offset,
2027 count, rows, cols, transpose, values);
2028 }
2029 }
2030
2031 uniform->Initialized = GL_TRUE;
2032 }
2033
2034
2035 /**
2036 * Validate a program's samplers.
2037 * Specifically, check that there aren't two samplers of different types
2038 * pointing to the same texture unit.
2039 * \return GL_TRUE if valid, GL_FALSE if invalid
2040 */
2041 static GLboolean
2042 validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
2043 {
2044 static const char *targetName[] = {
2045 "TEXTURE_2D_ARRAY",
2046 "TEXTURE_1D_ARRAY",
2047 "TEXTURE_CUBE",
2048 "TEXTURE_3D",
2049 "TEXTURE_RECT",
2050 "TEXTURE_2D",
2051 "TEXTURE_1D",
2052 };
2053 GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
2054 GLbitfield samplersUsed = prog->SamplersUsed;
2055 GLuint i;
2056
2057 assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
2058
2059 if (samplersUsed == 0x0)
2060 return GL_TRUE;
2061
2062 for (i = 0; i < Elements(targetUsed); i++)
2063 targetUsed[i] = -1;
2064
2065 /* walk over bits which are set in 'samplers' */
2066 while (samplersUsed) {
2067 GLuint unit;
2068 gl_texture_index target;
2069 GLint sampler = _mesa_ffs(samplersUsed) - 1;
2070 assert(sampler >= 0);
2071 assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
2072 unit = prog->SamplerUnits[sampler];
2073 target = prog->SamplerTargets[sampler];
2074 if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
2075 _mesa_snprintf(errMsg, 100,
2076 "Texture unit %d is accessed both as %s and %s",
2077 unit, targetName[targetUsed[unit]], targetName[target]);
2078 return GL_FALSE;
2079 }
2080 targetUsed[unit] = target;
2081 samplersUsed ^= (1 << sampler);
2082 }
2083
2084 return GL_TRUE;
2085 }
2086
2087
2088 /**
2089 * Do validation of the given shader program.
2090 * \param errMsg returns error message if validation fails.
2091 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2092 */
2093 GLboolean
2094 _mesa_validate_shader_program(GLcontext *ctx,
2095 const struct gl_shader_program *shProg,
2096 char *errMsg)
2097 {
2098 const struct gl_vertex_program *vp = shProg->VertexProgram;
2099 const struct gl_fragment_program *fp = shProg->FragmentProgram;
2100
2101 if (!shProg->LinkStatus) {
2102 return GL_FALSE;
2103 }
2104
2105 /* From the GL spec, a program is invalid if any of these are true:
2106
2107 any two active samplers in the current program object are of
2108 different types, but refer to the same texture image unit,
2109
2110 any active sampler in the current program object refers to a texture
2111 image unit where fixed-function fragment processing accesses a
2112 texture target that does not match the sampler type, or
2113
2114 the sum of the number of active samplers in the program and the
2115 number of texture image units enabled for fixed-function fragment
2116 processing exceeds the combined limit on the total number of texture
2117 image units allowed.
2118 */
2119
2120
2121 /*
2122 * Check: any two active samplers in the current program object are of
2123 * different types, but refer to the same texture image unit,
2124 */
2125 if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
2126 return GL_FALSE;
2127 }
2128 if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
2129 return GL_FALSE;
2130 }
2131
2132 return GL_TRUE;
2133 }
2134
2135
2136 /**
2137 * Called via glValidateProgram()
2138 */
2139 static void
2140 _mesa_validate_program(GLcontext *ctx, GLuint program)
2141 {
2142 struct gl_shader_program *shProg;
2143 char errMsg[100];
2144
2145 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
2146 if (!shProg) {
2147 return;
2148 }
2149
2150 shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
2151 if (!shProg->Validated) {
2152 /* update info log */
2153 if (shProg->InfoLog) {
2154 _mesa_free(shProg->InfoLog);
2155 }
2156 shProg->InfoLog = _mesa_strdup(errMsg);
2157 }
2158 }
2159
2160
2161 /**
2162 * Plug in Mesa's GLSL functions into the device driver function table.
2163 */
2164 void
2165 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
2166 {
2167 driver->AttachShader = _mesa_attach_shader;
2168 driver->BindAttribLocation = _mesa_bind_attrib_location;
2169 driver->CompileShader = _mesa_compile_shader;
2170 driver->CreateProgram = _mesa_create_program;
2171 driver->CreateShader = _mesa_create_shader;
2172 driver->DeleteProgram2 = _mesa_delete_program2;
2173 driver->DeleteShader = _mesa_delete_shader;
2174 driver->DetachShader = _mesa_detach_shader;
2175 driver->GetActiveAttrib = _mesa_get_active_attrib;
2176 driver->GetActiveUniform = _mesa_get_active_uniform;
2177 driver->GetAttachedShaders = _mesa_get_attached_shaders;
2178 driver->GetAttribLocation = _mesa_get_attrib_location;
2179 driver->GetHandle = _mesa_get_handle;
2180 driver->GetProgramiv = _mesa_get_programiv;
2181 driver->GetProgramInfoLog = _mesa_get_program_info_log;
2182 driver->GetShaderiv = _mesa_get_shaderiv;
2183 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
2184 driver->GetShaderSource = _mesa_get_shader_source;
2185 driver->GetUniformfv = _mesa_get_uniformfv;
2186 driver->GetUniformiv = _mesa_get_uniformiv;
2187 driver->GetUniformLocation = _mesa_get_uniform_location;
2188 driver->IsProgram = _mesa_is_program;
2189 driver->IsShader = _mesa_is_shader;
2190 driver->LinkProgram = _mesa_link_program;
2191 driver->ShaderSource = _mesa_shader_source;
2192 driver->Uniform = _mesa_uniform;
2193 driver->UniformMatrix = _mesa_uniform_matrix;
2194 driver->UseProgram = _mesa_use_program;
2195 driver->ValidateProgram = _mesa_validate_program;
2196 }