mesa: add some comments on shaderapi.c functions
[mesa.git] / src / mesa / main / shaderapi.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. 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 shaderapi.c
27 * \author Brian Paul
28 *
29 * Implementation of GLSL-related API functions.
30 * The glUniform* functions are in uniforms.c
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/dispatch.h"
42 #include "main/enums.h"
43 #include "main/hash.h"
44 #include "main/mfeatures.h"
45 #include "main/mtypes.h"
46 #include "main/shaderapi.h"
47 #include "main/shaderobj.h"
48 #include "main/uniforms.h"
49 #include "program/program.h"
50 #include "program/prog_parameter.h"
51 #include "ralloc.h"
52 #include <stdbool.h>
53 #include "../glsl/glsl_parser_extras.h"
54 #include "../glsl/ir_uniform.h"
55
56 /** Define this to enable shader substitution (see below) */
57 #define SHADER_SUBST 0
58
59
60 /**
61 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
62 */
63 static GLbitfield
64 get_shader_flags(void)
65 {
66 GLbitfield flags = 0x0;
67 const char *env = _mesa_getenv("MESA_GLSL");
68
69 if (env) {
70 if (strstr(env, "dump"))
71 flags |= GLSL_DUMP;
72 if (strstr(env, "log"))
73 flags |= GLSL_LOG;
74 if (strstr(env, "nopvert"))
75 flags |= GLSL_NOP_VERT;
76 if (strstr(env, "nopfrag"))
77 flags |= GLSL_NOP_FRAG;
78 if (strstr(env, "nopt"))
79 flags |= GLSL_NO_OPT;
80 else if (strstr(env, "opt"))
81 flags |= GLSL_OPT;
82 if (strstr(env, "uniform"))
83 flags |= GLSL_UNIFORMS;
84 if (strstr(env, "useprog"))
85 flags |= GLSL_USE_PROG;
86 }
87
88 return flags;
89 }
90
91
92 /**
93 * Initialize context's shader state.
94 */
95 void
96 _mesa_init_shader_state(struct gl_context *ctx)
97 {
98 /* Device drivers may override these to control what kind of instructions
99 * are generated by the GLSL compiler.
100 */
101 struct gl_shader_compiler_options options;
102 gl_shader_type sh;
103
104 memset(&options, 0, sizeof(options));
105 options.MaxUnrollIterations = 32;
106
107 /* Default pragma settings */
108 options.DefaultPragmas.Optimize = GL_TRUE;
109
110 for (sh = 0; sh < MESA_SHADER_TYPES; ++sh)
111 memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
112
113 ctx->Shader.Flags = get_shader_flags();
114 }
115
116
117 /**
118 * Free the per-context shader-related state.
119 */
120 void
121 _mesa_free_shader_state(struct gl_context *ctx)
122 {
123 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentVertexProgram, NULL);
124 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentGeometryProgram,
125 NULL);
126 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
127 NULL);
128 _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
129 NULL);
130 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
131 }
132
133
134 /**
135 * Copy string from <src> to <dst>, up to maxLength characters, returning
136 * length of <dst> in <length>.
137 * \param src the strings source
138 * \param maxLength max chars to copy
139 * \param length returns number of chars copied
140 * \param dst the string destination
141 */
142 void
143 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
144 GLsizei *length, const GLchar *src)
145 {
146 GLsizei len;
147 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
148 dst[len] = src[len];
149 if (maxLength > 0)
150 dst[len] = 0;
151 if (length)
152 *length = len;
153 }
154
155
156
157 /**
158 * Confirm that the a shader type is valid and supported by the implementation
159 *
160 * \param ctx Current GL context
161 * \param type Shader target
162 *
163 */
164 static bool
165 validate_shader_target(const struct gl_context *ctx, GLenum type)
166 {
167 switch (type) {
168 #if FEATURE_ARB_fragment_shader
169 case GL_FRAGMENT_SHADER:
170 return ctx->Extensions.ARB_fragment_shader;
171 #endif
172 #if FEATURE_ARB_vertex_shader
173 case GL_VERTEX_SHADER:
174 return ctx->Extensions.ARB_vertex_shader;
175 #endif
176 #if FEATURE_ARB_geometry_shader4
177 case GL_GEOMETRY_SHADER_ARB:
178 return ctx->Extensions.ARB_geometry_shader4;
179 #endif
180 default:
181 return false;
182 }
183 }
184
185
186 /**
187 * Find the length of the longest transform feedback varying name
188 * which was specified with glTransformFeedbackVaryings().
189 */
190 static GLint
191 longest_feedback_varying_name(const struct gl_shader_program *shProg)
192 {
193 GLuint i;
194 GLint max = 0;
195 for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
196 GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
197 if (len > max)
198 max = len;
199 }
200 return max;
201 }
202
203
204
205 static GLboolean
206 is_program(struct gl_context *ctx, GLuint name)
207 {
208 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
209 return shProg ? GL_TRUE : GL_FALSE;
210 }
211
212
213 static GLboolean
214 is_shader(struct gl_context *ctx, GLuint name)
215 {
216 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
217 return shader ? GL_TRUE : GL_FALSE;
218 }
219
220
221 /**
222 * Attach shader to a shader program.
223 */
224 static void
225 attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
226 {
227 struct gl_shader_program *shProg;
228 struct gl_shader *sh;
229 GLuint i, n;
230
231 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
232 if (!shProg)
233 return;
234
235 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
236 if (!sh) {
237 return;
238 }
239
240 n = shProg->NumShaders;
241 for (i = 0; i < n; i++) {
242 if (shProg->Shaders[i] == sh) {
243 /* The shader is already attched to this program. The
244 * GL_ARB_shader_objects spec says:
245 *
246 * "The error INVALID_OPERATION is generated by AttachObjectARB
247 * if <obj> is already attached to <containerObj>."
248 */
249 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
250 return;
251 }
252 }
253
254 /* grow list */
255 shProg->Shaders = (struct gl_shader **)
256 _mesa_realloc(shProg->Shaders,
257 n * sizeof(struct gl_shader *),
258 (n + 1) * sizeof(struct gl_shader *));
259 if (!shProg->Shaders) {
260 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
261 return;
262 }
263
264 /* append */
265 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
266 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
267 shProg->NumShaders++;
268 }
269
270
271 static GLuint
272 create_shader(struct gl_context *ctx, GLenum type)
273 {
274 struct gl_shader *sh;
275 GLuint name;
276
277 if (!validate_shader_target(ctx, type)) {
278 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
279 return 0;
280 }
281
282 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
283 sh = ctx->Driver.NewShader(ctx, name, type);
284 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
285
286 return name;
287 }
288
289
290 static GLuint
291 create_shader_program(struct gl_context *ctx)
292 {
293 GLuint name;
294 struct gl_shader_program *shProg;
295
296 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
297
298 shProg = ctx->Driver.NewShaderProgram(ctx, name);
299
300 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
301
302 assert(shProg->RefCount == 1);
303
304 return name;
305 }
306
307
308 /**
309 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
310 * DeleteProgramARB.
311 */
312 static void
313 delete_shader_program(struct gl_context *ctx, GLuint name)
314 {
315 /*
316 * NOTE: deleting shaders/programs works a bit differently than
317 * texture objects (and buffer objects, etc). Shader/program
318 * handles/IDs exist in the hash table until the object is really
319 * deleted (refcount==0). With texture objects, the handle/ID is
320 * removed from the hash table in glDeleteTextures() while the tex
321 * object itself might linger until its refcount goes to zero.
322 */
323 struct gl_shader_program *shProg;
324
325 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
326 if (!shProg)
327 return;
328
329 if (!shProg->DeletePending) {
330 shProg->DeletePending = GL_TRUE;
331
332 /* effectively, decr shProg's refcount */
333 _mesa_reference_shader_program(ctx, &shProg, NULL);
334 }
335 }
336
337
338 static void
339 delete_shader(struct gl_context *ctx, GLuint shader)
340 {
341 struct gl_shader *sh;
342
343 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
344 if (!sh)
345 return;
346
347 sh->DeletePending = GL_TRUE;
348
349 /* effectively, decr sh's refcount */
350 _mesa_reference_shader(ctx, &sh, NULL);
351 }
352
353
354 static void
355 detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
356 {
357 struct gl_shader_program *shProg;
358 GLuint n;
359 GLuint i, j;
360
361 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
362 if (!shProg)
363 return;
364
365 n = shProg->NumShaders;
366
367 for (i = 0; i < n; i++) {
368 if (shProg->Shaders[i]->Name == shader) {
369 /* found it */
370 struct gl_shader **newList;
371
372 /* release */
373 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
374
375 /* alloc new, smaller array */
376 newList = (struct gl_shader **)
377 malloc((n - 1) * sizeof(struct gl_shader *));
378 if (!newList) {
379 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
380 return;
381 }
382 for (j = 0; j < i; j++) {
383 newList[j] = shProg->Shaders[j];
384 }
385 while (++i < n)
386 newList[j++] = shProg->Shaders[i];
387 free(shProg->Shaders);
388
389 shProg->Shaders = newList;
390 shProg->NumShaders = n - 1;
391
392 #ifdef DEBUG
393 /* sanity check */
394 {
395 for (j = 0; j < shProg->NumShaders; j++) {
396 assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
397 shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
398 assert(shProg->Shaders[j]->RefCount > 0);
399 }
400 }
401 #endif
402
403 return;
404 }
405 }
406
407 /* not found */
408 {
409 GLenum err;
410 if (is_shader(ctx, shader))
411 err = GL_INVALID_OPERATION;
412 else if (is_program(ctx, shader))
413 err = GL_INVALID_OPERATION;
414 else
415 err = GL_INVALID_VALUE;
416 _mesa_error(ctx, err, "glDetachProgram(shader)");
417 return;
418 }
419 }
420
421
422 /**
423 * Return list of shaders attached to shader program.
424 */
425 static void
426 get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
427 GLsizei *count, GLuint *obj)
428 {
429 struct gl_shader_program *shProg =
430 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
431 if (shProg) {
432 GLuint i;
433 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
434 obj[i] = shProg->Shaders[i]->Name;
435 }
436 if (count)
437 *count = i;
438 }
439 }
440
441
442 /**
443 * glGetHandleARB() - return ID/name of currently bound shader program.
444 */
445 static GLuint
446 get_handle(struct gl_context *ctx, GLenum pname)
447 {
448 if (pname == GL_PROGRAM_OBJECT_ARB) {
449 if (ctx->Shader.ActiveProgram)
450 return ctx->Shader.ActiveProgram->Name;
451 else
452 return 0;
453 }
454 else {
455 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
456 return 0;
457 }
458 }
459
460
461 /**
462 * glGetProgramiv() - get shader program state.
463 * Note that this is for GLSL shader programs, not ARB vertex/fragment
464 * programs (see glGetProgramivARB).
465 */
466 static void
467 get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params)
468 {
469 struct gl_shader_program *shProg
470 = _mesa_lookup_shader_program(ctx, program);
471
472 if (!shProg) {
473 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
474 return;
475 }
476
477 switch (pname) {
478 case GL_DELETE_STATUS:
479 *params = shProg->DeletePending;
480 break;
481 case GL_LINK_STATUS:
482 *params = shProg->LinkStatus;
483 break;
484 case GL_VALIDATE_STATUS:
485 *params = shProg->Validated;
486 break;
487 case GL_INFO_LOG_LENGTH:
488 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
489 break;
490 case GL_ATTACHED_SHADERS:
491 *params = shProg->NumShaders;
492 break;
493 case GL_ACTIVE_ATTRIBUTES:
494 *params = _mesa_count_active_attribs(shProg);
495 break;
496 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
497 *params = _mesa_longest_attribute_name_length(shProg);
498 break;
499 case GL_ACTIVE_UNIFORMS:
500 *params = shProg->NumUserUniformStorage;
501 break;
502 case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
503 unsigned i;
504 GLint max_len = 0;
505
506 for (i = 0; i < shProg->NumUserUniformStorage; i++) {
507 /* Add one for the terminating NUL character.
508 */
509 const GLint len = strlen(shProg->UniformStorage[i].name) + 1;
510
511 if (len > max_len)
512 max_len = len;
513 }
514
515 *params = max_len;
516 break;
517 }
518 case GL_PROGRAM_BINARY_LENGTH_OES:
519 *params = 0;
520 break;
521 #if FEATURE_EXT_transform_feedback
522 case GL_TRANSFORM_FEEDBACK_VARYINGS:
523 *params = shProg->TransformFeedback.NumVarying;
524 break;
525 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
526 *params = longest_feedback_varying_name(shProg) + 1;
527 break;
528 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
529 *params = shProg->TransformFeedback.BufferMode;
530 break;
531 #endif
532 #if FEATURE_ARB_geometry_shader4
533 case GL_GEOMETRY_VERTICES_OUT_ARB:
534 *params = shProg->Geom.VerticesOut;
535 break;
536 case GL_GEOMETRY_INPUT_TYPE_ARB:
537 *params = shProg->Geom.InputType;
538 break;
539 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
540 *params = shProg->Geom.OutputType;
541 break;
542 #endif
543 default:
544 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
545 return;
546 }
547 }
548
549
550 /**
551 * glGetShaderiv() - get GLSL shader state
552 */
553 static void
554 get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
555 {
556 struct gl_shader *shader =
557 _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
558
559 if (!shader) {
560 return;
561 }
562
563 switch (pname) {
564 case GL_SHADER_TYPE:
565 *params = shader->Type;
566 break;
567 case GL_DELETE_STATUS:
568 *params = shader->DeletePending;
569 break;
570 case GL_COMPILE_STATUS:
571 *params = shader->CompileStatus;
572 break;
573 case GL_INFO_LOG_LENGTH:
574 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
575 break;
576 case GL_SHADER_SOURCE_LENGTH:
577 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
578 break;
579 default:
580 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
581 return;
582 }
583 }
584
585
586 static void
587 get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
588 GLsizei *length, GLchar *infoLog)
589 {
590 struct gl_shader_program *shProg
591 = _mesa_lookup_shader_program(ctx, program);
592 if (!shProg) {
593 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
594 return;
595 }
596 _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
597 }
598
599
600 static void
601 get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
602 GLsizei *length, GLchar *infoLog)
603 {
604 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
605 if (!sh) {
606 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
607 return;
608 }
609 _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
610 }
611
612
613 /**
614 * Return shader source code.
615 */
616 static void
617 get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
618 GLsizei *length, GLchar *sourceOut)
619 {
620 struct gl_shader *sh;
621 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
622 if (!sh) {
623 return;
624 }
625 _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
626 }
627
628
629 /**
630 * Set/replace shader source code. A helper function used by
631 * glShaderSource[ARB] and glCreateShaderProgramEXT.
632 */
633 static void
634 shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
635 {
636 struct gl_shader *sh;
637
638 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
639 if (!sh)
640 return;
641
642 /* free old shader source string and install new one */
643 if (sh->Source) {
644 free((void *) sh->Source);
645 }
646 sh->Source = source;
647 sh->CompileStatus = GL_FALSE;
648 #ifdef DEBUG
649 sh->SourceChecksum = _mesa_str_checksum(sh->Source);
650 #endif
651 }
652
653
654 /**
655 * Compile a shader.
656 */
657 static void
658 compile_shader(struct gl_context *ctx, GLuint shaderObj)
659 {
660 struct gl_shader *sh;
661 struct gl_shader_compiler_options *options;
662
663 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
664 if (!sh)
665 return;
666
667 options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)];
668
669 /* set default pragma state for shader */
670 sh->Pragmas = options->DefaultPragmas;
671
672 /* this call will set the sh->CompileStatus field to indicate if
673 * compilation was successful.
674 */
675 _mesa_glsl_compile_shader(ctx, sh);
676 }
677
678
679 /**
680 * Link a program's shaders.
681 */
682 static void
683 link_program(struct gl_context *ctx, GLuint program)
684 {
685 struct gl_shader_program *shProg;
686 struct gl_transform_feedback_object *obj =
687 ctx->TransformFeedback.CurrentObject;
688
689 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
690 if (!shProg)
691 return;
692
693 if (obj->Active
694 && (shProg == ctx->Shader.CurrentVertexProgram
695 || shProg == ctx->Shader.CurrentGeometryProgram
696 || shProg == ctx->Shader.CurrentFragmentProgram)) {
697 _mesa_error(ctx, GL_INVALID_OPERATION,
698 "glLinkProgram(transform feedback active)");
699 return;
700 }
701
702 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
703
704 _mesa_glsl_link_shader(ctx, shProg);
705
706 /* debug code */
707 if (0) {
708 GLuint i;
709
710 printf("Link %u shaders in program %u: %s\n",
711 shProg->NumShaders, shProg->Name,
712 shProg->LinkStatus ? "Success" : "Failed");
713
714 for (i = 0; i < shProg->NumShaders; i++) {
715 printf(" shader %u, type 0x%x\n",
716 shProg->Shaders[i]->Name,
717 shProg->Shaders[i]->Type);
718 }
719 }
720 }
721
722
723 /**
724 * Print basic shader info (for debug).
725 */
726 static void
727 print_shader_info(const struct gl_shader_program *shProg)
728 {
729 GLuint i;
730
731 printf("Mesa: glUseProgram(%u)\n", shProg->Name);
732 for (i = 0; i < shProg->NumShaders; i++) {
733 const char *s;
734 switch (shProg->Shaders[i]->Type) {
735 case GL_VERTEX_SHADER:
736 s = "vertex";
737 break;
738 case GL_FRAGMENT_SHADER:
739 s = "fragment";
740 break;
741 case GL_GEOMETRY_SHADER:
742 s = "geometry";
743 break;
744 default:
745 s = "";
746 }
747 printf(" %s shader %u, checksum %u\n", s,
748 shProg->Shaders[i]->Name,
749 shProg->Shaders[i]->SourceChecksum);
750 }
751 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
752 printf(" vert prog %u\n",
753 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
754 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
755 printf(" frag prog %u\n",
756 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
757 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
758 printf(" geom prog %u\n",
759 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
760 }
761
762
763 /**
764 * Use the named shader program for subsequent glUniform calls
765 */
766 void
767 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
768 const char *caller)
769 {
770 if ((shProg != NULL) && !shProg->LinkStatus) {
771 _mesa_error(ctx, GL_INVALID_OPERATION,
772 "%s(program %u not linked)", caller, shProg->Name);
773 return;
774 }
775
776 if (ctx->Shader.ActiveProgram != shProg) {
777 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
778 }
779 }
780
781 /**
782 */
783 static bool
784 use_shader_program(struct gl_context *ctx, GLenum type,
785 struct gl_shader_program *shProg)
786 {
787 struct gl_shader_program **target;
788
789 switch (type) {
790 #if FEATURE_ARB_vertex_shader
791 case GL_VERTEX_SHADER:
792 target = &ctx->Shader.CurrentVertexProgram;
793 if ((shProg == NULL)
794 || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) {
795 shProg = NULL;
796 }
797 break;
798 #endif
799 #if FEATURE_ARB_geometry_shader4
800 case GL_GEOMETRY_SHADER_ARB:
801 target = &ctx->Shader.CurrentGeometryProgram;
802 if ((shProg == NULL)
803 || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) {
804 shProg = NULL;
805 }
806 break;
807 #endif
808 #if FEATURE_ARB_fragment_shader
809 case GL_FRAGMENT_SHADER:
810 target = &ctx->Shader.CurrentFragmentProgram;
811 if ((shProg == NULL)
812 || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) {
813 shProg = NULL;
814 }
815 break;
816 #endif
817 default:
818 return false;
819 }
820
821 if (*target != shProg) {
822 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
823
824 /* If the shader is also bound as the current rendering shader, unbind
825 * it from that binding point as well. This ensures that the correct
826 * semantics of glDeleteProgram are maintained.
827 */
828 switch (type) {
829 #if FEATURE_ARB_vertex_shader
830 case GL_VERTEX_SHADER:
831 /* Empty for now. */
832 break;
833 #endif
834 #if FEATURE_ARB_geometry_shader4
835 case GL_GEOMETRY_SHADER_ARB:
836 /* Empty for now. */
837 break;
838 #endif
839 #if FEATURE_ARB_fragment_shader
840 case GL_FRAGMENT_SHADER:
841 if (*target == ctx->Shader._CurrentFragmentProgram) {
842 _mesa_reference_shader_program(ctx,
843 &ctx->Shader._CurrentFragmentProgram,
844 NULL);
845 }
846 break;
847 #endif
848 }
849
850 _mesa_reference_shader_program(ctx, target, shProg);
851 return true;
852 }
853
854 return false;
855 }
856
857 /**
858 * Use the named shader program for subsequent rendering.
859 */
860 void
861 _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
862 {
863 use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
864 use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg);
865 use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg);
866 _mesa_active_program(ctx, shProg, "glUseProgram");
867
868 if (ctx->Driver.UseProgram)
869 ctx->Driver.UseProgram(ctx, shProg);
870 }
871
872
873 /**
874 * Do validation of the given shader program.
875 * \param errMsg returns error message if validation fails.
876 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
877 */
878 static GLboolean
879 validate_shader_program(const struct gl_shader_program *shProg,
880 char *errMsg)
881 {
882 if (!shProg->LinkStatus) {
883 return GL_FALSE;
884 }
885
886 /* From the GL spec, a program is invalid if any of these are true:
887
888 any two active samplers in the current program object are of
889 different types, but refer to the same texture image unit,
890
891 any active sampler in the current program object refers to a texture
892 image unit where fixed-function fragment processing accesses a
893 texture target that does not match the sampler type, or
894
895 the sum of the number of active samplers in the program and the
896 number of texture image units enabled for fixed-function fragment
897 processing exceeds the combined limit on the total number of texture
898 image units allowed.
899 */
900
901
902 /*
903 * Check: any two active samplers in the current program object are of
904 * different types, but refer to the same texture image unit,
905 */
906 if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
907 return GL_FALSE;
908
909 return GL_TRUE;
910 }
911
912
913 /**
914 * Called via glValidateProgram()
915 */
916 static void
917 validate_program(struct gl_context *ctx, GLuint program)
918 {
919 struct gl_shader_program *shProg;
920 char errMsg[100] = "";
921
922 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
923 if (!shProg) {
924 return;
925 }
926
927 shProg->Validated = validate_shader_program(shProg, errMsg);
928 if (!shProg->Validated) {
929 /* update info log */
930 if (shProg->InfoLog) {
931 ralloc_free(shProg->InfoLog);
932 }
933 shProg->InfoLog = ralloc_strdup(shProg, errMsg);
934 }
935 }
936
937
938
939 void GLAPIENTRY
940 _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
941 {
942 GET_CURRENT_CONTEXT(ctx);
943 attach_shader(ctx, program, shader);
944 }
945
946
947 void GLAPIENTRY
948 _mesa_AttachShader(GLuint program, GLuint shader)
949 {
950 GET_CURRENT_CONTEXT(ctx);
951 attach_shader(ctx, program, shader);
952 }
953
954
955 void GLAPIENTRY
956 _mesa_CompileShaderARB(GLhandleARB shaderObj)
957 {
958 GET_CURRENT_CONTEXT(ctx);
959 if (MESA_VERBOSE & VERBOSE_API)
960 _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
961 compile_shader(ctx, shaderObj);
962 }
963
964
965 GLuint GLAPIENTRY
966 _mesa_CreateShader(GLenum type)
967 {
968 GET_CURRENT_CONTEXT(ctx);
969 if (MESA_VERBOSE & VERBOSE_API)
970 _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type));
971 return create_shader(ctx, type);
972 }
973
974
975 GLhandleARB GLAPIENTRY
976 _mesa_CreateShaderObjectARB(GLenum type)
977 {
978 GET_CURRENT_CONTEXT(ctx);
979 return create_shader(ctx, type);
980 }
981
982
983 GLuint GLAPIENTRY
984 _mesa_CreateProgram(void)
985 {
986 GET_CURRENT_CONTEXT(ctx);
987 if (MESA_VERBOSE & VERBOSE_API)
988 _mesa_debug(ctx, "glCreateProgram\n");
989 return create_shader_program(ctx);
990 }
991
992
993 GLhandleARB GLAPIENTRY
994 _mesa_CreateProgramObjectARB(void)
995 {
996 GET_CURRENT_CONTEXT(ctx);
997 return create_shader_program(ctx);
998 }
999
1000
1001 void GLAPIENTRY
1002 _mesa_DeleteObjectARB(GLhandleARB obj)
1003 {
1004 if (MESA_VERBOSE & VERBOSE_API) {
1005 GET_CURRENT_CONTEXT(ctx);
1006 _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj);
1007 }
1008
1009 if (obj) {
1010 GET_CURRENT_CONTEXT(ctx);
1011 FLUSH_VERTICES(ctx, 0);
1012 if (is_program(ctx, obj)) {
1013 delete_shader_program(ctx, obj);
1014 }
1015 else if (is_shader(ctx, obj)) {
1016 delete_shader(ctx, obj);
1017 }
1018 else {
1019 /* error? */
1020 }
1021 }
1022 }
1023
1024
1025 void GLAPIENTRY
1026 _mesa_DeleteProgram(GLuint name)
1027 {
1028 if (name) {
1029 GET_CURRENT_CONTEXT(ctx);
1030 FLUSH_VERTICES(ctx, 0);
1031 delete_shader_program(ctx, name);
1032 }
1033 }
1034
1035
1036 void GLAPIENTRY
1037 _mesa_DeleteShader(GLuint name)
1038 {
1039 if (name) {
1040 GET_CURRENT_CONTEXT(ctx);
1041 FLUSH_VERTICES(ctx, 0);
1042 delete_shader(ctx, name);
1043 }
1044 }
1045
1046
1047 void GLAPIENTRY
1048 _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1049 {
1050 GET_CURRENT_CONTEXT(ctx);
1051 detach_shader(ctx, program, shader);
1052 }
1053
1054
1055 void GLAPIENTRY
1056 _mesa_DetachShader(GLuint program, GLuint shader)
1057 {
1058 GET_CURRENT_CONTEXT(ctx);
1059 detach_shader(ctx, program, shader);
1060 }
1061
1062
1063 void GLAPIENTRY
1064 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1065 GLsizei * count, GLhandleARB * obj)
1066 {
1067 GET_CURRENT_CONTEXT(ctx);
1068 get_attached_shaders(ctx, container, maxCount, count, obj);
1069 }
1070
1071
1072 void GLAPIENTRY
1073 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1074 GLsizei *count, GLuint *obj)
1075 {
1076 GET_CURRENT_CONTEXT(ctx);
1077 get_attached_shaders(ctx, program, maxCount, count, obj);
1078 }
1079
1080
1081 void GLAPIENTRY
1082 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1083 GLcharARB * infoLog)
1084 {
1085 GET_CURRENT_CONTEXT(ctx);
1086 if (is_program(ctx, object)) {
1087 get_program_info_log(ctx, object, maxLength, length, infoLog);
1088 }
1089 else if (is_shader(ctx, object)) {
1090 get_shader_info_log(ctx, object, maxLength, length, infoLog);
1091 }
1092 else {
1093 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1094 }
1095 }
1096
1097
1098 void GLAPIENTRY
1099 _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1100 {
1101 GET_CURRENT_CONTEXT(ctx);
1102 /* Implement in terms of GetProgramiv, GetShaderiv */
1103 if (is_program(ctx, object)) {
1104 if (pname == GL_OBJECT_TYPE_ARB) {
1105 *params = GL_PROGRAM_OBJECT_ARB;
1106 }
1107 else {
1108 get_programiv(ctx, object, pname, params);
1109 }
1110 }
1111 else if (is_shader(ctx, object)) {
1112 if (pname == GL_OBJECT_TYPE_ARB) {
1113 *params = GL_SHADER_OBJECT_ARB;
1114 }
1115 else {
1116 get_shaderiv(ctx, object, pname, params);
1117 }
1118 }
1119 else {
1120 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1121 }
1122 }
1123
1124
1125 void GLAPIENTRY
1126 _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1127 GLfloat *params)
1128 {
1129 GLint iparams[1]; /* XXX is one element enough? */
1130 _mesa_GetObjectParameterivARB(object, pname, iparams);
1131 params[0] = (GLfloat) iparams[0];
1132 }
1133
1134
1135 void GLAPIENTRY
1136 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1137 {
1138 GET_CURRENT_CONTEXT(ctx);
1139 get_programiv(ctx, program, pname, params);
1140 }
1141
1142
1143 void GLAPIENTRY
1144 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1145 {
1146 GET_CURRENT_CONTEXT(ctx);
1147 get_shaderiv(ctx, shader, pname, params);
1148 }
1149
1150
1151 void GLAPIENTRY
1152 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1153 GLsizei *length, GLchar *infoLog)
1154 {
1155 GET_CURRENT_CONTEXT(ctx);
1156 get_program_info_log(ctx, program, bufSize, length, infoLog);
1157 }
1158
1159
1160 void GLAPIENTRY
1161 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1162 GLsizei *length, GLchar *infoLog)
1163 {
1164 GET_CURRENT_CONTEXT(ctx);
1165 get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1166 }
1167
1168
1169 void GLAPIENTRY
1170 _mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
1171 GLsizei *length, GLcharARB *sourceOut)
1172 {
1173 GET_CURRENT_CONTEXT(ctx);
1174 get_shader_source(ctx, shader, maxLength, length, sourceOut);
1175 }
1176
1177
1178 GLhandleARB GLAPIENTRY
1179 _mesa_GetHandleARB(GLenum pname)
1180 {
1181 GET_CURRENT_CONTEXT(ctx);
1182 return get_handle(ctx, pname);
1183 }
1184
1185
1186 GLboolean GLAPIENTRY
1187 _mesa_IsProgram(GLuint name)
1188 {
1189 GET_CURRENT_CONTEXT(ctx);
1190 return is_program(ctx, name);
1191 }
1192
1193
1194 GLboolean GLAPIENTRY
1195 _mesa_IsShader(GLuint name)
1196 {
1197 GET_CURRENT_CONTEXT(ctx);
1198 return is_shader(ctx, name);
1199 }
1200
1201
1202 void GLAPIENTRY
1203 _mesa_LinkProgramARB(GLhandleARB programObj)
1204 {
1205 GET_CURRENT_CONTEXT(ctx);
1206 link_program(ctx, programObj);
1207 }
1208
1209
1210
1211 /**
1212 * Read shader source code from a file.
1213 * Useful for debugging to override an app's shader.
1214 */
1215 static GLcharARB *
1216 read_shader(const char *fname)
1217 {
1218 const int max = 50*1000;
1219 FILE *f = fopen(fname, "r");
1220 GLcharARB *buffer, *shader;
1221 int len;
1222
1223 if (!f) {
1224 return NULL;
1225 }
1226
1227 buffer = (char *) malloc(max);
1228 len = fread(buffer, 1, max, f);
1229 buffer[len] = 0;
1230
1231 fclose(f);
1232
1233 shader = _mesa_strdup(buffer);
1234 free(buffer);
1235
1236 return shader;
1237 }
1238
1239
1240 /**
1241 * Called via glShaderSource() and glShaderSourceARB() API functions.
1242 * Basically, concatenate the source code strings into one long string
1243 * and pass it to _mesa_shader_source().
1244 */
1245 void GLAPIENTRY
1246 _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
1247 const GLcharARB ** string, const GLint * length)
1248 {
1249 GET_CURRENT_CONTEXT(ctx);
1250 GLint *offsets;
1251 GLsizei i, totalLength;
1252 GLcharARB *source;
1253 GLuint checksum;
1254
1255 if (!shaderObj || string == NULL) {
1256 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
1257 return;
1258 }
1259
1260 /*
1261 * This array holds offsets of where the appropriate string ends, thus the
1262 * last element will be set to the total length of the source code.
1263 */
1264 offsets = (GLint *) malloc(count * sizeof(GLint));
1265 if (offsets == NULL) {
1266 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1267 return;
1268 }
1269
1270 for (i = 0; i < count; i++) {
1271 if (string[i] == NULL) {
1272 free((GLvoid *) offsets);
1273 _mesa_error(ctx, GL_INVALID_OPERATION,
1274 "glShaderSourceARB(null string)");
1275 return;
1276 }
1277 if (length == NULL || length[i] < 0)
1278 offsets[i] = strlen(string[i]);
1279 else
1280 offsets[i] = length[i];
1281 /* accumulate string lengths */
1282 if (i > 0)
1283 offsets[i] += offsets[i - 1];
1284 }
1285
1286 /* Total length of source string is sum off all strings plus two.
1287 * One extra byte for terminating zero, another extra byte to silence
1288 * valgrind warnings in the parser/grammer code.
1289 */
1290 totalLength = offsets[count - 1] + 2;
1291 source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
1292 if (source == NULL) {
1293 free((GLvoid *) offsets);
1294 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1295 return;
1296 }
1297
1298 for (i = 0; i < count; i++) {
1299 GLint start = (i > 0) ? offsets[i - 1] : 0;
1300 memcpy(source + start, string[i],
1301 (offsets[i] - start) * sizeof(GLcharARB));
1302 }
1303 source[totalLength - 1] = '\0';
1304 source[totalLength - 2] = '\0';
1305
1306 if (SHADER_SUBST) {
1307 /* Compute the shader's source code checksum then try to open a file
1308 * named newshader_<CHECKSUM>. If it exists, use it in place of the
1309 * original shader source code. For debugging.
1310 */
1311 char filename[100];
1312 GLcharARB *newSource;
1313
1314 checksum = _mesa_str_checksum(source);
1315
1316 _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
1317
1318 newSource = read_shader(filename);
1319 if (newSource) {
1320 fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
1321 shaderObj, checksum, filename);
1322 free(source);
1323 source = newSource;
1324 }
1325 }
1326
1327 shader_source(ctx, shaderObj, source);
1328
1329 if (SHADER_SUBST) {
1330 struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
1331 if (sh)
1332 sh->SourceChecksum = checksum; /* save original checksum */
1333 }
1334
1335 free(offsets);
1336 }
1337
1338
1339 void GLAPIENTRY
1340 _mesa_UseProgramObjectARB(GLhandleARB program)
1341 {
1342 GET_CURRENT_CONTEXT(ctx);
1343 struct gl_shader_program *shProg;
1344 struct gl_transform_feedback_object *obj =
1345 ctx->TransformFeedback.CurrentObject;
1346
1347 ASSERT_OUTSIDE_BEGIN_END(ctx);
1348
1349 if (obj->Active && !obj->Paused) {
1350 _mesa_error(ctx, GL_INVALID_OPERATION,
1351 "glUseProgram(transform feedback active)");
1352 return;
1353 }
1354
1355 if (program) {
1356 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1357 if (!shProg) {
1358 return;
1359 }
1360 if (!shProg->LinkStatus) {
1361 _mesa_error(ctx, GL_INVALID_OPERATION,
1362 "glUseProgram(program %u not linked)", program);
1363 return;
1364 }
1365
1366 /* debug code */
1367 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1368 print_shader_info(shProg);
1369 }
1370 }
1371 else {
1372 shProg = NULL;
1373 }
1374
1375 _mesa_use_program(ctx, shProg);
1376 }
1377
1378
1379 void GLAPIENTRY
1380 _mesa_ValidateProgramARB(GLhandleARB program)
1381 {
1382 GET_CURRENT_CONTEXT(ctx);
1383 validate_program(ctx, program);
1384 }
1385
1386 #ifdef FEATURE_ES2
1387
1388 void GLAPIENTRY
1389 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1390 GLint* range, GLint* precision)
1391 {
1392 const struct gl_program_constants *limits;
1393 const struct gl_precision *p;
1394 GET_CURRENT_CONTEXT(ctx);
1395
1396 switch (shadertype) {
1397 case GL_VERTEX_SHADER:
1398 limits = &ctx->Const.VertexProgram;
1399 break;
1400 case GL_FRAGMENT_SHADER:
1401 limits = &ctx->Const.FragmentProgram;
1402 break;
1403 default:
1404 _mesa_error(ctx, GL_INVALID_ENUM,
1405 "glGetShaderPrecisionFormat(shadertype)");
1406 return;
1407 }
1408
1409 switch (precisiontype) {
1410 case GL_LOW_FLOAT:
1411 p = &limits->LowFloat;
1412 break;
1413 case GL_MEDIUM_FLOAT:
1414 p = &limits->MediumFloat;
1415 break;
1416 case GL_HIGH_FLOAT:
1417 p = &limits->HighFloat;
1418 break;
1419 case GL_LOW_INT:
1420 p = &limits->LowInt;
1421 break;
1422 case GL_MEDIUM_INT:
1423 p = &limits->MediumInt;
1424 break;
1425 case GL_HIGH_INT:
1426 p = &limits->HighInt;
1427 break;
1428 default:
1429 _mesa_error(ctx, GL_INVALID_ENUM,
1430 "glGetShaderPrecisionFormat(precisiontype)");
1431 return;
1432 }
1433
1434 range[0] = p->RangeMin;
1435 range[1] = p->RangeMax;
1436 precision[0] = p->Precision;
1437 }
1438
1439
1440 void GLAPIENTRY
1441 _mesa_ReleaseShaderCompiler(void)
1442 {
1443 _mesa_destroy_shader_compiler_caches();
1444 }
1445
1446
1447 void GLAPIENTRY
1448 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1449 const void* binary, GLint length)
1450 {
1451 GET_CURRENT_CONTEXT(ctx);
1452 (void) n;
1453 (void) shaders;
1454 (void) binaryformat;
1455 (void) binary;
1456 (void) length;
1457 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1458 }
1459
1460 #endif /* FEATURE_ES2 */
1461
1462
1463 #if FEATURE_ARB_geometry_shader4
1464
1465 void GLAPIENTRY
1466 _mesa_ProgramParameteriARB(GLuint program, GLenum pname, GLint value)
1467 {
1468 struct gl_shader_program *shProg;
1469 GET_CURRENT_CONTEXT(ctx);
1470
1471 ASSERT_OUTSIDE_BEGIN_END(ctx);
1472
1473 shProg = _mesa_lookup_shader_program_err(ctx, program,
1474 "glProgramParameteri");
1475 if (!shProg)
1476 return;
1477
1478 switch (pname) {
1479 case GL_GEOMETRY_VERTICES_OUT_ARB:
1480 if (value < 1 ||
1481 (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
1482 _mesa_error(ctx, GL_INVALID_VALUE,
1483 "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
1484 value);
1485 return;
1486 }
1487 shProg->Geom.VerticesOut = value;
1488 break;
1489 case GL_GEOMETRY_INPUT_TYPE_ARB:
1490 switch (value) {
1491 case GL_POINTS:
1492 case GL_LINES:
1493 case GL_LINES_ADJACENCY_ARB:
1494 case GL_TRIANGLES:
1495 case GL_TRIANGLES_ADJACENCY_ARB:
1496 shProg->Geom.InputType = value;
1497 break;
1498 default:
1499 _mesa_error(ctx, GL_INVALID_VALUE,
1500 "glProgramParameteri(geometry input type = %s",
1501 _mesa_lookup_enum_by_nr(value));
1502 return;
1503 }
1504 break;
1505 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
1506 switch (value) {
1507 case GL_POINTS:
1508 case GL_LINE_STRIP:
1509 case GL_TRIANGLE_STRIP:
1510 shProg->Geom.OutputType = value;
1511 break;
1512 default:
1513 _mesa_error(ctx, GL_INVALID_VALUE,
1514 "glProgramParameteri(geometry output type = %s",
1515 _mesa_lookup_enum_by_nr(value));
1516 return;
1517 }
1518 break;
1519 default:
1520 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)",
1521 _mesa_lookup_enum_by_nr(pname));
1522 break;
1523 }
1524 }
1525
1526 #endif
1527
1528 void
1529 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
1530 struct gl_shader_program *shProg)
1531 {
1532 use_shader_program(ctx, type, shProg);
1533
1534 if (ctx->Driver.UseProgram)
1535 ctx->Driver.UseProgram(ctx, shProg);
1536 }
1537
1538
1539 /**
1540 * For GL_EXT_separate_shader_objects
1541 */
1542 void GLAPIENTRY
1543 _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
1544 {
1545 GET_CURRENT_CONTEXT(ctx);
1546 struct gl_shader_program *shProg = NULL;
1547
1548 ASSERT_OUTSIDE_BEGIN_END(ctx);
1549
1550 if (!validate_shader_target(ctx, type)) {
1551 _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
1552 return;
1553 }
1554
1555 if (ctx->TransformFeedback.CurrentObject->Active &&
1556 !ctx->TransformFeedback.CurrentObject->Paused) {
1557 _mesa_error(ctx, GL_INVALID_OPERATION,
1558 "glUseShaderProgramEXT(transform feedback is active)");
1559 return;
1560 }
1561
1562 if (program) {
1563 shProg = _mesa_lookup_shader_program_err(ctx, program,
1564 "glUseShaderProgramEXT");
1565 if (shProg == NULL)
1566 return;
1567
1568 if (!shProg->LinkStatus) {
1569 _mesa_error(ctx, GL_INVALID_OPERATION,
1570 "glUseShaderProgramEXT(program not linked)");
1571 return;
1572 }
1573 }
1574
1575 _mesa_use_shader_program(ctx, type, shProg);
1576 }
1577
1578
1579 /**
1580 * For GL_EXT_separate_shader_objects
1581 */
1582 void GLAPIENTRY
1583 _mesa_ActiveProgramEXT(GLuint program)
1584 {
1585 GET_CURRENT_CONTEXT(ctx);
1586 struct gl_shader_program *shProg = (program != 0)
1587 ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
1588 : NULL;
1589
1590 _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
1591 return;
1592 }
1593
1594
1595 /**
1596 * For GL_EXT_separate_shader_objects
1597 */
1598 GLuint GLAPIENTRY
1599 _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
1600 {
1601 GET_CURRENT_CONTEXT(ctx);
1602 const GLuint shader = create_shader(ctx, type);
1603 GLuint program = 0;
1604
1605 if (shader) {
1606 shader_source(ctx, shader, _mesa_strdup(string));
1607 compile_shader(ctx, shader);
1608
1609 program = create_shader_program(ctx);
1610 if (program) {
1611 struct gl_shader_program *shProg;
1612 struct gl_shader *sh;
1613 GLint compiled = GL_FALSE;
1614
1615 shProg = _mesa_lookup_shader_program(ctx, program);
1616 sh = _mesa_lookup_shader(ctx, shader);
1617
1618 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
1619 if (compiled) {
1620 attach_shader(ctx, program, shader);
1621 link_program(ctx, program);
1622 detach_shader(ctx, program, shader);
1623
1624 #if 0
1625 /* Possibly... */
1626 if (active-user-defined-varyings-in-linked-program) {
1627 append-error-to-info-log;
1628 shProg->LinkStatus = GL_FALSE;
1629 }
1630 #endif
1631 }
1632
1633 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
1634 }
1635
1636 delete_shader(ctx, shader);
1637 }
1638
1639 return program;
1640 }
1641
1642 /**
1643 * Plug in shader-related functions into API dispatch table.
1644 */
1645 void
1646 _mesa_init_shader_dispatch(struct _glapi_table *exec)
1647 {
1648 #if FEATURE_GL
1649 /* GL_ARB_vertex/fragment_shader */
1650 SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
1651 SET_GetHandleARB(exec, _mesa_GetHandleARB);
1652 SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
1653 SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
1654 SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
1655 SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
1656 SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
1657 SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
1658 SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
1659 SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
1660 SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
1661 SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
1662 SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
1663 SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
1664 SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
1665 SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
1666
1667 /* OpenGL 2.0 */
1668 SET_AttachShader(exec, _mesa_AttachShader);
1669 SET_CreateProgram(exec, _mesa_CreateProgram);
1670 SET_CreateShader(exec, _mesa_CreateShader);
1671 SET_DeleteProgram(exec, _mesa_DeleteProgram);
1672 SET_DeleteShader(exec, _mesa_DeleteShader);
1673 SET_DetachShader(exec, _mesa_DetachShader);
1674 SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
1675 SET_GetProgramiv(exec, _mesa_GetProgramiv);
1676 SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
1677 SET_GetShaderiv(exec, _mesa_GetShaderiv);
1678 SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
1679 SET_IsProgram(exec, _mesa_IsProgram);
1680 SET_IsShader(exec, _mesa_IsShader);
1681
1682 #if FEATURE_ARB_vertex_shader
1683 SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
1684 SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
1685 SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
1686 #endif
1687
1688 #if FEATURE_ARB_geometry_shader4
1689 SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB);
1690 #endif
1691
1692 SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT);
1693 SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT);
1694 SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT);
1695
1696 /* GL_EXT_gpu_shader4 / GL 3.0 */
1697 SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
1698 SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
1699
1700 /* GL_ARB_ES2_compatibility */
1701 SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
1702 SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat);
1703
1704 /* GL_ARB_blend_func_extended */
1705 SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed);
1706 SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex);
1707 #endif /* FEATURE_GL */
1708 }
1709