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