shaderapi.c revision 848b8605
1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
5848b8605Smrg * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
6848b8605Smrg *
7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8848b8605Smrg * copy of this software and associated documentation files (the "Software"),
9848b8605Smrg * to deal in the Software without restriction, including without limitation
10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
12848b8605Smrg * Software is furnished to do so, subject to the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice shall be included
15848b8605Smrg * in all copies or substantial portions of the Software.
16848b8605Smrg *
17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
24848b8605Smrg */
25848b8605Smrg
26848b8605Smrg/**
27848b8605Smrg * \file shaderapi.c
28848b8605Smrg * \author Brian Paul
29848b8605Smrg *
30848b8605Smrg * Implementation of GLSL-related API functions.
31848b8605Smrg * The glUniform* functions are in uniforms.c
32848b8605Smrg *
33848b8605Smrg *
34848b8605Smrg * XXX things to do:
35848b8605Smrg * 1. Check that the right error code is generated for all _mesa_error() calls.
36848b8605Smrg * 2. Insert FLUSH_VERTICES calls in various places
37848b8605Smrg */
38848b8605Smrg
39848b8605Smrg
40848b8605Smrg#include "main/glheader.h"
41848b8605Smrg#include "main/context.h"
42848b8605Smrg#include "main/dispatch.h"
43848b8605Smrg#include "main/enums.h"
44848b8605Smrg#include "main/hash.h"
45848b8605Smrg#include "main/mtypes.h"
46848b8605Smrg#include "main/pipelineobj.h"
47848b8605Smrg#include "main/shaderapi.h"
48848b8605Smrg#include "main/shaderobj.h"
49848b8605Smrg#include "main/transformfeedback.h"
50848b8605Smrg#include "main/uniforms.h"
51848b8605Smrg#include "program/program.h"
52848b8605Smrg#include "program/prog_print.h"
53848b8605Smrg#include "program/prog_parameter.h"
54848b8605Smrg#include "util/ralloc.h"
55848b8605Smrg#include "util/hash_table.h"
56848b8605Smrg#include <stdbool.h>
57848b8605Smrg#include "../glsl/glsl_parser_extras.h"
58848b8605Smrg#include "../glsl/ir.h"
59848b8605Smrg#include "../glsl/ir_uniform.h"
60848b8605Smrg#include "../glsl/program.h"
61848b8605Smrg
62848b8605Smrg/** Define this to enable shader substitution (see below) */
63848b8605Smrg#define SHADER_SUBST 0
64848b8605Smrg
65848b8605Smrg
66848b8605Smrg/**
67848b8605Smrg * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
68848b8605Smrg */
69848b8605SmrgGLbitfield
70848b8605Smrg_mesa_get_shader_flags(void)
71848b8605Smrg{
72848b8605Smrg   GLbitfield flags = 0x0;
73848b8605Smrg   const char *env = _mesa_getenv("MESA_GLSL");
74848b8605Smrg
75848b8605Smrg   if (env) {
76848b8605Smrg      if (strstr(env, "dump_on_error"))
77848b8605Smrg         flags |= GLSL_DUMP_ON_ERROR;
78848b8605Smrg      else if (strstr(env, "dump"))
79848b8605Smrg         flags |= GLSL_DUMP;
80848b8605Smrg      if (strstr(env, "log"))
81848b8605Smrg         flags |= GLSL_LOG;
82848b8605Smrg      if (strstr(env, "nopvert"))
83848b8605Smrg         flags |= GLSL_NOP_VERT;
84848b8605Smrg      if (strstr(env, "nopfrag"))
85848b8605Smrg         flags |= GLSL_NOP_FRAG;
86848b8605Smrg      if (strstr(env, "nopt"))
87848b8605Smrg         flags |= GLSL_NO_OPT;
88848b8605Smrg      else if (strstr(env, "opt"))
89848b8605Smrg         flags |= GLSL_OPT;
90848b8605Smrg      if (strstr(env, "uniform"))
91848b8605Smrg         flags |= GLSL_UNIFORMS;
92848b8605Smrg      if (strstr(env, "useprog"))
93848b8605Smrg         flags |= GLSL_USE_PROG;
94848b8605Smrg      if (strstr(env, "errors"))
95848b8605Smrg         flags |= GLSL_REPORT_ERRORS;
96848b8605Smrg   }
97848b8605Smrg
98848b8605Smrg   return flags;
99848b8605Smrg}
100848b8605Smrg
101848b8605Smrg
102848b8605Smrg/**
103848b8605Smrg * Initialize context's shader state.
104848b8605Smrg */
105848b8605Smrgvoid
106848b8605Smrg_mesa_init_shader_state(struct gl_context *ctx)
107848b8605Smrg{
108848b8605Smrg   /* Device drivers may override these to control what kind of instructions
109848b8605Smrg    * are generated by the GLSL compiler.
110848b8605Smrg    */
111848b8605Smrg   struct gl_shader_compiler_options options;
112848b8605Smrg   gl_shader_stage sh;
113848b8605Smrg
114848b8605Smrg   memset(&options, 0, sizeof(options));
115848b8605Smrg   options.MaxUnrollIterations = 32;
116848b8605Smrg   options.MaxIfDepth = UINT_MAX;
117848b8605Smrg
118848b8605Smrg   /* Default pragma settings */
119848b8605Smrg   options.DefaultPragmas.Optimize = GL_TRUE;
120848b8605Smrg
121848b8605Smrg   for (sh = 0; sh < MESA_SHADER_STAGES; ++sh)
122848b8605Smrg      memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options));
123848b8605Smrg
124848b8605Smrg   ctx->Shader.Flags = _mesa_get_shader_flags();
125848b8605Smrg
126848b8605Smrg   /* Extended for ARB_separate_shader_objects */
127848b8605Smrg   ctx->Shader.RefCount = 1;
128848b8605Smrg   mtx_init(&ctx->Shader.Mutex, mtx_plain);
129848b8605Smrg}
130848b8605Smrg
131848b8605Smrg
132848b8605Smrg/**
133848b8605Smrg * Free the per-context shader-related state.
134848b8605Smrg */
135848b8605Smrgvoid
136848b8605Smrg_mesa_free_shader_state(struct gl_context *ctx)
137848b8605Smrg{
138848b8605Smrg   int i;
139848b8605Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++) {
140848b8605Smrg      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram[i],
141848b8605Smrg                                     NULL);
142848b8605Smrg   }
143848b8605Smrg   _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
144848b8605Smrg				  NULL);
145848b8605Smrg   _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
146848b8605Smrg
147848b8605Smrg   /* Extended for ARB_separate_shader_objects */
148848b8605Smrg   _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);
149848b8605Smrg
150848b8605Smrg   assert(ctx->Shader.RefCount == 1);
151848b8605Smrg   mtx_destroy(&ctx->Shader.Mutex);
152848b8605Smrg}
153848b8605Smrg
154848b8605Smrg
155848b8605Smrg/**
156848b8605Smrg * Copy string from <src> to <dst>, up to maxLength characters, returning
157848b8605Smrg * length of <dst> in <length>.
158848b8605Smrg * \param src  the strings source
159848b8605Smrg * \param maxLength  max chars to copy
160848b8605Smrg * \param length  returns number of chars copied
161848b8605Smrg * \param dst  the string destination
162848b8605Smrg */
163848b8605Smrgvoid
164848b8605Smrg_mesa_copy_string(GLchar *dst, GLsizei maxLength,
165848b8605Smrg                  GLsizei *length, const GLchar *src)
166848b8605Smrg{
167848b8605Smrg   GLsizei len;
168848b8605Smrg   for (len = 0; len < maxLength - 1 && src && src[len]; len++)
169848b8605Smrg      dst[len] = src[len];
170848b8605Smrg   if (maxLength > 0)
171848b8605Smrg      dst[len] = 0;
172848b8605Smrg   if (length)
173848b8605Smrg      *length = len;
174848b8605Smrg}
175848b8605Smrg
176848b8605Smrg
177848b8605Smrg
178848b8605Smrg/**
179848b8605Smrg * Confirm that the a shader type is valid and supported by the implementation
180848b8605Smrg *
181848b8605Smrg * \param ctx   Current GL context
182848b8605Smrg * \param type  Shader target
183848b8605Smrg *
184848b8605Smrg */
185848b8605Smrgbool
186848b8605Smrg_mesa_validate_shader_target(const struct gl_context *ctx, GLenum type)
187848b8605Smrg{
188848b8605Smrg   /* Note: when building built-in GLSL functions, this function may be
189848b8605Smrg    * invoked with ctx == NULL.  In that case, we can only validate that it's
190848b8605Smrg    * a shader target we recognize, not that it's supported in the current
191848b8605Smrg    * context.  But that's fine--we don't need any further validation than
192848b8605Smrg    * that when building built-in GLSL functions.
193848b8605Smrg    */
194848b8605Smrg
195848b8605Smrg   switch (type) {
196848b8605Smrg   case GL_FRAGMENT_SHADER:
197848b8605Smrg      return ctx == NULL || ctx->Extensions.ARB_fragment_shader;
198848b8605Smrg   case GL_VERTEX_SHADER:
199848b8605Smrg      return ctx == NULL || ctx->Extensions.ARB_vertex_shader;
200848b8605Smrg   case GL_GEOMETRY_SHADER_ARB:
201848b8605Smrg      return ctx == NULL || _mesa_has_geometry_shaders(ctx);
202848b8605Smrg   case GL_COMPUTE_SHADER:
203848b8605Smrg      return ctx == NULL || ctx->Extensions.ARB_compute_shader;
204848b8605Smrg   default:
205848b8605Smrg      return false;
206848b8605Smrg   }
207848b8605Smrg}
208848b8605Smrg
209848b8605Smrg
210848b8605Smrgstatic GLboolean
211848b8605Smrgis_program(struct gl_context *ctx, GLuint name)
212848b8605Smrg{
213848b8605Smrg   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
214848b8605Smrg   return shProg ? GL_TRUE : GL_FALSE;
215848b8605Smrg}
216848b8605Smrg
217848b8605Smrg
218848b8605Smrgstatic GLboolean
219848b8605Smrgis_shader(struct gl_context *ctx, GLuint name)
220848b8605Smrg{
221848b8605Smrg   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
222848b8605Smrg   return shader ? GL_TRUE : GL_FALSE;
223848b8605Smrg}
224848b8605Smrg
225848b8605Smrg
226848b8605Smrg/**
227848b8605Smrg * Attach shader to a shader program.
228848b8605Smrg */
229848b8605Smrgstatic void
230848b8605Smrgattach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
231848b8605Smrg{
232848b8605Smrg   struct gl_shader_program *shProg;
233848b8605Smrg   struct gl_shader *sh;
234848b8605Smrg   GLuint i, n;
235848b8605Smrg
236848b8605Smrg   const bool same_type_disallowed = _mesa_is_gles(ctx);
237848b8605Smrg
238848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
239848b8605Smrg   if (!shProg)
240848b8605Smrg      return;
241848b8605Smrg
242848b8605Smrg   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
243848b8605Smrg   if (!sh) {
244848b8605Smrg      return;
245848b8605Smrg   }
246848b8605Smrg
247848b8605Smrg   n = shProg->NumShaders;
248848b8605Smrg   for (i = 0; i < n; i++) {
249848b8605Smrg      if (shProg->Shaders[i] == sh) {
250848b8605Smrg         /* The shader is already attched to this program.  The
251848b8605Smrg          * GL_ARB_shader_objects spec says:
252848b8605Smrg          *
253848b8605Smrg          *     "The error INVALID_OPERATION is generated by AttachObjectARB
254848b8605Smrg          *     if <obj> is already attached to <containerObj>."
255848b8605Smrg          */
256848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
257848b8605Smrg         return;
258848b8605Smrg      } else if (same_type_disallowed &&
259848b8605Smrg                 shProg->Shaders[i]->Type == sh->Type) {
260848b8605Smrg        /* Shader with the same type is already attached to this program,
261848b8605Smrg         * OpenGL ES 2.0 and 3.0 specs say:
262848b8605Smrg         *
263848b8605Smrg         *      "Multiple shader objects of the same type may not be attached
264848b8605Smrg         *      to a single program object. [...] The error INVALID_OPERATION
265848b8605Smrg         *      is generated if [...] another shader object of the same type
266848b8605Smrg         *      as shader is already attached to program."
267848b8605Smrg         */
268848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
269848b8605Smrg         return;
270848b8605Smrg      }
271848b8605Smrg   }
272848b8605Smrg
273848b8605Smrg   /* grow list */
274848b8605Smrg   shProg->Shaders = (struct gl_shader **)
275848b8605Smrg      _mesa_realloc(shProg->Shaders,
276848b8605Smrg                    n * sizeof(struct gl_shader *),
277848b8605Smrg                    (n + 1) * sizeof(struct gl_shader *));
278848b8605Smrg   if (!shProg->Shaders) {
279848b8605Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
280848b8605Smrg      return;
281848b8605Smrg   }
282848b8605Smrg
283848b8605Smrg   /* append */
284848b8605Smrg   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
285848b8605Smrg   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
286848b8605Smrg   shProg->NumShaders++;
287848b8605Smrg}
288848b8605Smrg
289848b8605Smrg
290848b8605Smrgstatic GLuint
291848b8605Smrgcreate_shader(struct gl_context *ctx, GLenum type)
292848b8605Smrg{
293848b8605Smrg   struct gl_shader *sh;
294848b8605Smrg   GLuint name;
295848b8605Smrg
296848b8605Smrg   if (!_mesa_validate_shader_target(ctx, type)) {
297848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
298848b8605Smrg      return 0;
299848b8605Smrg   }
300848b8605Smrg
301848b8605Smrg   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
302848b8605Smrg   sh = ctx->Driver.NewShader(ctx, name, type);
303848b8605Smrg   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
304848b8605Smrg
305848b8605Smrg   return name;
306848b8605Smrg}
307848b8605Smrg
308848b8605Smrg
309848b8605Smrgstatic GLuint
310848b8605Smrgcreate_shader_program(struct gl_context *ctx)
311848b8605Smrg{
312848b8605Smrg   GLuint name;
313848b8605Smrg   struct gl_shader_program *shProg;
314848b8605Smrg
315848b8605Smrg   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
316848b8605Smrg
317848b8605Smrg   shProg = ctx->Driver.NewShaderProgram(ctx, name);
318848b8605Smrg
319848b8605Smrg   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
320848b8605Smrg
321848b8605Smrg   assert(shProg->RefCount == 1);
322848b8605Smrg
323848b8605Smrg   return name;
324848b8605Smrg}
325848b8605Smrg
326848b8605Smrg
327848b8605Smrg/**
328848b8605Smrg * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
329848b8605Smrg * DeleteProgramARB.
330848b8605Smrg */
331848b8605Smrgstatic void
332848b8605Smrgdelete_shader_program(struct gl_context *ctx, GLuint name)
333848b8605Smrg{
334848b8605Smrg   /*
335848b8605Smrg    * NOTE: deleting shaders/programs works a bit differently than
336848b8605Smrg    * texture objects (and buffer objects, etc).  Shader/program
337848b8605Smrg    * handles/IDs exist in the hash table until the object is really
338848b8605Smrg    * deleted (refcount==0).  With texture objects, the handle/ID is
339848b8605Smrg    * removed from the hash table in glDeleteTextures() while the tex
340848b8605Smrg    * object itself might linger until its refcount goes to zero.
341848b8605Smrg    */
342848b8605Smrg   struct gl_shader_program *shProg;
343848b8605Smrg
344848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
345848b8605Smrg   if (!shProg)
346848b8605Smrg      return;
347848b8605Smrg
348848b8605Smrg   if (!shProg->DeletePending) {
349848b8605Smrg      shProg->DeletePending = GL_TRUE;
350848b8605Smrg
351848b8605Smrg      /* effectively, decr shProg's refcount */
352848b8605Smrg      _mesa_reference_shader_program(ctx, &shProg, NULL);
353848b8605Smrg   }
354848b8605Smrg}
355848b8605Smrg
356848b8605Smrg
357848b8605Smrgstatic void
358848b8605Smrgdelete_shader(struct gl_context *ctx, GLuint shader)
359848b8605Smrg{
360848b8605Smrg   struct gl_shader *sh;
361848b8605Smrg
362848b8605Smrg   sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
363848b8605Smrg   if (!sh)
364848b8605Smrg      return;
365848b8605Smrg
366848b8605Smrg   if (!sh->DeletePending) {
367848b8605Smrg      sh->DeletePending = GL_TRUE;
368848b8605Smrg
369848b8605Smrg      /* effectively, decr sh's refcount */
370848b8605Smrg      _mesa_reference_shader(ctx, &sh, NULL);
371848b8605Smrg   }
372848b8605Smrg}
373848b8605Smrg
374848b8605Smrg
375848b8605Smrgstatic void
376848b8605Smrgdetach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
377848b8605Smrg{
378848b8605Smrg   struct gl_shader_program *shProg;
379848b8605Smrg   GLuint n;
380848b8605Smrg   GLuint i, j;
381848b8605Smrg
382848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
383848b8605Smrg   if (!shProg)
384848b8605Smrg      return;
385848b8605Smrg
386848b8605Smrg   n = shProg->NumShaders;
387848b8605Smrg
388848b8605Smrg   for (i = 0; i < n; i++) {
389848b8605Smrg      if (shProg->Shaders[i]->Name == shader) {
390848b8605Smrg         /* found it */
391848b8605Smrg         struct gl_shader **newList;
392848b8605Smrg
393848b8605Smrg         /* release */
394848b8605Smrg         _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
395848b8605Smrg
396848b8605Smrg         /* alloc new, smaller array */
397848b8605Smrg         newList = malloc((n - 1) * sizeof(struct gl_shader *));
398848b8605Smrg         if (!newList) {
399848b8605Smrg            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
400848b8605Smrg            return;
401848b8605Smrg         }
402848b8605Smrg         /* Copy old list entries to new list, skipping removed entry at [i] */
403848b8605Smrg         for (j = 0; j < i; j++) {
404848b8605Smrg            newList[j] = shProg->Shaders[j];
405848b8605Smrg         }
406848b8605Smrg         while (++i < n) {
407848b8605Smrg            newList[j++] = shProg->Shaders[i];
408848b8605Smrg         }
409848b8605Smrg
410848b8605Smrg         /* Free old list and install new one */
411848b8605Smrg         free(shProg->Shaders);
412848b8605Smrg         shProg->Shaders = newList;
413848b8605Smrg         shProg->NumShaders = n - 1;
414848b8605Smrg
415848b8605Smrg#ifdef DEBUG
416848b8605Smrg         /* sanity check - make sure the new list's entries are sensible */
417848b8605Smrg         for (j = 0; j < shProg->NumShaders; j++) {
418848b8605Smrg            assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
419848b8605Smrg                   shProg->Shaders[j]->Type == GL_GEOMETRY_SHADER ||
420848b8605Smrg                   shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
421848b8605Smrg            assert(shProg->Shaders[j]->RefCount > 0);
422848b8605Smrg         }
423848b8605Smrg#endif
424848b8605Smrg
425848b8605Smrg         return;
426848b8605Smrg      }
427848b8605Smrg   }
428848b8605Smrg
429848b8605Smrg   /* not found */
430848b8605Smrg   {
431848b8605Smrg      GLenum err;
432848b8605Smrg      if (is_shader(ctx, shader))
433848b8605Smrg         err = GL_INVALID_OPERATION;
434848b8605Smrg      else if (is_program(ctx, shader))
435848b8605Smrg         err = GL_INVALID_OPERATION;
436848b8605Smrg      else
437848b8605Smrg         err = GL_INVALID_VALUE;
438848b8605Smrg      _mesa_error(ctx, err, "glDetachShader(shader)");
439848b8605Smrg      return;
440848b8605Smrg   }
441848b8605Smrg}
442848b8605Smrg
443848b8605Smrg
444848b8605Smrg/**
445848b8605Smrg * Return list of shaders attached to shader program.
446848b8605Smrg */
447848b8605Smrgstatic void
448848b8605Smrgget_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
449848b8605Smrg                     GLsizei *count, GLuint *obj)
450848b8605Smrg{
451848b8605Smrg   struct gl_shader_program *shProg =
452848b8605Smrg      _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
453848b8605Smrg   if (shProg) {
454848b8605Smrg      GLuint i;
455848b8605Smrg      for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
456848b8605Smrg         obj[i] = shProg->Shaders[i]->Name;
457848b8605Smrg      }
458848b8605Smrg      if (count)
459848b8605Smrg         *count = i;
460848b8605Smrg   }
461848b8605Smrg}
462848b8605Smrg
463848b8605Smrg
464848b8605Smrg/**
465848b8605Smrg * glGetHandleARB() - return ID/name of currently bound shader program.
466848b8605Smrg */
467848b8605Smrgstatic GLuint
468848b8605Smrgget_handle(struct gl_context *ctx, GLenum pname)
469848b8605Smrg{
470848b8605Smrg   if (pname == GL_PROGRAM_OBJECT_ARB) {
471848b8605Smrg      if (ctx->_Shader->ActiveProgram)
472848b8605Smrg         return ctx->_Shader->ActiveProgram->Name;
473848b8605Smrg      else
474848b8605Smrg         return 0;
475848b8605Smrg   }
476848b8605Smrg   else {
477848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
478848b8605Smrg      return 0;
479848b8605Smrg   }
480848b8605Smrg}
481848b8605Smrg
482848b8605Smrg
483848b8605Smrg/**
484848b8605Smrg * Check if a geometry shader query is valid at this time.  If not, report an
485848b8605Smrg * error and return false.
486848b8605Smrg *
487848b8605Smrg * From GL 3.2 section 6.1.16 (Shader and Program Queries):
488848b8605Smrg *
489848b8605Smrg *     "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE
490848b8605Smrg *     are queried for a program which has not been linked successfully, or
491848b8605Smrg *     which does not contain objects to form a geometry shader, then an
492848b8605Smrg *     INVALID_OPERATION error is generated."
493848b8605Smrg */
494848b8605Smrgstatic bool
495848b8605Smrgcheck_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
496848b8605Smrg{
497848b8605Smrg   if (shProg->LinkStatus &&
498848b8605Smrg       shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
499848b8605Smrg      return true;
500848b8605Smrg   }
501848b8605Smrg
502848b8605Smrg   _mesa_error(ctx, GL_INVALID_OPERATION,
503848b8605Smrg               "glGetProgramv(linked geometry shader required)");
504848b8605Smrg   return false;
505848b8605Smrg}
506848b8605Smrg
507848b8605Smrg
508848b8605Smrg/**
509848b8605Smrg * glGetProgramiv() - get shader program state.
510848b8605Smrg * Note that this is for GLSL shader programs, not ARB vertex/fragment
511848b8605Smrg * programs (see glGetProgramivARB).
512848b8605Smrg */
513848b8605Smrgstatic void
514848b8605Smrgget_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params)
515848b8605Smrg{
516848b8605Smrg   struct gl_shader_program *shProg
517848b8605Smrg      = _mesa_lookup_shader_program(ctx, program);
518848b8605Smrg
519848b8605Smrg   /* Is transform feedback available in this context?
520848b8605Smrg    */
521848b8605Smrg   const bool has_xfb =
522848b8605Smrg      (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback)
523848b8605Smrg      || ctx->API == API_OPENGL_CORE
524848b8605Smrg      || _mesa_is_gles3(ctx);
525848b8605Smrg
526848b8605Smrg   /* True if geometry shaders (of the form that was adopted into GLSL 1.50
527848b8605Smrg    * and GL 3.2) are available in this context
528848b8605Smrg    */
529848b8605Smrg   const bool has_core_gs = _mesa_is_desktop_gl(ctx) && ctx->Version >= 32;
530848b8605Smrg
531848b8605Smrg   /* Are uniform buffer objects available in this context?
532848b8605Smrg    */
533848b8605Smrg   const bool has_ubo =
534848b8605Smrg      (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_uniform_buffer_object)
535848b8605Smrg      || ctx->API == API_OPENGL_CORE
536848b8605Smrg      || _mesa_is_gles3(ctx);
537848b8605Smrg
538848b8605Smrg   if (!shProg) {
539848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
540848b8605Smrg      return;
541848b8605Smrg   }
542848b8605Smrg
543848b8605Smrg   switch (pname) {
544848b8605Smrg   case GL_DELETE_STATUS:
545848b8605Smrg      *params = shProg->DeletePending;
546848b8605Smrg      return;
547848b8605Smrg   case GL_LINK_STATUS:
548848b8605Smrg      *params = shProg->LinkStatus;
549848b8605Smrg      return;
550848b8605Smrg   case GL_VALIDATE_STATUS:
551848b8605Smrg      *params = shProg->Validated;
552848b8605Smrg      return;
553848b8605Smrg   case GL_INFO_LOG_LENGTH:
554848b8605Smrg      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
555848b8605Smrg      return;
556848b8605Smrg   case GL_ATTACHED_SHADERS:
557848b8605Smrg      *params = shProg->NumShaders;
558848b8605Smrg      return;
559848b8605Smrg   case GL_ACTIVE_ATTRIBUTES:
560848b8605Smrg      *params = _mesa_count_active_attribs(shProg);
561848b8605Smrg      return;
562848b8605Smrg   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
563848b8605Smrg      *params = _mesa_longest_attribute_name_length(shProg);
564848b8605Smrg      return;
565848b8605Smrg   case GL_ACTIVE_UNIFORMS:
566848b8605Smrg      *params = shProg->NumUserUniformStorage;
567848b8605Smrg      return;
568848b8605Smrg   case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
569848b8605Smrg      unsigned i;
570848b8605Smrg      GLint max_len = 0;
571848b8605Smrg
572848b8605Smrg      for (i = 0; i < shProg->NumUserUniformStorage; i++) {
573848b8605Smrg	 /* Add one for the terminating NUL character for a non-array, and
574848b8605Smrg	  * 4 for the "[0]" and the NUL for an array.
575848b8605Smrg	  */
576848b8605Smrg	 const GLint len = strlen(shProg->UniformStorage[i].name) + 1 +
577848b8605Smrg	     ((shProg->UniformStorage[i].array_elements != 0) ? 3 : 0);
578848b8605Smrg
579848b8605Smrg	 if (len > max_len)
580848b8605Smrg	    max_len = len;
581848b8605Smrg      }
582848b8605Smrg
583848b8605Smrg      *params = max_len;
584848b8605Smrg      return;
585848b8605Smrg   }
586848b8605Smrg   case GL_TRANSFORM_FEEDBACK_VARYINGS:
587848b8605Smrg      if (!has_xfb)
588848b8605Smrg         break;
589848b8605Smrg      *params = shProg->TransformFeedback.NumVarying;
590848b8605Smrg      return;
591848b8605Smrg   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: {
592848b8605Smrg      unsigned i;
593848b8605Smrg      GLint max_len = 0;
594848b8605Smrg      if (!has_xfb)
595848b8605Smrg         break;
596848b8605Smrg
597848b8605Smrg      for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
598848b8605Smrg         /* Add one for the terminating NUL character.
599848b8605Smrg          */
600848b8605Smrg         const GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]) + 1;
601848b8605Smrg
602848b8605Smrg         if (len > max_len)
603848b8605Smrg            max_len = len;
604848b8605Smrg      }
605848b8605Smrg
606848b8605Smrg      *params = max_len;
607848b8605Smrg      return;
608848b8605Smrg   }
609848b8605Smrg   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
610848b8605Smrg      if (!has_xfb)
611848b8605Smrg         break;
612848b8605Smrg      *params = shProg->TransformFeedback.BufferMode;
613848b8605Smrg      return;
614848b8605Smrg   case GL_GEOMETRY_VERTICES_OUT:
615848b8605Smrg      if (!has_core_gs)
616848b8605Smrg         break;
617848b8605Smrg      if (check_gs_query(ctx, shProg))
618848b8605Smrg         *params = shProg->Geom.VerticesOut;
619848b8605Smrg      return;
620848b8605Smrg   case GL_GEOMETRY_SHADER_INVOCATIONS:
621848b8605Smrg      if (!has_core_gs || !ctx->Extensions.ARB_gpu_shader5)
622848b8605Smrg         break;
623848b8605Smrg      if (check_gs_query(ctx, shProg))
624848b8605Smrg         *params = shProg->Geom.Invocations;
625848b8605Smrg      return;
626848b8605Smrg   case GL_GEOMETRY_INPUT_TYPE:
627848b8605Smrg      if (!has_core_gs)
628848b8605Smrg         break;
629848b8605Smrg      if (check_gs_query(ctx, shProg))
630848b8605Smrg         *params = shProg->Geom.InputType;
631848b8605Smrg      return;
632848b8605Smrg   case GL_GEOMETRY_OUTPUT_TYPE:
633848b8605Smrg      if (!has_core_gs)
634848b8605Smrg         break;
635848b8605Smrg      if (check_gs_query(ctx, shProg))
636848b8605Smrg         *params = shProg->Geom.OutputType;
637848b8605Smrg      return;
638848b8605Smrg   case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
639848b8605Smrg      unsigned i;
640848b8605Smrg      GLint max_len = 0;
641848b8605Smrg
642848b8605Smrg      if (!has_ubo)
643848b8605Smrg         break;
644848b8605Smrg
645848b8605Smrg      for (i = 0; i < shProg->NumUniformBlocks; i++) {
646848b8605Smrg	 /* Add one for the terminating NUL character.
647848b8605Smrg	  */
648848b8605Smrg	 const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;
649848b8605Smrg
650848b8605Smrg	 if (len > max_len)
651848b8605Smrg	    max_len = len;
652848b8605Smrg      }
653848b8605Smrg
654848b8605Smrg      *params = max_len;
655848b8605Smrg      return;
656848b8605Smrg   }
657848b8605Smrg   case GL_ACTIVE_UNIFORM_BLOCKS:
658848b8605Smrg      if (!has_ubo)
659848b8605Smrg         break;
660848b8605Smrg
661848b8605Smrg      *params = shProg->NumUniformBlocks;
662848b8605Smrg      return;
663848b8605Smrg   case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
664848b8605Smrg      /* This enum isn't part of the OES extension for OpenGL ES 2.0.  It is
665848b8605Smrg       * only available with desktop OpenGL 3.0+ with the
666848b8605Smrg       * GL_ARB_get_program_binary extension or OpenGL ES 3.0.
667848b8605Smrg       *
668848b8605Smrg       * On desktop, we ignore the 3.0+ requirement because it is silly.
669848b8605Smrg       */
670848b8605Smrg      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
671848b8605Smrg         break;
672848b8605Smrg
673848b8605Smrg      *params = shProg->BinaryRetreivableHint;
674848b8605Smrg      return;
675848b8605Smrg   case GL_PROGRAM_BINARY_LENGTH:
676848b8605Smrg      *params = 0;
677848b8605Smrg      return;
678848b8605Smrg   case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
679848b8605Smrg      if (!ctx->Extensions.ARB_shader_atomic_counters)
680848b8605Smrg         break;
681848b8605Smrg
682848b8605Smrg      *params = shProg->NumAtomicBuffers;
683848b8605Smrg      return;
684848b8605Smrg   case GL_COMPUTE_WORK_GROUP_SIZE: {
685848b8605Smrg      int i;
686848b8605Smrg      if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_compute_shader)
687848b8605Smrg         break;
688848b8605Smrg      if (!shProg->LinkStatus) {
689848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(program not "
690848b8605Smrg                     "linked)");
691848b8605Smrg         return;
692848b8605Smrg      }
693848b8605Smrg      if (shProg->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) {
694848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(no compute "
695848b8605Smrg                     "shaders)");
696848b8605Smrg         return;
697848b8605Smrg      }
698848b8605Smrg      for (i = 0; i < 3; i++)
699848b8605Smrg         params[i] = shProg->Comp.LocalSize[i];
700848b8605Smrg      return;
701848b8605Smrg   }
702848b8605Smrg   case GL_PROGRAM_SEPARABLE:
703848b8605Smrg      *params = shProg->SeparateShader;
704848b8605Smrg      return;
705848b8605Smrg   default:
706848b8605Smrg      break;
707848b8605Smrg   }
708848b8605Smrg
709848b8605Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
710848b8605Smrg               _mesa_lookup_enum_by_nr(pname));
711848b8605Smrg}
712848b8605Smrg
713848b8605Smrg
714848b8605Smrg/**
715848b8605Smrg * glGetShaderiv() - get GLSL shader state
716848b8605Smrg */
717848b8605Smrgstatic void
718848b8605Smrgget_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
719848b8605Smrg{
720848b8605Smrg   struct gl_shader *shader =
721848b8605Smrg      _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
722848b8605Smrg
723848b8605Smrg   if (!shader) {
724848b8605Smrg      return;
725848b8605Smrg   }
726848b8605Smrg
727848b8605Smrg   switch (pname) {
728848b8605Smrg   case GL_SHADER_TYPE:
729848b8605Smrg      *params = shader->Type;
730848b8605Smrg      break;
731848b8605Smrg   case GL_DELETE_STATUS:
732848b8605Smrg      *params = shader->DeletePending;
733848b8605Smrg      break;
734848b8605Smrg   case GL_COMPILE_STATUS:
735848b8605Smrg      *params = shader->CompileStatus;
736848b8605Smrg      break;
737848b8605Smrg   case GL_INFO_LOG_LENGTH:
738848b8605Smrg      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
739848b8605Smrg      break;
740848b8605Smrg   case GL_SHADER_SOURCE_LENGTH:
741848b8605Smrg      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
742848b8605Smrg      break;
743848b8605Smrg   default:
744848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
745848b8605Smrg      return;
746848b8605Smrg   }
747848b8605Smrg}
748848b8605Smrg
749848b8605Smrg
750848b8605Smrgstatic void
751848b8605Smrgget_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
752848b8605Smrg                     GLsizei *length, GLchar *infoLog)
753848b8605Smrg{
754848b8605Smrg   struct gl_shader_program *shProg
755848b8605Smrg      = _mesa_lookup_shader_program(ctx, program);
756848b8605Smrg   if (!shProg) {
757848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
758848b8605Smrg      return;
759848b8605Smrg   }
760848b8605Smrg   _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
761848b8605Smrg}
762848b8605Smrg
763848b8605Smrg
764848b8605Smrgstatic void
765848b8605Smrgget_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
766848b8605Smrg                    GLsizei *length, GLchar *infoLog)
767848b8605Smrg{
768848b8605Smrg   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
769848b8605Smrg   if (!sh) {
770848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
771848b8605Smrg      return;
772848b8605Smrg   }
773848b8605Smrg   _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
774848b8605Smrg}
775848b8605Smrg
776848b8605Smrg
777848b8605Smrg/**
778848b8605Smrg * Return shader source code.
779848b8605Smrg */
780848b8605Smrgstatic void
781848b8605Smrgget_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
782848b8605Smrg                  GLsizei *length, GLchar *sourceOut)
783848b8605Smrg{
784848b8605Smrg   struct gl_shader *sh;
785848b8605Smrg   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
786848b8605Smrg   if (!sh) {
787848b8605Smrg      return;
788848b8605Smrg   }
789848b8605Smrg   _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
790848b8605Smrg}
791848b8605Smrg
792848b8605Smrg
793848b8605Smrg/**
794848b8605Smrg * Set/replace shader source code.  A helper function used by
795848b8605Smrg * glShaderSource[ARB].
796848b8605Smrg */
797848b8605Smrgstatic void
798848b8605Smrgshader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
799848b8605Smrg{
800848b8605Smrg   struct gl_shader *sh;
801848b8605Smrg
802848b8605Smrg   sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
803848b8605Smrg   if (!sh)
804848b8605Smrg      return;
805848b8605Smrg
806848b8605Smrg   /* free old shader source string and install new one */
807848b8605Smrg   free((void *)sh->Source);
808848b8605Smrg   sh->Source = source;
809848b8605Smrg   sh->CompileStatus = GL_FALSE;
810848b8605Smrg#ifdef DEBUG
811848b8605Smrg   sh->SourceChecksum = _mesa_str_checksum(sh->Source);
812848b8605Smrg#endif
813848b8605Smrg}
814848b8605Smrg
815848b8605Smrg
816848b8605Smrg/**
817848b8605Smrg * Compile a shader.
818848b8605Smrg */
819848b8605Smrgstatic void
820848b8605Smrgcompile_shader(struct gl_context *ctx, GLuint shaderObj)
821848b8605Smrg{
822848b8605Smrg   struct gl_shader *sh;
823848b8605Smrg   struct gl_shader_compiler_options *options;
824848b8605Smrg
825848b8605Smrg   sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
826848b8605Smrg   if (!sh)
827848b8605Smrg      return;
828848b8605Smrg
829848b8605Smrg   options = &ctx->Const.ShaderCompilerOptions[sh->Stage];
830848b8605Smrg
831848b8605Smrg   /* set default pragma state for shader */
832848b8605Smrg   sh->Pragmas = options->DefaultPragmas;
833848b8605Smrg
834848b8605Smrg   if (!sh->Source) {
835848b8605Smrg      /* If the user called glCompileShader without first calling
836848b8605Smrg       * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
837848b8605Smrg       */
838848b8605Smrg      sh->CompileStatus = GL_FALSE;
839848b8605Smrg   } else {
840848b8605Smrg      if (ctx->_Shader->Flags & GLSL_DUMP) {
841848b8605Smrg         fprintf(stderr, "GLSL source for %s shader %d:\n",
842848b8605Smrg                 _mesa_shader_stage_to_string(sh->Stage), sh->Name);
843848b8605Smrg         fprintf(stderr, "%s\n", sh->Source);
844848b8605Smrg         fflush(stderr);
845848b8605Smrg      }
846848b8605Smrg
847848b8605Smrg      /* this call will set the shader->CompileStatus field to indicate if
848848b8605Smrg       * compilation was successful.
849848b8605Smrg       */
850848b8605Smrg      _mesa_glsl_compile_shader(ctx, sh, false, false);
851848b8605Smrg
852848b8605Smrg      if (ctx->_Shader->Flags & GLSL_LOG) {
853848b8605Smrg         _mesa_write_shader_to_file(sh);
854848b8605Smrg      }
855848b8605Smrg
856848b8605Smrg      if (ctx->_Shader->Flags & GLSL_DUMP) {
857848b8605Smrg         if (sh->CompileStatus) {
858848b8605Smrg            fprintf(stderr, "GLSL IR for shader %d:\n", sh->Name);
859848b8605Smrg            _mesa_print_ir(stderr, sh->ir, NULL);
860848b8605Smrg            fprintf(stderr, "\n\n");
861848b8605Smrg         } else {
862848b8605Smrg            fprintf(stderr, "GLSL shader %d failed to compile.\n", sh->Name);
863848b8605Smrg         }
864848b8605Smrg         if (sh->InfoLog && sh->InfoLog[0] != 0) {
865848b8605Smrg            fprintf(stderr, "GLSL shader %d info log:\n", sh->Name);
866848b8605Smrg            fprintf(stderr, "%s\n", sh->InfoLog);
867848b8605Smrg         }
868848b8605Smrg         fflush(stderr);
869848b8605Smrg      }
870848b8605Smrg
871848b8605Smrg   }
872848b8605Smrg
873848b8605Smrg   if (!sh->CompileStatus) {
874848b8605Smrg      if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) {
875848b8605Smrg         fprintf(stderr, "GLSL source for %s shader %d:\n",
876848b8605Smrg                 _mesa_shader_stage_to_string(sh->Stage), sh->Name);
877848b8605Smrg         fprintf(stderr, "%s\n", sh->Source);
878848b8605Smrg         fprintf(stderr, "Info Log:\n%s\n", sh->InfoLog);
879848b8605Smrg         fflush(stderr);
880848b8605Smrg      }
881848b8605Smrg
882848b8605Smrg      if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) {
883848b8605Smrg         _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
884848b8605Smrg                     sh->Name, sh->InfoLog);
885848b8605Smrg      }
886848b8605Smrg   }
887848b8605Smrg}
888848b8605Smrg
889848b8605Smrg
890848b8605Smrg/**
891848b8605Smrg * Link a program's shaders.
892848b8605Smrg */
893848b8605Smrgstatic void
894848b8605Smrglink_program(struct gl_context *ctx, GLuint program)
895848b8605Smrg{
896848b8605Smrg   struct gl_shader_program *shProg;
897848b8605Smrg
898848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
899848b8605Smrg   if (!shProg)
900848b8605Smrg      return;
901848b8605Smrg
902848b8605Smrg   /* From the ARB_transform_feedback2 specification:
903848b8605Smrg    * "The error INVALID_OPERATION is generated by LinkProgram if <program> is
904848b8605Smrg    *  the name of a program being used by one or more transform feedback
905848b8605Smrg    *  objects, even if the objects are not currently bound or are paused."
906848b8605Smrg    */
907848b8605Smrg   if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
908848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
909848b8605Smrg                  "glLinkProgram(transform feedback is using the program)");
910848b8605Smrg      return;
911848b8605Smrg   }
912848b8605Smrg
913848b8605Smrg   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
914848b8605Smrg
915848b8605Smrg   _mesa_glsl_link_shader(ctx, shProg);
916848b8605Smrg
917848b8605Smrg   if (shProg->LinkStatus == GL_FALSE &&
918848b8605Smrg       (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
919848b8605Smrg      _mesa_debug(ctx, "Error linking program %u:\n%s\n",
920848b8605Smrg                  shProg->Name, shProg->InfoLog);
921848b8605Smrg   }
922848b8605Smrg
923848b8605Smrg   /* debug code */
924848b8605Smrg   if (0) {
925848b8605Smrg      GLuint i;
926848b8605Smrg
927848b8605Smrg      printf("Link %u shaders in program %u: %s\n",
928848b8605Smrg                   shProg->NumShaders, shProg->Name,
929848b8605Smrg                   shProg->LinkStatus ? "Success" : "Failed");
930848b8605Smrg
931848b8605Smrg      for (i = 0; i < shProg->NumShaders; i++) {
932848b8605Smrg         printf(" shader %u, type 0x%x\n",
933848b8605Smrg                      shProg->Shaders[i]->Name,
934848b8605Smrg                      shProg->Shaders[i]->Type);
935848b8605Smrg      }
936848b8605Smrg   }
937848b8605Smrg}
938848b8605Smrg
939848b8605Smrg
940848b8605Smrg/**
941848b8605Smrg * Print basic shader info (for debug).
942848b8605Smrg */
943848b8605Smrgstatic void
944848b8605Smrgprint_shader_info(const struct gl_shader_program *shProg)
945848b8605Smrg{
946848b8605Smrg   GLuint i;
947848b8605Smrg
948848b8605Smrg   printf("Mesa: glUseProgram(%u)\n", shProg->Name);
949848b8605Smrg   for (i = 0; i < shProg->NumShaders; i++) {
950848b8605Smrg      printf("  %s shader %u, checksum %u\n",
951848b8605Smrg             _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
952848b8605Smrg	     shProg->Shaders[i]->Name,
953848b8605Smrg	     shProg->Shaders[i]->SourceChecksum);
954848b8605Smrg   }
955848b8605Smrg   if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
956848b8605Smrg      printf("  vert prog %u\n",
957848b8605Smrg	     shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
958848b8605Smrg   if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
959848b8605Smrg      printf("  frag prog %u\n",
960848b8605Smrg	     shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
961848b8605Smrg   if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
962848b8605Smrg      printf("  geom prog %u\n",
963848b8605Smrg	     shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
964848b8605Smrg}
965848b8605Smrg
966848b8605Smrg
967848b8605Smrg/**
968848b8605Smrg * Use the named shader program for subsequent glUniform calls
969848b8605Smrg */
970848b8605Smrgvoid
971848b8605Smrg_mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
972848b8605Smrg		     const char *caller)
973848b8605Smrg{
974848b8605Smrg   if ((shProg != NULL) && !shProg->LinkStatus) {
975848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
976848b8605Smrg		  "%s(program %u not linked)", caller, shProg->Name);
977848b8605Smrg      return;
978848b8605Smrg   }
979848b8605Smrg
980848b8605Smrg   if (ctx->Shader.ActiveProgram != shProg) {
981848b8605Smrg      _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
982848b8605Smrg   }
983848b8605Smrg}
984848b8605Smrg
985848b8605Smrg/**
986848b8605Smrg */
987848b8605Smrgstatic void
988848b8605Smrguse_shader_program(struct gl_context *ctx, GLenum type,
989848b8605Smrg                   struct gl_shader_program *shProg,
990848b8605Smrg                   struct gl_pipeline_object *shTarget)
991848b8605Smrg{
992848b8605Smrg   struct gl_shader_program **target;
993848b8605Smrg   gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type);
994848b8605Smrg
995848b8605Smrg   target = &shTarget->CurrentProgram[stage];
996848b8605Smrg   if ((shProg == NULL) || (shProg->_LinkedShaders[stage] == NULL))
997848b8605Smrg      shProg = NULL;
998848b8605Smrg
999848b8605Smrg   if (*target != shProg) {
1000848b8605Smrg      /* Program is current, flush it */
1001848b8605Smrg      if (shTarget == ctx->_Shader) {
1002848b8605Smrg         FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1003848b8605Smrg      }
1004848b8605Smrg
1005848b8605Smrg      /* If the shader is also bound as the current rendering shader, unbind
1006848b8605Smrg       * it from that binding point as well.  This ensures that the correct
1007848b8605Smrg       * semantics of glDeleteProgram are maintained.
1008848b8605Smrg       */
1009848b8605Smrg      switch (type) {
1010848b8605Smrg      case GL_VERTEX_SHADER:
1011848b8605Smrg	 /* Empty for now. */
1012848b8605Smrg	 break;
1013848b8605Smrg      case GL_GEOMETRY_SHADER_ARB:
1014848b8605Smrg	 /* Empty for now. */
1015848b8605Smrg	 break;
1016848b8605Smrg      case GL_COMPUTE_SHADER:
1017848b8605Smrg         /* Empty for now. */
1018848b8605Smrg         break;
1019848b8605Smrg      case GL_FRAGMENT_SHADER:
1020848b8605Smrg         if (*target == ctx->_Shader->_CurrentFragmentProgram) {
1021848b8605Smrg	    _mesa_reference_shader_program(ctx,
1022848b8605Smrg                                           &ctx->_Shader->_CurrentFragmentProgram,
1023848b8605Smrg					   NULL);
1024848b8605Smrg	 }
1025848b8605Smrg	 break;
1026848b8605Smrg      }
1027848b8605Smrg
1028848b8605Smrg      _mesa_reference_shader_program(ctx, target, shProg);
1029848b8605Smrg      return;
1030848b8605Smrg   }
1031848b8605Smrg}
1032848b8605Smrg
1033848b8605Smrg/**
1034848b8605Smrg * Use the named shader program for subsequent rendering.
1035848b8605Smrg */
1036848b8605Smrgvoid
1037848b8605Smrg_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
1038848b8605Smrg{
1039848b8605Smrg   use_shader_program(ctx, GL_VERTEX_SHADER, shProg, &ctx->Shader);
1040848b8605Smrg   use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg, &ctx->Shader);
1041848b8605Smrg   use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg, &ctx->Shader);
1042848b8605Smrg   use_shader_program(ctx, GL_COMPUTE_SHADER, shProg, &ctx->Shader);
1043848b8605Smrg   _mesa_active_program(ctx, shProg, "glUseProgram");
1044848b8605Smrg
1045848b8605Smrg   if (ctx->Driver.UseProgram)
1046848b8605Smrg      ctx->Driver.UseProgram(ctx, shProg);
1047848b8605Smrg}
1048848b8605Smrg
1049848b8605Smrg
1050848b8605Smrg/**
1051848b8605Smrg * Do validation of the given shader program.
1052848b8605Smrg * \param errMsg  returns error message if validation fails.
1053848b8605Smrg * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
1054848b8605Smrg */
1055848b8605Smrgstatic GLboolean
1056848b8605Smrgvalidate_shader_program(const struct gl_shader_program *shProg,
1057848b8605Smrg                        char *errMsg)
1058848b8605Smrg{
1059848b8605Smrg   if (!shProg->LinkStatus) {
1060848b8605Smrg      return GL_FALSE;
1061848b8605Smrg   }
1062848b8605Smrg
1063848b8605Smrg   /* From the GL spec, a program is invalid if any of these are true:
1064848b8605Smrg
1065848b8605Smrg     any two active samplers in the current program object are of
1066848b8605Smrg     different types, but refer to the same texture image unit,
1067848b8605Smrg
1068848b8605Smrg     any active sampler in the current program object refers to a texture
1069848b8605Smrg     image unit where fixed-function fragment processing accesses a
1070848b8605Smrg     texture target that does not match the sampler type, or
1071848b8605Smrg
1072848b8605Smrg     the sum of the number of active samplers in the program and the
1073848b8605Smrg     number of texture image units enabled for fixed-function fragment
1074848b8605Smrg     processing exceeds the combined limit on the total number of texture
1075848b8605Smrg     image units allowed.
1076848b8605Smrg   */
1077848b8605Smrg
1078848b8605Smrg
1079848b8605Smrg   /*
1080848b8605Smrg    * Check: any two active samplers in the current program object are of
1081848b8605Smrg    * different types, but refer to the same texture image unit,
1082848b8605Smrg    */
1083848b8605Smrg   if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
1084848b8605Smrg      return GL_FALSE;
1085848b8605Smrg
1086848b8605Smrg   return GL_TRUE;
1087848b8605Smrg}
1088848b8605Smrg
1089848b8605Smrg
1090848b8605Smrg/**
1091848b8605Smrg * Called via glValidateProgram()
1092848b8605Smrg */
1093848b8605Smrgstatic void
1094848b8605Smrgvalidate_program(struct gl_context *ctx, GLuint program)
1095848b8605Smrg{
1096848b8605Smrg   struct gl_shader_program *shProg;
1097848b8605Smrg   char errMsg[100] = "";
1098848b8605Smrg
1099848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1100848b8605Smrg   if (!shProg) {
1101848b8605Smrg      return;
1102848b8605Smrg   }
1103848b8605Smrg
1104848b8605Smrg   shProg->Validated = validate_shader_program(shProg, errMsg);
1105848b8605Smrg   if (!shProg->Validated) {
1106848b8605Smrg      /* update info log */
1107848b8605Smrg      if (shProg->InfoLog) {
1108848b8605Smrg         ralloc_free(shProg->InfoLog);
1109848b8605Smrg      }
1110848b8605Smrg      shProg->InfoLog = ralloc_strdup(shProg, errMsg);
1111848b8605Smrg   }
1112848b8605Smrg}
1113848b8605Smrg
1114848b8605Smrg
1115848b8605Smrg
1116848b8605Smrgvoid GLAPIENTRY
1117848b8605Smrg_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1118848b8605Smrg{
1119848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1120848b8605Smrg   attach_shader(ctx, program, shader);
1121848b8605Smrg}
1122848b8605Smrg
1123848b8605Smrg
1124848b8605Smrgvoid GLAPIENTRY
1125848b8605Smrg_mesa_AttachShader(GLuint program, GLuint shader)
1126848b8605Smrg{
1127848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1128848b8605Smrg   attach_shader(ctx, program, shader);
1129848b8605Smrg}
1130848b8605Smrg
1131848b8605Smrg
1132848b8605Smrgvoid GLAPIENTRY
1133848b8605Smrg_mesa_CompileShader(GLhandleARB shaderObj)
1134848b8605Smrg{
1135848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1136848b8605Smrg   if (MESA_VERBOSE & VERBOSE_API)
1137848b8605Smrg      _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
1138848b8605Smrg   compile_shader(ctx, shaderObj);
1139848b8605Smrg}
1140848b8605Smrg
1141848b8605Smrg
1142848b8605SmrgGLuint GLAPIENTRY
1143848b8605Smrg_mesa_CreateShader(GLenum type)
1144848b8605Smrg{
1145848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1146848b8605Smrg   if (MESA_VERBOSE & VERBOSE_API)
1147848b8605Smrg      _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type));
1148848b8605Smrg   return create_shader(ctx, type);
1149848b8605Smrg}
1150848b8605Smrg
1151848b8605Smrg
1152848b8605SmrgGLhandleARB GLAPIENTRY
1153848b8605Smrg_mesa_CreateShaderObjectARB(GLenum type)
1154848b8605Smrg{
1155848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1156848b8605Smrg   return create_shader(ctx, type);
1157848b8605Smrg}
1158848b8605Smrg
1159848b8605Smrg
1160848b8605SmrgGLuint GLAPIENTRY
1161848b8605Smrg_mesa_CreateProgram(void)
1162848b8605Smrg{
1163848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1164848b8605Smrg   if (MESA_VERBOSE & VERBOSE_API)
1165848b8605Smrg      _mesa_debug(ctx, "glCreateProgram\n");
1166848b8605Smrg   return create_shader_program(ctx);
1167848b8605Smrg}
1168848b8605Smrg
1169848b8605Smrg
1170848b8605SmrgGLhandleARB GLAPIENTRY
1171848b8605Smrg_mesa_CreateProgramObjectARB(void)
1172848b8605Smrg{
1173848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1174848b8605Smrg   return create_shader_program(ctx);
1175848b8605Smrg}
1176848b8605Smrg
1177848b8605Smrg
1178848b8605Smrgvoid GLAPIENTRY
1179848b8605Smrg_mesa_DeleteObjectARB(GLhandleARB obj)
1180848b8605Smrg{
1181848b8605Smrg   if (MESA_VERBOSE & VERBOSE_API) {
1182848b8605Smrg      GET_CURRENT_CONTEXT(ctx);
1183848b8605Smrg      _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj);
1184848b8605Smrg   }
1185848b8605Smrg
1186848b8605Smrg   if (obj) {
1187848b8605Smrg      GET_CURRENT_CONTEXT(ctx);
1188848b8605Smrg      FLUSH_VERTICES(ctx, 0);
1189848b8605Smrg      if (is_program(ctx, obj)) {
1190848b8605Smrg         delete_shader_program(ctx, obj);
1191848b8605Smrg      }
1192848b8605Smrg      else if (is_shader(ctx, obj)) {
1193848b8605Smrg         delete_shader(ctx, obj);
1194848b8605Smrg      }
1195848b8605Smrg      else {
1196848b8605Smrg         /* error? */
1197848b8605Smrg      }
1198848b8605Smrg   }
1199848b8605Smrg}
1200848b8605Smrg
1201848b8605Smrg
1202848b8605Smrgvoid GLAPIENTRY
1203848b8605Smrg_mesa_DeleteProgram(GLuint name)
1204848b8605Smrg{
1205848b8605Smrg   if (name) {
1206848b8605Smrg      GET_CURRENT_CONTEXT(ctx);
1207848b8605Smrg      FLUSH_VERTICES(ctx, 0);
1208848b8605Smrg      delete_shader_program(ctx, name);
1209848b8605Smrg   }
1210848b8605Smrg}
1211848b8605Smrg
1212848b8605Smrg
1213848b8605Smrgvoid GLAPIENTRY
1214848b8605Smrg_mesa_DeleteShader(GLuint name)
1215848b8605Smrg{
1216848b8605Smrg   if (name) {
1217848b8605Smrg      GET_CURRENT_CONTEXT(ctx);
1218848b8605Smrg      FLUSH_VERTICES(ctx, 0);
1219848b8605Smrg      delete_shader(ctx, name);
1220848b8605Smrg   }
1221848b8605Smrg}
1222848b8605Smrg
1223848b8605Smrg
1224848b8605Smrgvoid GLAPIENTRY
1225848b8605Smrg_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1226848b8605Smrg{
1227848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1228848b8605Smrg   detach_shader(ctx, program, shader);
1229848b8605Smrg}
1230848b8605Smrg
1231848b8605Smrg
1232848b8605Smrgvoid GLAPIENTRY
1233848b8605Smrg_mesa_DetachShader(GLuint program, GLuint shader)
1234848b8605Smrg{
1235848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1236848b8605Smrg   detach_shader(ctx, program, shader);
1237848b8605Smrg}
1238848b8605Smrg
1239848b8605Smrg
1240848b8605Smrgvoid GLAPIENTRY
1241848b8605Smrg_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1242848b8605Smrg                            GLsizei * count, GLhandleARB * obj)
1243848b8605Smrg{
1244848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1245848b8605Smrg   get_attached_shaders(ctx, container, maxCount, count, obj);
1246848b8605Smrg}
1247848b8605Smrg
1248848b8605Smrg
1249848b8605Smrgvoid GLAPIENTRY
1250848b8605Smrg_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1251848b8605Smrg                         GLsizei *count, GLuint *obj)
1252848b8605Smrg{
1253848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1254848b8605Smrg   get_attached_shaders(ctx, program, maxCount, count, obj);
1255848b8605Smrg}
1256848b8605Smrg
1257848b8605Smrg
1258848b8605Smrgvoid GLAPIENTRY
1259848b8605Smrg_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1260848b8605Smrg                    GLcharARB * infoLog)
1261848b8605Smrg{
1262848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1263848b8605Smrg   if (is_program(ctx, object)) {
1264848b8605Smrg      get_program_info_log(ctx, object, maxLength, length, infoLog);
1265848b8605Smrg   }
1266848b8605Smrg   else if (is_shader(ctx, object)) {
1267848b8605Smrg      get_shader_info_log(ctx, object, maxLength, length, infoLog);
1268848b8605Smrg   }
1269848b8605Smrg   else {
1270848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1271848b8605Smrg   }
1272848b8605Smrg}
1273848b8605Smrg
1274848b8605Smrg
1275848b8605Smrgvoid GLAPIENTRY
1276848b8605Smrg_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1277848b8605Smrg{
1278848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1279848b8605Smrg   /* Implement in terms of GetProgramiv, GetShaderiv */
1280848b8605Smrg   if (is_program(ctx, object)) {
1281848b8605Smrg      if (pname == GL_OBJECT_TYPE_ARB) {
1282848b8605Smrg	 *params = GL_PROGRAM_OBJECT_ARB;
1283848b8605Smrg      }
1284848b8605Smrg      else {
1285848b8605Smrg	 get_programiv(ctx, object, pname, params);
1286848b8605Smrg      }
1287848b8605Smrg   }
1288848b8605Smrg   else if (is_shader(ctx, object)) {
1289848b8605Smrg      if (pname == GL_OBJECT_TYPE_ARB) {
1290848b8605Smrg	 *params = GL_SHADER_OBJECT_ARB;
1291848b8605Smrg      }
1292848b8605Smrg      else {
1293848b8605Smrg	 get_shaderiv(ctx, object, pname, params);
1294848b8605Smrg      }
1295848b8605Smrg   }
1296848b8605Smrg   else {
1297848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1298848b8605Smrg   }
1299848b8605Smrg}
1300848b8605Smrg
1301848b8605Smrg
1302848b8605Smrgvoid GLAPIENTRY
1303848b8605Smrg_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1304848b8605Smrg                              GLfloat *params)
1305848b8605Smrg{
1306848b8605Smrg   GLint iparams[1];  /* XXX is one element enough? */
1307848b8605Smrg   _mesa_GetObjectParameterivARB(object, pname, iparams);
1308848b8605Smrg   params[0] = (GLfloat) iparams[0];
1309848b8605Smrg}
1310848b8605Smrg
1311848b8605Smrg
1312848b8605Smrgvoid GLAPIENTRY
1313848b8605Smrg_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1314848b8605Smrg{
1315848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1316848b8605Smrg   get_programiv(ctx, program, pname, params);
1317848b8605Smrg}
1318848b8605Smrg
1319848b8605Smrg
1320848b8605Smrgvoid GLAPIENTRY
1321848b8605Smrg_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1322848b8605Smrg{
1323848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1324848b8605Smrg   get_shaderiv(ctx, shader, pname, params);
1325848b8605Smrg}
1326848b8605Smrg
1327848b8605Smrg
1328848b8605Smrgvoid GLAPIENTRY
1329848b8605Smrg_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1330848b8605Smrg                        GLsizei *length, GLchar *infoLog)
1331848b8605Smrg{
1332848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1333848b8605Smrg   get_program_info_log(ctx, program, bufSize, length, infoLog);
1334848b8605Smrg}
1335848b8605Smrg
1336848b8605Smrg
1337848b8605Smrgvoid GLAPIENTRY
1338848b8605Smrg_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1339848b8605Smrg                       GLsizei *length, GLchar *infoLog)
1340848b8605Smrg{
1341848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1342848b8605Smrg   get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1343848b8605Smrg}
1344848b8605Smrg
1345848b8605Smrg
1346848b8605Smrgvoid GLAPIENTRY
1347848b8605Smrg_mesa_GetShaderSource(GLhandleARB shader, GLsizei maxLength,
1348848b8605Smrg                         GLsizei *length, GLcharARB *sourceOut)
1349848b8605Smrg{
1350848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1351848b8605Smrg   get_shader_source(ctx, shader, maxLength, length, sourceOut);
1352848b8605Smrg}
1353848b8605Smrg
1354848b8605Smrg
1355848b8605SmrgGLhandleARB GLAPIENTRY
1356848b8605Smrg_mesa_GetHandleARB(GLenum pname)
1357848b8605Smrg{
1358848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1359848b8605Smrg   return get_handle(ctx, pname);
1360848b8605Smrg}
1361848b8605Smrg
1362848b8605Smrg
1363848b8605SmrgGLboolean GLAPIENTRY
1364848b8605Smrg_mesa_IsProgram(GLuint name)
1365848b8605Smrg{
1366848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1367848b8605Smrg   return is_program(ctx, name);
1368848b8605Smrg}
1369848b8605Smrg
1370848b8605Smrg
1371848b8605SmrgGLboolean GLAPIENTRY
1372848b8605Smrg_mesa_IsShader(GLuint name)
1373848b8605Smrg{
1374848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1375848b8605Smrg   return is_shader(ctx, name);
1376848b8605Smrg}
1377848b8605Smrg
1378848b8605Smrg
1379848b8605Smrgvoid GLAPIENTRY
1380848b8605Smrg_mesa_LinkProgram(GLhandleARB programObj)
1381848b8605Smrg{
1382848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1383848b8605Smrg   link_program(ctx, programObj);
1384848b8605Smrg}
1385848b8605Smrg
1386848b8605Smrg
1387848b8605Smrg
1388848b8605Smrg/**
1389848b8605Smrg * Read shader source code from a file.
1390848b8605Smrg * Useful for debugging to override an app's shader.
1391848b8605Smrg */
1392848b8605Smrgstatic GLcharARB *
1393848b8605Smrgread_shader(const char *fname)
1394848b8605Smrg{
1395848b8605Smrg   int shader_size = 0;
1396848b8605Smrg   FILE *f = fopen(fname, "r");
1397848b8605Smrg   GLcharARB *buffer, *shader;
1398848b8605Smrg   int len;
1399848b8605Smrg
1400848b8605Smrg   if (!f) {
1401848b8605Smrg      return NULL;
1402848b8605Smrg   }
1403848b8605Smrg
1404848b8605Smrg   /* allocate enough room for the entire shader */
1405848b8605Smrg   fseek(f, 0, SEEK_END);
1406848b8605Smrg   shader_size = ftell(f);
1407848b8605Smrg   rewind(f);
1408848b8605Smrg   assert(shader_size);
1409848b8605Smrg
1410848b8605Smrg   /* add one for terminating zero */
1411848b8605Smrg   shader_size++;
1412848b8605Smrg
1413848b8605Smrg   buffer = malloc(shader_size);
1414848b8605Smrg   assert(buffer);
1415848b8605Smrg
1416848b8605Smrg   len = fread(buffer, 1, shader_size, f);
1417848b8605Smrg   buffer[len] = 0;
1418848b8605Smrg
1419848b8605Smrg   fclose(f);
1420848b8605Smrg
1421848b8605Smrg   shader = _mesa_strdup(buffer);
1422848b8605Smrg   free(buffer);
1423848b8605Smrg
1424848b8605Smrg   return shader;
1425848b8605Smrg}
1426848b8605Smrg
1427848b8605Smrg
1428848b8605Smrg/**
1429848b8605Smrg * Called via glShaderSource() and glShaderSourceARB() API functions.
1430848b8605Smrg * Basically, concatenate the source code strings into one long string
1431848b8605Smrg * and pass it to _mesa_shader_source().
1432848b8605Smrg */
1433848b8605Smrgvoid GLAPIENTRY
1434848b8605Smrg_mesa_ShaderSource(GLhandleARB shaderObj, GLsizei count,
1435848b8605Smrg                      const GLcharARB * const * string, const GLint * length)
1436848b8605Smrg{
1437848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1438848b8605Smrg   GLint *offsets;
1439848b8605Smrg   GLsizei i, totalLength;
1440848b8605Smrg   GLcharARB *source;
1441848b8605Smrg   GLuint checksum;
1442848b8605Smrg
1443848b8605Smrg   if (!shaderObj || string == NULL) {
1444848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
1445848b8605Smrg      return;
1446848b8605Smrg   }
1447848b8605Smrg
1448848b8605Smrg   /*
1449848b8605Smrg    * This array holds offsets of where the appropriate string ends, thus the
1450848b8605Smrg    * last element will be set to the total length of the source code.
1451848b8605Smrg    */
1452848b8605Smrg   offsets = malloc(count * sizeof(GLint));
1453848b8605Smrg   if (offsets == NULL) {
1454848b8605Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1455848b8605Smrg      return;
1456848b8605Smrg   }
1457848b8605Smrg
1458848b8605Smrg   for (i = 0; i < count; i++) {
1459848b8605Smrg      if (string[i] == NULL) {
1460848b8605Smrg         free((GLvoid *) offsets);
1461848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
1462848b8605Smrg                     "glShaderSourceARB(null string)");
1463848b8605Smrg         return;
1464848b8605Smrg      }
1465848b8605Smrg      if (length == NULL || length[i] < 0)
1466848b8605Smrg         offsets[i] = strlen(string[i]);
1467848b8605Smrg      else
1468848b8605Smrg         offsets[i] = length[i];
1469848b8605Smrg      /* accumulate string lengths */
1470848b8605Smrg      if (i > 0)
1471848b8605Smrg         offsets[i] += offsets[i - 1];
1472848b8605Smrg   }
1473848b8605Smrg
1474848b8605Smrg   /* Total length of source string is sum off all strings plus two.
1475848b8605Smrg    * One extra byte for terminating zero, another extra byte to silence
1476848b8605Smrg    * valgrind warnings in the parser/grammer code.
1477848b8605Smrg    */
1478848b8605Smrg   totalLength = offsets[count - 1] + 2;
1479848b8605Smrg   source = malloc(totalLength * sizeof(GLcharARB));
1480848b8605Smrg   if (source == NULL) {
1481848b8605Smrg      free((GLvoid *) offsets);
1482848b8605Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1483848b8605Smrg      return;
1484848b8605Smrg   }
1485848b8605Smrg
1486848b8605Smrg   for (i = 0; i < count; i++) {
1487848b8605Smrg      GLint start = (i > 0) ? offsets[i - 1] : 0;
1488848b8605Smrg      memcpy(source + start, string[i],
1489848b8605Smrg             (offsets[i] - start) * sizeof(GLcharARB));
1490848b8605Smrg   }
1491848b8605Smrg   source[totalLength - 1] = '\0';
1492848b8605Smrg   source[totalLength - 2] = '\0';
1493848b8605Smrg
1494848b8605Smrg   if (SHADER_SUBST) {
1495848b8605Smrg      /* Compute the shader's source code checksum then try to open a file
1496848b8605Smrg       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
1497848b8605Smrg       * original shader source code.  For debugging.
1498848b8605Smrg       */
1499848b8605Smrg      char filename[100];
1500848b8605Smrg      GLcharARB *newSource;
1501848b8605Smrg
1502848b8605Smrg      checksum = _mesa_str_checksum(source);
1503848b8605Smrg
1504848b8605Smrg      _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
1505848b8605Smrg
1506848b8605Smrg      newSource = read_shader(filename);
1507848b8605Smrg      if (newSource) {
1508848b8605Smrg         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
1509848b8605Smrg                       shaderObj, checksum, filename);
1510848b8605Smrg         free(source);
1511848b8605Smrg         source = newSource;
1512848b8605Smrg      }
1513848b8605Smrg   }
1514848b8605Smrg
1515848b8605Smrg   shader_source(ctx, shaderObj, source);
1516848b8605Smrg
1517848b8605Smrg   if (SHADER_SUBST) {
1518848b8605Smrg      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
1519848b8605Smrg      if (sh)
1520848b8605Smrg         sh->SourceChecksum = checksum; /* save original checksum */
1521848b8605Smrg   }
1522848b8605Smrg
1523848b8605Smrg   free(offsets);
1524848b8605Smrg}
1525848b8605Smrg
1526848b8605Smrg
1527848b8605Smrgvoid GLAPIENTRY
1528848b8605Smrg_mesa_UseProgram(GLhandleARB program)
1529848b8605Smrg{
1530848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1531848b8605Smrg   struct gl_shader_program *shProg;
1532848b8605Smrg
1533848b8605Smrg   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1534848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
1535848b8605Smrg                  "glUseProgram(transform feedback active)");
1536848b8605Smrg      return;
1537848b8605Smrg   }
1538848b8605Smrg
1539848b8605Smrg   if (program) {
1540848b8605Smrg      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1541848b8605Smrg      if (!shProg) {
1542848b8605Smrg         return;
1543848b8605Smrg      }
1544848b8605Smrg      if (!shProg->LinkStatus) {
1545848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
1546848b8605Smrg                     "glUseProgram(program %u not linked)", program);
1547848b8605Smrg         return;
1548848b8605Smrg      }
1549848b8605Smrg
1550848b8605Smrg      /* debug code */
1551848b8605Smrg      if (ctx->_Shader->Flags & GLSL_USE_PROG) {
1552848b8605Smrg         print_shader_info(shProg);
1553848b8605Smrg      }
1554848b8605Smrg   }
1555848b8605Smrg   else {
1556848b8605Smrg      shProg = NULL;
1557848b8605Smrg   }
1558848b8605Smrg
1559848b8605Smrg   /* The ARB_separate_shader_object spec says:
1560848b8605Smrg    *
1561848b8605Smrg    *     "The executable code for an individual shader stage is taken from
1562848b8605Smrg    *     the current program for that stage.  If there is a current program
1563848b8605Smrg    *     object established by UseProgram, that program is considered current
1564848b8605Smrg    *     for all stages.  Otherwise, if there is a bound program pipeline
1565848b8605Smrg    *     object (section 2.14.PPO), the program bound to the appropriate
1566848b8605Smrg    *     stage of the pipeline object is considered current."
1567848b8605Smrg    */
1568848b8605Smrg   if (program) {
1569848b8605Smrg      /* Attach shader state to the binding point */
1570848b8605Smrg      _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
1571848b8605Smrg      /* Update the program */
1572848b8605Smrg      _mesa_use_program(ctx, shProg);
1573848b8605Smrg   } else {
1574848b8605Smrg      /* Must be done first: detach the progam */
1575848b8605Smrg      _mesa_use_program(ctx, shProg);
1576848b8605Smrg      /* Unattach shader_state binding point */
1577848b8605Smrg      _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
1578848b8605Smrg      /* If a pipeline was bound, rebind it */
1579848b8605Smrg      if (ctx->Pipeline.Current) {
1580848b8605Smrg         _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
1581848b8605Smrg      }
1582848b8605Smrg   }
1583848b8605Smrg}
1584848b8605Smrg
1585848b8605Smrg
1586848b8605Smrgvoid GLAPIENTRY
1587848b8605Smrg_mesa_ValidateProgram(GLhandleARB program)
1588848b8605Smrg{
1589848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1590848b8605Smrg   validate_program(ctx, program);
1591848b8605Smrg}
1592848b8605Smrg
1593848b8605Smrg
1594848b8605Smrg/**
1595848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1596848b8605Smrg */
1597848b8605Smrgvoid GLAPIENTRY
1598848b8605Smrg_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1599848b8605Smrg                               GLint* range, GLint* precision)
1600848b8605Smrg{
1601848b8605Smrg   const struct gl_program_constants *limits;
1602848b8605Smrg   const struct gl_precision *p;
1603848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1604848b8605Smrg
1605848b8605Smrg   switch (shadertype) {
1606848b8605Smrg   case GL_VERTEX_SHADER:
1607848b8605Smrg      limits = &ctx->Const.Program[MESA_SHADER_VERTEX];
1608848b8605Smrg      break;
1609848b8605Smrg   case GL_FRAGMENT_SHADER:
1610848b8605Smrg      limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT];
1611848b8605Smrg      break;
1612848b8605Smrg   default:
1613848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM,
1614848b8605Smrg                  "glGetShaderPrecisionFormat(shadertype)");
1615848b8605Smrg      return;
1616848b8605Smrg   }
1617848b8605Smrg
1618848b8605Smrg   switch (precisiontype) {
1619848b8605Smrg   case GL_LOW_FLOAT:
1620848b8605Smrg      p = &limits->LowFloat;
1621848b8605Smrg      break;
1622848b8605Smrg   case GL_MEDIUM_FLOAT:
1623848b8605Smrg      p = &limits->MediumFloat;
1624848b8605Smrg      break;
1625848b8605Smrg   case GL_HIGH_FLOAT:
1626848b8605Smrg      p = &limits->HighFloat;
1627848b8605Smrg      break;
1628848b8605Smrg   case GL_LOW_INT:
1629848b8605Smrg      p = &limits->LowInt;
1630848b8605Smrg      break;
1631848b8605Smrg   case GL_MEDIUM_INT:
1632848b8605Smrg      p = &limits->MediumInt;
1633848b8605Smrg      break;
1634848b8605Smrg   case GL_HIGH_INT:
1635848b8605Smrg      p = &limits->HighInt;
1636848b8605Smrg      break;
1637848b8605Smrg   default:
1638848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM,
1639848b8605Smrg                  "glGetShaderPrecisionFormat(precisiontype)");
1640848b8605Smrg      return;
1641848b8605Smrg   }
1642848b8605Smrg
1643848b8605Smrg   range[0] = p->RangeMin;
1644848b8605Smrg   range[1] = p->RangeMax;
1645848b8605Smrg   precision[0] = p->Precision;
1646848b8605Smrg}
1647848b8605Smrg
1648848b8605Smrg
1649848b8605Smrg/**
1650848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1651848b8605Smrg */
1652848b8605Smrgvoid GLAPIENTRY
1653848b8605Smrg_mesa_ReleaseShaderCompiler(void)
1654848b8605Smrg{
1655848b8605Smrg   _mesa_destroy_shader_compiler_caches();
1656848b8605Smrg}
1657848b8605Smrg
1658848b8605Smrg
1659848b8605Smrg/**
1660848b8605Smrg * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1661848b8605Smrg */
1662848b8605Smrgvoid GLAPIENTRY
1663848b8605Smrg_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1664848b8605Smrg                   const void* binary, GLint length)
1665848b8605Smrg{
1666848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1667848b8605Smrg   (void) n;
1668848b8605Smrg   (void) shaders;
1669848b8605Smrg   (void) binaryformat;
1670848b8605Smrg   (void) binary;
1671848b8605Smrg   (void) length;
1672848b8605Smrg   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1673848b8605Smrg}
1674848b8605Smrg
1675848b8605Smrg
1676848b8605Smrgvoid GLAPIENTRY
1677848b8605Smrg_mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
1678848b8605Smrg                       GLenum *binaryFormat, GLvoid *binary)
1679848b8605Smrg{
1680848b8605Smrg   struct gl_shader_program *shProg;
1681848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1682848b8605Smrg
1683848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
1684848b8605Smrg   if (!shProg)
1685848b8605Smrg      return;
1686848b8605Smrg
1687848b8605Smrg   if (!shProg->LinkStatus) {
1688848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
1689848b8605Smrg                  "glGetProgramBinary(program %u not linked)",
1690848b8605Smrg                  shProg->Name);
1691848b8605Smrg      return;
1692848b8605Smrg   }
1693848b8605Smrg
1694848b8605Smrg   if (bufSize < 0){
1695848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
1696848b8605Smrg      return;
1697848b8605Smrg   }
1698848b8605Smrg
1699848b8605Smrg   /* The ARB_get_program_binary spec says:
1700848b8605Smrg    *
1701848b8605Smrg    *     "If <length> is NULL, then no length is returned."
1702848b8605Smrg    */
1703848b8605Smrg   if (length != NULL)
1704848b8605Smrg      *length = 0;
1705848b8605Smrg
1706848b8605Smrg   (void) binaryFormat;
1707848b8605Smrg   (void) binary;
1708848b8605Smrg}
1709848b8605Smrg
1710848b8605Smrgvoid GLAPIENTRY
1711848b8605Smrg_mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
1712848b8605Smrg                    const GLvoid *binary, GLsizei length)
1713848b8605Smrg{
1714848b8605Smrg   struct gl_shader_program *shProg;
1715848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1716848b8605Smrg
1717848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary");
1718848b8605Smrg   if (!shProg)
1719848b8605Smrg      return;
1720848b8605Smrg
1721848b8605Smrg   (void) binaryFormat;
1722848b8605Smrg   (void) binary;
1723848b8605Smrg   (void) length;
1724848b8605Smrg   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1725848b8605Smrg}
1726848b8605Smrg
1727848b8605Smrg
1728848b8605Smrgvoid GLAPIENTRY
1729848b8605Smrg_mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
1730848b8605Smrg{
1731848b8605Smrg   struct gl_shader_program *shProg;
1732848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1733848b8605Smrg
1734848b8605Smrg   shProg = _mesa_lookup_shader_program_err(ctx, program,
1735848b8605Smrg                                            "glProgramParameteri");
1736848b8605Smrg   if (!shProg)
1737848b8605Smrg      return;
1738848b8605Smrg
1739848b8605Smrg   switch (pname) {
1740848b8605Smrg   case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1741848b8605Smrg      /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
1742848b8605Smrg       * is part of OpenGL ES 3.0.  For the ES2 case, this function shouldn't
1743848b8605Smrg       * even be in the dispatch table, so we shouldn't need to expclicitly
1744848b8605Smrg       * check here.
1745848b8605Smrg       *
1746848b8605Smrg       * On desktop, we ignore the 3.0+ requirement because it is silly.
1747848b8605Smrg       */
1748848b8605Smrg
1749848b8605Smrg      /* The ARB_get_program_binary extension spec says:
1750848b8605Smrg       *
1751848b8605Smrg       *     "An INVALID_VALUE error is generated if the <value> argument to
1752848b8605Smrg       *     ProgramParameteri is not TRUE or FALSE."
1753848b8605Smrg       */
1754848b8605Smrg      if (value != GL_TRUE && value != GL_FALSE) {
1755848b8605Smrg         _mesa_error(ctx, GL_INVALID_VALUE,
1756848b8605Smrg                     "glProgramParameteri(pname=%s, value=%d): "
1757848b8605Smrg                     "value must be 0 or 1.",
1758848b8605Smrg                     _mesa_lookup_enum_by_nr(pname),
1759848b8605Smrg                     value);
1760848b8605Smrg         return;
1761848b8605Smrg      }
1762848b8605Smrg
1763848b8605Smrg      /* No need to notify the driver.  Any changes will actually take effect
1764848b8605Smrg       * the next time the shader is linked.
1765848b8605Smrg       *
1766848b8605Smrg       * The ARB_get_program_binary extension spec says:
1767848b8605Smrg       *
1768848b8605Smrg       *     "To indicate that a program binary is likely to be retrieved,
1769848b8605Smrg       *     ProgramParameteri should be called with <pname>
1770848b8605Smrg       *     PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
1771848b8605Smrg       *     will not be in effect until the next time LinkProgram or
1772848b8605Smrg       *     ProgramBinary has been called successfully."
1773848b8605Smrg       *
1774848b8605Smrg       * The resloution of issue 9 in the extension spec also says:
1775848b8605Smrg       *
1776848b8605Smrg       *     "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
1777848b8605Smrg       *     to indicate to the GL implementation that this program will
1778848b8605Smrg       *     likely be saved with GetProgramBinary at some point. This will
1779848b8605Smrg       *     give the GL implementation the opportunity to track any state
1780848b8605Smrg       *     changes made to the program before being saved such that when it
1781848b8605Smrg       *     is loaded again a recompile can be avoided."
1782848b8605Smrg       */
1783848b8605Smrg      shProg->BinaryRetreivableHint = value;
1784848b8605Smrg      return;
1785848b8605Smrg
1786848b8605Smrg   case GL_PROGRAM_SEPARABLE:
1787848b8605Smrg      /* Spec imply that the behavior is the same as ARB_get_program_binary
1788848b8605Smrg       * Chapter 7.3 Program Objects
1789848b8605Smrg       */
1790848b8605Smrg      if (value != GL_TRUE && value != GL_FALSE) {
1791848b8605Smrg         _mesa_error(ctx, GL_INVALID_VALUE,
1792848b8605Smrg                     "glProgramParameteri(pname=%s, value=%d): "
1793848b8605Smrg                     "value must be 0 or 1.",
1794848b8605Smrg                     _mesa_lookup_enum_by_nr(pname),
1795848b8605Smrg                     value);
1796848b8605Smrg         return;
1797848b8605Smrg      }
1798848b8605Smrg      shProg->SeparateShader = value;
1799848b8605Smrg      return;
1800848b8605Smrg
1801848b8605Smrg   default:
1802848b8605Smrg      break;
1803848b8605Smrg   }
1804848b8605Smrg
1805848b8605Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
1806848b8605Smrg               _mesa_lookup_enum_by_nr(pname));
1807848b8605Smrg}
1808848b8605Smrg
1809848b8605Smrgvoid
1810848b8605Smrg_mesa_use_shader_program(struct gl_context *ctx, GLenum type,
1811848b8605Smrg                         struct gl_shader_program *shProg,
1812848b8605Smrg                         struct gl_pipeline_object *shTarget)
1813848b8605Smrg{
1814848b8605Smrg   use_shader_program(ctx, type, shProg, shTarget);
1815848b8605Smrg
1816848b8605Smrg   if (ctx->Driver.UseProgram)
1817848b8605Smrg      ctx->Driver.UseProgram(ctx, shProg);
1818848b8605Smrg}
1819848b8605Smrg
1820848b8605Smrg
1821848b8605Smrgstatic GLuint
1822848b8605Smrg_mesa_create_shader_program(struct gl_context* ctx, GLboolean separate,
1823848b8605Smrg                            GLenum type, GLsizei count, const GLchar* const *strings)
1824848b8605Smrg{
1825848b8605Smrg   const GLuint shader = create_shader(ctx, type);
1826848b8605Smrg   GLuint program = 0;
1827848b8605Smrg
1828848b8605Smrg   if (shader) {
1829848b8605Smrg      _mesa_ShaderSource(shader, count, strings, NULL);
1830848b8605Smrg
1831848b8605Smrg      compile_shader(ctx, shader);
1832848b8605Smrg
1833848b8605Smrg      program = create_shader_program(ctx);
1834848b8605Smrg      if (program) {
1835848b8605Smrg	 struct gl_shader_program *shProg;
1836848b8605Smrg	 struct gl_shader *sh;
1837848b8605Smrg	 GLint compiled = GL_FALSE;
1838848b8605Smrg
1839848b8605Smrg	 shProg = _mesa_lookup_shader_program(ctx, program);
1840848b8605Smrg	 sh = _mesa_lookup_shader(ctx, shader);
1841848b8605Smrg
1842848b8605Smrg	 shProg->SeparateShader = separate;
1843848b8605Smrg
1844848b8605Smrg	 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
1845848b8605Smrg	 if (compiled) {
1846848b8605Smrg	    attach_shader(ctx, program, shader);
1847848b8605Smrg	    link_program(ctx, program);
1848848b8605Smrg	    detach_shader(ctx, program, shader);
1849848b8605Smrg
1850848b8605Smrg#if 0
1851848b8605Smrg	    /* Possibly... */
1852848b8605Smrg	    if (active-user-defined-varyings-in-linked-program) {
1853848b8605Smrg	       append-error-to-info-log;
1854848b8605Smrg	       shProg->LinkStatus = GL_FALSE;
1855848b8605Smrg	    }
1856848b8605Smrg#endif
1857848b8605Smrg	 }
1858848b8605Smrg
1859848b8605Smrg	 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
1860848b8605Smrg      }
1861848b8605Smrg
1862848b8605Smrg      delete_shader(ctx, shader);
1863848b8605Smrg   }
1864848b8605Smrg
1865848b8605Smrg   return program;
1866848b8605Smrg}
1867848b8605Smrg
1868848b8605Smrg
1869848b8605Smrg/**
1870848b8605Smrg * Copy program-specific data generated by linking from the gl_shader_program
1871848b8605Smrg * object to a specific gl_program object.
1872848b8605Smrg */
1873848b8605Smrgvoid
1874848b8605Smrg_mesa_copy_linked_program_data(gl_shader_stage type,
1875848b8605Smrg                               const struct gl_shader_program *src,
1876848b8605Smrg                               struct gl_program *dst)
1877848b8605Smrg{
1878848b8605Smrg   switch (type) {
1879848b8605Smrg   case MESA_SHADER_VERTEX:
1880848b8605Smrg      dst->UsesClipDistanceOut = src->Vert.UsesClipDistance;
1881848b8605Smrg      break;
1882848b8605Smrg   case MESA_SHADER_GEOMETRY: {
1883848b8605Smrg      struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
1884848b8605Smrg      dst_gp->VerticesIn = src->Geom.VerticesIn;
1885848b8605Smrg      dst_gp->VerticesOut = src->Geom.VerticesOut;
1886848b8605Smrg      dst_gp->Invocations = src->Geom.Invocations;
1887848b8605Smrg      dst_gp->InputType = src->Geom.InputType;
1888848b8605Smrg      dst_gp->OutputType = src->Geom.OutputType;
1889848b8605Smrg      dst->UsesClipDistanceOut = src->Geom.UsesClipDistance;
1890848b8605Smrg      dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;
1891848b8605Smrg      dst_gp->UsesStreams = src->Geom.UsesStreams;
1892848b8605Smrg   }
1893848b8605Smrg      break;
1894848b8605Smrg   case MESA_SHADER_FRAGMENT: {
1895848b8605Smrg      struct gl_fragment_program *dst_fp = (struct gl_fragment_program *) dst;
1896848b8605Smrg      dst_fp->FragDepthLayout = src->FragDepthLayout;
1897848b8605Smrg   }
1898848b8605Smrg      break;
1899848b8605Smrg   case MESA_SHADER_COMPUTE: {
1900848b8605Smrg      struct gl_compute_program *dst_cp = (struct gl_compute_program *) dst;
1901848b8605Smrg      int i;
1902848b8605Smrg      for (i = 0; i < 3; i++)
1903848b8605Smrg         dst_cp->LocalSize[i] = src->Comp.LocalSize[i];
1904848b8605Smrg   }
1905848b8605Smrg      break;
1906848b8605Smrg   default:
1907848b8605Smrg      break;
1908848b8605Smrg   }
1909848b8605Smrg}
1910848b8605Smrg
1911848b8605Smrg/**
1912848b8605Smrg * ARB_separate_shader_objects: Compile & Link Program
1913848b8605Smrg */
1914848b8605SmrgGLuint GLAPIENTRY
1915848b8605Smrg_mesa_CreateShaderProgramv(GLenum type, GLsizei count,
1916848b8605Smrg                           const GLchar* const *strings)
1917848b8605Smrg{
1918848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1919848b8605Smrg
1920848b8605Smrg   return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings);
1921848b8605Smrg}
1922