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