• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 /**
27  * \file shaderapi.c
28  * \author Brian Paul
29  *
30  * Implementation of GLSL-related API functions.
31  * The glUniform* functions are in uniforms.c
32  *
33  *
34  * XXX things to do:
35  * 1. Check that the right error code is generated for all _mesa_error() calls.
36  * 2. Insert FLUSH_VERTICES calls in various places
37  */
38 
39 
40 #include <stdbool.h>
41 #include "main/glheader.h"
42 #include "main/context.h"
43 #include "main/dispatch.h"
44 #include "main/enums.h"
45 #include "main/hash.h"
46 #include "main/mtypes.h"
47 #include "main/pipelineobj.h"
48 #include "main/shaderapi.h"
49 #include "main/shaderobj.h"
50 #include "main/transformfeedback.h"
51 #include "main/uniforms.h"
52 #include "compiler/glsl/glsl_parser_extras.h"
53 #include "compiler/glsl/ir.h"
54 #include "compiler/glsl/ir_uniform.h"
55 #include "compiler/glsl/program.h"
56 #include "program/program.h"
57 #include "program/prog_print.h"
58 #include "program/prog_parameter.h"
59 #include "util/ralloc.h"
60 #include "util/hash_table.h"
61 #include "util/mesa-sha1.h"
62 #include "util/crc32.h"
63 
64 /**
65  * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
66  */
67 GLbitfield
_mesa_get_shader_flags(void)68 _mesa_get_shader_flags(void)
69 {
70    GLbitfield flags = 0x0;
71    const char *env = getenv("MESA_GLSL");
72 
73    if (env) {
74       if (strstr(env, "dump_on_error"))
75          flags |= GLSL_DUMP_ON_ERROR;
76       else if (strstr(env, "dump"))
77          flags |= GLSL_DUMP;
78       if (strstr(env, "log"))
79          flags |= GLSL_LOG;
80       if (strstr(env, "nopvert"))
81          flags |= GLSL_NOP_VERT;
82       if (strstr(env, "nopfrag"))
83          flags |= GLSL_NOP_FRAG;
84       if (strstr(env, "nopt"))
85          flags |= GLSL_NO_OPT;
86       else if (strstr(env, "opt"))
87          flags |= GLSL_OPT;
88       if (strstr(env, "uniform"))
89          flags |= GLSL_UNIFORMS;
90       if (strstr(env, "useprog"))
91          flags |= GLSL_USE_PROG;
92       if (strstr(env, "errors"))
93          flags |= GLSL_REPORT_ERRORS;
94    }
95 
96    return flags;
97 }
98 
99 /**
100  * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH").
101  */
102 const char *
_mesa_get_shader_capture_path(void)103 _mesa_get_shader_capture_path(void)
104 {
105    static bool read_env_var = false;
106    static const char *path = NULL;
107 
108    if (!read_env_var) {
109       path = getenv("MESA_SHADER_CAPTURE_PATH");
110       read_env_var = true;
111    }
112 
113    return path;
114 }
115 
116 /**
117  * Initialize context's shader state.
118  */
119 void
_mesa_init_shader_state(struct gl_context * ctx)120 _mesa_init_shader_state(struct gl_context *ctx)
121 {
122    /* Device drivers may override these to control what kind of instructions
123     * are generated by the GLSL compiler.
124     */
125    struct gl_shader_compiler_options options;
126    gl_shader_stage sh;
127    int i;
128 
129    memset(&options, 0, sizeof(options));
130    options.MaxUnrollIterations = 32;
131    options.MaxIfDepth = UINT_MAX;
132 
133    for (sh = 0; sh < MESA_SHADER_STAGES; ++sh)
134       memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options));
135 
136    ctx->Shader.Flags = _mesa_get_shader_flags();
137 
138    if (ctx->Shader.Flags != 0)
139       ctx->Const.GenerateTemporaryNames = true;
140 
141    /* Extended for ARB_separate_shader_objects */
142    ctx->Shader.RefCount = 1;
143    mtx_init(&ctx->Shader.Mutex, mtx_plain);
144 
145    ctx->TessCtrlProgram.patch_vertices = 3;
146    for (i = 0; i < 4; ++i)
147       ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0;
148    for (i = 0; i < 2; ++i)
149       ctx->TessCtrlProgram.patch_default_inner_level[i] = 1.0;
150 }
151 
152 
153 /**
154  * Free the per-context shader-related state.
155  */
156 void
_mesa_free_shader_state(struct gl_context * ctx)157 _mesa_free_shader_state(struct gl_context *ctx)
158 {
159    int i;
160    for (i = 0; i < MESA_SHADER_STAGES; i++) {
161       _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram[i],
162                                      NULL);
163    }
164    _mesa_reference_program(ctx, &ctx->Shader._CurrentFragmentProgram, NULL);
165    _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
166 
167    /* Extended for ARB_separate_shader_objects */
168    _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);
169 
170    assert(ctx->Shader.RefCount == 1);
171    mtx_destroy(&ctx->Shader.Mutex);
172 }
173 
174 
175 /**
176  * Copy string from <src> to <dst>, up to maxLength characters, returning
177  * length of <dst> in <length>.
178  * \param src  the strings source
179  * \param maxLength  max chars to copy
180  * \param length  returns number of chars copied
181  * \param dst  the string destination
182  */
183 void
_mesa_copy_string(GLchar * dst,GLsizei maxLength,GLsizei * length,const GLchar * src)184 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
185                   GLsizei *length, const GLchar *src)
186 {
187    GLsizei len;
188    for (len = 0; len < maxLength - 1 && src && src[len]; len++)
189       dst[len] = src[len];
190    if (maxLength > 0)
191       dst[len] = 0;
192    if (length)
193       *length = len;
194 }
195 
196 
197 
198 /**
199  * Confirm that the a shader type is valid and supported by the implementation
200  *
201  * \param ctx   Current GL context
202  * \param type  Shader target
203  *
204  */
205 bool
_mesa_validate_shader_target(const struct gl_context * ctx,GLenum type)206 _mesa_validate_shader_target(const struct gl_context *ctx, GLenum type)
207 {
208    /* Note: when building built-in GLSL functions, this function may be
209     * invoked with ctx == NULL.  In that case, we can only validate that it's
210     * a shader target we recognize, not that it's supported in the current
211     * context.  But that's fine--we don't need any further validation than
212     * that when building built-in GLSL functions.
213     */
214 
215    switch (type) {
216    case GL_FRAGMENT_SHADER:
217       return ctx == NULL || ctx->Extensions.ARB_fragment_shader;
218    case GL_VERTEX_SHADER:
219       return ctx == NULL || ctx->Extensions.ARB_vertex_shader;
220    case GL_GEOMETRY_SHADER_ARB:
221       return ctx == NULL || _mesa_has_geometry_shaders(ctx);
222    case GL_TESS_CONTROL_SHADER:
223    case GL_TESS_EVALUATION_SHADER:
224       return ctx == NULL || _mesa_has_tessellation(ctx);
225    case GL_COMPUTE_SHADER:
226       return ctx == NULL || _mesa_has_compute_shaders(ctx);
227    default:
228       return false;
229    }
230 }
231 
232 
233 static GLboolean
is_program(struct gl_context * ctx,GLuint name)234 is_program(struct gl_context *ctx, GLuint name)
235 {
236    struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
237    return shProg ? GL_TRUE : GL_FALSE;
238 }
239 
240 
241 static GLboolean
is_shader(struct gl_context * ctx,GLuint name)242 is_shader(struct gl_context *ctx, GLuint name)
243 {
244    struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
245    return shader ? GL_TRUE : GL_FALSE;
246 }
247 
248 
249 /**
250  * Attach shader to a shader program.
251  */
252 static void
attach_shader(struct gl_context * ctx,GLuint program,GLuint shader)253 attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
254 {
255    struct gl_shader_program *shProg;
256    struct gl_shader *sh;
257    GLuint i, n;
258 
259    const bool same_type_disallowed = _mesa_is_gles(ctx);
260 
261    shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
262    if (!shProg)
263       return;
264 
265    sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
266    if (!sh) {
267       return;
268    }
269 
270    n = shProg->NumShaders;
271    for (i = 0; i < n; i++) {
272       if (shProg->Shaders[i] == sh) {
273          /* The shader is already attched to this program.  The
274           * GL_ARB_shader_objects spec says:
275           *
276           *     "The error INVALID_OPERATION is generated by AttachObjectARB
277           *     if <obj> is already attached to <containerObj>."
278           */
279          _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
280          return;
281       } else if (same_type_disallowed &&
282                  shProg->Shaders[i]->Stage == sh->Stage) {
283         /* Shader with the same type is already attached to this program,
284          * OpenGL ES 2.0 and 3.0 specs say:
285          *
286          *      "Multiple shader objects of the same type may not be attached
287          *      to a single program object. [...] The error INVALID_OPERATION
288          *      is generated if [...] another shader object of the same type
289          *      as shader is already attached to program."
290          */
291          _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
292          return;
293       }
294    }
295 
296    /* grow list */
297    shProg->Shaders = realloc(shProg->Shaders,
298                              (n + 1) * sizeof(struct gl_shader *));
299    if (!shProg->Shaders) {
300       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
301       return;
302    }
303 
304    /* append */
305    shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
306    _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
307    shProg->NumShaders++;
308 }
309 
310 
311 static GLuint
create_shader(struct gl_context * ctx,GLenum type)312 create_shader(struct gl_context *ctx, GLenum type)
313 {
314    struct gl_shader *sh;
315    GLuint name;
316 
317    if (!_mesa_validate_shader_target(ctx, type)) {
318       _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(%s)",
319                   _mesa_enum_to_string(type));
320       return 0;
321    }
322 
323    _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
324    name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
325    sh = _mesa_new_shader(name, _mesa_shader_enum_to_shader_stage(type));
326    sh->Type = type;
327    _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh);
328    _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
329 
330    return name;
331 }
332 
333 
334 static GLuint
create_shader_program(struct gl_context * ctx)335 create_shader_program(struct gl_context *ctx)
336 {
337    GLuint name;
338    struct gl_shader_program *shProg;
339 
340    _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
341 
342    name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
343 
344    shProg = _mesa_new_shader_program(name);
345 
346    _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg);
347 
348    assert(shProg->RefCount == 1);
349 
350    _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
351 
352    return name;
353 }
354 
355 
356 /**
357  * Delete a shader program.  Actually, just decrement the program's
358  * reference count and mark it as DeletePending.
359  * Used to implement glDeleteProgram() and glDeleteObjectARB().
360  */
361 static void
delete_shader_program(struct gl_context * ctx,GLuint name)362 delete_shader_program(struct gl_context *ctx, GLuint name)
363 {
364    /*
365     * NOTE: deleting shaders/programs works a bit differently than
366     * texture objects (and buffer objects, etc).  Shader/program
367     * handles/IDs exist in the hash table until the object is really
368     * deleted (refcount==0).  With texture objects, the handle/ID is
369     * removed from the hash table in glDeleteTextures() while the tex
370     * object itself might linger until its refcount goes to zero.
371     */
372    struct gl_shader_program *shProg;
373 
374    shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
375    if (!shProg)
376       return;
377 
378    if (!shProg->DeletePending) {
379       shProg->DeletePending = GL_TRUE;
380 
381       /* effectively, decr shProg's refcount */
382       _mesa_reference_shader_program(ctx, &shProg, NULL);
383    }
384 }
385 
386 
387 static void
delete_shader(struct gl_context * ctx,GLuint shader)388 delete_shader(struct gl_context *ctx, GLuint shader)
389 {
390    struct gl_shader *sh;
391 
392    sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
393    if (!sh)
394       return;
395 
396    if (!sh->DeletePending) {
397       sh->DeletePending = GL_TRUE;
398 
399       /* effectively, decr sh's refcount */
400       _mesa_reference_shader(ctx, &sh, NULL);
401    }
402 }
403 
404 
405 static void
detach_shader(struct gl_context * ctx,GLuint program,GLuint shader)406 detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
407 {
408    struct gl_shader_program *shProg;
409    GLuint n;
410    GLuint i, j;
411 
412    shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
413    if (!shProg)
414       return;
415 
416    n = shProg->NumShaders;
417 
418    for (i = 0; i < n; i++) {
419       if (shProg->Shaders[i]->Name == shader) {
420          /* found it */
421          struct gl_shader **newList;
422 
423          /* release */
424          _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
425 
426          /* alloc new, smaller array */
427          newList = malloc((n - 1) * sizeof(struct gl_shader *));
428          if (!newList) {
429             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
430             return;
431          }
432          /* Copy old list entries to new list, skipping removed entry at [i] */
433          for (j = 0; j < i; j++) {
434             newList[j] = shProg->Shaders[j];
435          }
436          while (++i < n) {
437             newList[j++] = shProg->Shaders[i];
438          }
439 
440          /* Free old list and install new one */
441          free(shProg->Shaders);
442          shProg->Shaders = newList;
443          shProg->NumShaders = n - 1;
444 
445 #ifdef DEBUG
446          /* sanity check - make sure the new list's entries are sensible */
447          for (j = 0; j < shProg->NumShaders; j++) {
448             assert(shProg->Shaders[j]->Stage == MESA_SHADER_VERTEX ||
449                    shProg->Shaders[j]->Stage == MESA_SHADER_TESS_CTRL ||
450                    shProg->Shaders[j]->Stage == MESA_SHADER_TESS_EVAL ||
451                    shProg->Shaders[j]->Stage == MESA_SHADER_GEOMETRY ||
452                    shProg->Shaders[j]->Stage == MESA_SHADER_FRAGMENT);
453             assert(shProg->Shaders[j]->RefCount > 0);
454          }
455 #endif
456 
457          return;
458       }
459    }
460 
461    /* not found */
462    {
463       GLenum err;
464       if (is_shader(ctx, shader) || is_program(ctx, shader))
465          err = GL_INVALID_OPERATION;
466       else
467          err = GL_INVALID_VALUE;
468       _mesa_error(ctx, err, "glDetachShader(shader)");
469       return;
470    }
471 }
472 
473 
474 /**
475  * Return list of shaders attached to shader program.
476  */
477 static void
get_attached_shaders(struct gl_context * ctx,GLuint program,GLsizei maxCount,GLsizei * count,GLuint * obj)478 get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
479                      GLsizei *count, GLuint *obj)
480 {
481    struct gl_shader_program *shProg;
482 
483    if (maxCount < 0) {
484       _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders(maxCount < 0)");
485       return;
486    }
487 
488    shProg =
489       _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
490 
491    if (shProg) {
492       GLuint i;
493       for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
494          obj[i] = shProg->Shaders[i]->Name;
495       }
496       if (count)
497          *count = i;
498    }
499 }
500 
501 
502 /**
503  * glGetHandleARB() - return ID/name of currently bound shader program.
504  */
505 static GLuint
get_handle(struct gl_context * ctx,GLenum pname)506 get_handle(struct gl_context *ctx, GLenum pname)
507 {
508    if (pname == GL_PROGRAM_OBJECT_ARB) {
509       if (ctx->_Shader->ActiveProgram)
510          return ctx->_Shader->ActiveProgram->Name;
511       else
512          return 0;
513    }
514    else {
515       _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
516       return 0;
517    }
518 }
519 
520 
521 /**
522  * Check if a geometry shader query is valid at this time.  If not, report an
523  * error and return false.
524  *
525  * From GL 3.2 section 6.1.16 (Shader and Program Queries):
526  *
527  *     "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE
528  *     are queried for a program which has not been linked successfully, or
529  *     which does not contain objects to form a geometry shader, then an
530  *     INVALID_OPERATION error is generated."
531  */
532 static bool
check_gs_query(struct gl_context * ctx,const struct gl_shader_program * shProg)533 check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
534 {
535    if (shProg->data->LinkStatus &&
536        shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
537       return true;
538    }
539 
540    _mesa_error(ctx, GL_INVALID_OPERATION,
541                "glGetProgramv(linked geometry shader required)");
542    return false;
543 }
544 
545 
546 /**
547  * Check if a tessellation control shader query is valid at this time.
548  * If not, report an error and return false.
549  *
550  * From GL 4.0 section 6.1.12 (Shader and Program Queries):
551  *
552  *     "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has
553  *     not been linked successfully, or which does not contain objects to
554  *     form a tessellation control shader, then an INVALID_OPERATION error is
555  *     generated."
556  */
557 static bool
check_tcs_query(struct gl_context * ctx,const struct gl_shader_program * shProg)558 check_tcs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
559 {
560    if (shProg->data->LinkStatus &&
561        shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL] != NULL) {
562       return true;
563    }
564 
565    _mesa_error(ctx, GL_INVALID_OPERATION,
566                "glGetProgramv(linked tessellation control shader required)");
567    return false;
568 }
569 
570 
571 /**
572  * Check if a tessellation evaluation shader query is valid at this time.
573  * If not, report an error and return false.
574  *
575  * From GL 4.0 section 6.1.12 (Shader and Program Queries):
576  *
577  *     "If any of the pname values in this paragraph are queried for a program
578  *     which has not been linked successfully, or which does not contain
579  *     objects to form a tessellation evaluation shader, then an
580  *     INVALID_OPERATION error is generated."
581  *
582  */
583 static bool
check_tes_query(struct gl_context * ctx,const struct gl_shader_program * shProg)584 check_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
585 {
586    if (shProg->data->LinkStatus &&
587        shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL] != NULL) {
588       return true;
589    }
590 
591    _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramv(linked tessellation "
592                "evaluation shader required)");
593    return false;
594 }
595 
596 
597 /**
598  * glGetProgramiv() - get shader program state.
599  * Note that this is for GLSL shader programs, not ARB vertex/fragment
600  * programs (see glGetProgramivARB).
601  */
602 static void
get_programiv(struct gl_context * ctx,GLuint program,GLenum pname,GLint * params)603 get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
604               GLint *params)
605 {
606    struct gl_shader_program *shProg
607       = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramiv(program)");
608 
609    /* Is transform feedback available in this context?
610     */
611    const bool has_xfb =
612       (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback)
613       || ctx->API == API_OPENGL_CORE
614       || _mesa_is_gles3(ctx);
615 
616    /* True if geometry shaders (of the form that was adopted into GLSL 1.50
617     * and GL 3.2) are available in this context
618     */
619    const bool has_core_gs = _mesa_has_geometry_shaders(ctx);
620    const bool has_tess = _mesa_has_tessellation(ctx);
621 
622    /* Are uniform buffer objects available in this context?
623     */
624    const bool has_ubo =
625       (ctx->API == API_OPENGL_COMPAT &&
626        ctx->Extensions.ARB_uniform_buffer_object)
627       || ctx->API == API_OPENGL_CORE
628       || _mesa_is_gles3(ctx);
629 
630    if (!shProg) {
631       return;
632    }
633 
634    switch (pname) {
635    case GL_DELETE_STATUS:
636       *params = shProg->DeletePending;
637       return;
638    case GL_LINK_STATUS:
639       *params = shProg->data->LinkStatus;
640       return;
641    case GL_VALIDATE_STATUS:
642       *params = shProg->data->Validated;
643       return;
644    case GL_INFO_LOG_LENGTH:
645       *params = (shProg->data->InfoLog && shProg->data->InfoLog[0] != '\0') ?
646          strlen(shProg->data->InfoLog) + 1 : 0;
647       return;
648    case GL_ATTACHED_SHADERS:
649       *params = shProg->NumShaders;
650       return;
651    case GL_ACTIVE_ATTRIBUTES:
652       *params = _mesa_count_active_attribs(shProg);
653       return;
654    case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
655       *params = _mesa_longest_attribute_name_length(shProg);
656       return;
657    case GL_ACTIVE_UNIFORMS: {
658       unsigned i;
659       const unsigned num_uniforms =
660          shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms;
661       for (*params = 0, i = 0; i < num_uniforms; i++) {
662          if (!shProg->data->UniformStorage[i].is_shader_storage)
663             (*params)++;
664       }
665       return;
666    }
667    case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
668       unsigned i;
669       GLint max_len = 0;
670       const unsigned num_uniforms =
671          shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms;
672 
673       for (i = 0; i < num_uniforms; i++) {
674          if (shProg->data->UniformStorage[i].is_shader_storage)
675             continue;
676 
677 	 /* Add one for the terminating NUL character for a non-array, and
678 	  * 4 for the "[0]" and the NUL for an array.
679 	  */
680          const GLint len = strlen(shProg->data->UniformStorage[i].name) + 1 +
681              ((shProg->data->UniformStorage[i].array_elements != 0) ? 3 : 0);
682 
683 	 if (len > max_len)
684 	    max_len = len;
685       }
686 
687       *params = max_len;
688       return;
689    }
690    case GL_TRANSFORM_FEEDBACK_VARYINGS:
691       if (!has_xfb)
692          break;
693       *params = shProg->TransformFeedback.NumVarying;
694       return;
695    case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: {
696       unsigned i;
697       GLint max_len = 0;
698       if (!has_xfb)
699          break;
700 
701       for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
702          /* Add one for the terminating NUL character.
703           */
704          const GLint len =
705             strlen(shProg->TransformFeedback.VaryingNames[i]) + 1;
706 
707          if (len > max_len)
708             max_len = len;
709       }
710 
711       *params = max_len;
712       return;
713    }
714    case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
715       if (!has_xfb)
716          break;
717       *params = shProg->TransformFeedback.BufferMode;
718       return;
719    case GL_GEOMETRY_VERTICES_OUT:
720       if (!has_core_gs)
721          break;
722       if (check_gs_query(ctx, shProg)) {
723          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
724             info.Geom.VerticesOut;
725       }
726       return;
727    case GL_GEOMETRY_SHADER_INVOCATIONS:
728       if (!has_core_gs || !ctx->Extensions.ARB_gpu_shader5)
729          break;
730       if (check_gs_query(ctx, shProg)) {
731          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
732             info.Geom.Invocations;
733       }
734       return;
735    case GL_GEOMETRY_INPUT_TYPE:
736       if (!has_core_gs)
737          break;
738       if (check_gs_query(ctx, shProg)) {
739          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
740             info.Geom.InputType;
741       }
742       return;
743    case GL_GEOMETRY_OUTPUT_TYPE:
744       if (!has_core_gs)
745          break;
746       if (check_gs_query(ctx, shProg)) {
747          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
748             info.Geom.OutputType;
749       }
750       return;
751    case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
752       unsigned i;
753       GLint max_len = 0;
754 
755       if (!has_ubo)
756          break;
757 
758       for (i = 0; i < shProg->data->NumUniformBlocks; i++) {
759 	 /* Add one for the terminating NUL character.
760 	  */
761          const GLint len = strlen(shProg->data->UniformBlocks[i].Name) + 1;
762 
763 	 if (len > max_len)
764 	    max_len = len;
765       }
766 
767       *params = max_len;
768       return;
769    }
770    case GL_ACTIVE_UNIFORM_BLOCKS:
771       if (!has_ubo)
772          break;
773 
774       *params = shProg->data->NumUniformBlocks;
775       return;
776    case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
777       /* This enum isn't part of the OES extension for OpenGL ES 2.0.  It is
778        * only available with desktop OpenGL 3.0+ with the
779        * GL_ARB_get_program_binary extension or OpenGL ES 3.0.
780        *
781        * On desktop, we ignore the 3.0+ requirement because it is silly.
782        */
783       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
784          break;
785 
786       *params = shProg->BinaryRetreivableHint;
787       return;
788    case GL_PROGRAM_BINARY_LENGTH:
789       *params = 0;
790       return;
791    case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
792       if (!ctx->Extensions.ARB_shader_atomic_counters)
793          break;
794 
795       *params = shProg->data->NumAtomicBuffers;
796       return;
797    case GL_COMPUTE_WORK_GROUP_SIZE: {
798       int i;
799       if (!_mesa_has_compute_shaders(ctx))
800          break;
801       if (!shProg->data->LinkStatus) {
802          _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(program not "
803                      "linked)");
804          return;
805       }
806       if (shProg->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) {
807          _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(no compute "
808                      "shaders)");
809          return;
810       }
811       for (i = 0; i < 3; i++)
812          params[i] = shProg->Comp.LocalSize[i];
813       return;
814    }
815    case GL_PROGRAM_SEPARABLE:
816       /* If the program has not been linked, return initial value 0. */
817       *params = (shProg->data->LinkStatus == GL_FALSE) ? 0 : shProg->SeparateShader;
818       return;
819 
820    /* ARB_tessellation_shader */
821    case GL_TESS_CONTROL_OUTPUT_VERTICES:
822       if (!has_tess)
823          break;
824       if (check_tcs_query(ctx, shProg)) {
825          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->
826             info.TessCtrl.VerticesOut;
827       }
828       return;
829    case GL_TESS_GEN_MODE:
830       if (!has_tess)
831          break;
832       if (check_tes_query(ctx, shProg)) {
833          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
834             info.TessEval.PrimitiveMode;
835       }
836       return;
837    case GL_TESS_GEN_SPACING:
838       if (!has_tess)
839          break;
840       if (check_tes_query(ctx, shProg)) {
841          const struct gl_linked_shader *tes =
842             shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL];
843          switch (tes->info.TessEval.Spacing) {
844          case TESS_SPACING_EQUAL:
845             *params = GL_EQUAL;
846             break;
847          case TESS_SPACING_FRACTIONAL_ODD:
848             *params = GL_FRACTIONAL_ODD;
849             break;
850          case TESS_SPACING_FRACTIONAL_EVEN:
851             *params = GL_FRACTIONAL_EVEN;
852             break;
853          case TESS_SPACING_UNSPECIFIED:
854             *params = 0;
855             break;
856          }
857       }
858       return;
859    case GL_TESS_GEN_VERTEX_ORDER:
860       if (!has_tess)
861          break;
862       if (check_tes_query(ctx, shProg)) {
863          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
864             info.TessEval.VertexOrder;
865          }
866       return;
867    case GL_TESS_GEN_POINT_MODE:
868       if (!has_tess)
869          break;
870       if (check_tes_query(ctx, shProg)) {
871          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
872             info.TessEval.PointMode;
873       }
874       return;
875    default:
876       break;
877    }
878 
879    _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
880                _mesa_enum_to_string(pname));
881 }
882 
883 
884 /**
885  * glGetShaderiv() - get GLSL shader state
886  */
887 static void
get_shaderiv(struct gl_context * ctx,GLuint name,GLenum pname,GLint * params)888 get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
889 {
890    struct gl_shader *shader =
891       _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
892 
893    if (!shader) {
894       return;
895    }
896 
897    switch (pname) {
898    case GL_SHADER_TYPE:
899       *params = shader->Type;
900       break;
901    case GL_DELETE_STATUS:
902       *params = shader->DeletePending;
903       break;
904    case GL_COMPILE_STATUS:
905       *params = shader->CompileStatus;
906       break;
907    case GL_INFO_LOG_LENGTH:
908       *params = (shader->InfoLog && shader->InfoLog[0] != '\0') ?
909          strlen(shader->InfoLog) + 1 : 0;
910       break;
911    case GL_SHADER_SOURCE_LENGTH:
912       *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
913       break;
914    default:
915       _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
916       return;
917    }
918 }
919 
920 
921 static void
get_program_info_log(struct gl_context * ctx,GLuint program,GLsizei bufSize,GLsizei * length,GLchar * infoLog)922 get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
923                      GLsizei *length, GLchar *infoLog)
924 {
925    struct gl_shader_program *shProg;
926 
927    /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
928     * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
929     *
930     *     "If a negative number is provided where an argument of type sizei or
931     *     sizeiptr is specified, an INVALID_VALUE error is generated."
932     */
933    if (bufSize < 0) {
934       _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(bufSize < 0)");
935       return;
936    }
937 
938    shProg = _mesa_lookup_shader_program_err(ctx, program,
939                                             "glGetProgramInfoLog(program)");
940    if (!shProg) {
941       return;
942    }
943 
944    _mesa_copy_string(infoLog, bufSize, length, shProg->data->InfoLog);
945 }
946 
947 
948 static void
get_shader_info_log(struct gl_context * ctx,GLuint shader,GLsizei bufSize,GLsizei * length,GLchar * infoLog)949 get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
950                     GLsizei *length, GLchar *infoLog)
951 {
952    struct gl_shader *sh;
953 
954    /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
955     * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
956     *
957     *     "If a negative number is provided where an argument of type sizei or
958     *     sizeiptr is specified, an INVALID_VALUE error is generated."
959     */
960    if (bufSize < 0) {
961       _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(bufSize < 0)");
962       return;
963    }
964 
965    sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderInfoLog(shader)");
966    if (!sh) {
967       return;
968    }
969 
970    _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
971 }
972 
973 
974 /**
975  * Return shader source code.
976  */
977 static void
get_shader_source(struct gl_context * ctx,GLuint shader,GLsizei maxLength,GLsizei * length,GLchar * sourceOut)978 get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
979                   GLsizei *length, GLchar *sourceOut)
980 {
981    struct gl_shader *sh;
982 
983    if (maxLength < 0) {
984       _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(bufSize < 0)");
985       return;
986    }
987 
988    sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
989    if (!sh) {
990       return;
991    }
992    _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
993 }
994 
995 
996 /**
997  * Set/replace shader source code.  A helper function used by
998  * glShaderSource[ARB].
999  */
1000 static void
shader_source(struct gl_shader * sh,const GLchar * source)1001 shader_source(struct gl_shader *sh, const GLchar *source)
1002 {
1003    assert(sh);
1004 
1005    /* free old shader source string and install new one */
1006    free((void *)sh->Source);
1007    sh->Source = source;
1008 #ifdef DEBUG
1009    sh->SourceChecksum = util_hash_crc32(sh->Source, strlen(sh->Source));
1010 #endif
1011 }
1012 
1013 
1014 /**
1015  * Compile a shader.
1016  */
1017 void
_mesa_compile_shader(struct gl_context * ctx,struct gl_shader * sh)1018 _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh)
1019 {
1020    if (!sh)
1021       return;
1022 
1023    if (!sh->Source) {
1024       /* If the user called glCompileShader without first calling
1025        * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
1026        */
1027       sh->CompileStatus = GL_FALSE;
1028    } else {
1029       if (ctx->_Shader->Flags & GLSL_DUMP) {
1030          _mesa_log("GLSL source for %s shader %d:\n",
1031                  _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1032          _mesa_log("%s\n", sh->Source);
1033       }
1034 
1035       /* this call will set the shader->CompileStatus field to indicate if
1036        * compilation was successful.
1037        */
1038       _mesa_glsl_compile_shader(ctx, sh, false, false);
1039 
1040       if (ctx->_Shader->Flags & GLSL_LOG) {
1041          _mesa_write_shader_to_file(sh);
1042       }
1043 
1044       if (ctx->_Shader->Flags & GLSL_DUMP) {
1045          if (sh->CompileStatus) {
1046             if (sh->ir) {
1047                _mesa_log("GLSL IR for shader %d:\n", sh->Name);
1048                _mesa_print_ir(_mesa_get_log_file(), sh->ir, NULL);
1049             } else {
1050                _mesa_log("No GLSL IR for shader %d (shader may be from "
1051                          "cache)\n", sh->Name);
1052             }
1053             _mesa_log("\n\n");
1054          } else {
1055             _mesa_log("GLSL shader %d failed to compile.\n", sh->Name);
1056          }
1057          if (sh->InfoLog && sh->InfoLog[0] != 0) {
1058             _mesa_log("GLSL shader %d info log:\n", sh->Name);
1059             _mesa_log("%s\n", sh->InfoLog);
1060          }
1061       }
1062    }
1063 
1064    if (!sh->CompileStatus) {
1065       if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) {
1066          _mesa_log("GLSL source for %s shader %d:\n",
1067                  _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1068          _mesa_log("%s\n", sh->Source);
1069          _mesa_log("Info Log:\n%s\n", sh->InfoLog);
1070       }
1071 
1072       if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) {
1073          _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
1074                      sh->Name, sh->InfoLog);
1075       }
1076    }
1077 }
1078 
1079 
1080 /**
1081  * Link a program's shaders.
1082  */
1083 void
_mesa_link_program(struct gl_context * ctx,struct gl_shader_program * shProg)1084 _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
1085 {
1086    if (!shProg)
1087       return;
1088 
1089    /* From the ARB_transform_feedback2 specification:
1090     * "The error INVALID_OPERATION is generated by LinkProgram if <program> is
1091     *  the name of a program being used by one or more transform feedback
1092     *  objects, even if the objects are not currently bound or are paused."
1093     */
1094    if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
1095       _mesa_error(ctx, GL_INVALID_OPERATION,
1096                   "glLinkProgram(transform feedback is using the program)");
1097       return;
1098    }
1099 
1100    FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1101 
1102    _mesa_glsl_link_shader(ctx, shProg);
1103 
1104    /* Capture .shader_test files. */
1105    const char *capture_path = _mesa_get_shader_capture_path();
1106    if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
1107       FILE *file;
1108       char *filename = ralloc_asprintf(NULL, "%s/%u.shader_test",
1109                                        capture_path, shProg->Name);
1110       file = fopen(filename, "w");
1111       if (file) {
1112          fprintf(file, "[require]\nGLSL%s >= %u.%02u\n",
1113                  shProg->IsES ? " ES" : "",
1114                  shProg->data->Version / 100, shProg->data->Version % 100);
1115          if (shProg->SeparateShader)
1116             fprintf(file, "GL_ARB_separate_shader_objects\nSSO ENABLED\n");
1117          fprintf(file, "\n");
1118 
1119          for (unsigned i = 0; i < shProg->NumShaders; i++) {
1120             fprintf(file, "[%s shader]\n%s\n",
1121                     _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
1122                     shProg->Shaders[i]->Source);
1123          }
1124          fclose(file);
1125       } else {
1126          _mesa_warning(ctx, "Failed to open %s", filename);
1127       }
1128 
1129       ralloc_free(filename);
1130    }
1131 
1132    if (shProg->data->LinkStatus == GL_FALSE &&
1133        (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
1134       _mesa_debug(ctx, "Error linking program %u:\n%s\n",
1135                   shProg->Name, shProg->data->InfoLog);
1136    }
1137 
1138    /* debug code */
1139    if (0) {
1140       GLuint i;
1141 
1142       printf("Link %u shaders in program %u: %s\n",
1143                    shProg->NumShaders, shProg->Name,
1144                    shProg->data->LinkStatus ? "Success" : "Failed");
1145 
1146       for (i = 0; i < shProg->NumShaders; i++) {
1147          printf(" shader %u, stage %u\n",
1148                       shProg->Shaders[i]->Name,
1149                       shProg->Shaders[i]->Stage);
1150       }
1151    }
1152 }
1153 
1154 
1155 /**
1156  * Print basic shader info (for debug).
1157  */
1158 static void
print_shader_info(const struct gl_shader_program * shProg)1159 print_shader_info(const struct gl_shader_program *shProg)
1160 {
1161    GLuint i;
1162 
1163    printf("Mesa: glUseProgram(%u)\n", shProg->Name);
1164    for (i = 0; i < shProg->NumShaders; i++) {
1165 #ifdef DEBUG
1166       printf("  %s shader %u, checksum %u\n",
1167              _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
1168 	     shProg->Shaders[i]->Name,
1169 	     shProg->Shaders[i]->SourceChecksum);
1170 #else
1171       printf("  %s shader %u\n",
1172              _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
1173              shProg->Shaders[i]->Name);
1174 #endif
1175    }
1176    if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
1177       printf("  vert prog %u\n",
1178 	     shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
1179    if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
1180       printf("  frag prog %u\n",
1181 	     shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
1182    if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
1183       printf("  geom prog %u\n",
1184 	     shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
1185    if (shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL])
1186       printf("  tesc prog %u\n",
1187 	     shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program->Id);
1188    if (shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL])
1189       printf("  tese prog %u\n",
1190 	     shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program->Id);
1191 }
1192 
1193 
1194 /**
1195  * Use the named shader program for subsequent glUniform calls
1196  */
1197 void
_mesa_active_program(struct gl_context * ctx,struct gl_shader_program * shProg,const char * caller)1198 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
1199 		     const char *caller)
1200 {
1201    if ((shProg != NULL) && !shProg->data->LinkStatus) {
1202       _mesa_error(ctx, GL_INVALID_OPERATION,
1203 		  "%s(program %u not linked)", caller, shProg->Name);
1204       return;
1205    }
1206 
1207    if (ctx->Shader.ActiveProgram != shProg) {
1208       _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
1209    }
1210 }
1211 
1212 
1213 static void
use_shader_program(struct gl_context * ctx,gl_shader_stage stage,struct gl_shader_program * shProg,struct gl_pipeline_object * shTarget)1214 use_shader_program(struct gl_context *ctx, gl_shader_stage stage,
1215                    struct gl_shader_program *shProg,
1216                    struct gl_pipeline_object *shTarget)
1217 {
1218    struct gl_shader_program **target;
1219 
1220    target = &shTarget->CurrentProgram[stage];
1221    if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL))
1222       shProg = NULL;
1223 
1224    if (shProg)
1225       _mesa_shader_program_init_subroutine_defaults(ctx, shProg);
1226 
1227    if (*target != shProg) {
1228       /* Program is current, flush it */
1229       if (shTarget == ctx->_Shader) {
1230          FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1231       }
1232 
1233       /* If the shader is also bound as the current rendering shader, unbind
1234        * it from that binding point as well.  This ensures that the correct
1235        * semantics of glDeleteProgram are maintained.
1236        */
1237       switch (stage) {
1238       case MESA_SHADER_VERTEX:
1239       case MESA_SHADER_TESS_CTRL:
1240       case MESA_SHADER_TESS_EVAL:
1241       case MESA_SHADER_GEOMETRY:
1242       case MESA_SHADER_COMPUTE:
1243          /* Empty for now. */
1244          break;
1245       case MESA_SHADER_FRAGMENT:
1246          if (*target != NULL &&
1247              ((*target)->_LinkedShaders[MESA_SHADER_FRAGMENT] &&
1248               (*target)->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program ==
1249               ctx->_Shader->_CurrentFragmentProgram)) {
1250 	    _mesa_reference_program(ctx,
1251                                     &ctx->_Shader->_CurrentFragmentProgram,
1252                                     NULL);
1253 	 }
1254 	 break;
1255       }
1256 
1257       _mesa_reference_shader_program(ctx, target, shProg);
1258       return;
1259    }
1260 }
1261 
1262 
1263 /**
1264  * Use the named shader program for subsequent rendering.
1265  */
1266 void
_mesa_use_program(struct gl_context * ctx,struct gl_shader_program * shProg)1267 _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
1268 {
1269    int i;
1270    for (i = 0; i < MESA_SHADER_STAGES; i++)
1271       use_shader_program(ctx, i, shProg, &ctx->Shader);
1272    _mesa_active_program(ctx, shProg, "glUseProgram");
1273 }
1274 
1275 
1276 /**
1277  * Do validation of the given shader program.
1278  * \param errMsg  returns error message if validation fails.
1279  * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
1280  */
1281 static GLboolean
validate_shader_program(const struct gl_shader_program * shProg,char * errMsg)1282 validate_shader_program(const struct gl_shader_program *shProg,
1283                         char *errMsg)
1284 {
1285    if (!shProg->data->LinkStatus) {
1286       return GL_FALSE;
1287    }
1288 
1289    /* From the GL spec, a program is invalid if any of these are true:
1290 
1291      any two active samplers in the current program object are of
1292      different types, but refer to the same texture image unit,
1293 
1294      any active sampler in the current program object refers to a texture
1295      image unit where fixed-function fragment processing accesses a
1296      texture target that does not match the sampler type, or
1297 
1298      the sum of the number of active samplers in the program and the
1299      number of texture image units enabled for fixed-function fragment
1300      processing exceeds the combined limit on the total number of texture
1301      image units allowed.
1302    */
1303 
1304    /*
1305     * Check: any two active samplers in the current program object are of
1306     * different types, but refer to the same texture image unit,
1307     */
1308    if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
1309       return GL_FALSE;
1310 
1311    return GL_TRUE;
1312 }
1313 
1314 
1315 /**
1316  * Called via glValidateProgram()
1317  */
1318 static void
validate_program(struct gl_context * ctx,GLuint program)1319 validate_program(struct gl_context *ctx, GLuint program)
1320 {
1321    struct gl_shader_program *shProg;
1322    char errMsg[100] = "";
1323 
1324    shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1325    if (!shProg) {
1326       return;
1327    }
1328 
1329    shProg->data->Validated = validate_shader_program(shProg, errMsg);
1330    if (!shProg->data->Validated) {
1331       /* update info log */
1332       if (shProg->data->InfoLog) {
1333          ralloc_free(shProg->data->InfoLog);
1334       }
1335       shProg->data->InfoLog = ralloc_strdup(shProg->data, errMsg);
1336    }
1337 }
1338 
1339 
1340 
1341 void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB program,GLhandleARB shader)1342 _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1343 {
1344    GET_CURRENT_CONTEXT(ctx);
1345    attach_shader(ctx, program, shader);
1346 }
1347 
1348 
1349 void GLAPIENTRY
_mesa_AttachShader(GLuint program,GLuint shader)1350 _mesa_AttachShader(GLuint program, GLuint shader)
1351 {
1352    GET_CURRENT_CONTEXT(ctx);
1353    attach_shader(ctx, program, shader);
1354 }
1355 
1356 
1357 void GLAPIENTRY
_mesa_CompileShader(GLuint shaderObj)1358 _mesa_CompileShader(GLuint shaderObj)
1359 {
1360    GET_CURRENT_CONTEXT(ctx);
1361    if (MESA_VERBOSE & VERBOSE_API)
1362       _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
1363    _mesa_compile_shader(ctx, _mesa_lookup_shader_err(ctx, shaderObj,
1364                                                      "glCompileShader"));
1365 }
1366 
1367 
1368 GLuint GLAPIENTRY
_mesa_CreateShader(GLenum type)1369 _mesa_CreateShader(GLenum type)
1370 {
1371    GET_CURRENT_CONTEXT(ctx);
1372    if (MESA_VERBOSE & VERBOSE_API)
1373       _mesa_debug(ctx, "glCreateShader %s\n", _mesa_enum_to_string(type));
1374    return create_shader(ctx, type);
1375 }
1376 
1377 
1378 GLhandleARB GLAPIENTRY
_mesa_CreateShaderObjectARB(GLenum type)1379 _mesa_CreateShaderObjectARB(GLenum type)
1380 {
1381    GET_CURRENT_CONTEXT(ctx);
1382    return create_shader(ctx, type);
1383 }
1384 
1385 
1386 GLuint GLAPIENTRY
_mesa_CreateProgram(void)1387 _mesa_CreateProgram(void)
1388 {
1389    GET_CURRENT_CONTEXT(ctx);
1390    if (MESA_VERBOSE & VERBOSE_API)
1391       _mesa_debug(ctx, "glCreateProgram\n");
1392    return create_shader_program(ctx);
1393 }
1394 
1395 
1396 GLhandleARB GLAPIENTRY
_mesa_CreateProgramObjectARB(void)1397 _mesa_CreateProgramObjectARB(void)
1398 {
1399    GET_CURRENT_CONTEXT(ctx);
1400    return create_shader_program(ctx);
1401 }
1402 
1403 
1404 void GLAPIENTRY
_mesa_DeleteObjectARB(GLhandleARB obj)1405 _mesa_DeleteObjectARB(GLhandleARB obj)
1406 {
1407    if (MESA_VERBOSE & VERBOSE_API) {
1408       GET_CURRENT_CONTEXT(ctx);
1409       _mesa_debug(ctx, "glDeleteObjectARB(%lu)\n", (unsigned long)obj);
1410    }
1411 
1412    if (obj) {
1413       GET_CURRENT_CONTEXT(ctx);
1414       FLUSH_VERTICES(ctx, 0);
1415       if (is_program(ctx, obj)) {
1416          delete_shader_program(ctx, obj);
1417       }
1418       else if (is_shader(ctx, obj)) {
1419          delete_shader(ctx, obj);
1420       }
1421       else {
1422          /* error? */
1423       }
1424    }
1425 }
1426 
1427 
1428 void GLAPIENTRY
_mesa_DeleteProgram(GLuint name)1429 _mesa_DeleteProgram(GLuint name)
1430 {
1431    if (name) {
1432       GET_CURRENT_CONTEXT(ctx);
1433       FLUSH_VERTICES(ctx, 0);
1434       delete_shader_program(ctx, name);
1435    }
1436 }
1437 
1438 
1439 void GLAPIENTRY
_mesa_DeleteShader(GLuint name)1440 _mesa_DeleteShader(GLuint name)
1441 {
1442    if (name) {
1443       GET_CURRENT_CONTEXT(ctx);
1444       FLUSH_VERTICES(ctx, 0);
1445       delete_shader(ctx, name);
1446    }
1447 }
1448 
1449 
1450 void GLAPIENTRY
_mesa_DetachObjectARB(GLhandleARB program,GLhandleARB shader)1451 _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1452 {
1453    GET_CURRENT_CONTEXT(ctx);
1454    detach_shader(ctx, program, shader);
1455 }
1456 
1457 
1458 void GLAPIENTRY
_mesa_DetachShader(GLuint program,GLuint shader)1459 _mesa_DetachShader(GLuint program, GLuint shader)
1460 {
1461    GET_CURRENT_CONTEXT(ctx);
1462    detach_shader(ctx, program, shader);
1463 }
1464 
1465 
1466 void GLAPIENTRY
_mesa_GetAttachedObjectsARB(GLhandleARB container,GLsizei maxCount,GLsizei * count,GLhandleARB * obj)1467 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1468                             GLsizei * count, GLhandleARB * obj)
1469 {
1470    GET_CURRENT_CONTEXT(ctx);
1471    get_attached_shaders(ctx, container, maxCount, count, obj);
1472 }
1473 
1474 
1475 void GLAPIENTRY
_mesa_GetAttachedShaders(GLuint program,GLsizei maxCount,GLsizei * count,GLuint * obj)1476 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1477                          GLsizei *count, GLuint *obj)
1478 {
1479    GET_CURRENT_CONTEXT(ctx);
1480    get_attached_shaders(ctx, program, maxCount, count, obj);
1481 }
1482 
1483 
1484 void GLAPIENTRY
_mesa_GetInfoLogARB(GLhandleARB object,GLsizei maxLength,GLsizei * length,GLcharARB * infoLog)1485 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1486                     GLcharARB * infoLog)
1487 {
1488    GET_CURRENT_CONTEXT(ctx);
1489    if (is_program(ctx, object)) {
1490       get_program_info_log(ctx, object, maxLength, length, infoLog);
1491    }
1492    else if (is_shader(ctx, object)) {
1493       get_shader_info_log(ctx, object, maxLength, length, infoLog);
1494    }
1495    else {
1496       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1497    }
1498 }
1499 
1500 
1501 void GLAPIENTRY
_mesa_GetObjectParameterivARB(GLhandleARB object,GLenum pname,GLint * params)1502 _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1503 {
1504    GET_CURRENT_CONTEXT(ctx);
1505    /* Implement in terms of GetProgramiv, GetShaderiv */
1506    if (is_program(ctx, object)) {
1507       if (pname == GL_OBJECT_TYPE_ARB) {
1508 	 *params = GL_PROGRAM_OBJECT_ARB;
1509       }
1510       else {
1511 	 get_programiv(ctx, object, pname, params);
1512       }
1513    }
1514    else if (is_shader(ctx, object)) {
1515       if (pname == GL_OBJECT_TYPE_ARB) {
1516 	 *params = GL_SHADER_OBJECT_ARB;
1517       }
1518       else {
1519 	 get_shaderiv(ctx, object, pname, params);
1520       }
1521    }
1522    else {
1523       _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1524    }
1525 }
1526 
1527 
1528 void GLAPIENTRY
_mesa_GetObjectParameterfvARB(GLhandleARB object,GLenum pname,GLfloat * params)1529 _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1530                               GLfloat *params)
1531 {
1532    GLint iparams[1] = {0};  /* XXX is one element enough? */
1533    _mesa_GetObjectParameterivARB(object, pname, iparams);
1534    params[0] = (GLfloat) iparams[0];
1535 }
1536 
1537 
1538 void GLAPIENTRY
_mesa_GetProgramiv(GLuint program,GLenum pname,GLint * params)1539 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1540 {
1541    GET_CURRENT_CONTEXT(ctx);
1542    get_programiv(ctx, program, pname, params);
1543 }
1544 
1545 
1546 void GLAPIENTRY
_mesa_GetShaderiv(GLuint shader,GLenum pname,GLint * params)1547 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1548 {
1549    GET_CURRENT_CONTEXT(ctx);
1550    get_shaderiv(ctx, shader, pname, params);
1551 }
1552 
1553 
1554 void GLAPIENTRY
_mesa_GetProgramInfoLog(GLuint program,GLsizei bufSize,GLsizei * length,GLchar * infoLog)1555 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1556                         GLsizei *length, GLchar *infoLog)
1557 {
1558    GET_CURRENT_CONTEXT(ctx);
1559    get_program_info_log(ctx, program, bufSize, length, infoLog);
1560 }
1561 
1562 
1563 void GLAPIENTRY
_mesa_GetShaderInfoLog(GLuint shader,GLsizei bufSize,GLsizei * length,GLchar * infoLog)1564 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1565                        GLsizei *length, GLchar *infoLog)
1566 {
1567    GET_CURRENT_CONTEXT(ctx);
1568    get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1569 }
1570 
1571 
1572 void GLAPIENTRY
_mesa_GetShaderSource(GLuint shader,GLsizei maxLength,GLsizei * length,GLchar * sourceOut)1573 _mesa_GetShaderSource(GLuint shader, GLsizei maxLength,
1574                       GLsizei *length, GLchar *sourceOut)
1575 {
1576    GET_CURRENT_CONTEXT(ctx);
1577    get_shader_source(ctx, shader, maxLength, length, sourceOut);
1578 }
1579 
1580 
1581 GLhandleARB GLAPIENTRY
_mesa_GetHandleARB(GLenum pname)1582 _mesa_GetHandleARB(GLenum pname)
1583 {
1584    GET_CURRENT_CONTEXT(ctx);
1585    return get_handle(ctx, pname);
1586 }
1587 
1588 
1589 GLboolean GLAPIENTRY
_mesa_IsProgram(GLuint name)1590 _mesa_IsProgram(GLuint name)
1591 {
1592    GET_CURRENT_CONTEXT(ctx);
1593    return is_program(ctx, name);
1594 }
1595 
1596 
1597 GLboolean GLAPIENTRY
_mesa_IsShader(GLuint name)1598 _mesa_IsShader(GLuint name)
1599 {
1600    GET_CURRENT_CONTEXT(ctx);
1601    return is_shader(ctx, name);
1602 }
1603 
1604 
1605 void GLAPIENTRY
_mesa_LinkProgram(GLuint programObj)1606 _mesa_LinkProgram(GLuint programObj)
1607 {
1608    GET_CURRENT_CONTEXT(ctx);
1609    if (MESA_VERBOSE & VERBOSE_API)
1610       _mesa_debug(ctx, "glLinkProgram %u\n", programObj);
1611    _mesa_link_program(ctx, _mesa_lookup_shader_program_err(ctx, programObj,
1612                                                            "glLinkProgram"));
1613 }
1614 
1615 #ifdef ENABLE_SHADER_CACHE
1616 /**
1617  * Generate a SHA-1 hash value string for given source string.
1618  */
1619 static void
generate_sha1(const char * source,char sha_str[64])1620 generate_sha1(const char *source, char sha_str[64])
1621 {
1622    unsigned char sha[20];
1623    _mesa_sha1_compute(source, strlen(source), sha);
1624    _mesa_sha1_format(sha_str, sha);
1625 }
1626 
1627 /**
1628  * Construct a full path for shader replacement functionality using
1629  * following format:
1630  *
1631  * <path>/<stage prefix>_<CHECKSUM>.glsl
1632  */
1633 static char *
construct_name(const gl_shader_stage stage,const char * source,const char * path)1634 construct_name(const gl_shader_stage stage, const char *source,
1635                const char *path)
1636 {
1637    char sha[64];
1638    static const char *types[] = {
1639       "VS", "TC", "TE", "GS", "FS", "CS",
1640    };
1641 
1642    generate_sha1(source, sha);
1643    return ralloc_asprintf(NULL, "%s/%s_%s.glsl", path, types[stage], sha);
1644 }
1645 
1646 /**
1647  * Write given shader source to a file in MESA_SHADER_DUMP_PATH.
1648  */
1649 static void
dump_shader(const gl_shader_stage stage,const char * source)1650 dump_shader(const gl_shader_stage stage, const char *source)
1651 {
1652    static bool path_exists = true;
1653    char *dump_path;
1654    FILE *f;
1655 
1656    if (!path_exists)
1657       return;
1658 
1659    dump_path = getenv("MESA_SHADER_DUMP_PATH");
1660    if (!dump_path) {
1661       path_exists = false;
1662       return;
1663    }
1664 
1665    char *name = construct_name(stage, source, dump_path);
1666 
1667    f = fopen(name, "w");
1668    if (f) {
1669       fputs(source, f);
1670       fclose(f);
1671    } else {
1672       GET_CURRENT_CONTEXT(ctx);
1673       _mesa_warning(ctx, "could not open %s for dumping shader (%s)", name,
1674                     strerror(errno));
1675    }
1676    ralloc_free(name);
1677 }
1678 
1679 /**
1680  * Read shader source code from a file.
1681  * Useful for debugging to override an app's shader.
1682  */
1683 static GLcharARB *
read_shader(const gl_shader_stage stage,const char * source)1684 read_shader(const gl_shader_stage stage, const char *source)
1685 {
1686    char *read_path;
1687    static bool path_exists = true;
1688    int len, shader_size = 0;
1689    GLcharARB *buffer;
1690    FILE *f;
1691 
1692    if (!path_exists)
1693       return NULL;
1694 
1695    read_path = getenv("MESA_SHADER_READ_PATH");
1696    if (!read_path) {
1697       path_exists = false;
1698       return NULL;
1699    }
1700 
1701    char *name = construct_name(stage, source, read_path);
1702    f = fopen(name, "r");
1703    ralloc_free(name);
1704    if (!f)
1705       return NULL;
1706 
1707    /* allocate enough room for the entire shader */
1708    fseek(f, 0, SEEK_END);
1709    shader_size = ftell(f);
1710    rewind(f);
1711    assert(shader_size);
1712 
1713    /* add one for terminating zero */
1714    shader_size++;
1715 
1716    buffer = malloc(shader_size);
1717    assert(buffer);
1718 
1719    len = fread(buffer, 1, shader_size, f);
1720    buffer[len] = 0;
1721 
1722    fclose(f);
1723 
1724    return buffer;
1725 }
1726 
1727 #endif /* ENABLE_SHADER_CACHE */
1728 
1729 /**
1730  * Called via glShaderSource() and glShaderSourceARB() API functions.
1731  * Basically, concatenate the source code strings into one long string
1732  * and pass it to _mesa_shader_source().
1733  */
1734 void GLAPIENTRY
_mesa_ShaderSource(GLuint shaderObj,GLsizei count,const GLchar * const * string,const GLint * length)1735 _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
1736                    const GLchar * const * string, const GLint * length)
1737 {
1738    GET_CURRENT_CONTEXT(ctx);
1739    GLint *offsets;
1740    GLsizei i, totalLength;
1741    GLcharARB *source;
1742    struct gl_shader *sh;
1743 
1744    sh = _mesa_lookup_shader_err(ctx, shaderObj, "glShaderSourceARB");
1745    if (!sh)
1746       return;
1747 
1748    if (string == NULL) {
1749       _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
1750       return;
1751    }
1752 
1753    /*
1754     * This array holds offsets of where the appropriate string ends, thus the
1755     * last element will be set to the total length of the source code.
1756     */
1757    offsets = malloc(count * sizeof(GLint));
1758    if (offsets == NULL) {
1759       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1760       return;
1761    }
1762 
1763    for (i = 0; i < count; i++) {
1764       if (string[i] == NULL) {
1765          free((GLvoid *) offsets);
1766          _mesa_error(ctx, GL_INVALID_OPERATION,
1767                      "glShaderSourceARB(null string)");
1768          return;
1769       }
1770       if (length == NULL || length[i] < 0)
1771          offsets[i] = strlen(string[i]);
1772       else
1773          offsets[i] = length[i];
1774       /* accumulate string lengths */
1775       if (i > 0)
1776          offsets[i] += offsets[i - 1];
1777    }
1778 
1779    /* Total length of source string is sum off all strings plus two.
1780     * One extra byte for terminating zero, another extra byte to silence
1781     * valgrind warnings in the parser/grammer code.
1782     */
1783    totalLength = offsets[count - 1] + 2;
1784    source = malloc(totalLength * sizeof(GLcharARB));
1785    if (source == NULL) {
1786       free((GLvoid *) offsets);
1787       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1788       return;
1789    }
1790 
1791    for (i = 0; i < count; i++) {
1792       GLint start = (i > 0) ? offsets[i - 1] : 0;
1793       memcpy(source + start, string[i],
1794              (offsets[i] - start) * sizeof(GLcharARB));
1795    }
1796    source[totalLength - 1] = '\0';
1797    source[totalLength - 2] = '\0';
1798 
1799 #ifdef ENABLE_SHADER_CACHE
1800    GLcharARB *replacement;
1801 
1802    /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
1803     * if corresponding entry found from MESA_SHADER_READ_PATH.
1804     */
1805    dump_shader(sh->Stage, source);
1806 
1807    replacement = read_shader(sh->Stage, source);
1808    if (replacement) {
1809       free(source);
1810       source = replacement;
1811    }
1812 #endif /* ENABLE_SHADER_CACHE */
1813 
1814    shader_source(sh, source);
1815 
1816    free(offsets);
1817 }
1818 
1819 
1820 void GLAPIENTRY
_mesa_UseProgram(GLuint program)1821 _mesa_UseProgram(GLuint program)
1822 {
1823    GET_CURRENT_CONTEXT(ctx);
1824    struct gl_shader_program *shProg;
1825 
1826    if (MESA_VERBOSE & VERBOSE_API)
1827       _mesa_debug(ctx, "glUseProgram %u\n", program);
1828 
1829    if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1830       _mesa_error(ctx, GL_INVALID_OPERATION,
1831                   "glUseProgram(transform feedback active)");
1832       return;
1833    }
1834 
1835    if (program) {
1836       shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1837       if (!shProg) {
1838          return;
1839       }
1840       if (!shProg->data->LinkStatus) {
1841          _mesa_error(ctx, GL_INVALID_OPERATION,
1842                      "glUseProgram(program %u not linked)", program);
1843          return;
1844       }
1845 
1846       /* debug code */
1847       if (ctx->_Shader->Flags & GLSL_USE_PROG) {
1848          print_shader_info(shProg);
1849       }
1850    }
1851    else {
1852       shProg = NULL;
1853    }
1854 
1855    /* The ARB_separate_shader_object spec says:
1856     *
1857     *     "The executable code for an individual shader stage is taken from
1858     *     the current program for that stage.  If there is a current program
1859     *     object established by UseProgram, that program is considered current
1860     *     for all stages.  Otherwise, if there is a bound program pipeline
1861     *     object (section 2.14.PPO), the program bound to the appropriate
1862     *     stage of the pipeline object is considered current."
1863     */
1864    if (program) {
1865       /* Attach shader state to the binding point */
1866       _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
1867       /* Update the program */
1868       _mesa_use_program(ctx, shProg);
1869    } else {
1870       /* Must be done first: detach the progam */
1871       _mesa_use_program(ctx, shProg);
1872       /* Unattach shader_state binding point */
1873       _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
1874       /* If a pipeline was bound, rebind it */
1875       if (ctx->Pipeline.Current) {
1876          _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
1877       }
1878    }
1879 }
1880 
1881 
1882 void GLAPIENTRY
_mesa_ValidateProgram(GLuint program)1883 _mesa_ValidateProgram(GLuint program)
1884 {
1885    GET_CURRENT_CONTEXT(ctx);
1886    validate_program(ctx, program);
1887 }
1888 
1889 
1890 /**
1891  * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1892  */
1893 void GLAPIENTRY
_mesa_GetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)1894 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1895                                GLint* range, GLint* precision)
1896 {
1897    const struct gl_program_constants *limits;
1898    const struct gl_precision *p;
1899    GET_CURRENT_CONTEXT(ctx);
1900 
1901    switch (shadertype) {
1902    case GL_VERTEX_SHADER:
1903       limits = &ctx->Const.Program[MESA_SHADER_VERTEX];
1904       break;
1905    case GL_FRAGMENT_SHADER:
1906       limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT];
1907       break;
1908    default:
1909       _mesa_error(ctx, GL_INVALID_ENUM,
1910                   "glGetShaderPrecisionFormat(shadertype)");
1911       return;
1912    }
1913 
1914    switch (precisiontype) {
1915    case GL_LOW_FLOAT:
1916       p = &limits->LowFloat;
1917       break;
1918    case GL_MEDIUM_FLOAT:
1919       p = &limits->MediumFloat;
1920       break;
1921    case GL_HIGH_FLOAT:
1922       p = &limits->HighFloat;
1923       break;
1924    case GL_LOW_INT:
1925       p = &limits->LowInt;
1926       break;
1927    case GL_MEDIUM_INT:
1928       p = &limits->MediumInt;
1929       break;
1930    case GL_HIGH_INT:
1931       p = &limits->HighInt;
1932       break;
1933    default:
1934       _mesa_error(ctx, GL_INVALID_ENUM,
1935                   "glGetShaderPrecisionFormat(precisiontype)");
1936       return;
1937    }
1938 
1939    range[0] = p->RangeMin;
1940    range[1] = p->RangeMax;
1941    precision[0] = p->Precision;
1942 }
1943 
1944 
1945 /**
1946  * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1947  */
1948 void GLAPIENTRY
_mesa_ReleaseShaderCompiler(void)1949 _mesa_ReleaseShaderCompiler(void)
1950 {
1951    _mesa_destroy_shader_compiler_caches();
1952 }
1953 
1954 
1955 /**
1956  * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1957  */
1958 void GLAPIENTRY
_mesa_ShaderBinary(GLint n,const GLuint * shaders,GLenum binaryformat,const void * binary,GLint length)1959 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1960                    const void* binary, GLint length)
1961 {
1962    GET_CURRENT_CONTEXT(ctx);
1963    (void) shaders;
1964    (void) binaryformat;
1965    (void) binary;
1966 
1967    /* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and
1968     * page 88 of the OpenGL 4.5 specs state:
1969     *
1970     *     "An INVALID_VALUE error is generated if count or length is negative.
1971     *      An INVALID_ENUM error is generated if binaryformat is not a supported
1972     *      format returned in SHADER_BINARY_FORMATS."
1973     */
1974    if (n < 0 || length < 0) {
1975       _mesa_error(ctx, GL_INVALID_VALUE, "glShaderBinary(count or length < 0)");
1976       return;
1977    }
1978 
1979    _mesa_error(ctx, GL_INVALID_ENUM, "glShaderBinary(format)");
1980 }
1981 
1982 
1983 void GLAPIENTRY
_mesa_GetProgramBinary(GLuint program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,GLvoid * binary)1984 _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
1985                        GLenum *binaryFormat, GLvoid *binary)
1986 {
1987    struct gl_shader_program *shProg;
1988    GLsizei length_dummy;
1989    GET_CURRENT_CONTEXT(ctx);
1990 
1991    if (bufSize < 0){
1992       _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
1993       return;
1994    }
1995 
1996    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
1997    if (!shProg)
1998       return;
1999 
2000    /* The ARB_get_program_binary spec says:
2001     *
2002     *     "If <length> is NULL, then no length is returned."
2003     *
2004     * Ensure that length always points to valid storage to avoid multiple NULL
2005     * pointer checks below.
2006     */
2007    if (length == NULL)
2008       length = &length_dummy;
2009 
2010 
2011    /* The ARB_get_program_binary spec says:
2012     *
2013     *     "When a program object's LINK_STATUS is FALSE, its program binary
2014     *     length is zero, and a call to GetProgramBinary will generate an
2015     *     INVALID_OPERATION error.
2016     */
2017    if (!shProg->data->LinkStatus) {
2018       _mesa_error(ctx, GL_INVALID_OPERATION,
2019                   "glGetProgramBinary(program %u not linked)",
2020                   shProg->Name);
2021       *length = 0;
2022       return;
2023    }
2024 
2025    *length = 0;
2026    _mesa_error(ctx, GL_INVALID_OPERATION,
2027                "glGetProgramBinary(driver supports zero binary formats)");
2028 
2029    (void) binaryFormat;
2030    (void) binary;
2031 }
2032 
2033 void GLAPIENTRY
_mesa_ProgramBinary(GLuint program,GLenum binaryFormat,const GLvoid * binary,GLsizei length)2034 _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
2035                     const GLvoid *binary, GLsizei length)
2036 {
2037    struct gl_shader_program *shProg;
2038    GET_CURRENT_CONTEXT(ctx);
2039 
2040    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary");
2041    if (!shProg)
2042       return;
2043 
2044    (void) binaryFormat;
2045    (void) binary;
2046 
2047    /* Section 2.3.1 (Errors) of the OpenGL 4.5 spec says:
2048     *
2049     *     "If a negative number is provided where an argument of type sizei or
2050     *     sizeiptr is specified, an INVALID_VALUE error is generated."
2051     */
2052    if (length < 0) {
2053       _mesa_error(ctx, GL_INVALID_VALUE, "glProgramBinary(length < 0)");
2054       return;
2055    }
2056 
2057    /* The ARB_get_program_binary spec says:
2058     *
2059     *     "<binaryFormat> and <binary> must be those returned by a previous
2060     *     call to GetProgramBinary, and <length> must be the length of the
2061     *     program binary as returned by GetProgramBinary or GetProgramiv with
2062     *     <pname> PROGRAM_BINARY_LENGTH. Loading the program binary will fail,
2063     *     setting the LINK_STATUS of <program> to FALSE, if these conditions
2064     *     are not met."
2065     *
2066     * Since any value of binaryFormat passed "is not one of those specified as
2067     * allowable for [this] command, an INVALID_ENUM error is generated."
2068     */
2069    shProg->data->LinkStatus = GL_FALSE;
2070    _mesa_error(ctx, GL_INVALID_ENUM, "glProgramBinary");
2071 }
2072 
2073 
2074 void GLAPIENTRY
_mesa_ProgramParameteri(GLuint program,GLenum pname,GLint value)2075 _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
2076 {
2077    struct gl_shader_program *shProg;
2078    GET_CURRENT_CONTEXT(ctx);
2079 
2080    shProg = _mesa_lookup_shader_program_err(ctx, program,
2081                                             "glProgramParameteri");
2082    if (!shProg)
2083       return;
2084 
2085    switch (pname) {
2086    case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
2087       /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
2088        * is part of OpenGL ES 3.0.  For the ES2 case, this function shouldn't
2089        * even be in the dispatch table, so we shouldn't need to expclicitly
2090        * check here.
2091        *
2092        * On desktop, we ignore the 3.0+ requirement because it is silly.
2093        */
2094 
2095       /* The ARB_get_program_binary extension spec says:
2096        *
2097        *     "An INVALID_VALUE error is generated if the <value> argument to
2098        *     ProgramParameteri is not TRUE or FALSE."
2099        */
2100       if (value != GL_TRUE && value != GL_FALSE) {
2101          goto invalid_value;
2102       }
2103 
2104       /* No need to notify the driver.  Any changes will actually take effect
2105        * the next time the shader is linked.
2106        *
2107        * The ARB_get_program_binary extension spec says:
2108        *
2109        *     "To indicate that a program binary is likely to be retrieved,
2110        *     ProgramParameteri should be called with <pname>
2111        *     PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
2112        *     will not be in effect until the next time LinkProgram or
2113        *     ProgramBinary has been called successfully."
2114        *
2115        * The resloution of issue 9 in the extension spec also says:
2116        *
2117        *     "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
2118        *     to indicate to the GL implementation that this program will
2119        *     likely be saved with GetProgramBinary at some point. This will
2120        *     give the GL implementation the opportunity to track any state
2121        *     changes made to the program before being saved such that when it
2122        *     is loaded again a recompile can be avoided."
2123        */
2124       shProg->BinaryRetreivableHint = value;
2125       return;
2126 
2127    case GL_PROGRAM_SEPARABLE:
2128       /* Spec imply that the behavior is the same as ARB_get_program_binary
2129        * Chapter 7.3 Program Objects
2130        */
2131       if (value != GL_TRUE && value != GL_FALSE) {
2132          goto invalid_value;
2133       }
2134       shProg->SeparateShader = value;
2135       return;
2136 
2137    default:
2138       _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
2139                   _mesa_enum_to_string(pname));
2140       return;
2141    }
2142 
2143 invalid_value:
2144    _mesa_error(ctx, GL_INVALID_VALUE,
2145                "glProgramParameteri(pname=%s, value=%d): "
2146                "value must be 0 or 1.",
2147                _mesa_enum_to_string(pname),
2148                value);
2149 }
2150 
2151 
2152 void
_mesa_use_shader_program(struct gl_context * ctx,GLenum type,struct gl_shader_program * shProg,struct gl_pipeline_object * shTarget)2153 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
2154                          struct gl_shader_program *shProg,
2155                          struct gl_pipeline_object *shTarget)
2156 {
2157    gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type);
2158    use_shader_program(ctx, stage, shProg, shTarget);
2159 }
2160 
2161 
2162 /**
2163  * Copy program-specific data generated by linking from the gl_shader_program
2164  * object to the gl_program object referred to by the gl_linked_shader.
2165  *
2166  * This function expects _mesa_reference_program() to have been previously
2167  * called setting the gl_linked_shaders program reference.
2168  */
2169 void
_mesa_copy_linked_program_data(const struct gl_shader_program * src,struct gl_linked_shader * dst_sh)2170 _mesa_copy_linked_program_data(const struct gl_shader_program *src,
2171                                struct gl_linked_shader *dst_sh)
2172 {
2173    assert(dst_sh->Program);
2174 
2175    struct gl_program *dst = dst_sh->Program;
2176 
2177    dst->info.separate_shader = src->SeparateShader;
2178 
2179    switch (dst_sh->Stage) {
2180    case MESA_SHADER_VERTEX:
2181       dst->ClipDistanceArraySize = src->Vert.ClipDistanceArraySize;
2182       dst->CullDistanceArraySize = src->Vert.CullDistanceArraySize;
2183       break;
2184    case MESA_SHADER_TESS_CTRL: {
2185       dst->info.tess.tcs_vertices_out = dst_sh->info.TessCtrl.VerticesOut;
2186       break;
2187    }
2188    case MESA_SHADER_TESS_EVAL: {
2189       dst->info.tess.primitive_mode = dst_sh->info.TessEval.PrimitiveMode;
2190       dst->info.tess.spacing = dst_sh->info.TessEval.Spacing;
2191       dst->info.tess.ccw = dst_sh->info.TessEval.VertexOrder == GL_CCW;
2192       dst->info.tess.point_mode = dst_sh->info.TessEval.PointMode;
2193       dst->ClipDistanceArraySize = src->TessEval.ClipDistanceArraySize;
2194       dst->CullDistanceArraySize = src->TessEval.CullDistanceArraySize;
2195       break;
2196    }
2197    case MESA_SHADER_GEOMETRY: {
2198       dst->info.gs.vertices_in = src->Geom.VerticesIn;
2199       dst->info.gs.vertices_out = dst_sh->info.Geom.VerticesOut;
2200       dst->info.gs.invocations = dst_sh->info.Geom.Invocations;
2201       dst->info.gs.input_primitive = dst_sh->info.Geom.InputType;
2202       dst->info.gs.output_primitive = dst_sh->info.Geom.OutputType;
2203       dst->ClipDistanceArraySize = src->Geom.ClipDistanceArraySize;
2204       dst->CullDistanceArraySize = src->Geom.CullDistanceArraySize;
2205       dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive;
2206       dst->info.gs.uses_streams = src->Geom.UsesStreams;
2207       break;
2208    }
2209    case MESA_SHADER_FRAGMENT: {
2210       dst->info.fs.depth_layout = src->FragDepthLayout;
2211       dst->info.fs.early_fragment_tests = dst_sh->info.EarlyFragmentTests;
2212       dst->info.fs.inner_coverage = dst_sh->info.InnerCoverage;
2213       dst->info.fs.post_depth_coverage = dst_sh->info.PostDepthCoverage;
2214       break;
2215    }
2216    case MESA_SHADER_COMPUTE: {
2217       for (int i = 0; i < 3; i++)
2218          dst->info.cs.local_size[i] = src->Comp.LocalSize[i];
2219       dst->info.cs.shared_size = src->Comp.SharedSize;
2220       dst->info.cs.local_size_variable = src->Comp.LocalSizeVariable;
2221       break;
2222    }
2223    default:
2224       break;
2225    }
2226 }
2227 
2228 /**
2229  * ARB_separate_shader_objects: Compile & Link Program
2230  */
2231 GLuint GLAPIENTRY
_mesa_CreateShaderProgramv(GLenum type,GLsizei count,const GLchar * const * strings)2232 _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
2233                            const GLchar* const *strings)
2234 {
2235    GET_CURRENT_CONTEXT(ctx);
2236 
2237    const GLuint shader = create_shader(ctx, type);
2238    GLuint program = 0;
2239 
2240    /*
2241     * According to OpenGL 4.5 and OpenGL ES 3.1 standards, section 7.3:
2242     * GL_INVALID_VALUE should be generated if count < 0
2243     */
2244    if (count < 0) {
2245       _mesa_error(ctx, GL_INVALID_VALUE, "glCreateShaderProgram (count < 0)");
2246       return program;
2247    }
2248 
2249    if (shader) {
2250       struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
2251 
2252       _mesa_ShaderSource(shader, count, strings, NULL);
2253       _mesa_compile_shader(ctx, sh);
2254 
2255       program = create_shader_program(ctx);
2256       if (program) {
2257 	 struct gl_shader_program *shProg;
2258 	 GLint compiled = GL_FALSE;
2259 
2260 	 shProg = _mesa_lookup_shader_program(ctx, program);
2261 
2262 	 shProg->SeparateShader = GL_TRUE;
2263 
2264 	 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
2265 	 if (compiled) {
2266 	    attach_shader(ctx, program, shader);
2267 	    _mesa_link_program(ctx, shProg);
2268 	    detach_shader(ctx, program, shader);
2269 
2270 #if 0
2271 	    /* Possibly... */
2272 	    if (active-user-defined-varyings-in-linked-program) {
2273 	       append-error-to-info-log;
2274                shProg->data->LinkStatus = GL_FALSE;
2275 	    }
2276 #endif
2277 	 }
2278          if (sh->InfoLog)
2279             ralloc_strcat(&shProg->data->InfoLog, sh->InfoLog);
2280       }
2281 
2282       delete_shader(ctx, shader);
2283    }
2284 
2285    return program;
2286 }
2287 
2288 
2289 /**
2290  * For GL_ARB_tessellation_shader
2291  */
2292 extern void GLAPIENTRY
_mesa_PatchParameteri(GLenum pname,GLint value)2293 _mesa_PatchParameteri(GLenum pname, GLint value)
2294 {
2295    GET_CURRENT_CONTEXT(ctx);
2296 
2297    if (!_mesa_has_tessellation(ctx)) {
2298       _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameteri");
2299       return;
2300    }
2301 
2302    if (pname != GL_PATCH_VERTICES) {
2303       _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameteri");
2304       return;
2305    }
2306 
2307    if (value <= 0 || value > ctx->Const.MaxPatchVertices) {
2308       _mesa_error(ctx, GL_INVALID_VALUE, "glPatchParameteri");
2309       return;
2310    }
2311 
2312    ctx->TessCtrlProgram.patch_vertices = value;
2313 }
2314 
2315 
2316 extern void GLAPIENTRY
_mesa_PatchParameterfv(GLenum pname,const GLfloat * values)2317 _mesa_PatchParameterfv(GLenum pname, const GLfloat *values)
2318 {
2319    GET_CURRENT_CONTEXT(ctx);
2320 
2321    if (!_mesa_has_tessellation(ctx)) {
2322       _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameterfv");
2323       return;
2324    }
2325 
2326    switch(pname) {
2327    case GL_PATCH_DEFAULT_OUTER_LEVEL:
2328       FLUSH_VERTICES(ctx, 0);
2329       memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values,
2330              4 * sizeof(GLfloat));
2331       ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
2332       return;
2333    case GL_PATCH_DEFAULT_INNER_LEVEL:
2334       FLUSH_VERTICES(ctx, 0);
2335       memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values,
2336              2 * sizeof(GLfloat));
2337       ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
2338       return;
2339    default:
2340       _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv");
2341       return;
2342    }
2343 }
2344 
2345 /**
2346  * ARB_shader_subroutine
2347  */
2348 GLint GLAPIENTRY
_mesa_GetSubroutineUniformLocation(GLuint program,GLenum shadertype,const GLchar * name)2349 _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
2350                                    const GLchar *name)
2351 {
2352    GET_CURRENT_CONTEXT(ctx);
2353    const char *api_name = "glGetSubroutineUniformLocation";
2354    struct gl_shader_program *shProg;
2355    GLenum resource_type;
2356    gl_shader_stage stage;
2357 
2358    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2359       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2360       return -1;
2361    }
2362 
2363    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2364       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2365       return -1;
2366    }
2367 
2368    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2369    if (!shProg)
2370       return -1;
2371 
2372    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2373    if (!shProg->_LinkedShaders[stage]) {
2374       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2375       return -1;
2376    }
2377 
2378    resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2379    return _mesa_program_resource_location(shProg, resource_type, name);
2380 }
2381 
2382 GLuint GLAPIENTRY
_mesa_GetSubroutineIndex(GLuint program,GLenum shadertype,const GLchar * name)2383 _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
2384                          const GLchar *name)
2385 {
2386    GET_CURRENT_CONTEXT(ctx);
2387    const char *api_name = "glGetSubroutineIndex";
2388    struct gl_shader_program *shProg;
2389    struct gl_program_resource *res;
2390    GLenum resource_type;
2391    gl_shader_stage stage;
2392 
2393    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2394       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2395       return -1;
2396    }
2397 
2398    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2399       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2400       return -1;
2401    }
2402 
2403    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2404    if (!shProg)
2405       return -1;
2406 
2407    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2408    if (!shProg->_LinkedShaders[stage]) {
2409       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2410       return -1;
2411    }
2412 
2413    resource_type = _mesa_shader_stage_to_subroutine(stage);
2414    res = _mesa_program_resource_find_name(shProg, resource_type, name, NULL);
2415    if (!res) {
2416      return -1;
2417    }
2418 
2419    return _mesa_program_resource_index(shProg, res);
2420 }
2421 
2422 
2423 GLvoid GLAPIENTRY
_mesa_GetActiveSubroutineUniformiv(GLuint program,GLenum shadertype,GLuint index,GLenum pname,GLint * values)2424 _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
2425                                    GLuint index, GLenum pname, GLint *values)
2426 {
2427    GET_CURRENT_CONTEXT(ctx);
2428    const char *api_name = "glGetActiveSubroutineUniformiv";
2429    struct gl_shader_program *shProg;
2430    struct gl_linked_shader *sh;
2431    gl_shader_stage stage;
2432    struct gl_program_resource *res;
2433    const struct gl_uniform_storage *uni;
2434    GLenum resource_type;
2435    int count, i, j;
2436 
2437    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2438       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2439       return;
2440    }
2441 
2442    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2443       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2444       return;
2445    }
2446 
2447    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2448    if (!shProg)
2449       return;
2450 
2451    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2452    resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2453 
2454    sh = shProg->_LinkedShaders[stage];
2455    if (!sh) {
2456       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2457       return;
2458    }
2459 
2460    struct gl_program *p = shProg->_LinkedShaders[stage]->Program;
2461    if (index >= p->sh.NumSubroutineUniforms) {
2462       _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name);
2463       return;
2464    }
2465 
2466    switch (pname) {
2467    case GL_NUM_COMPATIBLE_SUBROUTINES: {
2468       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2469       if (res) {
2470          uni = res->Data;
2471          values[0] = uni->num_compatible_subroutines;
2472       }
2473       break;
2474    }
2475    case GL_COMPATIBLE_SUBROUTINES: {
2476       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2477       if (res) {
2478          uni = res->Data;
2479          count = 0;
2480          for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
2481             struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
2482             for (j = 0; j < fn->num_compat_types; j++) {
2483                if (fn->types[j] == uni->type) {
2484                   values[count++] = i;
2485                   break;
2486                }
2487             }
2488          }
2489       }
2490       break;
2491    }
2492    case GL_UNIFORM_SIZE:
2493       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2494       if (res) {
2495          uni = res->Data;
2496          values[0] = uni->array_elements ? uni->array_elements : 1;
2497       }
2498       break;
2499    case GL_UNIFORM_NAME_LENGTH:
2500       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2501       if (res) {
2502          values[0] = strlen(_mesa_program_resource_name(res)) + 1
2503             + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
2504       }
2505       break;
2506    default:
2507       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2508       return;
2509    }
2510 }
2511 
2512 
2513 GLvoid GLAPIENTRY
_mesa_GetActiveSubroutineUniformName(GLuint program,GLenum shadertype,GLuint index,GLsizei bufsize,GLsizei * length,GLchar * name)2514 _mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype,
2515                                      GLuint index, GLsizei bufsize,
2516                                      GLsizei *length, GLchar *name)
2517 {
2518    GET_CURRENT_CONTEXT(ctx);
2519    const char *api_name = "glGetActiveSubroutineUniformName";
2520    struct gl_shader_program *shProg;
2521    GLenum resource_type;
2522    gl_shader_stage stage;
2523 
2524    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2525       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2526       return;
2527    }
2528 
2529    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2530       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2531       return;
2532    }
2533 
2534    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2535    if (!shProg)
2536       return;
2537 
2538    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2539    if (!shProg->_LinkedShaders[stage]) {
2540       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2541       return;
2542    }
2543 
2544    resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2545    /* get program resource name */
2546    _mesa_get_program_resource_name(shProg, resource_type,
2547                                    index, bufsize,
2548                                    length, name, api_name);
2549 }
2550 
2551 
2552 GLvoid GLAPIENTRY
_mesa_GetActiveSubroutineName(GLuint program,GLenum shadertype,GLuint index,GLsizei bufsize,GLsizei * length,GLchar * name)2553 _mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype,
2554                               GLuint index, GLsizei bufsize,
2555                               GLsizei *length, GLchar *name)
2556 {
2557    GET_CURRENT_CONTEXT(ctx);
2558    const char *api_name = "glGetActiveSubroutineName";
2559    struct gl_shader_program *shProg;
2560    GLenum resource_type;
2561    gl_shader_stage stage;
2562 
2563    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2564       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2565       return;
2566    }
2567 
2568    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2569       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2570       return;
2571    }
2572 
2573    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2574    if (!shProg)
2575       return;
2576 
2577    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2578    if (!shProg->_LinkedShaders[stage]) {
2579       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2580       return;
2581    }
2582    resource_type = _mesa_shader_stage_to_subroutine(stage);
2583    _mesa_get_program_resource_name(shProg, resource_type,
2584                                    index, bufsize,
2585                                    length, name, api_name);
2586 }
2587 
2588 GLvoid GLAPIENTRY
_mesa_UniformSubroutinesuiv(GLenum shadertype,GLsizei count,const GLuint * indices)2589 _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
2590                             const GLuint *indices)
2591 {
2592    GET_CURRENT_CONTEXT(ctx);
2593    const char *api_name = "glUniformSubroutinesuiv";
2594    struct gl_shader_program *shProg;
2595    struct gl_linked_shader *sh;
2596    gl_shader_stage stage;
2597    int i;
2598 
2599    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2600       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2601       return;
2602    }
2603 
2604    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2605       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2606       return;
2607    }
2608 
2609    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2610    shProg = ctx->_Shader->CurrentProgram[stage];
2611    if (!shProg) {
2612       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2613       return;
2614    }
2615 
2616    sh = shProg->_LinkedShaders[stage];
2617    if (!sh) {
2618       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2619       return;
2620    }
2621 
2622    struct gl_program *p = shProg->_LinkedShaders[stage]->Program;
2623    if (count != p->sh.NumSubroutineUniformRemapTable) {
2624       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
2625       return;
2626    }
2627 
2628    i = 0;
2629    do {
2630       struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
2631       if (uni == NULL) {
2632          i++;
2633          continue;
2634       }
2635 
2636       int uni_count = uni->array_elements ? uni->array_elements : 1;
2637       int j, k, f;
2638 
2639       for (j = i; j < i + uni_count; j++) {
2640          struct gl_subroutine_function *subfn = NULL;
2641          if (indices[j] > p->sh.MaxSubroutineFunctionIndex) {
2642             _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
2643             return;
2644          }
2645 
2646          for (f = 0; f < p->sh.NumSubroutineFunctions; f++) {
2647             if (p->sh.SubroutineFunctions[f].index == indices[j])
2648                subfn = &p->sh.SubroutineFunctions[f];
2649          }
2650 
2651          if (!subfn) {
2652             continue;
2653          }
2654 
2655          for (k = 0; k < subfn->num_compat_types; k++) {
2656             if (subfn->types[k] == uni->type)
2657                break;
2658          }
2659          if (k == subfn->num_compat_types) {
2660             _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2661             return;
2662          }
2663 
2664          ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j];
2665       }
2666       i += uni_count;
2667    } while(i < count);
2668 
2669    FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
2670 }
2671 
2672 
2673 GLvoid GLAPIENTRY
_mesa_GetUniformSubroutineuiv(GLenum shadertype,GLint location,GLuint * params)2674 _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
2675                               GLuint *params)
2676 {
2677    GET_CURRENT_CONTEXT(ctx);
2678    const char *api_name = "glGetUniformSubroutineuiv";
2679    struct gl_shader_program *shProg;
2680    struct gl_linked_shader *sh;
2681    gl_shader_stage stage;
2682 
2683    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2684       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2685       return;
2686    }
2687 
2688    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2689       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2690       return;
2691    }
2692 
2693    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2694    shProg = ctx->_Shader->CurrentProgram[stage];
2695    if (!shProg) {
2696       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2697       return;
2698    }
2699 
2700    sh = shProg->_LinkedShaders[stage];
2701    if (!sh) {
2702       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2703       return;
2704    }
2705 
2706    struct gl_program *p = sh->Program;
2707    if (location >= p->sh.NumSubroutineUniformRemapTable) {
2708       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
2709       return;
2710    }
2711 
2712    *params = ctx->SubroutineIndex[p->info.stage].IndexPtr[location];
2713 }
2714 
2715 
2716 GLvoid GLAPIENTRY
_mesa_GetProgramStageiv(GLuint program,GLenum shadertype,GLenum pname,GLint * values)2717 _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
2718                         GLenum pname, GLint *values)
2719 {
2720    GET_CURRENT_CONTEXT(ctx);
2721    const char *api_name = "glGetProgramStageiv";
2722    struct gl_shader_program *shProg;
2723    struct gl_linked_shader *sh;
2724    gl_shader_stage stage;
2725 
2726    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2727       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2728       return;
2729    }
2730 
2731    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2732       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2733       return;
2734    }
2735 
2736    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2737    if (!shProg)
2738       return;
2739 
2740    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2741    sh = shProg->_LinkedShaders[stage];
2742 
2743    /* ARB_shader_subroutine doesn't ask the program to be linked, or list any
2744     * INVALID_OPERATION in the case of not be linked.
2745     *
2746     * And for some pnames, like GL_ACTIVE_SUBROUTINE_UNIFORMS, you can ask the
2747     * same info using other specs (ARB_program_interface_query), without the
2748     * need of the program to be linked, being the value for that case 0.
2749     *
2750     * But at the same time, some other methods require the program to be
2751     * linked for pname related to locations, so it would be inconsistent to
2752     * not do the same here. So we are:
2753     *   * Return GL_INVALID_OPERATION if not linked only for locations.
2754     *   * Setting a default value of 0, to be returned if not linked.
2755     */
2756    if (!sh) {
2757       values[0] = 0;
2758       if (pname == GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS) {
2759          _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2760       }
2761       return;
2762    }
2763 
2764    struct gl_program *p = sh->Program;
2765    switch (pname) {
2766    case GL_ACTIVE_SUBROUTINES:
2767       values[0] = p->sh.NumSubroutineFunctions;
2768       break;
2769    case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS:
2770       values[0] = p->sh.NumSubroutineUniformRemapTable;
2771       break;
2772    case GL_ACTIVE_SUBROUTINE_UNIFORMS:
2773       values[0] = p->sh.NumSubroutineUniforms;
2774       break;
2775    case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
2776    {
2777       unsigned i;
2778       GLint max_len = 0;
2779       GLenum resource_type;
2780       struct gl_program_resource *res;
2781 
2782       resource_type = _mesa_shader_stage_to_subroutine(stage);
2783       for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
2784          res = _mesa_program_resource_find_index(shProg, resource_type, i);
2785          if (res) {
2786             const GLint len = strlen(_mesa_program_resource_name(res)) + 1;
2787             if (len > max_len)
2788                max_len = len;
2789          }
2790       }
2791       values[0] = max_len;
2792       break;
2793    }
2794    case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH:
2795    {
2796       unsigned i;
2797       GLint max_len = 0;
2798       GLenum resource_type;
2799       struct gl_program_resource *res;
2800 
2801       resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2802       for (i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) {
2803          res = _mesa_program_resource_find_index(shProg, resource_type, i);
2804          if (res) {
2805             const GLint len = strlen(_mesa_program_resource_name(res)) + 1
2806                + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
2807 
2808             if (len > max_len)
2809                max_len = len;
2810          }
2811       }
2812       values[0] = max_len;
2813       break;
2814    }
2815    default:
2816       _mesa_error(ctx, GL_INVALID_ENUM, "%s", api_name);
2817       values[0] = -1;
2818       break;
2819    }
2820 }
2821 
2822 static int
find_compat_subroutine(struct gl_program * p,const struct glsl_type * type)2823 find_compat_subroutine(struct gl_program *p, const struct glsl_type *type)
2824 {
2825    int i, j;
2826 
2827    for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
2828       struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
2829       for (j = 0; j < fn->num_compat_types; j++) {
2830          if (fn->types[j] == type)
2831             return i;
2832       }
2833    }
2834    return 0;
2835 }
2836 
2837 static void
_mesa_shader_write_subroutine_index(struct gl_context * ctx,struct gl_program * p)2838 _mesa_shader_write_subroutine_index(struct gl_context *ctx,
2839                                     struct gl_program *p)
2840 {
2841    int i, j;
2842 
2843    if (p->sh.NumSubroutineUniformRemapTable == 0)
2844       return;
2845 
2846    i = 0;
2847    do {
2848       struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
2849       int uni_count;
2850       int val;
2851 
2852       if (!uni) {
2853          i++;
2854          continue;
2855       }
2856 
2857       uni_count = uni->array_elements ? uni->array_elements : 1;
2858       for (j = 0; j < uni_count; j++) {
2859          val = ctx->SubroutineIndex[p->info.stage].IndexPtr[i + j];
2860          memcpy(&uni->storage[j], &val, sizeof(int));
2861       }
2862 
2863       _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
2864       i += uni_count;
2865    } while(i < p->sh.NumSubroutineUniformRemapTable);
2866 }
2867 
2868 void
_mesa_shader_write_subroutine_indices(struct gl_context * ctx,gl_shader_stage stage)2869 _mesa_shader_write_subroutine_indices(struct gl_context *ctx,
2870                                       gl_shader_stage stage)
2871 {
2872    if (ctx->_Shader->CurrentProgram[stage] &&
2873        ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage])
2874       _mesa_shader_write_subroutine_index(ctx,
2875                                           ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]->Program);
2876 }
2877 
2878 static void
_mesa_program_init_subroutine_defaults(struct gl_context * ctx,struct gl_program * p)2879 _mesa_program_init_subroutine_defaults(struct gl_context *ctx,
2880                                        struct gl_program *p)
2881 {
2882    assert(p);
2883 
2884    struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[p->info.stage];
2885    if (binding->NumIndex != p->sh.NumSubroutineUniformRemapTable) {
2886       binding->IndexPtr = realloc(binding->IndexPtr,
2887                                   p->sh.NumSubroutineUniformRemapTable * (sizeof(GLuint)));
2888       binding->NumIndex = p->sh.NumSubroutineUniformRemapTable;
2889    }
2890 
2891    for (int i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) {
2892       struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
2893 
2894       if (!uni)
2895          continue;
2896 
2897       binding->IndexPtr[i] = find_compat_subroutine(p, uni->type);
2898    }
2899 }
2900 
2901 void
_mesa_shader_program_init_subroutine_defaults(struct gl_context * ctx,struct gl_shader_program * shProg)2902 _mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
2903                                               struct gl_shader_program *shProg)
2904 {
2905    int i;
2906 
2907    if (!shProg)
2908       return;
2909 
2910    for (i = 0; i < MESA_SHADER_STAGES; i++) {
2911       if (!shProg->_LinkedShaders[i])
2912          continue;
2913 
2914       _mesa_program_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]->Program);
2915    }
2916 }
2917