mesa: update the shader programs->TexturesUsed array at link time
[mesa.git] / src / mesa / shader / shader_api.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.2
4 *
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file shader_api.c
27 * Implementation of GLSL-related API functions
28 * \author Brian Paul
29 */
30
31 /**
32 * XXX things to do:
33 * 1. Check that the right error code is generated for all _mesa_error() calls.
34 * 2. Insert FLUSH_VERTICES calls in various places
35 */
36
37
38 #include "main/glheader.h"
39 #include "main/context.h"
40 #include "main/hash.h"
41 #include "main/macros.h"
42 #include "program.h"
43 #include "prog_parameter.h"
44 #include "prog_print.h"
45 #include "prog_statevars.h"
46 #include "prog_uniform.h"
47 #include "shader/shader_api.h"
48 #include "shader/slang/slang_compile.h"
49 #include "shader/slang/slang_link.h"
50
51
52
53 #ifndef GL_PROGRAM_BINARY_LENGTH_OES
54 #define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
55 #endif
56
57
58 /**
59 * Allocate a new gl_shader_program object, initialize it.
60 */
61 static struct gl_shader_program *
62 _mesa_new_shader_program(GLcontext *ctx, GLuint name)
63 {
64 struct gl_shader_program *shProg;
65 shProg = CALLOC_STRUCT(gl_shader_program);
66 if (shProg) {
67 shProg->Type = GL_SHADER_PROGRAM_MESA;
68 shProg->Name = name;
69 shProg->RefCount = 1;
70 shProg->Attributes = _mesa_new_parameter_list();
71 }
72 return shProg;
73 }
74
75
76 /**
77 * Clear (free) the shader program state that gets produced by linking.
78 */
79 void
80 _mesa_clear_shader_program_data(GLcontext *ctx,
81 struct gl_shader_program *shProg)
82 {
83 _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
84 _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
85
86 if (shProg->Uniforms) {
87 _mesa_free_uniform_list(shProg->Uniforms);
88 shProg->Uniforms = NULL;
89 }
90
91 if (shProg->Varying) {
92 _mesa_free_parameter_list(shProg->Varying);
93 shProg->Varying = NULL;
94 }
95 }
96
97
98 /**
99 * Free all the data that hangs off a shader program object, but not the
100 * object itself.
101 */
102 void
103 _mesa_free_shader_program_data(GLcontext *ctx,
104 struct gl_shader_program *shProg)
105 {
106 GLuint i;
107
108 assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
109
110 _mesa_clear_shader_program_data(ctx, shProg);
111
112 if (shProg->Attributes) {
113 _mesa_free_parameter_list(shProg->Attributes);
114 shProg->Attributes = NULL;
115 }
116
117 /* detach shaders */
118 for (i = 0; i < shProg->NumShaders; i++) {
119 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
120 }
121 shProg->NumShaders = 0;
122
123 if (shProg->Shaders) {
124 _mesa_free(shProg->Shaders);
125 shProg->Shaders = NULL;
126 }
127
128 if (shProg->InfoLog) {
129 _mesa_free(shProg->InfoLog);
130 shProg->InfoLog = NULL;
131 }
132 }
133
134
135 /**
136 * Free/delete a shader program object.
137 */
138 void
139 _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
140 {
141 _mesa_free_shader_program_data(ctx, shProg);
142
143 _mesa_free(shProg);
144 }
145
146
147 /**
148 * Set ptr to point to shProg.
149 * If ptr is pointing to another object, decrement its refcount (and delete
150 * if refcount hits zero).
151 * Then set ptr to point to shProg, incrementing its refcount.
152 */
153 /* XXX this could be static */
154 void
155 _mesa_reference_shader_program(GLcontext *ctx,
156 struct gl_shader_program **ptr,
157 struct gl_shader_program *shProg)
158 {
159 assert(ptr);
160 if (*ptr == shProg) {
161 /* no-op */
162 return;
163 }
164 if (*ptr) {
165 /* Unreference the old shader program */
166 GLboolean deleteFlag = GL_FALSE;
167 struct gl_shader_program *old = *ptr;
168
169 ASSERT(old->RefCount > 0);
170 old->RefCount--;
171 #if 0
172 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
173 (void *) old, old->Name, old->RefCount);
174 #endif
175 deleteFlag = (old->RefCount == 0);
176
177 if (deleteFlag) {
178 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
179 _mesa_free_shader_program(ctx, old);
180 }
181
182 *ptr = NULL;
183 }
184 assert(!*ptr);
185
186 if (shProg) {
187 shProg->RefCount++;
188 #if 0
189 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
190 (void *) shProg, shProg->Name, shProg->RefCount);
191 #endif
192 *ptr = shProg;
193 }
194 }
195
196
197 /**
198 * Lookup a GLSL program object.
199 */
200 struct gl_shader_program *
201 _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
202 {
203 struct gl_shader_program *shProg;
204 if (name) {
205 shProg = (struct gl_shader_program *)
206 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
207 /* Note that both gl_shader and gl_shader_program objects are kept
208 * in the same hash table. Check the object's type to be sure it's
209 * what we're expecting.
210 */
211 if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
212 return NULL;
213 }
214 return shProg;
215 }
216 return NULL;
217 }
218
219
220 /**
221 * As above, but record an error if program is not found.
222 */
223 static struct gl_shader_program *
224 _mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
225 const char *caller)
226 {
227 if (!name) {
228 _mesa_error(ctx, GL_INVALID_VALUE, caller);
229 return NULL;
230 }
231 else {
232 struct gl_shader_program *shProg = (struct gl_shader_program *)
233 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
234 if (!shProg) {
235 _mesa_error(ctx, GL_INVALID_VALUE, caller);
236 return NULL;
237 }
238 if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
239 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
240 return NULL;
241 }
242 return shProg;
243 }
244 }
245
246
247
248
249 /**
250 * Allocate a new gl_shader object, initialize it.
251 */
252 struct gl_shader *
253 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
254 {
255 struct gl_shader *shader;
256 assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
257 shader = CALLOC_STRUCT(gl_shader);
258 if (shader) {
259 shader->Type = type;
260 shader->Name = name;
261 shader->RefCount = 1;
262 }
263 return shader;
264 }
265
266
267 void
268 _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
269 {
270 if (sh->Source)
271 _mesa_free((void *) sh->Source);
272 if (sh->InfoLog)
273 _mesa_free(sh->InfoLog);
274 _mesa_reference_program(ctx, &sh->Program, NULL);
275 _mesa_free(sh);
276 }
277
278
279 /**
280 * Set ptr to point to sh.
281 * If ptr is pointing to another shader, decrement its refcount (and delete
282 * if refcount hits zero).
283 * Then set ptr to point to sh, incrementing its refcount.
284 */
285 /* XXX this could be static */
286 void
287 _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
288 struct gl_shader *sh)
289 {
290 assert(ptr);
291 if (*ptr == sh) {
292 /* no-op */
293 return;
294 }
295 if (*ptr) {
296 /* Unreference the old shader */
297 GLboolean deleteFlag = GL_FALSE;
298 struct gl_shader *old = *ptr;
299
300 ASSERT(old->RefCount > 0);
301 old->RefCount--;
302 /*printf("SHADER DECR %p (%d) to %d\n",
303 (void*) old, old->Name, old->RefCount);*/
304 deleteFlag = (old->RefCount == 0);
305
306 if (deleteFlag) {
307 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
308 _mesa_free_shader(ctx, old);
309 }
310
311 *ptr = NULL;
312 }
313 assert(!*ptr);
314
315 if (sh) {
316 /* reference new */
317 sh->RefCount++;
318 /*printf("SHADER INCR %p (%d) to %d\n",
319 (void*) sh, sh->Name, sh->RefCount);*/
320 *ptr = sh;
321 }
322 }
323
324
325 /**
326 * Lookup a GLSL shader object.
327 */
328 struct gl_shader *
329 _mesa_lookup_shader(GLcontext *ctx, GLuint name)
330 {
331 if (name) {
332 struct gl_shader *sh = (struct gl_shader *)
333 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
334 /* Note that both gl_shader and gl_shader_program objects are kept
335 * in the same hash table. Check the object's type to be sure it's
336 * what we're expecting.
337 */
338 if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
339 return NULL;
340 }
341 return sh;
342 }
343 return NULL;
344 }
345
346
347 /**
348 * As above, but record an error if shader is not found.
349 */
350 static struct gl_shader *
351 _mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
352 {
353 if (!name) {
354 _mesa_error(ctx, GL_INVALID_VALUE, caller);
355 return NULL;
356 }
357 else {
358 struct gl_shader *sh = (struct gl_shader *)
359 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
360 if (!sh) {
361 _mesa_error(ctx, GL_INVALID_VALUE, caller);
362 return NULL;
363 }
364 if (sh->Type == GL_SHADER_PROGRAM_MESA) {
365 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
366 return NULL;
367 }
368 return sh;
369 }
370 }
371
372
373
374 /**
375 * Initialize context's shader state.
376 */
377 void
378 _mesa_init_shader_state(GLcontext * ctx)
379 {
380 /* Device drivers may override these to control what kind of instructions
381 * are generated by the GLSL compiler.
382 */
383 ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
384 ctx->Shader.EmitCondCodes = GL_FALSE;/*GL_TRUE;*/ /* XXX probably want GL_FALSE... */
385 ctx->Shader.EmitComments = GL_FALSE;
386 }
387
388
389 /**
390 * Free the per-context shader-related state.
391 */
392 void
393 _mesa_free_shader_state(GLcontext *ctx)
394 {
395 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
396 }
397
398
399 /**
400 * Copy string from <src> to <dst>, up to maxLength characters, returning
401 * length of <dst> in <length>.
402 * \param src the strings source
403 * \param maxLength max chars to copy
404 * \param length returns number of chars copied
405 * \param dst the string destination
406 */
407 static void
408 copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src)
409 {
410 GLsizei len;
411 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
412 dst[len] = src[len];
413 if (maxLength > 0)
414 dst[len] = 0;
415 if (length)
416 *length = len;
417 }
418
419
420 static GLboolean
421 _mesa_is_program(GLcontext *ctx, GLuint name)
422 {
423 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
424 return shProg ? GL_TRUE : GL_FALSE;
425 }
426
427
428 static GLboolean
429 _mesa_is_shader(GLcontext *ctx, GLuint name)
430 {
431 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
432 return shader ? GL_TRUE : GL_FALSE;
433 }
434
435
436 /**
437 * Called via ctx->Driver.AttachShader()
438 */
439 static void
440 _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
441 {
442 struct gl_shader_program *shProg;
443 struct gl_shader *sh;
444 GLuint i, n;
445
446 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
447 if (!shProg)
448 return;
449
450 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
451 if (!sh) {
452 return;
453 }
454
455 n = shProg->NumShaders;
456 for (i = 0; i < n; i++) {
457 if (shProg->Shaders[i] == sh) {
458 /* already attached */
459 return;
460 }
461 }
462
463 /* grow list */
464 shProg->Shaders = (struct gl_shader **)
465 _mesa_realloc(shProg->Shaders,
466 n * sizeof(struct gl_shader *),
467 (n + 1) * sizeof(struct gl_shader *));
468 if (!shProg->Shaders) {
469 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
470 return;
471 }
472
473 /* append */
474 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
475 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
476 shProg->NumShaders++;
477 }
478
479
480 static GLint
481 _mesa_get_attrib_location(GLcontext *ctx, GLuint program,
482 const GLchar *name)
483 {
484 struct gl_shader_program *shProg
485 = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
486
487 if (!shProg) {
488 return -1;
489 }
490
491 if (!shProg->LinkStatus) {
492 _mesa_error(ctx, GL_INVALID_OPERATION,
493 "glGetAttribLocation(program not linked)");
494 return -1;
495 }
496
497 if (!name)
498 return -1;
499
500 if (shProg->VertexProgram) {
501 const struct gl_program_parameter_list *attribs =
502 shProg->VertexProgram->Base.Attributes;
503 if (attribs) {
504 GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
505 if (i >= 0) {
506 return attribs->Parameters[i].StateIndexes[0];
507 }
508 }
509 }
510 return -1;
511 }
512
513
514 static void
515 _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
516 const GLchar *name)
517 {
518 struct gl_shader_program *shProg;
519 const GLint size = -1; /* unknown size */
520 GLint i;
521 GLenum datatype = GL_FLOAT_VEC4;
522
523 shProg = _mesa_lookup_shader_program_err(ctx, program,
524 "glBindAttribLocation");
525 if (!shProg) {
526 return;
527 }
528
529 if (!name)
530 return;
531
532 if (strncmp(name, "gl_", 3) == 0) {
533 _mesa_error(ctx, GL_INVALID_OPERATION,
534 "glBindAttribLocation(illegal name)");
535 return;
536 }
537
538 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
539 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
540 return;
541 }
542
543 /* this will replace the current value if it's already in the list */
544 i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
545 if (i < 0) {
546 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
547 return;
548 }
549
550 /*
551 * Note that this attribute binding won't go into effect until
552 * glLinkProgram is called again.
553 */
554 }
555
556
557 static GLuint
558 _mesa_create_shader(GLcontext *ctx, GLenum type)
559 {
560 struct gl_shader *sh;
561 GLuint name;
562
563 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
564
565 switch (type) {
566 case GL_FRAGMENT_SHADER:
567 case GL_VERTEX_SHADER:
568 sh = _mesa_new_shader(ctx, name, type);
569 break;
570 default:
571 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
572 return 0;
573 }
574
575 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
576
577 return name;
578 }
579
580
581 static GLuint
582 _mesa_create_program(GLcontext *ctx)
583 {
584 GLuint name;
585 struct gl_shader_program *shProg;
586
587 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
588 shProg = _mesa_new_shader_program(ctx, name);
589
590 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
591
592 assert(shProg->RefCount == 1);
593
594 return name;
595 }
596
597
598 /**
599 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
600 * DeleteProgramARB.
601 */
602 static void
603 _mesa_delete_program2(GLcontext *ctx, GLuint name)
604 {
605 /*
606 * NOTE: deleting shaders/programs works a bit differently than
607 * texture objects (and buffer objects, etc). Shader/program
608 * handles/IDs exist in the hash table until the object is really
609 * deleted (refcount==0). With texture objects, the handle/ID is
610 * removed from the hash table in glDeleteTextures() while the tex
611 * object itself might linger until its refcount goes to zero.
612 */
613 struct gl_shader_program *shProg;
614
615 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
616 if (!shProg)
617 return;
618
619 shProg->DeletePending = GL_TRUE;
620
621 /* effectively, decr shProg's refcount */
622 _mesa_reference_shader_program(ctx, &shProg, NULL);
623 }
624
625
626 static void
627 _mesa_delete_shader(GLcontext *ctx, GLuint shader)
628 {
629 struct gl_shader *sh;
630
631 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
632 if (!sh)
633 return;
634
635 sh->DeletePending = GL_TRUE;
636
637 /* effectively, decr sh's refcount */
638 _mesa_reference_shader(ctx, &sh, NULL);
639 }
640
641
642 static void
643 _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
644 {
645 struct gl_shader_program *shProg;
646 GLuint n;
647 GLuint i, j;
648
649 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
650 if (!shProg)
651 return;
652
653 n = shProg->NumShaders;
654
655 for (i = 0; i < n; i++) {
656 if (shProg->Shaders[i]->Name == shader) {
657 /* found it */
658 struct gl_shader **newList;
659
660 /* release */
661 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
662
663 /* alloc new, smaller array */
664 newList = (struct gl_shader **)
665 _mesa_malloc((n - 1) * sizeof(struct gl_shader *));
666 if (!newList) {
667 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
668 return;
669 }
670 for (j = 0; j < i; j++) {
671 newList[j] = shProg->Shaders[j];
672 }
673 while (++i < n)
674 newList[j++] = shProg->Shaders[i];
675 _mesa_free(shProg->Shaders);
676
677 shProg->Shaders = newList;
678 shProg->NumShaders = n - 1;
679
680 #ifdef DEBUG
681 /* sanity check */
682 {
683 for (j = 0; j < shProg->NumShaders; j++) {
684 assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
685 shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
686 assert(shProg->Shaders[j]->RefCount > 0);
687 }
688 }
689 #endif
690
691 return;
692 }
693 }
694
695 /* not found */
696 {
697 GLenum err;
698 if (_mesa_is_shader(ctx, shader))
699 err = GL_INVALID_OPERATION;
700 else if (_mesa_is_program(ctx, shader))
701 err = GL_INVALID_OPERATION;
702 else
703 err = GL_INVALID_VALUE;
704 _mesa_error(ctx, err, "glDetachProgram(shader)");
705 return;
706 }
707 }
708
709
710 static GLint
711 sizeof_glsl_type(GLenum type)
712 {
713 switch (type) {
714 case GL_FLOAT:
715 case GL_INT:
716 case GL_BOOL:
717 case GL_SAMPLER_1D:
718 case GL_SAMPLER_2D:
719 case GL_SAMPLER_3D:
720 case GL_SAMPLER_CUBE:
721 case GL_SAMPLER_1D_SHADOW:
722 case GL_SAMPLER_2D_SHADOW:
723 case GL_SAMPLER_2D_RECT_ARB:
724 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
725 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
726 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
727 case GL_SAMPLER_CUBE_SHADOW_EXT:
728 return 1;
729 case GL_FLOAT_VEC2:
730 case GL_INT_VEC2:
731 case GL_BOOL_VEC2:
732 return 2;
733 case GL_FLOAT_VEC3:
734 case GL_INT_VEC3:
735 case GL_BOOL_VEC3:
736 return 3;
737 case GL_FLOAT_VEC4:
738 case GL_INT_VEC4:
739 case GL_BOOL_VEC4:
740 return 4;
741 case GL_FLOAT_MAT2:
742 case GL_FLOAT_MAT2x3:
743 case GL_FLOAT_MAT2x4:
744 return 8; /* two float[4] vectors */
745 case GL_FLOAT_MAT3:
746 case GL_FLOAT_MAT3x2:
747 case GL_FLOAT_MAT3x4:
748 return 12; /* three float[4] vectors */
749 case GL_FLOAT_MAT4:
750 case GL_FLOAT_MAT4x2:
751 case GL_FLOAT_MAT4x3:
752 return 16; /* four float[4] vectors */
753 default:
754 _mesa_problem(NULL, "Invalid type in sizeof_glsl_type()");
755 return 1;
756 }
757 }
758
759
760 static GLboolean
761 is_boolean_type(GLenum type)
762 {
763 switch (type) {
764 case GL_BOOL:
765 case GL_BOOL_VEC2:
766 case GL_BOOL_VEC3:
767 case GL_BOOL_VEC4:
768 return GL_TRUE;
769 default:
770 return GL_FALSE;
771 }
772 }
773
774
775 static GLboolean
776 is_integer_type(GLenum type)
777 {
778 switch (type) {
779 case GL_INT:
780 case GL_INT_VEC2:
781 case GL_INT_VEC3:
782 case GL_INT_VEC4:
783 return GL_TRUE;
784 default:
785 return GL_FALSE;
786 }
787 }
788
789
790 static void
791 _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
792 GLsizei maxLength, GLsizei *length, GLint *size,
793 GLenum *type, GLchar *nameOut)
794 {
795 const struct gl_program_parameter_list *attribs = NULL;
796 struct gl_shader_program *shProg;
797
798 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
799 if (!shProg)
800 return;
801
802 if (shProg->VertexProgram)
803 attribs = shProg->VertexProgram->Base.Attributes;
804
805 if (!attribs || index >= attribs->NumParameters) {
806 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
807 return;
808 }
809
810 copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name);
811
812 if (size)
813 *size = attribs->Parameters[index].Size
814 / sizeof_glsl_type(attribs->Parameters[index].DataType);
815
816 if (type)
817 *type = attribs->Parameters[index].DataType;
818 }
819
820
821 static struct gl_program_parameter *
822 get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
823 {
824 const struct gl_program *prog;
825 GLint progPos;
826
827 progPos = shProg->Uniforms->Uniforms[index].VertPos;
828 if (progPos >= 0) {
829 prog = &shProg->VertexProgram->Base;
830 }
831 else {
832 progPos = shProg->Uniforms->Uniforms[index].FragPos;
833 if (progPos >= 0) {
834 prog = &shProg->FragmentProgram->Base;
835 }
836 }
837
838 if (!prog || progPos < 0)
839 return NULL; /* should never happen */
840
841 return &prog->Parameters->Parameters[progPos];
842 }
843
844
845 /**
846 * Called via ctx->Driver.GetActiveUniform().
847 */
848 static void
849 _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
850 GLsizei maxLength, GLsizei *length, GLint *size,
851 GLenum *type, GLchar *nameOut)
852 {
853 const struct gl_shader_program *shProg;
854 const struct gl_program *prog;
855 GLint progPos;
856
857 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
858 if (!shProg)
859 return;
860
861 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
862 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
863 return;
864 }
865
866 progPos = shProg->Uniforms->Uniforms[index].VertPos;
867 if (progPos >= 0) {
868 prog = &shProg->VertexProgram->Base;
869 }
870 else {
871 progPos = shProg->Uniforms->Uniforms[index].FragPos;
872 if (progPos >= 0) {
873 prog = &shProg->FragmentProgram->Base;
874 }
875 }
876
877 if (!prog || progPos < 0)
878 return; /* should never happen */
879
880 if (nameOut)
881 copy_string(nameOut, maxLength, length,
882 prog->Parameters->Parameters[progPos].Name);
883 if (size)
884 *size = prog->Parameters->Parameters[progPos].Size
885 / sizeof_glsl_type(prog->Parameters->Parameters[progPos].DataType);
886 if (type)
887 *type = prog->Parameters->Parameters[progPos].DataType;
888 }
889
890
891 /**
892 * Called via ctx->Driver.GetAttachedShaders().
893 */
894 static void
895 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
896 GLsizei *count, GLuint *obj)
897 {
898 struct gl_shader_program *shProg =
899 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
900 if (shProg) {
901 GLuint i;
902 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
903 obj[i] = shProg->Shaders[i]->Name;
904 }
905 if (count)
906 *count = i;
907 }
908 }
909
910
911 static GLuint
912 _mesa_get_handle(GLcontext *ctx, GLenum pname)
913 {
914 #if 0
915 GET_CURRENT_CONTEXT(ctx);
916
917 switch (pname) {
918 case GL_PROGRAM_OBJECT_ARB:
919 {
920 struct gl2_program_intf **pro = ctx->Shader.CurrentProgram;
921
922 if (pro != NULL)
923 return (**pro)._container._generic.
924 GetName((struct gl2_generic_intf **) (pro));
925 }
926 break;
927 default:
928 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
929 }
930 #endif
931 return 0;
932 }
933
934
935 static void
936 _mesa_get_programiv(GLcontext *ctx, GLuint program,
937 GLenum pname, GLint *params)
938 {
939 const struct gl_program_parameter_list *attribs;
940 struct gl_shader_program *shProg
941 = _mesa_lookup_shader_program(ctx, program);
942
943 if (!shProg) {
944 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
945 return;
946 }
947
948 if (shProg->VertexProgram)
949 attribs = shProg->VertexProgram->Base.Attributes;
950 else
951 attribs = NULL;
952
953 switch (pname) {
954 case GL_DELETE_STATUS:
955 *params = shProg->DeletePending;
956 break;
957 case GL_LINK_STATUS:
958 *params = shProg->LinkStatus;
959 break;
960 case GL_VALIDATE_STATUS:
961 *params = shProg->Validated;
962 break;
963 case GL_INFO_LOG_LENGTH:
964 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
965 break;
966 case GL_ATTACHED_SHADERS:
967 *params = shProg->NumShaders;
968 break;
969 case GL_ACTIVE_ATTRIBUTES:
970 *params = attribs ? attribs->NumParameters : 0;
971 break;
972 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
973 *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
974 break;
975 case GL_ACTIVE_UNIFORMS:
976 *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
977 break;
978 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
979 *params = _mesa_longest_uniform_name(shProg->Uniforms);
980 if (*params > 0)
981 (*params)++; /* add one for terminating zero */
982 break;
983 case GL_PROGRAM_BINARY_LENGTH_OES:
984 *params = 0;
985 break;
986 default:
987 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
988 return;
989 }
990 }
991
992
993 static void
994 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
995 {
996 struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
997
998 if (!shader) {
999 return;
1000 }
1001
1002 switch (pname) {
1003 case GL_SHADER_TYPE:
1004 *params = shader->Type;
1005 break;
1006 case GL_DELETE_STATUS:
1007 *params = shader->DeletePending;
1008 break;
1009 case GL_COMPILE_STATUS:
1010 *params = shader->CompileStatus;
1011 break;
1012 case GL_INFO_LOG_LENGTH:
1013 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
1014 break;
1015 case GL_SHADER_SOURCE_LENGTH:
1016 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1017 break;
1018 default:
1019 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1020 return;
1021 }
1022 }
1023
1024
1025 static void
1026 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
1027 GLsizei *length, GLchar *infoLog)
1028 {
1029 struct gl_shader_program *shProg
1030 = _mesa_lookup_shader_program(ctx, program);
1031 if (!shProg) {
1032 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
1033 return;
1034 }
1035 copy_string(infoLog, bufSize, length, shProg->InfoLog);
1036 }
1037
1038
1039 static void
1040 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
1041 GLsizei *length, GLchar *infoLog)
1042 {
1043 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
1044 if (!sh) {
1045 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
1046 return;
1047 }
1048 copy_string(infoLog, bufSize, length, sh->InfoLog);
1049 }
1050
1051
1052 /**
1053 * Called via ctx->Driver.GetShaderSource().
1054 */
1055 static void
1056 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
1057 GLsizei *length, GLchar *sourceOut)
1058 {
1059 struct gl_shader *sh;
1060 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1061 if (!sh) {
1062 return;
1063 }
1064 copy_string(sourceOut, maxLength, length, sh->Source);
1065 }
1066
1067
1068 static void
1069 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
1070 {
1071 switch (type) {
1072 case GL_FLOAT_MAT2:
1073 *rows = *cols = 2;
1074 break;
1075 case GL_FLOAT_MAT2x3:
1076 *rows = 3;
1077 *cols = 2;
1078 break;
1079 case GL_FLOAT_MAT2x4:
1080 *rows = 4;
1081 *cols = 2;
1082 break;
1083 case GL_FLOAT_MAT3:
1084 *rows = 3;
1085 *cols = 3;
1086 break;
1087 case GL_FLOAT_MAT3x2:
1088 *rows = 2;
1089 *cols = 3;
1090 break;
1091 case GL_FLOAT_MAT3x4:
1092 *rows = 4;
1093 *cols = 3;
1094 break;
1095 case GL_FLOAT_MAT4:
1096 *rows = 4;
1097 *cols = 4;
1098 break;
1099 case GL_FLOAT_MAT4x2:
1100 *rows = 2;
1101 *cols = 4;
1102 break;
1103 case GL_FLOAT_MAT4x3:
1104 *rows = 3;
1105 *cols = 4;
1106 break;
1107 default:
1108 *rows = *cols = 0;
1109 }
1110 }
1111
1112
1113 /**
1114 * Determine the number of rows and columns occupied by a uniform
1115 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
1116 * the number of rows = 1 and cols = number of elements in the vector.
1117 */
1118 static void
1119 get_uniform_rows_cols(const struct gl_program_parameter *p,
1120 GLint *rows, GLint *cols)
1121 {
1122 get_matrix_dims(p->DataType, rows, cols);
1123 if (*rows == 0 && *cols == 0) {
1124 /* not a matrix type, probably a float or vector */
1125 if (p->Size <= 4) {
1126 *rows = 1;
1127 *cols = p->Size;
1128 }
1129 else {
1130 *rows = p->Size / 4 + 1;
1131 if (p->Size % 4 == 0)
1132 *cols = 4;
1133 else
1134 *cols = p->Size % 4;
1135 }
1136 }
1137 }
1138
1139
1140 #define MAX_UNIFORM_ELEMENTS 16
1141
1142 /**
1143 * Helper for GetUniformfv(), GetUniformiv()
1144 * Returns number of elements written to 'params' output.
1145 */
1146 static GLuint
1147 get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1148 GLfloat *params)
1149 {
1150 struct gl_shader_program *shProg
1151 = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
1152 if (shProg) {
1153 if (shProg->Uniforms &&
1154 location >= 0 && location < (GLint) shProg->Uniforms->NumUniforms) {
1155 GLint progPos;
1156 const struct gl_program *prog = NULL;
1157
1158 progPos = shProg->Uniforms->Uniforms[location].VertPos;
1159 if (progPos >= 0) {
1160 prog = &shProg->VertexProgram->Base;
1161 }
1162 else {
1163 progPos = shProg->Uniforms->Uniforms[location].FragPos;
1164 if (progPos >= 0) {
1165 prog = &shProg->FragmentProgram->Base;
1166 }
1167 }
1168
1169 ASSERT(prog);
1170 if (prog) {
1171 const struct gl_program_parameter *p =
1172 &prog->Parameters->Parameters[progPos];
1173 GLint rows, cols, i, j, k;
1174
1175 /* See uniformiv() below */
1176 assert(p->Size <= MAX_UNIFORM_ELEMENTS);
1177
1178 get_uniform_rows_cols(p, &rows, &cols);
1179
1180 k = 0;
1181 for (i = 0; i < rows; i++) {
1182 for (j = 0; j < cols; j++ ) {
1183 params[k++] = prog->Parameters->ParameterValues[progPos+i][j];
1184 }
1185 }
1186
1187 return p->Size;
1188 }
1189 }
1190 else {
1191 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
1192 }
1193 }
1194 return 0;
1195 }
1196
1197
1198 /**
1199 * Called via ctx->Driver.GetUniformfv().
1200 */
1201 static void
1202 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1203 GLfloat *params)
1204 {
1205 (void) get_uniformfv(ctx, program, location, params);
1206 }
1207
1208
1209 /**
1210 * Called via ctx->Driver.GetUniformiv().
1211 */
1212 static void
1213 _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
1214 GLint *params)
1215 {
1216 GLfloat fparams[MAX_UNIFORM_ELEMENTS];
1217 GLuint n = get_uniformfv(ctx, program, location, fparams);
1218 GLuint i;
1219 assert(n <= MAX_UNIFORM_ELEMENTS);
1220 for (i = 0; i < n; i++) {
1221 params[i] = (GLint) fparams[i];
1222 }
1223 }
1224
1225
1226 /**
1227 * The value returned by GetUniformLocation actually encodes two things:
1228 * 1. the index into the prog->Uniforms[] array for the uniform
1229 * 2. an offset in the prog->ParameterValues[] array for specifying array
1230 * elements or structure fields.
1231 * This function merges those two values.
1232 */
1233 static void
1234 merge_location_offset(GLint *location, GLint offset)
1235 {
1236 *location = *location | (offset << 16);
1237 }
1238
1239
1240 /**
1241 * Seperate the uniform location and parameter offset. See above.
1242 */
1243 static void
1244 split_location_offset(GLint *location, GLint *offset)
1245 {
1246 *offset = (*location >> 16);
1247 *location = *location & 0xffff;
1248 }
1249
1250
1251 /**
1252 * Called via ctx->Driver.GetUniformLocation().
1253 *
1254 * The return value will encode two values, the uniform location and an
1255 * offset (used for arrays, structs).
1256 */
1257 static GLint
1258 _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
1259 {
1260 GLint offset = 0, location = -1;
1261
1262 struct gl_shader_program *shProg =
1263 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
1264
1265 if (!shProg)
1266 return -1;
1267
1268 if (shProg->LinkStatus == GL_FALSE) {
1269 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1270 return -1;
1271 }
1272
1273 /* XXX we should return -1 if the uniform was declared, but not
1274 * actually used.
1275 */
1276
1277 /* XXX we need to be able to parse uniform names for structs and arrays
1278 * such as:
1279 * mymatrix[1]
1280 * mystruct.field1
1281 */
1282
1283 {
1284 /* handle 1-dimension arrays here... */
1285 char *c = strchr(name, '[');
1286 if (c) {
1287 /* truncate name at [ */
1288 const GLint len = c - name;
1289 GLchar *newName = _mesa_malloc(len + 1);
1290 if (!newName)
1291 return -1; /* out of mem */
1292 _mesa_memcpy(newName, name, len);
1293 newName[len] = 0;
1294
1295 location = _mesa_lookup_uniform(shProg->Uniforms, newName);
1296 if (location >= 0) {
1297 const GLint element = _mesa_atoi(c + 1);
1298 if (element > 0) {
1299 /* get type of the uniform array element */
1300 struct gl_program_parameter *p;
1301 p = get_uniform_parameter(shProg, location);
1302 if (p) {
1303 GLint rows, cols;
1304 get_matrix_dims(p->DataType, &rows, &cols);
1305 if (rows < 1)
1306 rows = 1;
1307 offset = element * rows;
1308 }
1309 }
1310 }
1311
1312 _mesa_free(newName);
1313 }
1314 }
1315
1316 if (location < 0) {
1317 location = _mesa_lookup_uniform(shProg->Uniforms, name);
1318 }
1319
1320 if (location >= 0) {
1321 merge_location_offset(&location, offset);
1322 }
1323
1324 return location;
1325 }
1326
1327
1328
1329 /**
1330 * Called via ctx->Driver.ShaderSource()
1331 */
1332 static void
1333 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1334 {
1335 struct gl_shader *sh;
1336
1337 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1338 if (!sh)
1339 return;
1340
1341 /* free old shader source string and install new one */
1342 if (sh->Source) {
1343 _mesa_free((void *) sh->Source);
1344 }
1345 sh->Source = source;
1346 sh->CompileStatus = GL_FALSE;
1347 }
1348
1349
1350 /**
1351 * Called via ctx->Driver.CompileShader()
1352 */
1353 static void
1354 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1355 {
1356 struct gl_shader *sh;
1357
1358 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1359 if (!sh)
1360 return;
1361
1362 sh->CompileStatus = _slang_compile(ctx, sh);
1363 }
1364
1365
1366 /**
1367 * Called via ctx->Driver.LinkProgram()
1368 */
1369 static void
1370 _mesa_link_program(GLcontext *ctx, GLuint program)
1371 {
1372 struct gl_shader_program *shProg;
1373
1374 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1375 if (!shProg)
1376 return;
1377
1378 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1379
1380 _slang_link(ctx, program, shProg);
1381 }
1382
1383
1384 /**
1385 * Called via ctx->Driver.UseProgram()
1386 */
1387 void
1388 _mesa_use_program(GLcontext *ctx, GLuint program)
1389 {
1390 struct gl_shader_program *shProg;
1391
1392 if (ctx->Shader.CurrentProgram &&
1393 ctx->Shader.CurrentProgram->Name == program) {
1394 /* no-op */
1395 return;
1396 }
1397
1398 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1399
1400 if (program) {
1401 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1402 if (!shProg) {
1403 return;
1404 }
1405 if (!shProg->LinkStatus) {
1406 _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgram");
1407 return;
1408 }
1409 }
1410 else {
1411 shProg = NULL;
1412 }
1413
1414 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1415 }
1416
1417
1418
1419 /**
1420 * Update the vertex/fragment program's TexturesUsed array.
1421 *
1422 * This needs to be called after glUniform(set sampler var) is called.
1423 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1424 * particular texture unit. We know the sampler's texture target
1425 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1426 * set by glUniform() calls.
1427 *
1428 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1429 * information to update the prog->TexturesUsed[] values.
1430 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1431 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1432 * We'll use that info for state validation before rendering.
1433 */
1434 void
1435 _mesa_update_shader_textures_used(struct gl_program *prog)
1436 {
1437 GLuint s;
1438
1439 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1440
1441 for (s = 0; s < MAX_SAMPLERS; s++) {
1442 if (prog->SamplersUsed & (1 << s)) {
1443 GLuint u = prog->SamplerUnits[s];
1444 GLuint t = prog->SamplerTargets[s];
1445 assert(u < MAX_TEXTURE_IMAGE_UNITS);
1446 prog->TexturesUsed[u] |= (1 << t);
1447 }
1448 }
1449 }
1450
1451
1452 static GLboolean
1453 is_sampler_type(GLenum type)
1454 {
1455 switch (type) {
1456 case GL_SAMPLER_1D:
1457 case GL_SAMPLER_2D:
1458 case GL_SAMPLER_3D:
1459 case GL_SAMPLER_CUBE:
1460 case GL_SAMPLER_1D_SHADOW:
1461 case GL_SAMPLER_2D_SHADOW:
1462 case GL_SAMPLER_2D_RECT_ARB:
1463 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
1464 case GL_SAMPLER_1D_ARRAY_EXT:
1465 case GL_SAMPLER_2D_ARRAY_EXT:
1466 return GL_TRUE;
1467 default:
1468 return GL_FALSE;
1469 }
1470 }
1471
1472
1473 /**
1474 * Check if the type given by userType is allowed to set a uniform of the
1475 * target type. Generally, equivalence is required, but setting Boolean
1476 * uniforms can be done with glUniformiv or glUniformfv.
1477 */
1478 static GLboolean
1479 compatible_types(GLenum userType, GLenum targetType)
1480 {
1481 if (userType == targetType)
1482 return GL_TRUE;
1483
1484 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1485 return GL_TRUE;
1486
1487 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1488 userType == GL_INT_VEC2))
1489 return GL_TRUE;
1490
1491 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1492 userType == GL_INT_VEC3))
1493 return GL_TRUE;
1494
1495 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1496 userType == GL_INT_VEC4))
1497 return GL_TRUE;
1498
1499 if (is_sampler_type(targetType) && userType == GL_INT)
1500 return GL_TRUE;
1501
1502 return GL_FALSE;
1503 }
1504
1505
1506 /**
1507 * Set the value of a program's uniform variable.
1508 * \param program the program whose uniform to update
1509 * \param index the index of the program parameter for the uniform
1510 * \param offset additional parameter slot offset (for arrays)
1511 * \param type the datatype of the uniform
1512 * \param count the number of uniforms to set
1513 * \param elems number of elements per uniform
1514 * \param values the new values
1515 */
1516 static void
1517 set_program_uniform(GLcontext *ctx, struct gl_program *program,
1518 GLint index, GLint offset,
1519 GLenum type, GLsizei count, GLint elems,
1520 const void *values)
1521 {
1522 struct gl_program_parameter *param =
1523 &program->Parameters->Parameters[index];
1524
1525 assert(offset >= 0);
1526
1527 if (!compatible_types(type, param->DataType)) {
1528 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1529 return;
1530 }
1531
1532 if (index + offset > (GLint) program->Parameters->Size) {
1533 /* out of bounds! */
1534 return;
1535 }
1536
1537 if (param->Type == PROGRAM_SAMPLER) {
1538 /* This controls which texture unit which is used by a sampler */
1539 GLuint texUnit, sampler;
1540
1541 /* data type for setting samplers must be int */
1542 if (type != GL_INT || count != 1) {
1543 _mesa_error(ctx, GL_INVALID_OPERATION,
1544 "glUniform(only glUniform1i can be used "
1545 "to set sampler uniforms)");
1546 return;
1547 }
1548
1549 sampler = (GLuint) program->Parameters->ParameterValues[index][0];
1550 texUnit = ((GLuint *) values)[0];
1551
1552 /* check that the sampler (tex unit index) is legal */
1553 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1554 _mesa_error(ctx, GL_INVALID_VALUE,
1555 "glUniform1(invalid sampler/tex unit index)");
1556 return;
1557 }
1558
1559 /* This maps a sampler to a texture unit: */
1560 program->SamplerUnits[sampler] = texUnit;
1561 _mesa_update_shader_textures_used(program);
1562
1563 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1564 }
1565 else {
1566 /* ordinary uniform variable */
1567 GLsizei k, i;
1568 GLint slots = (param->Size + 3) / 4;
1569
1570 if (count * elems > (GLint) param->Size) {
1571 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)");
1572 return;
1573 }
1574
1575 if (count > slots)
1576 count = slots;
1577
1578 for (k = 0; k < count; k++) {
1579 GLfloat *uniformVal =
1580 program->Parameters->ParameterValues[index + offset + k];
1581 if (is_integer_type(type)) {
1582 const GLint *iValues = ((const GLint *) values) + k * elems;
1583 for (i = 0; i < elems; i++) {
1584 uniformVal[i] = (GLfloat) iValues[i];
1585 }
1586 }
1587 else {
1588 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1589 for (i = 0; i < elems; i++) {
1590 uniformVal[i] = fValues[i];
1591 }
1592 }
1593
1594 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1595 if (is_boolean_type(param->DataType)) {
1596 for (i = 0; i < elems; i++) {
1597 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1598 }
1599 }
1600 }
1601 }
1602 }
1603
1604
1605 /**
1606 * Called via ctx->Driver.Uniform().
1607 */
1608 static void
1609 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1610 const GLvoid *values, GLenum type)
1611 {
1612 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1613 GLint elems, offset;
1614
1615 if (!shProg || !shProg->LinkStatus) {
1616 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1617 return;
1618 }
1619
1620 if (location == -1)
1621 return; /* The standard specifies this as a no-op */
1622
1623 split_location_offset(&location, &offset);
1624
1625 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1626 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1627 return;
1628 }
1629
1630 if (count < 0) {
1631 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1632 return;
1633 }
1634
1635 switch (type) {
1636 case GL_FLOAT:
1637 case GL_INT:
1638 elems = 1;
1639 break;
1640 case GL_FLOAT_VEC2:
1641 case GL_INT_VEC2:
1642 elems = 2;
1643 break;
1644 case GL_FLOAT_VEC3:
1645 case GL_INT_VEC3:
1646 elems = 3;
1647 break;
1648 case GL_FLOAT_VEC4:
1649 case GL_INT_VEC4:
1650 elems = 4;
1651 break;
1652 default:
1653 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1654 return;
1655 }
1656
1657 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1658
1659 /* A uniform var may be used by both a vertex shader and a fragment
1660 * shader. We may need to update one or both shader's uniform here:
1661 */
1662 if (shProg->VertexProgram) {
1663 /* convert uniform location to program parameter index */
1664 GLint index = shProg->Uniforms->Uniforms[location].VertPos;
1665 if (index >= 0) {
1666 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1667 index, offset, type, count, elems, values);
1668 }
1669 }
1670
1671 if (shProg->FragmentProgram) {
1672 /* convert uniform location to program parameter index */
1673 GLint index = shProg->Uniforms->Uniforms[location].FragPos;
1674 if (index >= 0) {
1675 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1676 index, offset, type, count, elems, values);
1677 }
1678 }
1679
1680 shProg->Uniforms->Uniforms[location].Initialized = GL_TRUE;
1681 }
1682
1683
1684 /**
1685 * Set a matrix-valued program parameter.
1686 */
1687 static void
1688 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1689 GLuint index, GLuint offset,
1690 GLuint count, GLuint rows, GLuint cols,
1691 GLboolean transpose, const GLfloat *values)
1692 {
1693 GLuint mat, row, col;
1694 GLuint dst = index + offset, src = 0;
1695 GLint nr, nc;
1696
1697 /* check that the number of rows, columns is correct */
1698 get_matrix_dims(program->Parameters->Parameters[index].DataType, &nr, &nc);
1699 if (rows != nr || cols != nc) {
1700 _mesa_error(ctx, GL_INVALID_OPERATION,
1701 "glUniformMatrix(matrix size mismatch)");
1702 return;
1703 }
1704
1705 if (index + offset > program->Parameters->Size) {
1706 /* out of bounds! */
1707 return;
1708 }
1709
1710 /*
1711 * Note: the _columns_ of a matrix are stored in program registers, not
1712 * the rows. So, the loops below look a little funny.
1713 * XXX could optimize this a bit...
1714 */
1715
1716 /* loop over matrices */
1717 for (mat = 0; mat < count; mat++) {
1718
1719 /* each matrix: */
1720 for (col = 0; col < cols; col++) {
1721 GLfloat *v = program->Parameters->ParameterValues[dst];
1722 for (row = 0; row < rows; row++) {
1723 if (transpose) {
1724 v[row] = values[src + row * cols + col];
1725 }
1726 else {
1727 v[row] = values[src + col * rows + row];
1728 }
1729 }
1730 dst++;
1731 }
1732
1733 src += rows * cols; /* next matrix */
1734 }
1735 }
1736
1737
1738 /**
1739 * Called by ctx->Driver.UniformMatrix().
1740 * Note: cols=2, rows=4 ==> array[2] of vec4
1741 */
1742 static void
1743 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1744 GLenum matrixType, GLint location, GLsizei count,
1745 GLboolean transpose, const GLfloat *values)
1746 {
1747 GLint offset;
1748 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1749
1750 if (!shProg || !shProg->LinkStatus) {
1751 _mesa_error(ctx, GL_INVALID_OPERATION,
1752 "glUniformMatrix(program not linked)");
1753 return;
1754 }
1755
1756 if (location == -1)
1757 return; /* The standard specifies this as a no-op */
1758
1759 split_location_offset(&location, &offset);
1760
1761 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1762 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
1763 return;
1764 }
1765 if (values == NULL) {
1766 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
1767 return;
1768 }
1769
1770 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1771
1772 if (shProg->VertexProgram) {
1773 /* convert uniform location to program parameter index */
1774 GLint index = shProg->Uniforms->Uniforms[location].VertPos;
1775 if (index >= 0) {
1776 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
1777 index, offset,
1778 count, rows, cols, transpose, values);
1779 }
1780 }
1781
1782 if (shProg->FragmentProgram) {
1783 /* convert uniform location to program parameter index */
1784 GLint index = shProg->Uniforms->Uniforms[location].FragPos;
1785 if (index >= 0) {
1786 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
1787 index, offset,
1788 count, rows, cols, transpose, values);
1789 }
1790 }
1791
1792 shProg->Uniforms->Uniforms[location].Initialized = GL_TRUE;
1793 }
1794
1795
1796 static void
1797 _mesa_validate_program(GLcontext *ctx, GLuint program)
1798 {
1799 struct gl_shader_program *shProg;
1800
1801 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1802 if (!shProg) {
1803 return;
1804 }
1805
1806 if (!shProg->LinkStatus) {
1807 shProg->Validated = GL_FALSE;
1808 return;
1809 }
1810
1811 /* From the GL spec, a program is invalid if any of these are true:
1812
1813 any two active samplers in the current program object are of
1814 different types, but refer to the same texture image unit,
1815
1816 any active sampler in the current program object refers to a texture
1817 image unit where fixed-function fragment processing accesses a
1818 texture target that does not match the sampler type, or
1819
1820 the sum of the number of active samplers in the program and the
1821 number of texture image units enabled for fixed-function fragment
1822 processing exceeds the combined limit on the total number of texture
1823 image units allowed.
1824 */
1825
1826 shProg->Validated = GL_TRUE;
1827 }
1828
1829
1830 /**
1831 * Plug in Mesa's GLSL functions into the device driver function table.
1832 */
1833 void
1834 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
1835 {
1836 driver->AttachShader = _mesa_attach_shader;
1837 driver->BindAttribLocation = _mesa_bind_attrib_location;
1838 driver->CompileShader = _mesa_compile_shader;
1839 driver->CreateProgram = _mesa_create_program;
1840 driver->CreateShader = _mesa_create_shader;
1841 driver->DeleteProgram2 = _mesa_delete_program2;
1842 driver->DeleteShader = _mesa_delete_shader;
1843 driver->DetachShader = _mesa_detach_shader;
1844 driver->GetActiveAttrib = _mesa_get_active_attrib;
1845 driver->GetActiveUniform = _mesa_get_active_uniform;
1846 driver->GetAttachedShaders = _mesa_get_attached_shaders;
1847 driver->GetAttribLocation = _mesa_get_attrib_location;
1848 driver->GetHandle = _mesa_get_handle;
1849 driver->GetProgramiv = _mesa_get_programiv;
1850 driver->GetProgramInfoLog = _mesa_get_program_info_log;
1851 driver->GetShaderiv = _mesa_get_shaderiv;
1852 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
1853 driver->GetShaderSource = _mesa_get_shader_source;
1854 driver->GetUniformfv = _mesa_get_uniformfv;
1855 driver->GetUniformiv = _mesa_get_uniformiv;
1856 driver->GetUniformLocation = _mesa_get_uniform_location;
1857 driver->IsProgram = _mesa_is_program;
1858 driver->IsShader = _mesa_is_shader;
1859 driver->LinkProgram = _mesa_link_program;
1860 driver->ShaderSource = _mesa_shader_source;
1861 driver->Uniform = _mesa_uniform;
1862 driver->UniformMatrix = _mesa_uniform_matrix;
1863 driver->UseProgram = _mesa_use_program;
1864 driver->ValidateProgram = _mesa_validate_program;
1865 }