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