03fb1a91cef6bc21df9e413d7e072c4c0ad5ffb4
[mesa.git] / src / mesa / shader / shader_api.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.6
4 *
5 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file shader_api.c
28 * Implementation of GLSL-related API functions
29 * \author Brian Paul
30 */
31
32 /**
33 * XXX things to do:
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
36 */
37
38
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/hash.h"
42 #include "shader/program.h"
43 #include "shader/prog_parameter.h"
44 #include "shader/prog_statevars.h"
45 #include "shader/prog_uniform.h"
46 #include "shader/shader_api.h"
47 #include "shader/uniforms.h"
48 #include "shader/slang/slang_compile.h"
49 #include "shader/slang/slang_link.h"
50 #include "main/dispatch.h"
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 free(shProg->Shaders);
120 shProg->Shaders = NULL;
121 }
122
123 if (shProg->InfoLog) {
124 free(shProg->InfoLog);
125 shProg->InfoLog = NULL;
126 }
127
128 /* Transform feedback varying vars */
129 for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
130 free(shProg->TransformFeedback.VaryingNames[i]);
131 }
132 free(shProg->TransformFeedback.VaryingNames);
133 shProg->TransformFeedback.VaryingNames = NULL;
134 shProg->TransformFeedback.NumVarying = 0;
135 }
136
137
138 /**
139 * Free/delete a shader program object.
140 */
141 void
142 _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
143 {
144 _mesa_free_shader_program_data(ctx, shProg);
145
146 free(shProg);
147 }
148
149
150 /**
151 * Set ptr to point to shProg.
152 * If ptr is pointing to another object, decrement its refcount (and delete
153 * if refcount hits zero).
154 * Then set ptr to point to shProg, incrementing its refcount.
155 */
156 /* XXX this could be static */
157 void
158 _mesa_reference_shader_program(GLcontext *ctx,
159 struct gl_shader_program **ptr,
160 struct gl_shader_program *shProg)
161 {
162 assert(ptr);
163 if (*ptr == shProg) {
164 /* no-op */
165 return;
166 }
167 if (*ptr) {
168 /* Unreference the old shader program */
169 GLboolean deleteFlag = GL_FALSE;
170 struct gl_shader_program *old = *ptr;
171
172 ASSERT(old->RefCount > 0);
173 old->RefCount--;
174 #if 0
175 printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
176 (void *) old, old->Name, old->RefCount);
177 #endif
178 deleteFlag = (old->RefCount == 0);
179
180 if (deleteFlag) {
181 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
182 _mesa_free_shader_program(ctx, old);
183 }
184
185 *ptr = NULL;
186 }
187 assert(!*ptr);
188
189 if (shProg) {
190 shProg->RefCount++;
191 #if 0
192 printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
193 (void *) shProg, shProg->Name, shProg->RefCount);
194 #endif
195 *ptr = shProg;
196 }
197 }
198
199
200 /**
201 * Lookup a GLSL program object.
202 */
203 struct gl_shader_program *
204 _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
205 {
206 struct gl_shader_program *shProg;
207 if (name) {
208 shProg = (struct gl_shader_program *)
209 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
210 /* Note that both gl_shader and gl_shader_program objects are kept
211 * in the same hash table. Check the object's type to be sure it's
212 * what we're expecting.
213 */
214 if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
215 return NULL;
216 }
217 return shProg;
218 }
219 return NULL;
220 }
221
222
223 /**
224 * As above, but record an error if program is not found.
225 */
226 struct gl_shader_program *
227 _mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
228 const char *caller)
229 {
230 if (!name) {
231 _mesa_error(ctx, GL_INVALID_VALUE, caller);
232 return NULL;
233 }
234 else {
235 struct gl_shader_program *shProg = (struct gl_shader_program *)
236 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
237 if (!shProg) {
238 _mesa_error(ctx, GL_INVALID_VALUE, caller);
239 return NULL;
240 }
241 if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
242 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
243 return NULL;
244 }
245 return shProg;
246 }
247 }
248
249
250
251
252 /**
253 * Allocate a new gl_shader object, initialize it.
254 */
255 struct gl_shader *
256 _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
257 {
258 struct gl_shader *shader;
259 assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
260 shader = CALLOC_STRUCT(gl_shader);
261 if (shader) {
262 shader->Type = type;
263 shader->Name = name;
264 shader->RefCount = 1;
265 }
266 return shader;
267 }
268
269
270 void
271 _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
272 {
273 if (sh->Source)
274 free((void *) sh->Source);
275 if (sh->InfoLog)
276 free(sh->InfoLog);
277 _mesa_reference_program(ctx, &sh->Program, NULL);
278 free(sh);
279 }
280
281
282 /**
283 * Set ptr to point to sh.
284 * If ptr is pointing to another shader, decrement its refcount (and delete
285 * if refcount hits zero).
286 * Then set ptr to point to sh, incrementing its refcount.
287 */
288 /* XXX this could be static */
289 void
290 _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
291 struct gl_shader *sh)
292 {
293 assert(ptr);
294 if (*ptr == sh) {
295 /* no-op */
296 return;
297 }
298 if (*ptr) {
299 /* Unreference the old shader */
300 GLboolean deleteFlag = GL_FALSE;
301 struct gl_shader *old = *ptr;
302
303 ASSERT(old->RefCount > 0);
304 old->RefCount--;
305 /*printf("SHADER DECR %p (%d) to %d\n",
306 (void*) old, old->Name, old->RefCount);*/
307 deleteFlag = (old->RefCount == 0);
308
309 if (deleteFlag) {
310 _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
311 _mesa_free_shader(ctx, old);
312 }
313
314 *ptr = NULL;
315 }
316 assert(!*ptr);
317
318 if (sh) {
319 /* reference new */
320 sh->RefCount++;
321 /*printf("SHADER INCR %p (%d) to %d\n",
322 (void*) sh, sh->Name, sh->RefCount);*/
323 *ptr = sh;
324 }
325 }
326
327
328 /**
329 * Lookup a GLSL shader object.
330 */
331 struct gl_shader *
332 _mesa_lookup_shader(GLcontext *ctx, GLuint name)
333 {
334 if (name) {
335 struct gl_shader *sh = (struct gl_shader *)
336 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
337 /* Note that both gl_shader and gl_shader_program objects are kept
338 * in the same hash table. Check the object's type to be sure it's
339 * what we're expecting.
340 */
341 if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
342 return NULL;
343 }
344 return sh;
345 }
346 return NULL;
347 }
348
349
350 /**
351 * As above, but record an error if shader is not found.
352 */
353 static struct gl_shader *
354 _mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
355 {
356 if (!name) {
357 _mesa_error(ctx, GL_INVALID_VALUE, caller);
358 return NULL;
359 }
360 else {
361 struct gl_shader *sh = (struct gl_shader *)
362 _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
363 if (!sh) {
364 _mesa_error(ctx, GL_INVALID_VALUE, caller);
365 return NULL;
366 }
367 if (sh->Type == GL_SHADER_PROGRAM_MESA) {
368 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
369 return NULL;
370 }
371 return sh;
372 }
373 }
374
375
376 /**
377 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
378 */
379 static GLbitfield
380 get_shader_flags(void)
381 {
382 GLbitfield flags = 0x0;
383 const char *env = _mesa_getenv("MESA_GLSL");
384
385 if (env) {
386 if (strstr(env, "dump"))
387 flags |= GLSL_DUMP;
388 if (strstr(env, "log"))
389 flags |= GLSL_LOG;
390 if (strstr(env, "nopvert"))
391 flags |= GLSL_NOP_VERT;
392 if (strstr(env, "nopfrag"))
393 flags |= GLSL_NOP_FRAG;
394 if (strstr(env, "nopt"))
395 flags |= GLSL_NO_OPT;
396 else if (strstr(env, "opt"))
397 flags |= GLSL_OPT;
398 if (strstr(env, "uniform"))
399 flags |= GLSL_UNIFORMS;
400 if (strstr(env, "useprog"))
401 flags |= GLSL_USE_PROG;
402 }
403
404 return flags;
405 }
406
407
408 /**
409 * Find the length of the longest transform feedback varying name
410 * which was specified with glTransformFeedbackVaryings().
411 */
412 static GLint
413 longest_feedback_varying_name(const struct gl_shader_program *shProg)
414 {
415 GLuint i;
416 GLint max = 0;
417 for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
418 GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
419 if (len > max)
420 max = len;
421 }
422 return max;
423 }
424
425
426
427 /**
428 * Initialize context's shader state.
429 */
430 void
431 _mesa_init_shader_state(GLcontext * ctx)
432 {
433 /* Device drivers may override these to control what kind of instructions
434 * are generated by the GLSL compiler.
435 */
436 ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
437 ctx->Shader.EmitContReturn = GL_TRUE;
438 ctx->Shader.EmitCondCodes = GL_FALSE;
439 ctx->Shader.EmitComments = GL_FALSE;
440 ctx->Shader.Flags = get_shader_flags();
441
442 /* Default pragma settings */
443 ctx->Shader.DefaultPragmas.IgnoreOptimize = GL_FALSE;
444 ctx->Shader.DefaultPragmas.IgnoreDebug = GL_FALSE;
445 ctx->Shader.DefaultPragmas.Optimize = GL_TRUE;
446 ctx->Shader.DefaultPragmas.Debug = GL_FALSE;
447 }
448
449
450 /**
451 * Free the per-context shader-related state.
452 */
453 void
454 _mesa_free_shader_state(GLcontext *ctx)
455 {
456 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
457 }
458
459
460 /**
461 * Copy string from <src> to <dst>, up to maxLength characters, returning
462 * length of <dst> in <length>.
463 * \param src the strings source
464 * \param maxLength max chars to copy
465 * \param length returns number of chars copied
466 * \param dst the string destination
467 */
468 void
469 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
470 GLsizei *length, const GLchar *src)
471 {
472 GLsizei len;
473 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
474 dst[len] = src[len];
475 if (maxLength > 0)
476 dst[len] = 0;
477 if (length)
478 *length = len;
479 }
480
481
482 static GLboolean
483 _mesa_is_program(GLcontext *ctx, GLuint name)
484 {
485 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
486 return shProg ? GL_TRUE : GL_FALSE;
487 }
488
489
490 static GLboolean
491 _mesa_is_shader(GLcontext *ctx, GLuint name)
492 {
493 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
494 return shader ? GL_TRUE : GL_FALSE;
495 }
496
497
498 /**
499 * Called via ctx->Driver.AttachShader()
500 */
501 static void
502 _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
503 {
504 struct gl_shader_program *shProg;
505 struct gl_shader *sh;
506 GLuint i, n;
507
508 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
509 if (!shProg)
510 return;
511
512 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
513 if (!sh) {
514 return;
515 }
516
517 n = shProg->NumShaders;
518 for (i = 0; i < n; i++) {
519 if (shProg->Shaders[i] == sh) {
520 /* The shader is already attched to this program. The
521 * GL_ARB_shader_objects spec says:
522 *
523 * "The error INVALID_OPERATION is generated by AttachObjectARB
524 * if <obj> is already attached to <containerObj>."
525 */
526 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
527 return;
528 }
529 }
530
531 /* grow list */
532 shProg->Shaders = (struct gl_shader **)
533 _mesa_realloc(shProg->Shaders,
534 n * sizeof(struct gl_shader *),
535 (n + 1) * sizeof(struct gl_shader *));
536 if (!shProg->Shaders) {
537 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
538 return;
539 }
540
541 /* append */
542 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
543 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
544 shProg->NumShaders++;
545 }
546
547
548 static GLint
549 _mesa_get_attrib_location(GLcontext *ctx, GLuint program,
550 const GLchar *name)
551 {
552 struct gl_shader_program *shProg
553 = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
554
555 if (!shProg) {
556 return -1;
557 }
558
559 if (!shProg->LinkStatus) {
560 _mesa_error(ctx, GL_INVALID_OPERATION,
561 "glGetAttribLocation(program not linked)");
562 return -1;
563 }
564
565 if (!name)
566 return -1;
567
568 if (shProg->VertexProgram) {
569 const struct gl_program_parameter_list *attribs =
570 shProg->VertexProgram->Base.Attributes;
571 if (attribs) {
572 GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
573 if (i >= 0) {
574 return attribs->Parameters[i].StateIndexes[0];
575 }
576 }
577 }
578 return -1;
579 }
580
581
582 static void
583 _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
584 const GLchar *name)
585 {
586 struct gl_shader_program *shProg;
587 const GLint size = -1; /* unknown size */
588 GLint i, oldIndex;
589 GLenum datatype = GL_FLOAT_VEC4;
590
591 shProg = _mesa_lookup_shader_program_err(ctx, program,
592 "glBindAttribLocation");
593 if (!shProg) {
594 return;
595 }
596
597 if (!name)
598 return;
599
600 if (strncmp(name, "gl_", 3) == 0) {
601 _mesa_error(ctx, GL_INVALID_OPERATION,
602 "glBindAttribLocation(illegal name)");
603 return;
604 }
605
606 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
607 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
608 return;
609 }
610
611 if (shProg->LinkStatus) {
612 /* get current index/location for the attribute */
613 oldIndex = _mesa_get_attrib_location(ctx, program, name);
614 }
615 else {
616 oldIndex = -1;
617 }
618
619 /* this will replace the current value if it's already in the list */
620 i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
621 if (i < 0) {
622 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
623 return;
624 }
625
626 /*
627 * Note that this attribute binding won't go into effect until
628 * glLinkProgram is called again.
629 */
630 }
631
632
633 static GLuint
634 _mesa_create_shader(GLcontext *ctx, GLenum type)
635 {
636 struct gl_shader *sh;
637 GLuint name;
638
639 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
640
641 switch (type) {
642 case GL_FRAGMENT_SHADER:
643 case GL_VERTEX_SHADER:
644 sh = _mesa_new_shader(ctx, name, type);
645 break;
646 default:
647 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
648 return 0;
649 }
650
651 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
652
653 return name;
654 }
655
656
657 static GLuint
658 _mesa_create_program(GLcontext *ctx)
659 {
660 GLuint name;
661 struct gl_shader_program *shProg;
662
663 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
664 shProg = _mesa_new_shader_program(ctx, name);
665
666 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
667
668 assert(shProg->RefCount == 1);
669
670 return name;
671 }
672
673
674 /**
675 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
676 * DeleteProgramARB.
677 */
678 static void
679 _mesa_delete_program2(GLcontext *ctx, GLuint name)
680 {
681 /*
682 * NOTE: deleting shaders/programs works a bit differently than
683 * texture objects (and buffer objects, etc). Shader/program
684 * handles/IDs exist in the hash table until the object is really
685 * deleted (refcount==0). With texture objects, the handle/ID is
686 * removed from the hash table in glDeleteTextures() while the tex
687 * object itself might linger until its refcount goes to zero.
688 */
689 struct gl_shader_program *shProg;
690
691 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
692 if (!shProg)
693 return;
694
695 shProg->DeletePending = GL_TRUE;
696
697 /* effectively, decr shProg's refcount */
698 _mesa_reference_shader_program(ctx, &shProg, NULL);
699 }
700
701
702 static void
703 _mesa_delete_shader(GLcontext *ctx, GLuint shader)
704 {
705 struct gl_shader *sh;
706
707 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
708 if (!sh)
709 return;
710
711 sh->DeletePending = GL_TRUE;
712
713 /* effectively, decr sh's refcount */
714 _mesa_reference_shader(ctx, &sh, NULL);
715 }
716
717
718 static void
719 _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
720 {
721 struct gl_shader_program *shProg;
722 GLuint n;
723 GLuint i, j;
724
725 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
726 if (!shProg)
727 return;
728
729 n = shProg->NumShaders;
730
731 for (i = 0; i < n; i++) {
732 if (shProg->Shaders[i]->Name == shader) {
733 /* found it */
734 struct gl_shader **newList;
735
736 /* release */
737 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
738
739 /* alloc new, smaller array */
740 newList = (struct gl_shader **)
741 malloc((n - 1) * sizeof(struct gl_shader *));
742 if (!newList) {
743 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
744 return;
745 }
746 for (j = 0; j < i; j++) {
747 newList[j] = shProg->Shaders[j];
748 }
749 while (++i < n)
750 newList[j++] = shProg->Shaders[i];
751 free(shProg->Shaders);
752
753 shProg->Shaders = newList;
754 shProg->NumShaders = n - 1;
755
756 #ifdef DEBUG
757 /* sanity check */
758 {
759 for (j = 0; j < shProg->NumShaders; j++) {
760 assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
761 shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
762 assert(shProg->Shaders[j]->RefCount > 0);
763 }
764 }
765 #endif
766
767 return;
768 }
769 }
770
771 /* not found */
772 {
773 GLenum err;
774 if (_mesa_is_shader(ctx, shader))
775 err = GL_INVALID_OPERATION;
776 else if (_mesa_is_program(ctx, shader))
777 err = GL_INVALID_OPERATION;
778 else
779 err = GL_INVALID_VALUE;
780 _mesa_error(ctx, err, "glDetachProgram(shader)");
781 return;
782 }
783 }
784
785
786 /**
787 * Return the size of the given GLSL datatype, in floats (components).
788 */
789 GLint
790 _mesa_sizeof_glsl_type(GLenum type)
791 {
792 switch (type) {
793 case GL_FLOAT:
794 case GL_INT:
795 case GL_BOOL:
796 case GL_SAMPLER_1D:
797 case GL_SAMPLER_2D:
798 case GL_SAMPLER_3D:
799 case GL_SAMPLER_CUBE:
800 case GL_SAMPLER_1D_SHADOW:
801 case GL_SAMPLER_2D_SHADOW:
802 case GL_SAMPLER_2D_RECT_ARB:
803 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
804 case GL_SAMPLER_1D_ARRAY_EXT:
805 case GL_SAMPLER_2D_ARRAY_EXT:
806 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
807 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
808 case GL_SAMPLER_CUBE_SHADOW_EXT:
809 return 1;
810 case GL_FLOAT_VEC2:
811 case GL_INT_VEC2:
812 case GL_UNSIGNED_INT_VEC2:
813 case GL_BOOL_VEC2:
814 return 2;
815 case GL_FLOAT_VEC3:
816 case GL_INT_VEC3:
817 case GL_UNSIGNED_INT_VEC3:
818 case GL_BOOL_VEC3:
819 return 3;
820 case GL_FLOAT_VEC4:
821 case GL_INT_VEC4:
822 case GL_UNSIGNED_INT_VEC4:
823 case GL_BOOL_VEC4:
824 return 4;
825 case GL_FLOAT_MAT2:
826 case GL_FLOAT_MAT2x3:
827 case GL_FLOAT_MAT2x4:
828 return 8; /* two float[4] vectors */
829 case GL_FLOAT_MAT3:
830 case GL_FLOAT_MAT3x2:
831 case GL_FLOAT_MAT3x4:
832 return 12; /* three float[4] vectors */
833 case GL_FLOAT_MAT4:
834 case GL_FLOAT_MAT4x2:
835 case GL_FLOAT_MAT4x3:
836 return 16; /* four float[4] vectors */
837 default:
838 _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()");
839 return 1;
840 }
841 }
842
843
844 static void
845 _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
846 GLsizei maxLength, GLsizei *length, GLint *size,
847 GLenum *type, GLchar *nameOut)
848 {
849 const struct gl_program_parameter_list *attribs = NULL;
850 struct gl_shader_program *shProg;
851
852 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
853 if (!shProg)
854 return;
855
856 if (shProg->VertexProgram)
857 attribs = shProg->VertexProgram->Base.Attributes;
858
859 if (!attribs || index >= attribs->NumParameters) {
860 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
861 return;
862 }
863
864 _mesa_copy_string(nameOut, maxLength, length,
865 attribs->Parameters[index].Name);
866
867 if (size)
868 *size = attribs->Parameters[index].Size
869 / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType);
870
871 if (type)
872 *type = attribs->Parameters[index].DataType;
873 }
874
875
876 /**
877 * Called via ctx->Driver.GetAttachedShaders().
878 */
879 static void
880 _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
881 GLsizei *count, GLuint *obj)
882 {
883 struct gl_shader_program *shProg =
884 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
885 if (shProg) {
886 GLuint i;
887 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
888 obj[i] = shProg->Shaders[i]->Name;
889 }
890 if (count)
891 *count = i;
892 }
893 }
894
895
896 /** glGetHandleARB() - return ID/name of currently bound shader program */
897 static GLuint
898 _mesa_get_handle(GLcontext *ctx, GLenum pname)
899 {
900 if (pname == GL_PROGRAM_OBJECT_ARB) {
901 if (ctx->Shader.CurrentProgram)
902 return ctx->Shader.CurrentProgram->Name;
903 else
904 return 0;
905 }
906 else {
907 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
908 return 0;
909 }
910 }
911
912
913 /**
914 * glGetProgramiv() - get shader program state.
915 * Note that this is for GLSL shader programs, not ARB vertex/fragment
916 * programs (see glGetProgramivARB).
917 */
918 static void
919 _mesa_get_programiv(GLcontext *ctx, GLuint program,
920 GLenum pname, GLint *params)
921 {
922 const struct gl_program_parameter_list *attribs;
923 struct gl_shader_program *shProg
924 = _mesa_lookup_shader_program(ctx, program);
925
926 if (!shProg) {
927 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
928 return;
929 }
930
931 if (shProg->VertexProgram)
932 attribs = shProg->VertexProgram->Base.Attributes;
933 else
934 attribs = NULL;
935
936 switch (pname) {
937 case GL_DELETE_STATUS:
938 *params = shProg->DeletePending;
939 break;
940 case GL_LINK_STATUS:
941 *params = shProg->LinkStatus;
942 break;
943 case GL_VALIDATE_STATUS:
944 *params = shProg->Validated;
945 break;
946 case GL_INFO_LOG_LENGTH:
947 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
948 break;
949 case GL_ATTACHED_SHADERS:
950 *params = shProg->NumShaders;
951 break;
952 case GL_ACTIVE_ATTRIBUTES:
953 *params = attribs ? attribs->NumParameters : 0;
954 break;
955 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
956 *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
957 break;
958 case GL_ACTIVE_UNIFORMS:
959 *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
960 break;
961 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
962 *params = _mesa_longest_uniform_name(shProg->Uniforms);
963 if (*params > 0)
964 (*params)++; /* add one for terminating zero */
965 break;
966 case GL_PROGRAM_BINARY_LENGTH_OES:
967 *params = 0;
968 break;
969 #if FEATURE_EXT_transform_feedback
970 case GL_TRANSFORM_FEEDBACK_VARYINGS:
971 *params = shProg->TransformFeedback.NumVarying;
972 break;
973 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
974 *params = longest_feedback_varying_name(shProg) + 1;
975 break;
976 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
977 *params = shProg->TransformFeedback.BufferMode;
978 break;
979 #endif
980 default:
981 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
982 return;
983 }
984 }
985
986
987 /** glGetShaderiv() - get GLSL shader state */
988 static void
989 _mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
990 {
991 struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
992
993 if (!shader) {
994 return;
995 }
996
997 switch (pname) {
998 case GL_SHADER_TYPE:
999 *params = shader->Type;
1000 break;
1001 case GL_DELETE_STATUS:
1002 *params = shader->DeletePending;
1003 break;
1004 case GL_COMPILE_STATUS:
1005 *params = shader->CompileStatus;
1006 break;
1007 case GL_INFO_LOG_LENGTH:
1008 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
1009 break;
1010 case GL_SHADER_SOURCE_LENGTH:
1011 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1012 break;
1013 default:
1014 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1015 return;
1016 }
1017 }
1018
1019
1020 static void
1021 _mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
1022 GLsizei *length, GLchar *infoLog)
1023 {
1024 struct gl_shader_program *shProg
1025 = _mesa_lookup_shader_program(ctx, program);
1026 if (!shProg) {
1027 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
1028 return;
1029 }
1030 _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
1031 }
1032
1033
1034 static void
1035 _mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
1036 GLsizei *length, GLchar *infoLog)
1037 {
1038 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
1039 if (!sh) {
1040 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
1041 return;
1042 }
1043 _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
1044 }
1045
1046
1047 /**
1048 * Called via ctx->Driver.GetShaderSource().
1049 */
1050 static void
1051 _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
1052 GLsizei *length, GLchar *sourceOut)
1053 {
1054 struct gl_shader *sh;
1055 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1056 if (!sh) {
1057 return;
1058 }
1059 _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
1060 }
1061
1062
1063 /**
1064 * Called via ctx->Driver.ShaderSource()
1065 */
1066 static void
1067 _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
1068 {
1069 struct gl_shader *sh;
1070
1071 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
1072 if (!sh)
1073 return;
1074
1075 /* free old shader source string and install new one */
1076 if (sh->Source) {
1077 free((void *) sh->Source);
1078 }
1079 sh->Source = source;
1080 sh->CompileStatus = GL_FALSE;
1081 #ifdef DEBUG
1082 sh->SourceChecksum = _mesa_str_checksum(sh->Source);
1083 #endif
1084 }
1085
1086
1087 /**
1088 * Called via ctx->Driver.CompileShader()
1089 */
1090 static void
1091 _mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
1092 {
1093 struct gl_shader *sh;
1094
1095 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
1096 if (!sh)
1097 return;
1098
1099 /* set default pragma state for shader */
1100 sh->Pragmas = ctx->Shader.DefaultPragmas;
1101
1102 /* this call will set the sh->CompileStatus field to indicate if
1103 * compilation was successful.
1104 */
1105 (void) _slang_compile(ctx, sh);
1106 }
1107
1108
1109 /**
1110 * Called via ctx->Driver.LinkProgram()
1111 */
1112 static void
1113 _mesa_link_program(GLcontext *ctx, GLuint program)
1114 {
1115 struct gl_shader_program *shProg;
1116 struct gl_transform_feedback_object *obj =
1117 ctx->TransformFeedback.CurrentObject;
1118
1119 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
1120 if (!shProg)
1121 return;
1122
1123 if (obj->Active && shProg == ctx->Shader.CurrentProgram) {
1124 _mesa_error(ctx, GL_INVALID_OPERATION,
1125 "glLinkProgram(transform feedback active");
1126 return;
1127 }
1128
1129 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1130
1131 _slang_link(ctx, program, shProg);
1132
1133 /* debug code */
1134 if (0) {
1135 GLuint i;
1136
1137 printf("Link %u shaders in program %u: %s\n",
1138 shProg->NumShaders, shProg->Name,
1139 shProg->LinkStatus ? "Success" : "Failed");
1140
1141 for (i = 0; i < shProg->NumShaders; i++) {
1142 printf(" shader %u, type 0x%x\n",
1143 shProg->Shaders[i]->Name,
1144 shProg->Shaders[i]->Type);
1145 }
1146 }
1147 }
1148
1149
1150 /**
1151 * Print basic shader info (for debug).
1152 */
1153 static void
1154 print_shader_info(const struct gl_shader_program *shProg)
1155 {
1156 GLuint i;
1157
1158 printf("Mesa: glUseProgram(%u)\n", shProg->Name);
1159 for (i = 0; i < shProg->NumShaders; i++) {
1160 const char *s;
1161 switch (shProg->Shaders[i]->Type) {
1162 case GL_VERTEX_SHADER:
1163 s = "vertex";
1164 break;
1165 case GL_FRAGMENT_SHADER:
1166 s = "fragment";
1167 break;
1168 case GL_GEOMETRY_SHADER:
1169 s = "geometry";
1170 break;
1171 default:
1172 s = "";
1173 }
1174 printf(" %s shader %u, checksum %u\n", s,
1175 shProg->Shaders[i]->Name,
1176 shProg->Shaders[i]->SourceChecksum);
1177 }
1178 if (shProg->VertexProgram)
1179 printf(" vert prog %u\n", shProg->VertexProgram->Base.Id);
1180 if (shProg->FragmentProgram)
1181 printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id);
1182 }
1183
1184
1185 /**
1186 * Called via ctx->Driver.UseProgram()
1187 */
1188 void
1189 _mesa_use_program(GLcontext *ctx, GLuint program)
1190 {
1191 struct gl_shader_program *shProg;
1192 struct gl_transform_feedback_object *obj =
1193 ctx->TransformFeedback.CurrentObject;
1194
1195 if (obj->Active) {
1196 _mesa_error(ctx, GL_INVALID_OPERATION,
1197 "glUseProgram(transform feedback active)");
1198 return;
1199 }
1200
1201 if (ctx->Shader.CurrentProgram &&
1202 ctx->Shader.CurrentProgram->Name == program) {
1203 /* no-op */
1204 return;
1205 }
1206
1207 if (program) {
1208 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1209 if (!shProg) {
1210 return;
1211 }
1212 if (!shProg->LinkStatus) {
1213 _mesa_error(ctx, GL_INVALID_OPERATION,
1214 "glUseProgram(program %u not linked)", program);
1215 return;
1216 }
1217
1218 /* debug code */
1219 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1220 print_shader_info(shProg);
1221 }
1222 }
1223 else {
1224 shProg = NULL;
1225 }
1226
1227 if (ctx->Shader.CurrentProgram != shProg) {
1228 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1229 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
1230 }
1231 }
1232
1233
1234
1235 /**
1236 * Update the vertex/fragment program's TexturesUsed array.
1237 *
1238 * This needs to be called after glUniform(set sampler var) is called.
1239 * A call to glUniform(samplerVar, value) causes a sampler to point to a
1240 * particular texture unit. We know the sampler's texture target
1241 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
1242 * set by glUniform() calls.
1243 *
1244 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
1245 * information to update the prog->TexturesUsed[] values.
1246 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
1247 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
1248 * We'll use that info for state validation before rendering.
1249 */
1250 void
1251 _mesa_update_shader_textures_used(struct gl_program *prog)
1252 {
1253 GLuint s;
1254
1255 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
1256
1257 for (s = 0; s < MAX_SAMPLERS; s++) {
1258 if (prog->SamplersUsed & (1 << s)) {
1259 GLuint unit = prog->SamplerUnits[s];
1260 GLuint tgt = prog->SamplerTargets[s];
1261 assert(unit < MAX_TEXTURE_IMAGE_UNITS);
1262 assert(tgt < NUM_TEXTURE_TARGETS);
1263 prog->TexturesUsed[unit] |= (1 << tgt);
1264 }
1265 }
1266 }
1267
1268
1269 /**
1270 * Validate a program's samplers.
1271 * Specifically, check that there aren't two samplers of different types
1272 * pointing to the same texture unit.
1273 * \return GL_TRUE if valid, GL_FALSE if invalid
1274 */
1275 static GLboolean
1276 validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
1277 {
1278 static const char *targetName[] = {
1279 "TEXTURE_2D_ARRAY",
1280 "TEXTURE_1D_ARRAY",
1281 "TEXTURE_CUBE",
1282 "TEXTURE_3D",
1283 "TEXTURE_RECT",
1284 "TEXTURE_2D",
1285 "TEXTURE_1D",
1286 };
1287 GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
1288 GLbitfield samplersUsed = prog->SamplersUsed;
1289 GLuint i;
1290
1291 assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
1292
1293 if (samplersUsed == 0x0)
1294 return GL_TRUE;
1295
1296 for (i = 0; i < Elements(targetUsed); i++)
1297 targetUsed[i] = -1;
1298
1299 /* walk over bits which are set in 'samplers' */
1300 while (samplersUsed) {
1301 GLuint unit;
1302 gl_texture_index target;
1303 GLint sampler = _mesa_ffs(samplersUsed) - 1;
1304 assert(sampler >= 0);
1305 assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
1306 unit = prog->SamplerUnits[sampler];
1307 target = prog->SamplerTargets[sampler];
1308 if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
1309 _mesa_snprintf(errMsg, 100,
1310 "Texture unit %d is accessed both as %s and %s",
1311 unit, targetName[targetUsed[unit]], targetName[target]);
1312 return GL_FALSE;
1313 }
1314 targetUsed[unit] = target;
1315 samplersUsed ^= (1 << sampler);
1316 }
1317
1318 return GL_TRUE;
1319 }
1320
1321
1322 /**
1323 * Do validation of the given shader program.
1324 * \param errMsg returns error message if validation fails.
1325 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
1326 */
1327 GLboolean
1328 _mesa_validate_shader_program(GLcontext *ctx,
1329 const struct gl_shader_program *shProg,
1330 char *errMsg)
1331 {
1332 const struct gl_vertex_program *vp = shProg->VertexProgram;
1333 const struct gl_fragment_program *fp = shProg->FragmentProgram;
1334
1335 if (!shProg->LinkStatus) {
1336 return GL_FALSE;
1337 }
1338
1339 /* From the GL spec, a program is invalid if any of these are true:
1340
1341 any two active samplers in the current program object are of
1342 different types, but refer to the same texture image unit,
1343
1344 any active sampler in the current program object refers to a texture
1345 image unit where fixed-function fragment processing accesses a
1346 texture target that does not match the sampler type, or
1347
1348 the sum of the number of active samplers in the program and the
1349 number of texture image units enabled for fixed-function fragment
1350 processing exceeds the combined limit on the total number of texture
1351 image units allowed.
1352 */
1353
1354
1355 /*
1356 * Check: any two active samplers in the current program object are of
1357 * different types, but refer to the same texture image unit,
1358 */
1359 if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
1360 return GL_FALSE;
1361 }
1362 if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
1363 return GL_FALSE;
1364 }
1365
1366 return GL_TRUE;
1367 }
1368
1369
1370 /**
1371 * Called via glValidateProgram()
1372 */
1373 static void
1374 _mesa_validate_program(GLcontext *ctx, GLuint program)
1375 {
1376 struct gl_shader_program *shProg;
1377 char errMsg[100];
1378
1379 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1380 if (!shProg) {
1381 return;
1382 }
1383
1384 shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
1385 if (!shProg->Validated) {
1386 /* update info log */
1387 if (shProg->InfoLog) {
1388 free(shProg->InfoLog);
1389 }
1390 shProg->InfoLog = _mesa_strdup(errMsg);
1391 }
1392 }
1393
1394
1395 /**
1396 * Plug in Mesa's GLSL functions into the device driver function table.
1397 */
1398 void
1399 _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
1400 {
1401 driver->AttachShader = _mesa_attach_shader;
1402 driver->BindAttribLocation = _mesa_bind_attrib_location;
1403 driver->CompileShader = _mesa_compile_shader;
1404 driver->CreateProgram = _mesa_create_program;
1405 driver->CreateShader = _mesa_create_shader;
1406 driver->DeleteProgram2 = _mesa_delete_program2;
1407 driver->DeleteShader = _mesa_delete_shader;
1408 driver->DetachShader = _mesa_detach_shader;
1409 driver->GetActiveAttrib = _mesa_get_active_attrib;
1410 driver->GetAttachedShaders = _mesa_get_attached_shaders;
1411 driver->GetAttribLocation = _mesa_get_attrib_location;
1412 driver->GetHandle = _mesa_get_handle;
1413 driver->GetProgramiv = _mesa_get_programiv;
1414 driver->GetProgramInfoLog = _mesa_get_program_info_log;
1415 driver->GetShaderiv = _mesa_get_shaderiv;
1416 driver->GetShaderInfoLog = _mesa_get_shader_info_log;
1417 driver->GetShaderSource = _mesa_get_shader_source;
1418 driver->IsProgram = _mesa_is_program;
1419 driver->IsShader = _mesa_is_shader;
1420 driver->LinkProgram = _mesa_link_program;
1421 driver->ShaderSource = _mesa_shader_source;
1422 driver->UseProgram = _mesa_use_program;
1423 driver->ValidateProgram = _mesa_validate_program;
1424
1425 _mesa_init_uniform_functions(driver);
1426 }