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
189static GLboolean
190is_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
197static GLboolean
198is_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 */
208static void
209attach_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
255static GLuint
256create_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
274static GLuint
275create_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 */
296static void
297delete_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
322static void
323delete_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
340static void
341detach_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 */
411static void
412get_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 */
431static GLuint
432get_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 */
452static void
453get_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 */
611static void
612get_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
644static void
645get_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
658static void
659get_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 */
674static void
675get_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 */
691static void
692shader_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 */
715static void
716compile_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 */
746static void
747link_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 */
796static void
797print_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 */
836void
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 */
853static bool
854use_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 */
930void
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 */
948static GLboolean
949validate_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 */
986static void
987validate_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
1009void GLAPIENTRY
1010_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1011{
1012   GET_CURRENT_CONTEXT(ctx);
1013   attach_shader(ctx, program, shader);
1014}
1015
1016
1017void GLAPIENTRY
1018_mesa_AttachShader(GLuint program, GLuint shader)
1019{
1020   GET_CURRENT_CONTEXT(ctx);
1021   attach_shader(ctx, program, shader);
1022}
1023
1024
1025void 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
1035GLuint 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
1045GLhandleARB GLAPIENTRY
1046_mesa_CreateShaderObjectARB(GLenum type)
1047{
1048   GET_CURRENT_CONTEXT(ctx);
1049   return create_shader(ctx, type);
1050}
1051
1052
1053GLuint 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
1063GLhandleARB GLAPIENTRY
1064_mesa_CreateProgramObjectARB(void)
1065{
1066   GET_CURRENT_CONTEXT(ctx);
1067   return create_shader_program(ctx);
1068}
1069
1070
1071void 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
1095void 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
1106void 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
1117void GLAPIENTRY
1118_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1119{
1120   GET_CURRENT_CONTEXT(ctx);
1121   detach_shader(ctx, program, shader);
1122}
1123
1124
1125void GLAPIENTRY
1126_mesa_DetachShader(GLuint program, GLuint shader)
1127{
1128   GET_CURRENT_CONTEXT(ctx);
1129   detach_shader(ctx, program, shader);
1130}
1131
1132
1133void 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
1142void 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
1151void 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
1168void 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
1195void 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
1205void 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
1213void 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
1221void 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
1230void 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
1239void 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
1248GLhandleARB GLAPIENTRY
1249_mesa_GetHandleARB(GLenum pname)
1250{
1251   GET_CURRENT_CONTEXT(ctx);
1252   return get_handle(ctx, pname);
1253}
1254
1255
1256GLboolean GLAPIENTRY
1257_mesa_IsProgram(GLuint name)
1258{
1259   GET_CURRENT_CONTEXT(ctx);
1260   return is_program(ctx, name);
1261}
1262
1263
1264GLboolean GLAPIENTRY
1265_mesa_IsShader(GLuint name)
1266{
1267   GET_CURRENT_CONTEXT(ctx);
1268   return is_shader(ctx, name);
1269}
1270
1271
1272void 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 */
1285static GLcharARB *
1286read_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 */
1315void 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
1409void 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
1449void GLAPIENTRY
1450_mesa_ValidateProgramARB(GLhandleARB program)
1451{
1452   GET_CURRENT_CONTEXT(ctx);
1453   validate_program(ctx, program);
1454}
1455
1456#ifdef FEATURE_ES2
1457
1458void 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
1510void GLAPIENTRY
1511_mesa_ReleaseShaderCompiler(void)
1512{
1513   _mesa_destroy_shader_compiler_caches();
1514}
1515
1516
1517void 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
1535void 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
1598void
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 */
1612void 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 */
1652void 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 */
1668GLuint 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 */
1715void
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
1792