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