Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / shader / shader_api.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.6
4 *
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file shader_api.c
28 * Implementation of GLSL-related API functions
29 * \author Brian Paul
30 */
31
32 /**
33 * XXX things to do:
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
36 */
37
38
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/hash.h"
42 #include "main/macros.h"
43 #include "shader/program.h"
44 #include "shader/prog_parameter.h"
45 #include "shader/prog_print.h"
46 #include "shader/prog_statevars.h"
47 #include "shader/prog_uniform.h"
48 #include "shader/shader_api.h"
49 #include "shader/slang/slang_compile.h"
50 #include "shader/slang/slang_link.h"
51 #include "glapi/dispatch.h"
52
53
54 /**
55 * Allocate a new gl_shader_program object, initialize it.
56 */
57 static struct gl_shader_program *
58 _mesa_new_shader_program(GLcontext *ctx, GLuint name)
59 {
60 struct gl_shader_program *shProg;
61 shProg = CALLOC_STRUCT(gl_shader_program);
62 if (shProg) {
63 shProg->Type = GL_SHADER_PROGRAM_MESA;
64 shProg->Name = name;
65 shProg->RefCount = 1;
66 shProg->Attributes = _mesa_new_parameter_list();
67 }
68 return shProg;
69 }
70
71
72 /**
73 * Clear (free) the shader program state that gets produced by linking.
74 */
75 void
76 _mesa_clear_shader_program_data(GLcontext *ctx,
77 struct gl_shader_program *shProg)
78 {
79 _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
80 _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
81
82 if (shProg->Uniforms) {
83 _mesa_free_uniform_list(shProg->Uniforms);
84 shProg->Uniforms = NULL;
85 }
86
87 if (shProg->Varying) {
88 _mesa_free_parameter_list(shProg->Varying);
89 shProg->Varying = NULL;
90 }
91 }
92
93
94 /**
95 * Free all the data that hangs off a shader program object, but not the
96 * object itself.
97 */
98 void
99 _mesa_free_shader_program_data(GLcontext *ctx,
100 struct gl_shader_program *shProg)
101 {
102 GLuint i;
103
104 assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
105
106 _mesa_clear_shader_program_data(ctx, shProg);
107
108 if (shProg->Attributes) {
109 _mesa_free_parameter_list(shProg->Attributes);
110 shProg->Attributes = NULL;
111 }
112
113 /* detach shaders */
114 for (i = 0; i < shProg->NumShaders; i++) {
115 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
116 }
117 shProg->NumShaders = 0;
118
119 if (shProg->Shaders) {
120 _mesa_free(shProg->Shaders);
121 shProg->Shaders = NULL;
122 }
123
124 if (shProg->InfoLog) {
125 _mesa_free(shProg->InfoLog);
126 shProg->InfoLog = NULL;
127 }
128 }
129
130
131 /**
132 * Free/delete a shader program object.
133 */
134 void
135 _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
136 {
137 _mesa_free_shader_program_data(ctx, shProg);
138
139 _mesa_free(shProg);
140 }
141
142
143 /**
144 * Set ptr to point to shProg.
145 * If ptr is pointing to another object, decrement its refcount (and delete
146 * if refcount hits zero).
147 * Then set ptr to point to shProg, incrementing its refcount.
148 */
149 /* XXX this could be static */
150 void
151 _mesa_reference_shader_program(GLcontext *ctx,
152 struct gl_shader_program **ptr,
153 struct gl_shader_program *shProg)
154 {
155 assert(ptr);
156 if (*ptr == shProg) {
157 /* no-op */
158 return;
159 }
160 if (*ptr) {
161 /* Unreference the old shader program */
162 GLboolean deleteFlag = GL_FALSE;
163 struct gl_shader_program *old = *ptr;
164
165 ASSERT(old->RefCount > 0);
166 old->RefCount--;
167 #if 0
168 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
169 (void *) old, old->Name, old->RefCount);
170 #endif
171 deleteFlag = (old->RefCount == 0);
172
173 if (deleteFlag) {
174 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
175 _mesa_free_shader_program(ctx, old);
176 }
177
178 *ptr = NULL;
179 }
180 assert(!*ptr);
181
182 if (shProg) {
183 shProg->RefCount++;
184 #if 0
185 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
186 (void *) shProg, shProg->Name, shProg->RefCount);
187 #endif
188 *ptr = shProg;
189 }
190 }
191
192
193 /**
194 * Lookup a GLSL program object.
195 */
196 struct gl_shader_program *
197 _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
198 {
199 struct gl_shader_program *shProg;
200 if (name) {
201 shProg = (struct gl_shader_program *)
202 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
203 /* Note that both gl_shader and gl_shader_program objects are kept
204 * in the same hash table. Check the object's type to be sure it's
205 * what we're expecting.
206 */
207 if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
208 return NULL;
209 }
210 return shProg;
211 }
212 return NULL;
213 }
214
215
216 /**
217 * As above, but record an error if program is not found.
218 */
219 static struct gl_shader_program *
220 _mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
221 const char *caller)
222 {
223 if (!name) {
224 _mesa_error(ctx, GL_INVALID_VALUE, caller);
225 return NULL;
226 }
227 else {
228 struct gl_shader_program *shProg = (struct gl_shader_program *)
229 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
230 if (!shProg) {
231 _mesa_error(ctx, GL_INVALID_VALUE, caller);
232 return NULL;
233 }
234 if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
235 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
236 return NULL;
237 }
238 return shProg;
239 }
240 }
241
242
243
244
245 /**
246 * Allocate a new gl_shader object, initialize it.
247 */
248 struct gl_shader *
249 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
250 {
251 struct gl_shader *shader;
252 assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
253 shader = CALLOC_STRUCT(gl_shader);
254 if (shader) {
255 shader->Type = type;
256 shader->Name = name;
257 shader->RefCount = 1;
258 }
259 return shader;
260 }
261
262
263 void
264 _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
265 {
266 if (sh->Source)
267 _mesa_free((void *) sh->Source);
268 if (sh->InfoLog)
269 _mesa_free(sh->InfoLog);
270 _mesa_reference_program(ctx, &sh->Program, NULL);
271 _mesa_free(sh);
272 }
273
274
275 /**
276 * Set ptr to point to sh.
277 * If ptr is pointing to another shader, decrement its refcount (and delete
278 * if refcount hits zero).
279 * Then set ptr to point to sh, incrementing its refcount.
280 */
281 /* XXX this could be static */
282 void
283 _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
284 struct gl_shader *sh)
285 {
286 assert(ptr);
287 if (*ptr == sh) {
288 /* no-op */
289 return;
290 }
291 if (*ptr) {
292 /* Unreference the old shader */
293 GLboolean deleteFlag = GL_FALSE;
294 struct gl_shader *old = *ptr;
295
296 ASSERT(old->RefCount > 0);
297 old->RefCount--;
298 /*printf("SHADER DECR %p (%d) to %d\n",
299 (void*) old, old->Name, old->RefCount);*/
300 deleteFlag = (old->RefCount == 0);
301
302 if (deleteFlag) {
303 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
304 _mesa_free_shader(ctx, old);
305 }
306
307 *ptr = NULL;
308 }
309 assert(!*ptr);
310
311 if (sh) {
312 /* reference new */
313 sh->RefCount++;
314 /*printf("SHADER INCR %p (%d) to %d\n",
315 (void*) sh, sh->Name, sh->RefCount);*/
316 *ptr = sh;
317 }
318 }
319
320
321 /**
322 * Lookup a GLSL shader object.
323 */
324 struct gl_shader *
325 _mesa_lookup_shader(GLcontext *ctx, GLuint name)
326 {
327 if (name) {
328 struct gl_shader *sh = (struct gl_shader *)
329 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
330 /* Note that both gl_shader and gl_shader_program objects are kept
331 * in the same hash table. Check the object's type to be sure it's
332 * what we're expecting.
333 */
334 if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
335 return NULL;
336 }
337 return sh;
338 }
339 return NULL;
340 }
341
342
343 /**
344 * As above, but record an error if shader is not found.
345 */
346 static struct gl_shader *
347 _mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
348 {
349 if (!name) {
350 _mesa_error(ctx, GL_INVALID_VALUE, caller);
351 return NULL;
352 }
353 else {
354 struct gl_shader *sh = (struct gl_shader *)
355 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
356 if (!sh) {
357 _mesa_error(ctx, GL_INVALID_VALUE, caller);
358 return NULL;
359 }
360 if (sh->Type == GL_SHADER_PROGRAM_MESA) {
361 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
362 return NULL;
363 }
364 return sh;
365 }
366 }
367
368
369 /**
370 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
371 */
372 static GLbitfield
373 get_shader_flags(void)
374 {
375 GLbitfield flags = 0x0;
376 const char *env = _mesa_getenv("MESA_GLSL");
377
378 if (env) {
379 if (_mesa_strstr(env, "dump"))
380 flags |= GLSL_DUMP;
381 if (_mesa_strstr(env, "log"))
382 flags |= GLSL_LOG;
383 if (_mesa_strstr(env, "nopvert"))
384 flags |= GLSL_NOP_VERT;
385 if (_mesa_strstr(env, "nopfrag"))
386 flags |= GLSL_NOP_FRAG;
387 if (_mesa_strstr(env, "nopt"))
388 flags |= GLSL_NO_OPT;
389 else if (_mesa_strstr(env, "opt"))
390 flags |= GLSL_OPT;
391 if (_mesa_strstr(env, "uniform"))
392 flags |= GLSL_UNIFORMS;
393 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 if (program) {
1551 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1552 if (!shProg) {
1553 return;
1554 }
1555 if (!shProg->LinkStatus) {
1556 _mesa_error(ctx, GL_INVALID_OPERATION,
1557 "glUseProgram(program %u not linked)", program);
1558 return;
1559 }
1560
1561 /* debug code */
1562 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1563 print_shader_info(shProg);
1564 }
1565 }
1566 else {
1567 shProg = NULL;
1568 }
1569
1570 if (ctx->Shader.CurrentProgram != shProg) {
1571 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1572 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1573 }
1574 }
1575
1576
1577
1578 /**
1579 * Update the vertex/fragment program's TexturesUsed array.
1580 *
1581 * This needs to be called after glUniform(set sampler var) is called.
1582 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1583 * particular texture unit. We know the sampler's texture target
1584 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1585 * set by glUniform() calls.
1586 *
1587 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1588 * information to update the prog->TexturesUsed[] values.
1589 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1590 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1591 * We'll use that info for state validation before rendering.
1592 */
1593 void
1594 _mesa_update_shader_textures_used(struct gl_program *prog)
1595 {
1596 GLuint s;
1597
1598 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1599
1600 for (s = 0; s < MAX_SAMPLERS; s++) {
1601 if (prog->SamplersUsed & (1 << s)) {
1602 GLuint unit = prog->SamplerUnits[s];
1603 GLuint tgt = prog->SamplerTargets[s];
1604 assert(unit < MAX_TEXTURE_IMAGE_UNITS);
1605 assert(tgt < NUM_TEXTURE_TARGETS);
1606 prog->TexturesUsed[unit] |= (1 << tgt);
1607 }
1608 }
1609 }
1610
1611
1612 /**
1613 * Check if the type given by userType is allowed to set a uniform of the
1614 * target type. Generally, equivalence is required, but setting Boolean
1615 * uniforms can be done with glUniformiv or glUniformfv.
1616 */
1617 static GLboolean
1618 compatible_types(GLenum userType, GLenum targetType)
1619 {
1620 if (userType == targetType)
1621 return GL_TRUE;
1622
1623 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1624 return GL_TRUE;
1625
1626 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1627 userType == GL_INT_VEC2))
1628 return GL_TRUE;
1629
1630 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1631 userType == GL_INT_VEC3))
1632 return GL_TRUE;
1633
1634 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1635 userType == GL_INT_VEC4))
1636 return GL_TRUE;
1637
1638 if (is_sampler_type(targetType) && userType == GL_INT)
1639 return GL_TRUE;
1640
1641 return GL_FALSE;
1642 }
1643
1644
1645 /**
1646 * Set the value of a program's uniform variable.
1647 * \param program the program whose uniform to update
1648 * \param index the index of the program parameter for the uniform
1649 * \param offset additional parameter slot offset (for arrays)
1650 * \param type the incoming datatype of 'values'
1651 * \param count the number of uniforms to set
1652 * \param elems number of elements per uniform (1, 2, 3 or 4)
1653 * \param values the new values, of datatype 'type'
1654 */
1655 static void
1656 set_program_uniform(GLcontext *ctx, struct gl_program *program,
1657 GLint index, GLint offset,
1658 GLenum type, GLsizei count, GLint elems,
1659 const void *values)
1660 {
1661 const struct gl_program_parameter *param =
1662 &program->Parameters->Parameters[index];
1663
1664 assert(offset >= 0);
1665 assert(elems >= 1);
1666 assert(elems <= 4);
1667
1668 if (!compatible_types(type, param->DataType)) {
1669 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1670 return;
1671 }
1672
1673 if (index + offset > (GLint) program->Parameters->Size) {
1674 /* out of bounds! */
1675 return;
1676 }
1677
1678 if (param->Type == PROGRAM_SAMPLER) {
1679 /* This controls which texture unit which is used by a sampler */
1680 GLboolean changed = GL_FALSE;
1681 GLint i;
1682
1683 /* this should have been caught by the compatible_types() check */
1684 ASSERT(type == GL_INT);
1685
1686 /* loop over number of samplers to change */
1687 for (i = 0; i < count; i++) {
1688 GLuint sampler =
1689 (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
1690 GLuint texUnit = ((GLuint *) values)[i];
1691
1692 /* check that the sampler (tex unit index) is legal */
1693 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1694 _mesa_error(ctx, GL_INVALID_VALUE,
1695 "glUniform1(invalid sampler/tex unit index)");
1696 return;
1697 }
1698
1699 /* This maps a sampler to a texture unit: */
1700 if (sampler < MAX_SAMPLERS) {
1701 #if 0
1702 _mesa_printf("Set program %p sampler %d '%s' to unit %u\n",
1703 program, sampler, param->Name, texUnit);
1704 #endif
1705 if (program->SamplerUnits[sampler] != texUnit) {
1706 program->SamplerUnits[sampler] = texUnit;
1707 changed = GL_TRUE;
1708 }
1709 }
1710 }
1711
1712 if (changed) {
1713 /* When a sampler's value changes it usually requires rewriting
1714 * a GPU program's TEX instructions since there may not be a
1715 * sampler->texture lookup table. We signal this with the
1716 * ProgramStringNotify() callback.
1717 */
1718 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
1719 _mesa_update_shader_textures_used(program);
1720 ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
1721 }
1722 }
1723 else {
1724 /* ordinary uniform variable */
1725 const GLboolean isUniformBool = is_boolean_type(param->DataType);
1726 const GLboolean areIntValues = is_integer_type(type);
1727 const GLint slots = (param->Size + 3) / 4;
1728 const GLint typeSize = sizeof_glsl_type(param->DataType);
1729 GLsizei k, i;
1730
1731 if (param->Size > typeSize) {
1732 /* an array */
1733 /* we'll ignore extra data below */
1734 }
1735 else {
1736 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1737 if (count > 1) {
1738 _mesa_error(ctx, GL_INVALID_OPERATION,
1739 "glUniform(uniform is not an array)");
1740 return;
1741 }
1742 }
1743
1744 /* loop over number of array elements */
1745 for (k = 0; k < count; k++) {
1746 GLfloat *uniformVal;
1747
1748 if (offset + k >= slots) {
1749 /* Extra array data is ignored */
1750 break;
1751 }
1752
1753 /* uniformVal (the destination) is always float[4] */
1754 uniformVal = program->Parameters->ParameterValues[index + offset + k];
1755
1756 if (areIntValues) {
1757 /* convert user's ints to floats */
1758 const GLint *iValues = ((const GLint *) values) + k * elems;
1759 for (i = 0; i < elems; i++) {
1760 uniformVal[i] = (GLfloat) iValues[i];
1761 }
1762 }
1763 else {
1764 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1765 for (i = 0; i < elems; i++) {
1766 uniformVal[i] = fValues[i];
1767 }
1768 }
1769
1770 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1771 if (isUniformBool) {
1772 for (i = 0; i < elems; i++) {
1773 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1774 }
1775 }
1776 }
1777 }
1778 }
1779
1780
1781 /**
1782 * Called via ctx->Driver.Uniform().
1783 */
1784 static void
1785 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1786 const GLvoid *values, GLenum type)
1787 {
1788 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1789 struct gl_uniform *uniform;
1790 GLint elems, offset;
1791 GLenum basicType;
1792
1793 if (!shProg || !shProg->LinkStatus) {
1794 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1795 return;
1796 }
1797
1798 if (location == -1)
1799 return; /* The standard specifies this as a no-op */
1800
1801 if (location < -1) {
1802 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)");
1803 return;
1804 }
1805
1806 split_location_offset(&location, &offset);
1807
1808 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1809 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1810 return;
1811 }
1812
1813 if (count < 0) {
1814 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1815 return;
1816 }
1817
1818 switch (type) {
1819 case GL_FLOAT:
1820 basicType = GL_FLOAT;
1821 elems = 1;
1822 break;
1823 case GL_INT:
1824 basicType = GL_INT;
1825 elems = 1;
1826 break;
1827 case GL_FLOAT_VEC2:
1828 basicType = GL_FLOAT;
1829 elems = 2;
1830 break;
1831 case GL_INT_VEC2:
1832 basicType = GL_INT;
1833 elems = 2;
1834 break;
1835 case GL_FLOAT_VEC3:
1836 basicType = GL_FLOAT;
1837 elems = 3;
1838 break;
1839 case GL_INT_VEC3:
1840 basicType = GL_INT;
1841 elems = 3;
1842 break;
1843 case GL_FLOAT_VEC4:
1844 basicType = GL_FLOAT;
1845 elems = 4;
1846 break;
1847 case GL_INT_VEC4:
1848 basicType = GL_INT;
1849 elems = 4;
1850 break;
1851 default:
1852 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1853 return;
1854 }
1855
1856 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1857
1858 uniform = &shProg->Uniforms->Uniforms[location];
1859
1860 if (ctx->Shader.Flags & GLSL_UNIFORMS) {
1861 GLint i;
1862 _mesa_printf("Mesa: set program %u uniform %s (loc %d) to: ",
1863 shProg->Name, uniform->Name, location);
1864 if (basicType == GL_INT) {
1865 const GLint *v = (const GLint *) values;
1866 for (i = 0; i < count * elems; i++) {
1867 _mesa_printf("%d ", v[i]);
1868 }
1869 }
1870 else {
1871 const GLfloat *v = (const GLfloat *) values;
1872 for (i = 0; i < count * elems; i++) {
1873 _mesa_printf("%g ", v[i]);
1874 }
1875 }
1876 _mesa_printf("\n");
1877 }
1878
1879 /* A uniform var may be used by both a vertex shader and a fragment
1880 * shader. We may need to update one or both shader's uniform here:
1881 */
1882 if (shProg->VertexProgram) {
1883 /* convert uniform location to program parameter index */
1884 GLint index = uniform->VertPos;
1885 if (index >= 0) {
1886 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1887 index, offset, type, count, elems, values);
1888 }
1889 }
1890
1891 if (shProg->FragmentProgram) {
1892 /* convert uniform location to program parameter index */
1893 GLint index = uniform->FragPos;
1894 if (index >= 0) {
1895 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1896 index, offset, type, count, elems, values);
1897 }
1898 }
1899
1900 uniform->Initialized = GL_TRUE;
1901 }
1902
1903
1904 /**
1905 * Set a matrix-valued program parameter.
1906 */
1907 static void
1908 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1909 GLuint index, GLuint offset,
1910 GLuint count, GLuint rows, GLuint cols,
1911 GLboolean transpose, const GLfloat *values)
1912 {
1913 GLuint mat, row, col;
1914 GLuint src = 0;
1915 const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
1916 const GLint slots = (param->Size + 3) / 4;
1917 const GLint typeSize = sizeof_glsl_type(param->DataType);
1918 GLint nr, nc;
1919
1920 /* check that the number of rows, columns is correct */
1921 get_matrix_dims(param->DataType, &nr, &nc);
1922 if (rows != nr || cols != nc) {
1923 _mesa_error(ctx, GL_INVALID_OPERATION,
1924 "glUniformMatrix(matrix size mismatch)");
1925 return;
1926 }
1927
1928 if (param->Size <= typeSize) {
1929 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1930 if (count > 1) {
1931 _mesa_error(ctx, GL_INVALID_OPERATION,
1932 "glUniformMatrix(uniform is not an array)");
1933 return;
1934 }
1935 }
1936
1937 /*
1938 * Note: the _columns_ of a matrix are stored in program registers, not
1939 * the rows. So, the loops below look a little funny.
1940 * XXX could optimize this a bit...
1941 */
1942
1943 /* loop over matrices */
1944 for (mat = 0; mat < count; mat++) {
1945
1946 /* each matrix: */
1947 for (col = 0; col < cols; col++) {
1948 GLfloat *v;
1949 if (offset >= slots) {
1950 /* Ignore writes beyond the end of (the used part of) an array */
1951 return;
1952 }
1953 v = program->Parameters->ParameterValues[index + offset];
1954 for (row = 0; row < rows; row++) {
1955 if (transpose) {
1956 v[row] = values[src + row * cols + col];
1957 }
1958 else {
1959 v[row] = values[src + col * rows + row];
1960 }
1961 }
1962
1963 offset++;
1964 }
1965
1966 src += rows * cols; /* next matrix */
1967 }
1968 }
1969
1970
1971 /**
1972 * Called by ctx->Driver.UniformMatrix().
1973 * Note: cols=2, rows=4 ==> array[2] of vec4
1974 */
1975 static void
1976 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1977 GLint location, GLsizei count,
1978 GLboolean transpose, const GLfloat *values)
1979 {
1980 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1981 struct gl_uniform *uniform;
1982 GLint offset;
1983
1984 if (!shProg || !shProg->LinkStatus) {
1985 _mesa_error(ctx, GL_INVALID_OPERATION,
1986 "glUniformMatrix(program not linked)");
1987 return;
1988 }
1989
1990 if (location == -1)
1991 return; /* The standard specifies this as a no-op */
1992
1993 if (location < -1) {
1994 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
1995 return;
1996 }
1997
1998 split_location_offset(&location, &offset);
1999
2000 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
2001 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
2002 return;
2003 }
2004 if (values == NULL) {
2005 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
2006 return;
2007 }
2008
2009 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
2010
2011 uniform = &shProg->Uniforms->Uniforms[location];
2012
2013 if (shProg->VertexProgram) {
2014 /* convert uniform location to program parameter index */
2015 GLint index = uniform->VertPos;
2016 if (index >= 0) {
2017 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
2018 index, offset,
2019 count, rows, cols, transpose, values);
2020 }
2021 }
2022
2023 if (shProg->FragmentProgram) {
2024 /* convert uniform location to program parameter index */
2025 GLint index = uniform->FragPos;
2026 if (index >= 0) {
2027 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
2028 index, offset,
2029 count, rows, cols, transpose, values);
2030 }
2031 }
2032
2033 uniform->Initialized = GL_TRUE;
2034 }
2035
2036
2037 /**
2038 * Validate a program's samplers.
2039 * Specifically, check that there aren't two samplers of different types
2040 * pointing to the same texture unit.
2041 * \return GL_TRUE if valid, GL_FALSE if invalid
2042 */
2043 static GLboolean
2044 validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
2045 {
2046 static const char *targetName[] = {
2047 "TEXTURE_2D_ARRAY",
2048 "TEXTURE_1D_ARRAY",
2049 "TEXTURE_CUBE",
2050 "TEXTURE_3D",
2051 "TEXTURE_RECT",
2052 "TEXTURE_2D",
2053 "TEXTURE_1D",
2054 };
2055 GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
2056 GLbitfield samplersUsed = prog->SamplersUsed;
2057 GLuint i;
2058
2059 assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
2060
2061 if (samplersUsed == 0x0)
2062 return GL_TRUE;
2063
2064 for (i = 0; i < Elements(targetUsed); i++)
2065 targetUsed[i] = -1;
2066
2067 /* walk over bits which are set in 'samplers' */
2068 while (samplersUsed) {
2069 GLuint unit;
2070 gl_texture_index target;
2071 GLint sampler = _mesa_ffs(samplersUsed) - 1;
2072 assert(sampler >= 0);
2073 assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
2074 unit = prog->SamplerUnits[sampler];
2075 target = prog->SamplerTargets[sampler];
2076 if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
2077 _mesa_snprintf(errMsg, 100,
2078 "Texture unit %d is accessed both as %s and %s",
2079 unit, targetName[targetUsed[unit]], targetName[target]);
2080 return GL_FALSE;
2081 }
2082 targetUsed[unit] = target;
2083 samplersUsed ^= (1 << sampler);
2084 }
2085
2086 return GL_TRUE;
2087 }
2088
2089
2090 /**
2091 * Do validation of the given shader program.
2092 * \param errMsg returns error message if validation fails.
2093 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
2094 */
2095 GLboolean
2096 _mesa_validate_shader_program(GLcontext *ctx,
2097 const struct gl_shader_program *shProg,
2098 char *errMsg)
2099 {
2100 const struct gl_vertex_program *vp = shProg->VertexProgram;
2101 const struct gl_fragment_program *fp = shProg->FragmentProgram;
2102
2103 if (!shProg->LinkStatus) {
2104 return GL_FALSE;
2105 }
2106
2107 /* From the GL spec, a program is invalid if any of these are true:
2108
2109 any two active samplers in the current program object are of
2110 different types, but refer to the same texture image unit,
2111
2112 any active sampler in the current program object refers to a texture
2113 image unit where fixed-function fragment processing accesses a
2114 texture target that does not match the sampler type, or
2115
2116 the sum of the number of active samplers in the program and the
2117 number of texture image units enabled for fixed-function fragment
2118 processing exceeds the combined limit on the total number of texture
2119 image units allowed.
2120 */
2121
2122
2123 /*
2124 * Check: any two active samplers in the current program object are of
2125 * different types, but refer to the same texture image unit,
2126 */
2127 if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
2128 return GL_FALSE;
2129 }
2130 if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
2131 return GL_FALSE;
2132 }
2133
2134 return GL_TRUE;
2135 }
2136
2137
2138 /**
2139 * Called via glValidateProgram()
2140 */
2141 static void
2142 _mesa_validate_program(GLcontext *ctx, GLuint program)
2143 {
2144 struct gl_shader_program *shProg;
2145 char errMsg[100];
2146
2147 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
2148 if (!shProg) {
2149 return;
2150 }
2151
2152 shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
2153 if (!shProg->Validated) {
2154 /* update info log */
2155 if (shProg->InfoLog) {
2156 _mesa_free(shProg->InfoLog);
2157 }
2158 shProg->InfoLog = _mesa_strdup(errMsg);
2159 }
2160 }
2161
2162
2163 /**
2164 * Plug in Mesa's GLSL functions into the device driver function table.
2165 */
2166 void
2167 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
2168 {
2169 driver->AttachShader = _mesa_attach_shader;
2170 driver->BindAttribLocation = _mesa_bind_attrib_location;
2171 driver->CompileShader = _mesa_compile_shader;
2172 driver->CreateProgram = _mesa_create_program;
2173 driver->CreateShader = _mesa_create_shader;
2174 driver->DeleteProgram2 = _mesa_delete_program2;
2175 driver->DeleteShader = _mesa_delete_shader;
2176 driver->DetachShader = _mesa_detach_shader;
2177 driver->GetActiveAttrib = _mesa_get_active_attrib;
2178 driver->GetActiveUniform = _mesa_get_active_uniform;
2179 driver->GetAttachedShaders = _mesa_get_attached_shaders;
2180 driver->GetAttribLocation = _mesa_get_attrib_location;
2181 driver->GetHandle = _mesa_get_handle;
2182 driver->GetProgramiv = _mesa_get_programiv;
2183 driver->GetProgramInfoLog = _mesa_get_program_info_log;
2184 driver->GetShaderiv = _mesa_get_shaderiv;
2185 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
2186 driver->GetShaderSource = _mesa_get_shader_source;
2187 driver->GetUniformfv = _mesa_get_uniformfv;
2188 driver->GetUniformiv = _mesa_get_uniformiv;
2189 driver->GetUniformLocation = _mesa_get_uniform_location;
2190 driver->IsProgram = _mesa_is_program;
2191 driver->IsShader = _mesa_is_shader;
2192 driver->LinkProgram = _mesa_link_program;
2193 driver->ShaderSource = _mesa_shader_source;
2194 driver->Uniform = _mesa_uniform;
2195 driver->UniformMatrix = _mesa_uniform_matrix;
2196 driver->UseProgram = _mesa_use_program;
2197 driver->ValidateProgram = _mesa_validate_program;
2198 }