mesa: glsl: only try to link shaders defining main()
[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 if (sh->Source)
266 _mesa_free((void *) sh->Source);
267 if (sh->InfoLog)
268 _mesa_free(sh->InfoLog);
269 _mesa_reference_program(ctx, &sh->Program, NULL);
270 _mesa_free(sh);
271 }
272
273
274 /**
275 * Set ptr to point to sh.
276 * If ptr is pointing to another shader, decrement its refcount (and delete
277 * if refcount hits zero).
278 * Then set ptr to point to sh, incrementing its refcount.
279 */
280 /* XXX this could be static */
281 void
282 _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
283 struct gl_shader *sh)
284 {
285 assert(ptr);
286 if (*ptr == sh) {
287 /* no-op */
288 return;
289 }
290 if (*ptr) {
291 /* Unreference the old shader */
292 GLboolean deleteFlag = GL_FALSE;
293 struct gl_shader *old = *ptr;
294
295 ASSERT(old->RefCount > 0);
296 old->RefCount--;
297 /*printf("SHADER DECR %p (%d) to %d\n",
298 (void*) old, old->Name, old->RefCount);*/
299 deleteFlag = (old->RefCount == 0);
300
301 if (deleteFlag) {
302 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
303 _mesa_free_shader(ctx, old);
304 }
305
306 *ptr = NULL;
307 }
308 assert(!*ptr);
309
310 if (sh) {
311 /* reference new */
312 sh->RefCount++;
313 /*printf("SHADER INCR %p (%d) to %d\n",
314 (void*) sh, sh->Name, sh->RefCount);*/
315 *ptr = sh;
316 }
317 }
318
319
320 /**
321 * Lookup a GLSL shader object.
322 */
323 struct gl_shader *
324 _mesa_lookup_shader(GLcontext *ctx, GLuint name)
325 {
326 if (name) {
327 struct gl_shader *sh = (struct gl_shader *)
328 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
329 /* Note that both gl_shader and gl_shader_program objects are kept
330 * in the same hash table. Check the object's type to be sure it's
331 * what we're expecting.
332 */
333 if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
334 return NULL;
335 }
336 return sh;
337 }
338 return NULL;
339 }
340
341
342 /**
343 * As above, but record an error if shader is not found.
344 */
345 static struct gl_shader *
346 _mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
347 {
348 if (!name) {
349 _mesa_error(ctx, GL_INVALID_VALUE, caller);
350 return NULL;
351 }
352 else {
353 struct gl_shader *sh = (struct gl_shader *)
354 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
355 if (!sh) {
356 _mesa_error(ctx, GL_INVALID_VALUE, caller);
357 return NULL;
358 }
359 if (sh->Type == GL_SHADER_PROGRAM_MESA) {
360 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
361 return NULL;
362 }
363 return sh;
364 }
365 }
366
367
368
369 /**
370 * Initialize context's shader state.
371 */
372 void
373 _mesa_init_shader_state(GLcontext * ctx)
374 {
375 /* Device drivers may override these to control what kind of instructions
376 * are generated by the GLSL compiler.
377 */
378 ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
379 ctx->Shader.EmitCondCodes = GL_TRUE; /* XXX probably want GL_FALSE... */
380 ctx->Shader.EmitComments = GL_FALSE;
381 }
382
383
384 /**
385 * Free the per-context shader-related state.
386 */
387 void
388 _mesa_free_shader_state(GLcontext *ctx)
389 {
390 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
391 }
392
393
394 /**
395 * Copy string from <src> to <dst>, up to maxLength characters, returning
396 * length of <dst> in <length>.
397 * \param src the strings source
398 * \param maxLength max chars to copy
399 * \param length returns number of chars copied
400 * \param dst the string destination
401 */
402 static void
403 copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src)
404 {
405 GLsizei len;
406 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
407 dst[len] = src[len];
408 if (maxLength > 0)
409 dst[len] = 0;
410 if (length)
411 *length = len;
412 }
413
414
415 static GLboolean
416 _mesa_is_program(GLcontext *ctx, GLuint name)
417 {
418 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
419 return shProg ? GL_TRUE : GL_FALSE;
420 }
421
422
423 static GLboolean
424 _mesa_is_shader(GLcontext *ctx, GLuint name)
425 {
426 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
427 return shader ? GL_TRUE : GL_FALSE;
428 }
429
430
431 /**
432 * Called via ctx->Driver.AttachShader()
433 */
434 static void
435 _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
436 {
437 struct gl_shader_program *shProg;
438 struct gl_shader *sh;
439 GLuint i, n;
440
441 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
442 if (!shProg)
443 return;
444
445 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
446 if (!sh) {
447 return;
448 }
449
450 n = shProg->NumShaders;
451 for (i = 0; i < n; i++) {
452 if (shProg->Shaders[i] == sh) {
453 /* already attached */
454 return;
455 }
456 }
457
458 /* grow list */
459 shProg->Shaders = (struct gl_shader **)
460 _mesa_realloc(shProg->Shaders,
461 n * sizeof(struct gl_shader *),
462 (n + 1) * sizeof(struct gl_shader *));
463 if (!shProg->Shaders) {
464 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
465 return;
466 }
467
468 /* append */
469 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
470 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
471 shProg->NumShaders++;
472 }
473
474
475 static GLint
476 _mesa_get_attrib_location(GLcontext *ctx, GLuint program,
477 const GLchar *name)
478 {
479 struct gl_shader_program *shProg
480 = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
481
482 if (!shProg) {
483 return -1;
484 }
485
486 if (!shProg->LinkStatus) {
487 _mesa_error(ctx, GL_INVALID_OPERATION,
488 "glGetAttribLocation(program not linked)");
489 return -1;
490 }
491
492 if (!name)
493 return -1;
494
495 if (shProg->Attributes) {
496 GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name);
497 if (i >= 0) {
498 return shProg->Attributes->Parameters[i].StateIndexes[0];
499 }
500 }
501 return -1;
502 }
503
504
505 static void
506 _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
507 const GLchar *name)
508 {
509 struct gl_shader_program *shProg;
510 const GLint size = -1; /* unknown size */
511 GLint i, oldIndex;
512 GLenum datatype;
513
514 shProg = _mesa_lookup_shader_program_err(ctx, program,
515 "glBindAttribLocation");
516 if (!shProg) {
517 return;
518 }
519
520 if (!name)
521 return;
522
523 if (strncmp(name, "gl_", 3) == 0) {
524 _mesa_error(ctx, GL_INVALID_OPERATION,
525 "glBindAttribLocation(illegal name)");
526 return;
527 }
528
529 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
530 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
531 return;
532 }
533
534 if (shProg->LinkStatus) {
535 /* get current index/location for the attribute */
536 oldIndex = _mesa_get_attrib_location(ctx, program, name);
537 }
538 else {
539 oldIndex = -1;
540 }
541
542 /* this will replace the current value if it's already in the list */
543 i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
544 if (i < 0) {
545 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
546 }
547
548 if (shProg->VertexProgram && oldIndex >= 0 && oldIndex != index) {
549 /* If the index changed, need to search/replace references to that attribute
550 * in the vertex program.
551 */
552 _slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index);
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 return 1;
718 case GL_FLOAT_VEC2:
719 case GL_INT_VEC2:
720 case GL_BOOL_VEC2:
721 return 2;
722 case GL_FLOAT_VEC3:
723 case GL_INT_VEC3:
724 case GL_BOOL_VEC3:
725 return 3;
726 case GL_FLOAT_VEC4:
727 case GL_INT_VEC4:
728 case GL_BOOL_VEC4:
729 return 4;
730 case GL_FLOAT_MAT2:
731 case GL_FLOAT_MAT2x3:
732 case GL_FLOAT_MAT2x4:
733 return 8; /* two float[4] vectors */
734 case GL_FLOAT_MAT3:
735 case GL_FLOAT_MAT3x2:
736 case GL_FLOAT_MAT3x4:
737 return 12; /* three float[4] vectors */
738 case GL_FLOAT_MAT4:
739 case GL_FLOAT_MAT4x2:
740 case GL_FLOAT_MAT4x3:
741 return 16; /* four float[4] vectors */
742 default:
743 _mesa_problem(NULL, "Invalid type in sizeof_glsl_type()");
744 return 1;
745 }
746 }
747
748
749 static void
750 _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
751 GLsizei maxLength, GLsizei *length, GLint *size,
752 GLenum *type, GLchar *nameOut)
753 {
754 struct gl_shader_program *shProg;
755
756 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
757 if (!shProg)
758 return;
759
760 if (!shProg->Attributes || index >= shProg->Attributes->NumParameters) {
761 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
762 return;
763 }
764
765 copy_string(nameOut, maxLength, length,
766 shProg->Attributes->Parameters[index].Name);
767 if (size)
768 *size = shProg->Attributes->Parameters[index].Size
769 / sizeof_glsl_type(shProg->Attributes->Parameters[index].DataType);
770 if (type)
771 *type = shProg->Attributes->Parameters[index].DataType;
772 }
773
774
775 /**
776 * Called via ctx->Driver.GetActiveUniform().
777 */
778 static void
779 _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
780 GLsizei maxLength, GLsizei *length, GLint *size,
781 GLenum *type, GLchar *nameOut)
782 {
783 const struct gl_shader_program *shProg;
784 const struct gl_program *prog;
785 GLint progPos;
786
787 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
788 if (!shProg)
789 return;
790
791 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
792 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
793 return;
794 }
795
796 progPos = shProg->Uniforms->Uniforms[index].VertPos;
797 if (progPos >= 0) {
798 prog = &shProg->VertexProgram->Base;
799 }
800 else {
801 progPos = shProg->Uniforms->Uniforms[index].FragPos;
802 if (progPos >= 0) {
803 prog = &shProg->FragmentProgram->Base;
804 }
805 }
806
807 if (!prog || progPos < 0)
808 return; /* should never happen */
809
810 if (nameOut)
811 copy_string(nameOut, maxLength, length,
812 prog->Parameters->Parameters[progPos].Name);
813 if (size)
814 *size = prog->Parameters->Parameters[progPos].Size
815 / sizeof_glsl_type(prog->Parameters->Parameters[progPos].DataType);
816 if (type)
817 *type = prog->Parameters->Parameters[progPos].DataType;
818 }
819
820
821 /**
822 * Called via ctx->Driver.GetAttachedShaders().
823 */
824 static void
825 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
826 GLsizei *count, GLuint *obj)
827 {
828 struct gl_shader_program *shProg =
829 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
830 if (shProg) {
831 GLuint i;
832 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
833 obj[i] = shProg->Shaders[i]->Name;
834 }
835 if (count)
836 *count = i;
837 }
838 }
839
840
841 static GLuint
842 _mesa_get_handle(GLcontext *ctx, GLenum pname)
843 {
844 #if 0
845 GET_CURRENT_CONTEXT(ctx);
846
847 switch (pname) {
848 case GL_PROGRAM_OBJECT_ARB:
849 {
850 struct gl2_program_intf **pro = ctx->Shader.CurrentProgram;
851
852 if (pro != NULL)
853 return (**pro)._container._generic.
854 GetName((struct gl2_generic_intf **) (pro));
855 }
856 break;
857 default:
858 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
859 }
860 #endif
861 return 0;
862 }
863
864
865 static void
866 _mesa_get_programiv(GLcontext *ctx, GLuint program,
867 GLenum pname, GLint *params)
868 {
869 struct gl_shader_program *shProg
870 = _mesa_lookup_shader_program(ctx, program);
871
872 if (!shProg) {
873 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
874 return;
875 }
876
877 switch (pname) {
878 case GL_DELETE_STATUS:
879 *params = shProg->DeletePending;
880 break;
881 case GL_LINK_STATUS:
882 *params = shProg->LinkStatus;
883 break;
884 case GL_VALIDATE_STATUS:
885 *params = shProg->Validated;
886 break;
887 case GL_INFO_LOG_LENGTH:
888 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
889 break;
890 case GL_ATTACHED_SHADERS:
891 *params = shProg->NumShaders;
892 break;
893 case GL_ACTIVE_ATTRIBUTES:
894 *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0;
895 break;
896 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
897 *params = _mesa_longest_parameter_name(shProg->Attributes,
898 PROGRAM_INPUT) + 1;
899 break;
900 case GL_ACTIVE_UNIFORMS:
901 *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
902 break;
903 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
904 *params = _mesa_longest_uniform_name(shProg->Uniforms);
905 if (*params > 0)
906 (*params)++; /* add one for terminating zero */
907 break;
908 default:
909 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
910 return;
911 }
912 }
913
914
915 static void
916 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
917 {
918 struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
919
920 if (!shader) {
921 return;
922 }
923
924 switch (pname) {
925 case GL_SHADER_TYPE:
926 *params = shader->Type;
927 break;
928 case GL_DELETE_STATUS:
929 *params = shader->DeletePending;
930 break;
931 case GL_COMPILE_STATUS:
932 *params = shader->CompileStatus;
933 break;
934 case GL_INFO_LOG_LENGTH:
935 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
936 break;
937 case GL_SHADER_SOURCE_LENGTH:
938 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
939 break;
940 default:
941 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
942 return;
943 }
944 }
945
946
947 static void
948 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
949 GLsizei *length, GLchar *infoLog)
950 {
951 struct gl_shader_program *shProg
952 = _mesa_lookup_shader_program(ctx, program);
953 if (!shProg) {
954 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
955 return;
956 }
957 copy_string(infoLog, bufSize, length, shProg->InfoLog);
958 }
959
960
961 static void
962 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
963 GLsizei *length, GLchar *infoLog)
964 {
965 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
966 if (!sh) {
967 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
968 return;
969 }
970 copy_string(infoLog, bufSize, length, sh->InfoLog);
971 }
972
973
974 /**
975 * Called via ctx->Driver.GetShaderSource().
976 */
977 static void
978 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
979 GLsizei *length, GLchar *sourceOut)
980 {
981 struct gl_shader *sh;
982 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
983 if (!sh) {
984 return;
985 }
986 copy_string(sourceOut, maxLength, length, sh->Source);
987 }
988
989
990 #define MAX_UNIFORM_ELEMENTS 16
991
992 /**
993 * Helper for GetUniformfv(), GetUniformiv()
994 * Returns number of elements written to 'params' output.
995 */
996 static GLuint
997 get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
998 GLfloat *params)
999 {
1000 struct gl_shader_program *shProg
1001 = _mesa_lookup_shader_program(ctx, program);
1002 if (shProg) {
1003 if (shProg->Uniforms &&
1004 location >= 0 && location < shProg->Uniforms->NumUniforms) {
1005 GLint progPos;
1006 GLuint i;
1007 const struct gl_program *prog = NULL;
1008
1009 progPos = shProg->Uniforms->Uniforms[location].VertPos;
1010 if (progPos >= 0) {
1011 prog = &shProg->VertexProgram->Base;
1012 }
1013 else {
1014 progPos = shProg->Uniforms->Uniforms[location].FragPos;
1015 if (progPos >= 0) {
1016 prog = &shProg->FragmentProgram->Base;
1017 }
1018 }
1019
1020 ASSERT(prog);
1021 if (prog) {
1022 /* See uniformiv() below */
1023 assert(prog->Parameters->Parameters[progPos].Size <= MAX_UNIFORM_ELEMENTS);
1024
1025 for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) {
1026 params[i] = prog->Parameters->ParameterValues[progPos][i];
1027 }
1028 return prog->Parameters->Parameters[progPos].Size;
1029 }
1030 }
1031 else {
1032 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
1033 }
1034 }
1035 else {
1036 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1037 }
1038 return 0;
1039 }
1040
1041
1042 /**
1043 * Called via ctx->Driver.GetUniformfv().
1044 */
1045 static void
1046 _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
1047 GLfloat *params)
1048 {
1049 (void) get_uniformfv(ctx, program, location, params);
1050 }
1051
1052
1053 /**
1054 * Called via ctx->Driver.GetUniformiv().
1055 */
1056 static void
1057 _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
1058 GLint *params)
1059 {
1060 GLfloat fparams[MAX_UNIFORM_ELEMENTS];
1061 GLuint n = get_uniformfv(ctx, program, location, fparams);
1062 GLuint i;
1063 assert(n <= MAX_UNIFORM_ELEMENTS);
1064 for (i = 0; i < n; i++) {
1065 params[i] = (GLint) fparams[i];
1066 }
1067 }
1068
1069
1070 /**
1071 * Called via ctx->Driver.GetUniformLocation().
1072 */
1073 static GLint
1074 _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
1075 {
1076 struct gl_shader_program *shProg =
1077 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
1078
1079 if (!shProg)
1080 return -1;
1081
1082 if (shProg->LinkStatus == GL_FALSE) {
1083 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
1084 return -1;
1085 }
1086
1087 /* XXX we should return -1 if the uniform was declared, but not
1088 * actually used.
1089 */
1090
1091 return _mesa_lookup_uniform(shProg->Uniforms, name);
1092 }
1093
1094
1095
1096 /**
1097 * Called via ctx->Driver.ShaderSource()
1098 */
1099 static void
1100 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1101 {
1102 struct gl_shader *sh;
1103
1104 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1105 if (!sh)
1106 return;
1107
1108 /* free old shader source string and install new one */
1109 if (sh->Source) {
1110 _mesa_free((void *) sh->Source);
1111 }
1112 sh->Source = source;
1113 sh->CompileStatus = GL_FALSE;
1114 }
1115
1116
1117 /**
1118 * Called via ctx->Driver.CompileShader()
1119 */
1120 static void
1121 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1122 {
1123 struct gl_shader *sh;
1124
1125 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1126 if (!sh)
1127 return;
1128
1129 sh->CompileStatus = _slang_compile(ctx, sh);
1130 }
1131
1132
1133 /**
1134 * Called via ctx->Driver.LinkProgram()
1135 */
1136 static void
1137 _mesa_link_program(GLcontext *ctx, GLuint program)
1138 {
1139 struct gl_shader_program *shProg;
1140
1141 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1142 if (!shProg)
1143 return;
1144
1145 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1146
1147 _slang_link(ctx, program, shProg);
1148 }
1149
1150
1151 /**
1152 * Called via ctx->Driver.UseProgram()
1153 */
1154 void
1155 _mesa_use_program(GLcontext *ctx, GLuint program)
1156 {
1157 struct gl_shader_program *shProg;
1158
1159 if (ctx->Shader.CurrentProgram &&
1160 ctx->Shader.CurrentProgram->Name == program) {
1161 /* no-op */
1162 return;
1163 }
1164
1165 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1166
1167 if (program) {
1168 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1169 if (!shProg) {
1170 return;
1171 }
1172 if (!shProg->LinkStatus) {
1173 _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgram");
1174 return;
1175 }
1176 }
1177 else {
1178 shProg = NULL;
1179 }
1180
1181 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1182 }
1183
1184
1185
1186 /**
1187 * Update the vertex and fragment program's TexturesUsed arrays.
1188 */
1189 static void
1190 update_textures_used(struct gl_program *prog)
1191 {
1192 GLuint s;
1193
1194 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1195
1196 for (s = 0; s < MAX_SAMPLERS; s++) {
1197 if (prog->SamplersUsed & (1 << s)) {
1198 GLuint u = prog->SamplerUnits[s];
1199 GLuint t = prog->SamplerTargets[s];
1200 assert(u < MAX_TEXTURE_IMAGE_UNITS);
1201 prog->TexturesUsed[u] |= (1 << t);
1202 }
1203 }
1204 }
1205
1206
1207 static GLboolean
1208 is_sampler_type(GLenum type)
1209 {
1210 switch (type) {
1211 case GL_SAMPLER_1D:
1212 case GL_SAMPLER_2D:
1213 case GL_SAMPLER_3D:
1214 case GL_SAMPLER_CUBE:
1215 case GL_SAMPLER_1D_SHADOW:
1216 case GL_SAMPLER_2D_SHADOW:
1217 case GL_SAMPLER_2D_RECT_ARB:
1218 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
1219 case GL_SAMPLER_1D_ARRAY_EXT:
1220 case GL_SAMPLER_2D_ARRAY_EXT:
1221 return GL_TRUE;
1222 default:
1223 return GL_FALSE;
1224 }
1225 }
1226
1227
1228 /**
1229 * Check if the type given by userType is allowed to set a uniform of the
1230 * target type. Generally, equivalence is required, but setting Boolean
1231 * uniforms can be done with glUniformiv or glUniformfv.
1232 */
1233 static GLboolean
1234 compatible_types(GLenum userType, GLenum targetType)
1235 {
1236 if (userType == targetType)
1237 return GL_TRUE;
1238
1239 if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT))
1240 return GL_TRUE;
1241
1242 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
1243 userType == GL_INT_VEC2))
1244 return GL_TRUE;
1245
1246 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
1247 userType == GL_INT_VEC3))
1248 return GL_TRUE;
1249
1250 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
1251 userType == GL_INT_VEC4))
1252 return GL_TRUE;
1253
1254 if (is_sampler_type(targetType) && userType == GL_INT)
1255 return GL_TRUE;
1256
1257 return GL_FALSE;
1258 }
1259
1260
1261 /**
1262 * Set the value of a program's uniform variable.
1263 * \param program the program whose uniform to update
1264 * \param location the location/index of the uniform
1265 * \param type the datatype of the uniform
1266 * \param count the number of uniforms to set
1267 * \param elems number of elements per uniform
1268 * \param values the new values
1269 */
1270 static void
1271 set_program_uniform(GLcontext *ctx, struct gl_program *program, GLint location,
1272 GLenum type, GLsizei count, GLint elems, const void *values)
1273 {
1274 if (!compatible_types(type,
1275 program->Parameters->Parameters[location].DataType)) {
1276 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
1277 return;
1278 }
1279
1280 if (program->Parameters->Parameters[location].Type == PROGRAM_SAMPLER) {
1281 /* This controls which texture unit which is used by a sampler */
1282 GLuint texUnit, sampler;
1283
1284 /* data type for setting samplers must be int */
1285 if (type != GL_INT || count != 1) {
1286 _mesa_error(ctx, GL_INVALID_OPERATION,
1287 "glUniform(only glUniform1i can be used "
1288 "to set sampler uniforms)");
1289 return;
1290 }
1291
1292 sampler = (GLuint) program->Parameters->ParameterValues[location][0];
1293 texUnit = ((GLuint *) values)[0];
1294
1295 /* check that the sampler (tex unit index) is legal */
1296 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
1297 _mesa_error(ctx, GL_INVALID_VALUE,
1298 "glUniform1(invalid sampler/tex unit index)");
1299 return;
1300 }
1301
1302 /* This maps a sampler to a texture unit: */
1303 program->SamplerUnits[sampler] = texUnit;
1304 update_textures_used(program);
1305
1306 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1307 }
1308 else {
1309 /* ordinary uniform variable */
1310 GLsizei k, i;
1311
1312 if (count * elems > program->Parameters->Parameters[location].Size) {
1313 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)");
1314 return;
1315 }
1316
1317 for (k = 0; k < count; k++) {
1318 GLfloat *uniformVal = program->Parameters->ParameterValues[location + k];
1319 if (type == GL_INT ||
1320 type == GL_INT_VEC2 ||
1321 type == GL_INT_VEC3 ||
1322 type == GL_INT_VEC4) {
1323 const GLint *iValues = ((const GLint *) values) + k * elems;
1324 for (i = 0; i < elems; i++) {
1325 uniformVal[i] = (GLfloat) iValues[i];
1326 }
1327 }
1328 else {
1329 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
1330 for (i = 0; i < elems; i++) {
1331 uniformVal[i] = fValues[i];
1332 }
1333 }
1334 }
1335 }
1336 }
1337
1338
1339 /**
1340 * Called via ctx->Driver.Uniform().
1341 */
1342 static void
1343 _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
1344 const GLvoid *values, GLenum type)
1345 {
1346 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1347 GLint elems;
1348
1349 if (!shProg || !shProg->LinkStatus) {
1350 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1351 return;
1352 }
1353
1354 if (location == -1)
1355 return; /* The standard specifies this as a no-op */
1356
1357 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1358 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
1359 return;
1360 }
1361
1362 if (count < 0) {
1363 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1364 return;
1365 }
1366
1367 switch (type) {
1368 case GL_FLOAT:
1369 case GL_INT:
1370 elems = 1;
1371 break;
1372 case GL_FLOAT_VEC2:
1373 case GL_INT_VEC2:
1374 elems = 2;
1375 break;
1376 case GL_FLOAT_VEC3:
1377 case GL_INT_VEC3:
1378 elems = 3;
1379 break;
1380 case GL_FLOAT_VEC4:
1381 case GL_INT_VEC4:
1382 elems = 4;
1383 break;
1384 default:
1385 _mesa_problem(ctx, "Invalid type in _mesa_uniform");
1386 return;
1387 }
1388
1389 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1390
1391 /* A uniform var may be used by both a vertex shader and a fragment
1392 * shader. We may need to update one or both shader's uniform here:
1393 */
1394 if (shProg->VertexProgram) {
1395 GLint loc = shProg->Uniforms->Uniforms[location].VertPos;
1396 if (loc >= 0) {
1397 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1398 loc, type, count, elems, values);
1399 }
1400 }
1401
1402 if (shProg->FragmentProgram) {
1403 GLint loc = shProg->Uniforms->Uniforms[location].FragPos;
1404 if (loc >= 0) {
1405 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1406 loc, type, count, elems, values);
1407 }
1408 }
1409 }
1410
1411
1412 static void
1413 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
1414 {
1415 switch (type) {
1416 case GL_FLOAT_MAT2:
1417 *rows = *cols = 2;
1418 break;
1419 case GL_FLOAT_MAT2x3:
1420 *rows = 3;
1421 *cols = 2;
1422 break;
1423 case GL_FLOAT_MAT2x4:
1424 *rows = 4;
1425 *cols = 2;
1426 break;
1427 case GL_FLOAT_MAT3:
1428 *rows = 3;
1429 *cols = 3;
1430 break;
1431 case GL_FLOAT_MAT3x2:
1432 *rows = 2;
1433 *cols = 3;
1434 break;
1435 case GL_FLOAT_MAT3x4:
1436 *rows = 4;
1437 *cols = 3;
1438 break;
1439 case GL_FLOAT_MAT4:
1440 *rows = 4;
1441 *cols = 4;
1442 break;
1443 case GL_FLOAT_MAT4x2:
1444 *rows = 2;
1445 *cols = 4;
1446 break;
1447 case GL_FLOAT_MAT4x3:
1448 *rows = 3;
1449 *cols = 4;
1450 break;
1451 default:
1452 *rows = *cols = 0;
1453 }
1454 }
1455
1456
1457 static void
1458 set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
1459 GLuint location, GLuint count,
1460 GLuint rows, GLuint cols,
1461 GLboolean transpose, const GLfloat *values)
1462 {
1463 GLuint mat, row, col;
1464 GLuint dst = location, src = 0;
1465 GLint nr, nc;
1466
1467 /* check that the number of rows, columns is correct */
1468 get_matrix_dims(program->Parameters->Parameters[location].DataType, &nr, &nc);
1469 if (rows != nr || cols != nc) {
1470 _mesa_error(ctx, GL_INVALID_OPERATION,
1471 "glUniformMatrix(matrix size mismatch");
1472 return;
1473 }
1474
1475 /*
1476 * Note: the _columns_ of a matrix are stored in program registers, not
1477 * the rows. So, the loops below look a little funny.
1478 * XXX could optimize this a bit...
1479 */
1480
1481 /* loop over matrices */
1482 for (mat = 0; mat < count; mat++) {
1483
1484 /* each matrix: */
1485 for (col = 0; col < cols; col++) {
1486 GLfloat *v = program->Parameters->ParameterValues[dst];
1487 for (row = 0; row < rows; row++) {
1488 if (transpose) {
1489 v[row] = values[src + row * cols + col];
1490 }
1491 else {
1492 v[row] = values[src + col * rows + row];
1493 }
1494 }
1495 dst++;
1496 }
1497
1498 src += rows * cols; /* next matrix */
1499 }
1500 }
1501
1502
1503 /**
1504 * Called by ctx->Driver.UniformMatrix().
1505 * Note: cols=2, rows=4 ==> array[2] of vec4
1506 */
1507 static void
1508 _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
1509 GLenum matrixType, GLint location, GLsizei count,
1510 GLboolean transpose, const GLfloat *values)
1511 {
1512 struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
1513
1514 if (!shProg || !shProg->LinkStatus) {
1515 _mesa_error(ctx, GL_INVALID_OPERATION,
1516 "glUniformMatrix(program not linked)");
1517 return;
1518 }
1519
1520 if (location == -1)
1521 return; /* The standard specifies this as a no-op */
1522
1523 if (location < 0 || location >= shProg->Uniforms->NumUniforms) {
1524 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
1525 return;
1526 }
1527 if (values == NULL) {
1528 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
1529 return;
1530 }
1531
1532 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1533
1534 if (shProg->VertexProgram) {
1535 GLint loc = shProg->Uniforms->Uniforms[location].VertPos;
1536 if (loc >= 0) {
1537 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
1538 loc, count, rows, cols, transpose, values);
1539 }
1540 }
1541
1542 if (shProg->FragmentProgram) {
1543 GLint loc = shProg->Uniforms->Uniforms[location].FragPos;
1544 if (loc >= 0) {
1545 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
1546 loc, count, rows, cols, transpose, values);
1547 }
1548 }
1549 }
1550
1551
1552 static void
1553 _mesa_validate_program(GLcontext *ctx, GLuint program)
1554 {
1555 struct gl_shader_program *shProg;
1556
1557 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1558 if (!shProg) {
1559 return;
1560 }
1561
1562 if (!shProg->LinkStatus) {
1563 shProg->Validated = GL_FALSE;
1564 return;
1565 }
1566
1567 /* From the GL spec, a program is invalid if any of these are true:
1568
1569 any two active samplers in the current program object are of
1570 different types, but refer to the same texture image unit,
1571
1572 any active sampler in the current program object refers to a texture
1573 image unit where fixed-function fragment processing accesses a
1574 texture target that does not match the sampler type, or
1575
1576 the sum of the number of active samplers in the program and the
1577 number of texture image units enabled for fixed-function fragment
1578 processing exceeds the combined limit on the total number of texture
1579 image units allowed.
1580 */
1581
1582 shProg->Validated = GL_TRUE;
1583 }
1584
1585
1586 /**
1587 * Plug in Mesa's GLSL functions into the device driver function table.
1588 */
1589 void
1590 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
1591 {
1592 driver->AttachShader = _mesa_attach_shader;
1593 driver->BindAttribLocation = _mesa_bind_attrib_location;
1594 driver->CompileShader = _mesa_compile_shader;
1595 driver->CreateProgram = _mesa_create_program;
1596 driver->CreateShader = _mesa_create_shader;
1597 driver->DeleteProgram2 = _mesa_delete_program2;
1598 driver->DeleteShader = _mesa_delete_shader;
1599 driver->DetachShader = _mesa_detach_shader;
1600 driver->GetActiveAttrib = _mesa_get_active_attrib;
1601 driver->GetActiveUniform = _mesa_get_active_uniform;
1602 driver->GetAttachedShaders = _mesa_get_attached_shaders;
1603 driver->GetAttribLocation = _mesa_get_attrib_location;
1604 driver->GetHandle = _mesa_get_handle;
1605 driver->GetProgramiv = _mesa_get_programiv;
1606 driver->GetProgramInfoLog = _mesa_get_program_info_log;
1607 driver->GetShaderiv = _mesa_get_shaderiv;
1608 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
1609 driver->GetShaderSource = _mesa_get_shader_source;
1610 driver->GetUniformfv = _mesa_get_uniformfv;
1611 driver->GetUniformiv = _mesa_get_uniformiv;
1612 driver->GetUniformLocation = _mesa_get_uniform_location;
1613 driver->IsProgram = _mesa_is_program;
1614 driver->IsShader = _mesa_is_shader;
1615 driver->LinkProgram = _mesa_link_program;
1616 driver->ShaderSource = _mesa_shader_source;
1617 driver->Uniform = _mesa_uniform;
1618 driver->UniformMatrix = _mesa_uniform_matrix;
1619 driver->UseProgram = _mesa_use_program;
1620 driver->ValidateProgram = _mesa_validate_program;
1621 }