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