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