• 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 
35 #include <errno.h>
36 #include <stdbool.h>
37 #include <c99_alloca.h>
38 
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "draw_validate.h"
42 #include "main/enums.h"
43 #include "main/glspirv.h"
44 #include "main/hash.h"
45 #include "main/mtypes.h"
46 #include "main/pipelineobj.h"
47 #include "main/program_binary.h"
48 #include "main/shaderapi.h"
49 #include "main/shaderobj.h"
50 #include "main/state.h"
51 #include "main/transformfeedback.h"
52 #include "main/uniforms.h"
53 #include "compiler/glsl/builtin_functions.h"
54 #include "compiler/glsl/glsl_parser_extras.h"
55 #include "compiler/glsl/ir.h"
56 #include "compiler/glsl/ir_uniform.h"
57 #include "compiler/glsl/program.h"
58 #include "program/program.h"
59 #include "program/prog_print.h"
60 #include "program/prog_parameter.h"
61 #include "util/ralloc.h"
62 #include "util/hash_table.h"
63 #include "util/crc32.h"
64 #include "util/os_file.h"
65 #include "util/list.h"
66 #include "util/u_process.h"
67 #include "util/u_string.h"
68 #include "api_exec_decl.h"
69 
70 #include "state_tracker/st_context.h"
71 #include "state_tracker/st_program.h"
72 
73 #ifdef ENABLE_SHADER_CACHE
74 #if CUSTOM_SHADER_REPLACEMENT
75 #include "shader_replacement.h"
76 /* shader_replacement.h must declare a variable like this:
77 
78    struct _shader_replacement {
79       // process name. If null, only sha1 is used to match
80       const char *app;
81       // original glsl shader sha1
82       const char *sha1;
83       // shader stage
84       gl_shader_stage stage;
85       ... any other information ...
86    };
87    struct _shader_replacement shader_replacements[...];
88 
89    And a method to load a given replacement and return the new
90    glsl source:
91 
92    char* load_shader_replacement(struct _shader_replacement *repl);
93 
94    And a method to replace the shader without sha1 matching:
95 
96    char *try_direct_replace(const char *app, const char *source)
97 
98    shader_replacement.h can be generated at build time, or copied
99    from an external folder, or any other method.
100 */
101 #else
102 struct _shader_replacement {
103    const char *app;
104    const char *sha1;
105    gl_shader_stage stage;
106 };
107 struct _shader_replacement shader_replacements[0];
108 
try_direct_replace(const char * app,const char * source)109 static char *try_direct_replace(const char *app, const char *source)
110 {
111    return NULL;
112 }
113 
load_shader_replacement(struct _shader_replacement * repl)114 static char* load_shader_replacement(struct _shader_replacement *repl)
115 {
116    return NULL;
117 }
118 #endif
119 #endif
120 
121 /**
122  * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
123  */
124 GLbitfield
_mesa_get_shader_flags(void)125 _mesa_get_shader_flags(void)
126 {
127    GLbitfield flags = 0x0;
128    const char *env = getenv("MESA_GLSL");
129 
130    if (env) {
131       if (strstr(env, "dump_on_error"))
132          flags |= GLSL_DUMP_ON_ERROR;
133 #ifndef CUSTOM_SHADER_REPLACEMENT
134       else if (strstr(env, "dump"))
135          flags |= GLSL_DUMP;
136       if (strstr(env, "log"))
137          flags |= GLSL_LOG;
138 #endif
139       if (strstr(env, "cache_fb"))
140          flags |= GLSL_CACHE_FALLBACK;
141       if (strstr(env, "cache_info"))
142          flags |= GLSL_CACHE_INFO;
143       if (strstr(env, "nopvert"))
144          flags |= GLSL_NOP_VERT;
145       if (strstr(env, "nopfrag"))
146          flags |= GLSL_NOP_FRAG;
147       if (strstr(env, "uniform"))
148          flags |= GLSL_UNIFORMS;
149       if (strstr(env, "useprog"))
150          flags |= GLSL_USE_PROG;
151       if (strstr(env, "errors"))
152          flags |= GLSL_REPORT_ERRORS;
153    }
154 
155    return flags;
156 }
157 
158 #define ANDROID_SHADER_CAPTURE 0
159 
160 #if ANDROID_SHADER_CAPTURE
161 #include "util/u_process.h"
162 #include <sys/stat.h>
163 #include <sys/types.h>
164 #endif
165 
166 /**
167  * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH").
168  */
169 const char *
_mesa_get_shader_capture_path(void)170 _mesa_get_shader_capture_path(void)
171 {
172    static bool read_env_var = false;
173    static const char *path = NULL;
174 
175    if (!read_env_var) {
176       path = getenv("MESA_SHADER_CAPTURE_PATH");
177       read_env_var = true;
178 
179 #if ANDROID_SHADER_CAPTURE
180       if (!path) {
181          char *p;
182          asprintf(&p, "/data/shaders/%s", util_get_process_name());
183          mkdir(p, 0755);
184          path = p;
185       }
186 #endif
187    }
188 
189    return path;
190 }
191 
192 /**
193  * Initialize context's shader state.
194  */
195 void
_mesa_init_shader_state(struct gl_context * ctx)196 _mesa_init_shader_state(struct gl_context *ctx)
197 {
198    /* Device drivers may override these to control what kind of instructions
199     * are generated by the GLSL compiler.
200     */
201    struct gl_shader_compiler_options options;
202    gl_shader_stage sh;
203    int i;
204 
205    memset(&options, 0, sizeof(options));
206    options.MaxIfDepth = UINT_MAX;
207 
208    for (sh = 0; sh < MESA_SHADER_STAGES; ++sh)
209       memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options));
210 
211    ctx->Shader.Flags = _mesa_get_shader_flags();
212 
213    if (ctx->Shader.Flags != 0)
214       ctx->Const.GenerateTemporaryNames = true;
215 
216    /* Extended for ARB_separate_shader_objects */
217    ctx->Shader.RefCount = 1;
218    ctx->TessCtrlProgram.patch_vertices = 3;
219    for (i = 0; i < 4; ++i)
220       ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0;
221    for (i = 0; i < 2; ++i)
222       ctx->TessCtrlProgram.patch_default_inner_level[i] = 1.0;
223 }
224 
225 
226 /**
227  * Free the per-context shader-related state.
228  */
229 void
_mesa_free_shader_state(struct gl_context * ctx)230 _mesa_free_shader_state(struct gl_context *ctx)
231 {
232    for (int i = 0; i < MESA_SHADER_STAGES; i++) {
233       _mesa_reference_program(ctx, &ctx->Shader.CurrentProgram[i], NULL);
234       _mesa_reference_shader_program(ctx,
235                                      &ctx->Shader.ReferencedPrograms[i],
236                                      NULL);
237       free(ctx->SubroutineIndex[i].IndexPtr);
238       ctx->SubroutineIndex[i].IndexPtr = NULL;
239    }
240    _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
241 
242    /* Extended for ARB_separate_shader_objects */
243    _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);
244 
245    assert(ctx->Shader.RefCount == 1);
246 }
247 
248 
249 /**
250  * Copy string from <src> to <dst>, up to maxLength characters, returning
251  * length of <dst> in <length>.
252  * \param src  the strings source
253  * \param maxLength  max chars to copy
254  * \param length  returns number of chars copied
255  * \param dst  the string destination
256  */
257 void
_mesa_copy_string(GLchar * dst,GLsizei maxLength,GLsizei * length,const GLchar * src)258 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
259                   GLsizei *length, const GLchar *src)
260 {
261    GLsizei len;
262    for (len = 0; len < maxLength - 1 && src && src[len]; len++)
263       dst[len] = src[len];
264    if (maxLength > 0)
265       dst[len] = 0;
266    if (length)
267       *length = len;
268 }
269 
270 
271 
272 /**
273  * Confirm that the a shader type is valid and supported by the implementation
274  *
275  * \param ctx   Current GL context
276  * \param type  Shader target
277  *
278  */
279 bool
_mesa_validate_shader_target(const struct gl_context * ctx,GLenum type)280 _mesa_validate_shader_target(const struct gl_context *ctx, GLenum type)
281 {
282    /* Note: when building built-in GLSL functions, this function may be
283     * invoked with ctx == NULL.  In that case, we can only validate that it's
284     * a shader target we recognize, not that it's supported in the current
285     * context.  But that's fine--we don't need any further validation than
286     * that when building built-in GLSL functions.
287     */
288 
289    switch (type) {
290    case GL_FRAGMENT_SHADER:
291       return ctx == NULL || ctx->Extensions.ARB_fragment_shader;
292    case GL_VERTEX_SHADER:
293       return ctx == NULL || ctx->Extensions.ARB_vertex_shader;
294    case GL_GEOMETRY_SHADER_ARB:
295       return ctx == NULL || _mesa_has_geometry_shaders(ctx);
296    case GL_TESS_CONTROL_SHADER:
297    case GL_TESS_EVALUATION_SHADER:
298       return ctx == NULL || _mesa_has_tessellation(ctx);
299    case GL_COMPUTE_SHADER:
300       return ctx == NULL || _mesa_has_compute_shaders(ctx);
301    default:
302       return false;
303    }
304 }
305 
306 
307 static GLboolean
is_program(struct gl_context * ctx,GLuint name)308 is_program(struct gl_context *ctx, GLuint name)
309 {
310    struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
311    return shProg ? GL_TRUE : GL_FALSE;
312 }
313 
314 
315 static GLboolean
is_shader(struct gl_context * ctx,GLuint name)316 is_shader(struct gl_context *ctx, GLuint name)
317 {
318    struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
319    return shader ? GL_TRUE : GL_FALSE;
320 }
321 
322 
323 /**
324  * Attach shader to a shader program.
325  */
326 static void
attach_shader(struct gl_context * ctx,struct gl_shader_program * shProg,struct gl_shader * sh)327 attach_shader(struct gl_context *ctx, struct gl_shader_program *shProg,
328               struct gl_shader *sh)
329 {
330    GLuint n = shProg->NumShaders;
331 
332    shProg->Shaders = realloc(shProg->Shaders,
333                              (n + 1) * sizeof(struct gl_shader *));
334    if (!shProg->Shaders) {
335       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
336       return;
337    }
338 
339    /* append */
340    shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
341    _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
342    shProg->NumShaders++;
343 }
344 
345 static void
attach_shader_err(struct gl_context * ctx,GLuint program,GLuint shader,const char * caller)346 attach_shader_err(struct gl_context *ctx, GLuint program, GLuint shader,
347                   const char *caller)
348 {
349    struct gl_shader_program *shProg;
350    struct gl_shader *sh;
351    GLuint i, n;
352 
353    const bool same_type_disallowed = _mesa_is_gles(ctx);
354 
355    shProg = _mesa_lookup_shader_program_err(ctx, program, caller);
356    if (!shProg)
357       return;
358 
359    sh = _mesa_lookup_shader_err(ctx, shader, caller);
360    if (!sh) {
361       return;
362    }
363 
364    n = shProg->NumShaders;
365    for (i = 0; i < n; i++) {
366       if (shProg->Shaders[i] == sh) {
367          /* The shader is already attched to this program.  The
368           * GL_ARB_shader_objects spec says:
369           *
370           *     "The error INVALID_OPERATION is generated by AttachObjectARB
371           *     if <obj> is already attached to <containerObj>."
372           */
373          _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
374          return;
375       } else if (same_type_disallowed &&
376                  shProg->Shaders[i]->Stage == sh->Stage) {
377         /* Shader with the same type is already attached to this program,
378          * OpenGL ES 2.0 and 3.0 specs say:
379          *
380          *      "Multiple shader objects of the same type may not be attached
381          *      to a single program object. [...] The error INVALID_OPERATION
382          *      is generated if [...] another shader object of the same type
383          *      as shader is already attached to program."
384          */
385          _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
386          return;
387       }
388    }
389 
390    attach_shader(ctx, shProg, sh);
391 }
392 
393 static void
attach_shader_no_error(struct gl_context * ctx,GLuint program,GLuint shader)394 attach_shader_no_error(struct gl_context *ctx, GLuint program, GLuint shader)
395 {
396    struct gl_shader_program *shProg;
397    struct gl_shader *sh;
398 
399    shProg = _mesa_lookup_shader_program(ctx, program);
400    sh = _mesa_lookup_shader(ctx, shader);
401 
402    attach_shader(ctx, shProg, sh);
403 }
404 
405 static GLuint
create_shader(struct gl_context * ctx,GLenum type)406 create_shader(struct gl_context *ctx, GLenum type)
407 {
408    struct gl_shader *sh;
409    GLuint name;
410 
411    _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
412    name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
413    sh = _mesa_new_shader(name, _mesa_shader_enum_to_shader_stage(type));
414    sh->Type = type;
415    _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh, true);
416    _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
417 
418    return name;
419 }
420 
421 
422 static GLuint
create_shader_err(struct gl_context * ctx,GLenum type,const char * caller)423 create_shader_err(struct gl_context *ctx, GLenum type, const char *caller)
424 {
425    if (!_mesa_validate_shader_target(ctx, type)) {
426       _mesa_error(ctx, GL_INVALID_ENUM, "%s(%s)",
427                   caller, _mesa_enum_to_string(type));
428       return 0;
429    }
430 
431    return create_shader(ctx, type);
432 }
433 
434 
435 static GLuint
create_shader_program(struct gl_context * ctx)436 create_shader_program(struct gl_context *ctx)
437 {
438    GLuint name;
439    struct gl_shader_program *shProg;
440 
441    _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
442 
443    name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
444 
445    shProg = _mesa_new_shader_program(name);
446 
447    _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg, true);
448 
449    assert(shProg->RefCount == 1);
450 
451    _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
452 
453    return name;
454 }
455 
456 
457 /**
458  * Delete a shader program.  Actually, just decrement the program's
459  * reference count and mark it as DeletePending.
460  * Used to implement glDeleteProgram() and glDeleteObjectARB().
461  */
462 static void
delete_shader_program(struct gl_context * ctx,GLuint name)463 delete_shader_program(struct gl_context *ctx, GLuint name)
464 {
465    /*
466     * NOTE: deleting shaders/programs works a bit differently than
467     * texture objects (and buffer objects, etc).  Shader/program
468     * handles/IDs exist in the hash table until the object is really
469     * deleted (refcount==0).  With texture objects, the handle/ID is
470     * removed from the hash table in glDeleteTextures() while the tex
471     * object itself might linger until its refcount goes to zero.
472     */
473    struct gl_shader_program *shProg;
474 
475    shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
476    if (!shProg)
477       return;
478 
479    if (!shProg->DeletePending) {
480       shProg->DeletePending = GL_TRUE;
481 
482       /* effectively, decr shProg's refcount */
483       _mesa_reference_shader_program(ctx, &shProg, NULL);
484    }
485 }
486 
487 
488 static void
delete_shader(struct gl_context * ctx,GLuint shader)489 delete_shader(struct gl_context *ctx, GLuint shader)
490 {
491    struct gl_shader *sh;
492 
493    sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
494    if (!sh)
495       return;
496 
497    if (!sh->DeletePending) {
498       sh->DeletePending = GL_TRUE;
499 
500       /* effectively, decr sh's refcount */
501       _mesa_reference_shader(ctx, &sh, NULL);
502    }
503 }
504 
505 
506 static ALWAYS_INLINE void
detach_shader(struct gl_context * ctx,GLuint program,GLuint shader,bool no_error)507 detach_shader(struct gl_context *ctx, GLuint program, GLuint shader,
508               bool no_error)
509 {
510    struct gl_shader_program *shProg;
511    GLuint n;
512    GLuint i, j;
513 
514    if (!no_error) {
515       shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
516       if (!shProg)
517          return;
518    } else {
519       shProg = _mesa_lookup_shader_program(ctx, program);
520    }
521 
522    n = shProg->NumShaders;
523 
524    for (i = 0; i < n; i++) {
525       if (shProg->Shaders[i]->Name == shader) {
526          /* found it */
527          struct gl_shader **newList;
528 
529          /* release */
530          _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
531 
532          /* alloc new, smaller array */
533          newList = malloc((n - 1) * sizeof(struct gl_shader *));
534          if (!newList) {
535             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
536             return;
537          }
538          /* Copy old list entries to new list, skipping removed entry at [i] */
539          for (j = 0; j < i; j++) {
540             newList[j] = shProg->Shaders[j];
541          }
542          while (++i < n) {
543             newList[j++] = shProg->Shaders[i];
544          }
545 
546          /* Free old list and install new one */
547          free(shProg->Shaders);
548          shProg->Shaders = newList;
549          shProg->NumShaders = n - 1;
550 
551 #ifndef NDEBUG
552          /* sanity check - make sure the new list's entries are sensible */
553          for (j = 0; j < shProg->NumShaders; j++) {
554             assert(shProg->Shaders[j]->Stage == MESA_SHADER_VERTEX ||
555                    shProg->Shaders[j]->Stage == MESA_SHADER_TESS_CTRL ||
556                    shProg->Shaders[j]->Stage == MESA_SHADER_TESS_EVAL ||
557                    shProg->Shaders[j]->Stage == MESA_SHADER_GEOMETRY ||
558                    shProg->Shaders[j]->Stage == MESA_SHADER_FRAGMENT);
559             assert(shProg->Shaders[j]->RefCount > 0);
560          }
561 #endif
562 
563          return;
564       }
565    }
566 
567    /* not found */
568    if (!no_error) {
569       GLenum err;
570       if (is_shader(ctx, shader) || is_program(ctx, shader))
571          err = GL_INVALID_OPERATION;
572       else
573          err = GL_INVALID_VALUE;
574       _mesa_error(ctx, err, "glDetachShader(shader)");
575       return;
576    }
577 }
578 
579 
580 static void
detach_shader_error(struct gl_context * ctx,GLuint program,GLuint shader)581 detach_shader_error(struct gl_context *ctx, GLuint program, GLuint shader)
582 {
583    detach_shader(ctx, program, shader, false);
584 }
585 
586 
587 static void
detach_shader_no_error(struct gl_context * ctx,GLuint program,GLuint shader)588 detach_shader_no_error(struct gl_context *ctx, GLuint program, GLuint shader)
589 {
590    detach_shader(ctx, program, shader, true);
591 }
592 
593 
594 /**
595  * Return list of shaders attached to shader program.
596  * \param objOut  returns GLuint ids
597  * \param handleOut  returns GLhandleARB handles
598  */
599 static void
get_attached_shaders(struct gl_context * ctx,GLuint program,GLsizei maxCount,GLsizei * countOut,GLuint * objOut,GLhandleARB * handleOut)600 get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
601                      GLsizei *countOut, GLuint *objOut, GLhandleARB *handleOut)
602 {
603    struct gl_shader_program *shProg;
604 
605    if (maxCount < 0) {
606       _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders(maxCount < 0)");
607       return;
608    }
609 
610    shProg =
611       _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
612 
613    if (shProg) {
614       GLuint i;
615       for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
616          if (objOut) {
617             objOut[i] = shProg->Shaders[i]->Name;
618          }
619 
620          if (handleOut) {
621             handleOut[i] = (GLhandleARB) shProg->Shaders[i]->Name;
622          }
623       }
624       if (countOut) {
625          *countOut = i;
626       }
627    }
628 }
629 
630 /**
631  * glGetHandleARB() - return ID/name of currently bound shader program.
632  */
633 static GLuint
get_handle(struct gl_context * ctx,GLenum pname)634 get_handle(struct gl_context *ctx, GLenum pname)
635 {
636    if (pname == GL_PROGRAM_OBJECT_ARB) {
637       if (ctx->_Shader->ActiveProgram)
638          return ctx->_Shader->ActiveProgram->Name;
639       else
640          return 0;
641    }
642    else {
643       _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
644       return 0;
645    }
646 }
647 
648 
649 /**
650  * Check if a geometry shader query is valid at this time.  If not, report an
651  * error and return false.
652  *
653  * From GL 3.2 section 6.1.16 (Shader and Program Queries):
654  *
655  *     "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE
656  *     are queried for a program which has not been linked successfully, or
657  *     which does not contain objects to form a geometry shader, then an
658  *     INVALID_OPERATION error is generated."
659  */
660 static bool
check_gs_query(struct gl_context * ctx,const struct gl_shader_program * shProg)661 check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
662 {
663    if (shProg->data->LinkStatus &&
664        shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
665       return true;
666    }
667 
668    _mesa_error(ctx, GL_INVALID_OPERATION,
669                "glGetProgramv(linked geometry shader required)");
670    return false;
671 }
672 
673 
674 /**
675  * Check if a tessellation control shader query is valid at this time.
676  * If not, report an error and return false.
677  *
678  * From GL 4.0 section 6.1.12 (Shader and Program Queries):
679  *
680  *     "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has
681  *     not been linked successfully, or which does not contain objects to
682  *     form a tessellation control shader, then an INVALID_OPERATION error is
683  *     generated."
684  */
685 static bool
check_tcs_query(struct gl_context * ctx,const struct gl_shader_program * shProg)686 check_tcs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
687 {
688    if (shProg->data->LinkStatus &&
689        shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL] != NULL) {
690       return true;
691    }
692 
693    _mesa_error(ctx, GL_INVALID_OPERATION,
694                "glGetProgramv(linked tessellation control shader required)");
695    return false;
696 }
697 
698 
699 /**
700  * Check if a tessellation evaluation shader query is valid at this time.
701  * If not, report an error and return false.
702  *
703  * From GL 4.0 section 6.1.12 (Shader and Program Queries):
704  *
705  *     "If any of the pname values in this paragraph are queried for a program
706  *     which has not been linked successfully, or which does not contain
707  *     objects to form a tessellation evaluation shader, then an
708  *     INVALID_OPERATION error is generated."
709  *
710  */
711 static bool
check_tes_query(struct gl_context * ctx,const struct gl_shader_program * shProg)712 check_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
713 {
714    if (shProg->data->LinkStatus &&
715        shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL] != NULL) {
716       return true;
717    }
718 
719    _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramv(linked tessellation "
720                "evaluation shader required)");
721    return false;
722 }
723 
724 static bool
get_shader_program_completion_status(struct gl_context * ctx,struct gl_shader_program * shprog)725 get_shader_program_completion_status(struct gl_context *ctx,
726                                      struct gl_shader_program *shprog)
727 {
728    struct pipe_screen *screen = ctx->screen;
729 
730    if (!screen->is_parallel_shader_compilation_finished)
731       return true;
732 
733    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
734       struct gl_linked_shader *linked = shprog->_LinkedShaders[i];
735       void *sh = NULL;
736 
737       if (!linked || !linked->Program)
738          continue;
739 
740       if (linked->Program->variants)
741          sh = linked->Program->variants->driver_shader;
742 
743       unsigned type = pipe_shader_type_from_mesa(i);
744 
745       if (sh &&
746           !screen->is_parallel_shader_compilation_finished(screen, sh, type))
747          return false;
748    }
749    return true;
750 }
751 
752 /**
753  * glGetProgramiv() - get shader program state.
754  * Note that this is for GLSL shader programs, not ARB vertex/fragment
755  * programs (see glGetProgramivARB).
756  */
757 static void
get_programiv(struct gl_context * ctx,GLuint program,GLenum pname,GLint * params)758 get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
759               GLint *params)
760 {
761    struct gl_shader_program *shProg
762       = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramiv(program)");
763 
764    /* Is transform feedback available in this context?
765     */
766    const bool has_xfb =
767       (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback)
768       || ctx->API == API_OPENGL_CORE
769       || _mesa_is_gles3(ctx);
770 
771    /* True if geometry shaders (of the form that was adopted into GLSL 1.50
772     * and GL 3.2) are available in this context
773     */
774    const bool has_gs = _mesa_has_geometry_shaders(ctx);
775    const bool has_tess = _mesa_has_tessellation(ctx);
776 
777    /* Are uniform buffer objects available in this context?
778     */
779    const bool has_ubo =
780       (ctx->API == API_OPENGL_COMPAT &&
781        ctx->Extensions.ARB_uniform_buffer_object)
782       || ctx->API == API_OPENGL_CORE
783       || _mesa_is_gles3(ctx);
784 
785    if (!shProg) {
786       return;
787    }
788 
789    switch (pname) {
790    case GL_DELETE_STATUS:
791       *params = shProg->DeletePending;
792       return;
793    case GL_COMPLETION_STATUS_ARB:
794       *params = get_shader_program_completion_status(ctx, shProg);
795       return;
796    case GL_LINK_STATUS:
797       *params = shProg->data->LinkStatus ? GL_TRUE : GL_FALSE;
798       return;
799    case GL_VALIDATE_STATUS:
800       *params = shProg->data->Validated;
801       return;
802    case GL_INFO_LOG_LENGTH:
803       *params = (shProg->data->InfoLog && shProg->data->InfoLog[0] != '\0') ?
804          strlen(shProg->data->InfoLog) + 1 : 0;
805       return;
806    case GL_ATTACHED_SHADERS:
807       *params = shProg->NumShaders;
808       return;
809    case GL_ACTIVE_ATTRIBUTES:
810       *params = _mesa_count_active_attribs(shProg);
811       return;
812    case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
813       *params = _mesa_longest_attribute_name_length(shProg);
814       return;
815    case GL_ACTIVE_UNIFORMS: {
816       _mesa_get_program_interfaceiv(shProg, GL_UNIFORM, GL_ACTIVE_RESOURCES,
817                                     params);
818       return;
819    }
820    case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
821       _mesa_get_program_interfaceiv(shProg, GL_UNIFORM, GL_MAX_NAME_LENGTH,
822                                     params);
823       return;
824    }
825    case GL_TRANSFORM_FEEDBACK_VARYINGS:
826       if (!has_xfb)
827          break;
828 
829       /* Check first if there are transform feedback varyings specified in the
830        * shader (ARB_enhanced_layouts). If there isn't any, return the number of
831        * varyings specified using the API.
832        */
833       if (shProg->last_vert_prog &&
834           shProg->last_vert_prog->sh.LinkedTransformFeedback->NumVarying > 0)
835          *params =
836             shProg->last_vert_prog->sh.LinkedTransformFeedback->NumVarying;
837       else
838          *params = shProg->TransformFeedback.NumVarying;
839       return;
840    case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: {
841       if (!has_xfb)
842          break;
843 
844       _mesa_get_program_interfaceiv(shProg, GL_TRANSFORM_FEEDBACK_VARYING,
845                                     GL_MAX_NAME_LENGTH, params);
846       return;
847    }
848    case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
849       if (!has_xfb)
850          break;
851       *params = shProg->TransformFeedback.BufferMode;
852       return;
853    case GL_GEOMETRY_VERTICES_OUT:
854       if (!has_gs)
855          break;
856       if (check_gs_query(ctx, shProg)) {
857          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
858             Program->info.gs.vertices_out;
859       }
860       return;
861    case GL_GEOMETRY_SHADER_INVOCATIONS:
862       if (!has_gs ||
863           (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_gpu_shader5)) {
864          break;
865       }
866       if (check_gs_query(ctx, shProg)) {
867          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
868             Program->info.gs.invocations;
869       }
870       return;
871    case GL_GEOMETRY_INPUT_TYPE:
872       if (!has_gs)
873          break;
874       if (check_gs_query(ctx, shProg)) {
875          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
876             Program->info.gs.input_primitive;
877       }
878       return;
879    case GL_GEOMETRY_OUTPUT_TYPE:
880       if (!has_gs)
881          break;
882       if (check_gs_query(ctx, shProg)) {
883          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
884             Program->info.gs.output_primitive;
885       }
886       return;
887    case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
888       if (!has_ubo)
889          break;
890 
891       _mesa_get_program_interfaceiv(shProg, GL_UNIFORM_BLOCK,
892                                     GL_MAX_NAME_LENGTH, params);
893       return;
894    }
895    case GL_ACTIVE_UNIFORM_BLOCKS:
896       if (!has_ubo)
897          break;
898 
899       *params = shProg->data->NumUniformBlocks;
900       return;
901    case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
902       /* This enum isn't part of the OES extension for OpenGL ES 2.0.  It is
903        * only available with desktop OpenGL 3.0+ with the
904        * GL_ARB_get_program_binary extension or OpenGL ES 3.0.
905        *
906        * On desktop, we ignore the 3.0+ requirement because it is silly.
907        */
908       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
909          break;
910 
911       *params = shProg->BinaryRetrievableHint;
912       return;
913    case GL_PROGRAM_BINARY_LENGTH:
914       if (ctx->Const.NumProgramBinaryFormats == 0 || !shProg->data->LinkStatus) {
915          *params = 0;
916       } else {
917          _mesa_get_program_binary_length(ctx, shProg, params);
918       }
919       return;
920    case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
921       if (!ctx->Extensions.ARB_shader_atomic_counters && !_mesa_is_gles31(ctx))
922          break;
923 
924       *params = shProg->data->NumAtomicBuffers;
925       return;
926    case GL_COMPUTE_WORK_GROUP_SIZE: {
927       int i;
928       if (!_mesa_has_compute_shaders(ctx))
929          break;
930       if (!shProg->data->LinkStatus) {
931          _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(program not "
932                      "linked)");
933          return;
934       }
935       if (shProg->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) {
936          _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(no compute "
937                      "shaders)");
938          return;
939       }
940       for (i = 0; i < 3; i++)
941          params[i] = shProg->_LinkedShaders[MESA_SHADER_COMPUTE]->
942             Program->info.workgroup_size[i];
943       return;
944    }
945    case GL_PROGRAM_SEPARABLE:
946       /* If the program has not been linked, return initial value 0. */
947       *params = (shProg->data->LinkStatus == LINKING_FAILURE) ? 0 : shProg->SeparateShader;
948       return;
949 
950    /* ARB_tessellation_shader */
951    case GL_TESS_CONTROL_OUTPUT_VERTICES:
952       if (!has_tess)
953          break;
954       if (check_tcs_query(ctx, shProg)) {
955          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->
956             Program->info.tess.tcs_vertices_out;
957       }
958       return;
959    case GL_TESS_GEN_MODE:
960       if (!has_tess)
961          break;
962       if (check_tes_query(ctx, shProg)) {
963          const struct gl_linked_shader *tes =
964             shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL];
965          switch (tes->Program->info.tess._primitive_mode) {
966          case TESS_PRIMITIVE_TRIANGLES:
967             *params = GL_TRIANGLES;
968             break;
969          case TESS_PRIMITIVE_QUADS:
970             *params = GL_QUADS;
971             break;
972          case TESS_PRIMITIVE_ISOLINES:
973             *params = GL_ISOLINES;
974             break;
975          case TESS_PRIMITIVE_UNSPECIFIED:
976             *params = 0;
977             break;
978          }
979       }
980       return;
981    case GL_TESS_GEN_SPACING:
982       if (!has_tess)
983          break;
984       if (check_tes_query(ctx, shProg)) {
985          const struct gl_linked_shader *tes =
986             shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL];
987          switch (tes->Program->info.tess.spacing) {
988          case TESS_SPACING_EQUAL:
989             *params = GL_EQUAL;
990             break;
991          case TESS_SPACING_FRACTIONAL_ODD:
992             *params = GL_FRACTIONAL_ODD;
993             break;
994          case TESS_SPACING_FRACTIONAL_EVEN:
995             *params = GL_FRACTIONAL_EVEN;
996             break;
997          case TESS_SPACING_UNSPECIFIED:
998             *params = 0;
999             break;
1000          }
1001       }
1002       return;
1003    case GL_TESS_GEN_VERTEX_ORDER:
1004       if (!has_tess)
1005          break;
1006       if (check_tes_query(ctx, shProg)) {
1007          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
1008             Program->info.tess.ccw ? GL_CCW : GL_CW;
1009          }
1010       return;
1011    case GL_TESS_GEN_POINT_MODE:
1012       if (!has_tess)
1013          break;
1014       if (check_tes_query(ctx, shProg)) {
1015          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
1016             Program->info.tess.point_mode ? GL_TRUE : GL_FALSE;
1017       }
1018       return;
1019    default:
1020       break;
1021    }
1022 
1023    _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
1024                _mesa_enum_to_string(pname));
1025 }
1026 
1027 
1028 /**
1029  * glGetShaderiv() - get GLSL shader state
1030  */
1031 static void
get_shaderiv(struct gl_context * ctx,GLuint name,GLenum pname,GLint * params)1032 get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
1033 {
1034    struct gl_shader *shader =
1035       _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
1036 
1037    if (!shader) {
1038       return;
1039    }
1040 
1041    switch (pname) {
1042    case GL_SHADER_TYPE:
1043       *params = shader->Type;
1044       break;
1045    case GL_DELETE_STATUS:
1046       *params = shader->DeletePending;
1047       break;
1048    case GL_COMPLETION_STATUS_ARB:
1049       /* _mesa_glsl_compile_shader is not offloaded to other threads. */
1050       *params = GL_TRUE;
1051       return;
1052    case GL_COMPILE_STATUS:
1053       *params = shader->CompileStatus ? GL_TRUE : GL_FALSE;
1054       break;
1055    case GL_INFO_LOG_LENGTH:
1056       *params = (shader->InfoLog && shader->InfoLog[0] != '\0') ?
1057          strlen(shader->InfoLog) + 1 : 0;
1058       break;
1059    case GL_SHADER_SOURCE_LENGTH:
1060       *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
1061       break;
1062    case GL_SPIR_V_BINARY_ARB:
1063       *params = (shader->spirv_data != NULL);
1064       break;
1065    default:
1066       _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1067       return;
1068    }
1069 }
1070 
1071 
1072 static void
get_program_info_log(struct gl_context * ctx,GLuint program,GLsizei bufSize,GLsizei * length,GLchar * infoLog)1073 get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
1074                      GLsizei *length, GLchar *infoLog)
1075 {
1076    struct gl_shader_program *shProg;
1077 
1078    /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
1079     * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
1080     *
1081     *     "If a negative number is provided where an argument of type sizei or
1082     *     sizeiptr is specified, an INVALID_VALUE error is generated."
1083     */
1084    if (bufSize < 0) {
1085       _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(bufSize < 0)");
1086       return;
1087    }
1088 
1089    shProg = _mesa_lookup_shader_program_err(ctx, program,
1090                                             "glGetProgramInfoLog(program)");
1091    if (!shProg) {
1092       return;
1093    }
1094 
1095    _mesa_copy_string(infoLog, bufSize, length, shProg->data->InfoLog);
1096 }
1097 
1098 
1099 static void
get_shader_info_log(struct gl_context * ctx,GLuint shader,GLsizei bufSize,GLsizei * length,GLchar * infoLog)1100 get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
1101                     GLsizei *length, GLchar *infoLog)
1102 {
1103    struct gl_shader *sh;
1104 
1105    /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
1106     * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
1107     *
1108     *     "If a negative number is provided where an argument of type sizei or
1109     *     sizeiptr is specified, an INVALID_VALUE error is generated."
1110     */
1111    if (bufSize < 0) {
1112       _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(bufSize < 0)");
1113       return;
1114    }
1115 
1116    sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderInfoLog(shader)");
1117    if (!sh) {
1118       return;
1119    }
1120 
1121    _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
1122 }
1123 
1124 
1125 /**
1126  * Return shader source code.
1127  */
1128 static void
get_shader_source(struct gl_context * ctx,GLuint shader,GLsizei maxLength,GLsizei * length,GLchar * sourceOut)1129 get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
1130                   GLsizei *length, GLchar *sourceOut)
1131 {
1132    struct gl_shader *sh;
1133 
1134    if (maxLength < 0) {
1135       _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(bufSize < 0)");
1136       return;
1137    }
1138 
1139    sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
1140    if (!sh) {
1141       return;
1142    }
1143    _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
1144 }
1145 
1146 
1147 /**
1148  * Set/replace shader source code.  A helper function used by
1149  * glShaderSource[ARB].
1150  */
1151 static void
set_shader_source(struct gl_shader * sh,const GLchar * source,const uint8_t original_sha1[SHA1_DIGEST_LENGTH])1152 set_shader_source(struct gl_shader *sh, const GLchar *source,
1153                   const uint8_t original_sha1[SHA1_DIGEST_LENGTH])
1154 {
1155    assert(sh);
1156 
1157    /* The GL_ARB_gl_spirv spec adds the following to the end of the description
1158     * of ShaderSource:
1159     *
1160     *   "If <shader> was previously associated with a SPIR-V module (via the
1161     *    ShaderBinary command), that association is broken. Upon successful
1162     *    completion of this command the SPIR_V_BINARY_ARB state of <shader>
1163     *    is set to FALSE."
1164     */
1165    _mesa_shader_spirv_data_reference(&sh->spirv_data, NULL);
1166 
1167    if (sh->CompileStatus == COMPILE_SKIPPED && !sh->FallbackSource) {
1168       /* If shader was previously compiled back-up the source in case of cache
1169        * fallback.
1170        */
1171       sh->FallbackSource = sh->Source;
1172       memcpy(sh->fallback_source_sha1, sh->source_sha1, SHA1_DIGEST_LENGTH);
1173       sh->Source = source;
1174    } else {
1175       /* free old shader source string and install new one */
1176       free((void *)sh->Source);
1177       sh->Source = source;
1178    }
1179 
1180    memcpy(sh->source_sha1, original_sha1, SHA1_DIGEST_LENGTH);
1181 }
1182 
1183 static void
ensure_builtin_types(struct gl_context * ctx)1184 ensure_builtin_types(struct gl_context *ctx)
1185 {
1186    if (!ctx->shader_builtin_ref) {
1187       _mesa_glsl_builtin_functions_init_or_ref();
1188       ctx->shader_builtin_ref = true;
1189    }
1190 }
1191 
1192 /**
1193  * Compile a shader.
1194  */
1195 void
_mesa_compile_shader(struct gl_context * ctx,struct gl_shader * sh)1196 _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh)
1197 {
1198    if (!sh)
1199       return;
1200 
1201    /* The GL_ARB_gl_spirv spec says:
1202     *
1203     *    "Add a new error for the CompileShader command:
1204     *
1205     *      An INVALID_OPERATION error is generated if the SPIR_V_BINARY_ARB
1206     *      state of <shader> is TRUE."
1207     */
1208    if (sh->spirv_data) {
1209       _mesa_error(ctx, GL_INVALID_OPERATION, "glCompileShader(SPIR-V)");
1210       return;
1211    }
1212 
1213    if (!sh->Source) {
1214       /* If the user called glCompileShader without first calling
1215        * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
1216        */
1217       sh->CompileStatus = COMPILE_FAILURE;
1218    } else {
1219       if (ctx->_Shader->Flags & GLSL_DUMP) {
1220          _mesa_log("GLSL source for %s shader %d:\n",
1221                  _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1222          _mesa_log_direct(sh->Source);
1223       }
1224 
1225       ensure_builtin_types(ctx);
1226 
1227       /* this call will set the shader->CompileStatus field to indicate if
1228        * compilation was successful.
1229        */
1230       _mesa_glsl_compile_shader(ctx, sh, false, false, false);
1231 
1232       if (ctx->_Shader->Flags & GLSL_LOG) {
1233          _mesa_write_shader_to_file(sh);
1234       }
1235 
1236       if (ctx->_Shader->Flags & GLSL_DUMP) {
1237          if (sh->CompileStatus) {
1238             if (sh->ir) {
1239                _mesa_log("GLSL IR for shader %d:\n", sh->Name);
1240                _mesa_print_ir(_mesa_get_log_file(), sh->ir, NULL);
1241             } else {
1242                _mesa_log("No GLSL IR for shader %d (shader may be from "
1243                          "cache)\n", sh->Name);
1244             }
1245             _mesa_log("\n\n");
1246          } else {
1247             _mesa_log("GLSL shader %d failed to compile.\n", sh->Name);
1248          }
1249          if (sh->InfoLog && sh->InfoLog[0] != 0) {
1250             _mesa_log("GLSL shader %d info log:\n", sh->Name);
1251             _mesa_log("%s\n", sh->InfoLog);
1252          }
1253       }
1254    }
1255 
1256    if (!sh->CompileStatus) {
1257       if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) {
1258          _mesa_log("GLSL source for %s shader %d:\n",
1259                  _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1260          _mesa_log("%s\n", sh->Source);
1261          _mesa_log("Info Log:\n%s\n", sh->InfoLog);
1262       }
1263 
1264       if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) {
1265          _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
1266                      sh->Name, sh->InfoLog);
1267       }
1268    }
1269 }
1270 
1271 
1272 struct update_programs_in_pipeline_params
1273 {
1274    struct gl_context *ctx;
1275    struct gl_shader_program *shProg;
1276 };
1277 
1278 static void
update_programs_in_pipeline(void * data,void * userData)1279 update_programs_in_pipeline(void *data, void *userData)
1280 {
1281    struct update_programs_in_pipeline_params *params =
1282       (struct update_programs_in_pipeline_params *) userData;
1283    struct gl_pipeline_object *obj = (struct gl_pipeline_object *) data;
1284 
1285    for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
1286       if (obj->CurrentProgram[stage] &&
1287           obj->CurrentProgram[stage]->Id == params->shProg->Name) {
1288          struct gl_program *prog = params->shProg->_LinkedShaders[stage]->Program;
1289          _mesa_use_program(params->ctx, stage, params->shProg, prog, obj);
1290       }
1291    }
1292 }
1293 
1294 
1295 /**
1296  * Link a program's shaders.
1297  */
1298 static ALWAYS_INLINE void
link_program(struct gl_context * ctx,struct gl_shader_program * shProg,bool no_error)1299 link_program(struct gl_context *ctx, struct gl_shader_program *shProg,
1300              bool no_error)
1301 {
1302    if (!shProg)
1303       return;
1304 
1305    if (!no_error) {
1306       /* From the ARB_transform_feedback2 specification:
1307        * "The error INVALID_OPERATION is generated by LinkProgram if <program>
1308        * is the name of a program being used by one or more transform feedback
1309        * objects, even if the objects are not currently bound or are paused."
1310        */
1311       if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
1312          _mesa_error(ctx, GL_INVALID_OPERATION,
1313                      "glLinkProgram(transform feedback is using the program)");
1314          return;
1315       }
1316    }
1317 
1318    unsigned programs_in_use = 0;
1319    if (ctx->_Shader)
1320       for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
1321          if (ctx->_Shader->CurrentProgram[stage] &&
1322              ctx->_Shader->CurrentProgram[stage]->Id == shProg->Name) {
1323             programs_in_use |= 1 << stage;
1324          }
1325       }
1326 
1327    ensure_builtin_types(ctx);
1328 
1329    FLUSH_VERTICES(ctx, 0, 0);
1330    _mesa_glsl_link_shader(ctx, shProg);
1331 
1332    /* From section 7.3 (Program Objects) of the OpenGL 4.5 spec:
1333     *
1334     *    "If LinkProgram or ProgramBinary successfully re-links a program
1335     *     object that is active for any shader stage, then the newly generated
1336     *     executable code will be installed as part of the current rendering
1337     *     state for all shader stages where the program is active.
1338     *     Additionally, the newly generated executable code is made part of
1339     *     the state of any program pipeline for all stages where the program
1340     *     is attached."
1341     */
1342    if (shProg->data->LinkStatus) {
1343       while (programs_in_use) {
1344          const int stage = u_bit_scan(&programs_in_use);
1345 
1346          struct gl_program *prog = NULL;
1347          if (shProg->_LinkedShaders[stage])
1348             prog = shProg->_LinkedShaders[stage]->Program;
1349 
1350          _mesa_use_program(ctx, stage, shProg, prog, ctx->_Shader);
1351       }
1352 
1353       if (ctx->Pipeline.Objects) {
1354          struct update_programs_in_pipeline_params params = {
1355             .ctx = ctx,
1356             .shProg = shProg
1357          };
1358          _mesa_HashWalk(ctx->Pipeline.Objects, update_programs_in_pipeline,
1359                         &params);
1360       }
1361    }
1362 
1363 #ifndef CUSTOM_SHADER_REPLACEMENT
1364    /* Capture .shader_test files. */
1365    const char *capture_path = _mesa_get_shader_capture_path();
1366    if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
1367       /* Find an unused filename. */
1368       FILE *file = NULL;
1369       char *filename = NULL;
1370       for (unsigned i = 0;; i++) {
1371          if (i) {
1372             filename = ralloc_asprintf(NULL, "%s/%u-%u.shader_test",
1373                                        capture_path, shProg->Name, i);
1374          } else {
1375             filename = ralloc_asprintf(NULL, "%s/%u.shader_test",
1376                                        capture_path, shProg->Name);
1377          }
1378          file = os_file_create_unique(filename, 0644);
1379          if (file)
1380             break;
1381          /* If we are failing for another reason than "this filename already
1382           * exists", we are likely to fail again with another filename, so
1383           * let's just give up */
1384          if (errno != EEXIST)
1385             break;
1386          ralloc_free(filename);
1387       }
1388       if (file) {
1389          fprintf(file, "[require]\nGLSL%s >= %u.%02u\n",
1390                  shProg->IsES ? " ES" : "",
1391                  shProg->data->Version / 100, shProg->data->Version % 100);
1392          if (shProg->SeparateShader)
1393             fprintf(file, "GL_ARB_separate_shader_objects\nSSO ENABLED\n");
1394          fprintf(file, "\n");
1395 
1396          for (unsigned i = 0; i < shProg->NumShaders; i++) {
1397             fprintf(file, "[%s shader]\n%s\n",
1398                     _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
1399                     shProg->Shaders[i]->Source);
1400          }
1401          fclose(file);
1402       } else {
1403          _mesa_warning(ctx, "Failed to open %s", filename);
1404       }
1405 
1406       ralloc_free(filename);
1407    }
1408 #endif
1409 
1410    if (shProg->data->LinkStatus == LINKING_FAILURE &&
1411        (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
1412       _mesa_debug(ctx, "Error linking program %u:\n%s\n",
1413                   shProg->Name, shProg->data->InfoLog);
1414    }
1415 
1416    _mesa_update_vertex_processing_mode(ctx);
1417    _mesa_update_valid_to_render_state(ctx);
1418 
1419    shProg->BinaryRetrievableHint = shProg->BinaryRetrievableHintPending;
1420 
1421    /* debug code */
1422    if (0) {
1423       GLuint i;
1424 
1425       printf("Link %u shaders in program %u: %s\n",
1426                    shProg->NumShaders, shProg->Name,
1427                    shProg->data->LinkStatus ? "Success" : "Failed");
1428 
1429       for (i = 0; i < shProg->NumShaders; i++) {
1430          printf(" shader %u, stage %u\n",
1431                       shProg->Shaders[i]->Name,
1432                       shProg->Shaders[i]->Stage);
1433       }
1434    }
1435 }
1436 
1437 
1438 static void
link_program_error(struct gl_context * ctx,struct gl_shader_program * shProg)1439 link_program_error(struct gl_context *ctx, struct gl_shader_program *shProg)
1440 {
1441    link_program(ctx, shProg, false);
1442 }
1443 
1444 
1445 static void
link_program_no_error(struct gl_context * ctx,struct gl_shader_program * shProg)1446 link_program_no_error(struct gl_context *ctx, struct gl_shader_program *shProg)
1447 {
1448    link_program(ctx, shProg, true);
1449 }
1450 
1451 
1452 void
_mesa_link_program(struct gl_context * ctx,struct gl_shader_program * shProg)1453 _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
1454 {
1455    link_program_error(ctx, shProg);
1456 }
1457 
1458 
1459 /**
1460  * Print basic shader info (for debug).
1461  */
1462 static void
print_shader_info(const struct gl_shader_program * shProg)1463 print_shader_info(const struct gl_shader_program *shProg)
1464 {
1465    GLuint i;
1466 
1467    printf("Mesa: glUseProgram(%u)\n", shProg->Name);
1468    for (i = 0; i < shProg->NumShaders; i++) {
1469       printf("  %s shader %u\n",
1470              _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
1471              shProg->Shaders[i]->Name);
1472    }
1473    if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
1474       printf("  vert prog %u\n",
1475 	     shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
1476    if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
1477       printf("  frag prog %u\n",
1478 	     shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
1479    if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
1480       printf("  geom prog %u\n",
1481 	     shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
1482    if (shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL])
1483       printf("  tesc prog %u\n",
1484 	     shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program->Id);
1485    if (shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL])
1486       printf("  tese prog %u\n",
1487 	     shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program->Id);
1488 }
1489 
1490 
1491 /**
1492  * Use the named shader program for subsequent glUniform calls
1493  */
1494 void
_mesa_active_program(struct gl_context * ctx,struct gl_shader_program * shProg,const char * caller)1495 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
1496 		     const char *caller)
1497 {
1498    if ((shProg != NULL) && !shProg->data->LinkStatus) {
1499       _mesa_error(ctx, GL_INVALID_OPERATION,
1500 		  "%s(program %u not linked)", caller, shProg->Name);
1501       return;
1502    }
1503 
1504    if (ctx->Shader.ActiveProgram != shProg) {
1505       _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
1506       _mesa_update_valid_to_render_state(ctx);
1507    }
1508 }
1509 
1510 
1511 /**
1512  * Use the named shader program for subsequent rendering.
1513  */
1514 void
_mesa_use_shader_program(struct gl_context * ctx,struct gl_shader_program * shProg)1515 _mesa_use_shader_program(struct gl_context *ctx,
1516                          struct gl_shader_program *shProg)
1517 {
1518    for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1519       struct gl_program *new_prog = NULL;
1520       if (shProg && shProg->_LinkedShaders[i])
1521          new_prog = shProg->_LinkedShaders[i]->Program;
1522       _mesa_use_program(ctx, i, shProg, new_prog, &ctx->Shader);
1523    }
1524    _mesa_active_program(ctx, shProg, "glUseProgram");
1525 }
1526 
1527 
1528 /**
1529  * Do validation of the given shader program.
1530  * \param errMsg  returns error message if validation fails.
1531  * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
1532  */
1533 static GLboolean
validate_shader_program(const struct gl_shader_program * shProg,char * errMsg)1534 validate_shader_program(const struct gl_shader_program *shProg,
1535                         char *errMsg)
1536 {
1537    if (!shProg->data->LinkStatus) {
1538       return GL_FALSE;
1539    }
1540 
1541    /* From the GL spec, a program is invalid if any of these are true:
1542 
1543      any two active samplers in the current program object are of
1544      different types, but refer to the same texture image unit,
1545 
1546      any active sampler in the current program object refers to a texture
1547      image unit where fixed-function fragment processing accesses a
1548      texture target that does not match the sampler type, or
1549 
1550      the sum of the number of active samplers in the program and the
1551      number of texture image units enabled for fixed-function fragment
1552      processing exceeds the combined limit on the total number of texture
1553      image units allowed.
1554    */
1555 
1556    /*
1557     * Check: any two active samplers in the current program object are of
1558     * different types, but refer to the same texture image unit,
1559     */
1560    if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
1561       return GL_FALSE;
1562 
1563    return GL_TRUE;
1564 }
1565 
1566 
1567 /**
1568  * Called via glValidateProgram()
1569  */
1570 static void
validate_program(struct gl_context * ctx,GLuint program)1571 validate_program(struct gl_context *ctx, GLuint program)
1572 {
1573    struct gl_shader_program *shProg;
1574    char errMsg[100] = "";
1575 
1576    shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1577    if (!shProg) {
1578       return;
1579    }
1580 
1581    shProg->data->Validated = validate_shader_program(shProg, errMsg);
1582    if (!shProg->data->Validated) {
1583       /* update info log */
1584       if (shProg->data->InfoLog) {
1585          ralloc_free(shProg->data->InfoLog);
1586       }
1587       shProg->data->InfoLog = ralloc_strdup(shProg->data, errMsg);
1588    }
1589 }
1590 
1591 
1592 void GLAPIENTRY
_mesa_AttachObjectARB_no_error(GLhandleARB program,GLhandleARB shader)1593 _mesa_AttachObjectARB_no_error(GLhandleARB program, GLhandleARB shader)
1594 {
1595    GET_CURRENT_CONTEXT(ctx);
1596    attach_shader_no_error(ctx, program, shader);
1597 }
1598 
1599 
1600 void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB program,GLhandleARB shader)1601 _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1602 {
1603    GET_CURRENT_CONTEXT(ctx);
1604    attach_shader_err(ctx, program, shader, "glAttachObjectARB");
1605 }
1606 
1607 
1608 void GLAPIENTRY
_mesa_AttachShader_no_error(GLuint program,GLuint shader)1609 _mesa_AttachShader_no_error(GLuint program, GLuint shader)
1610 {
1611    GET_CURRENT_CONTEXT(ctx);
1612    attach_shader_no_error(ctx, program, shader);
1613 }
1614 
1615 
1616 void GLAPIENTRY
_mesa_AttachShader(GLuint program,GLuint shader)1617 _mesa_AttachShader(GLuint program, GLuint shader)
1618 {
1619    GET_CURRENT_CONTEXT(ctx);
1620    attach_shader_err(ctx, program, shader, "glAttachShader");
1621 }
1622 
1623 
1624 void GLAPIENTRY
_mesa_CompileShader(GLuint shaderObj)1625 _mesa_CompileShader(GLuint shaderObj)
1626 {
1627    GET_CURRENT_CONTEXT(ctx);
1628    if (MESA_VERBOSE & VERBOSE_API)
1629       _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
1630    _mesa_compile_shader(ctx, _mesa_lookup_shader_err(ctx, shaderObj,
1631                                                      "glCompileShader"));
1632 }
1633 
1634 
1635 GLuint GLAPIENTRY
_mesa_CreateShader_no_error(GLenum type)1636 _mesa_CreateShader_no_error(GLenum type)
1637 {
1638    GET_CURRENT_CONTEXT(ctx);
1639    return create_shader(ctx, type);
1640 }
1641 
1642 
1643 GLuint GLAPIENTRY
_mesa_CreateShader(GLenum type)1644 _mesa_CreateShader(GLenum type)
1645 {
1646    GET_CURRENT_CONTEXT(ctx);
1647 
1648    if (MESA_VERBOSE & VERBOSE_API)
1649       _mesa_debug(ctx, "glCreateShader %s\n", _mesa_enum_to_string(type));
1650 
1651    return create_shader_err(ctx, type, "glCreateShader");
1652 }
1653 
1654 
1655 GLhandleARB GLAPIENTRY
_mesa_CreateShaderObjectARB_no_error(GLenum type)1656 _mesa_CreateShaderObjectARB_no_error(GLenum type)
1657 {
1658    GET_CURRENT_CONTEXT(ctx);
1659    return create_shader(ctx, type);
1660 }
1661 
1662 
1663 GLhandleARB GLAPIENTRY
_mesa_CreateShaderObjectARB(GLenum type)1664 _mesa_CreateShaderObjectARB(GLenum type)
1665 {
1666    GET_CURRENT_CONTEXT(ctx);
1667    return create_shader_err(ctx, type, "glCreateShaderObjectARB");
1668 }
1669 
1670 
1671 GLuint GLAPIENTRY
_mesa_CreateProgram(void)1672 _mesa_CreateProgram(void)
1673 {
1674    GET_CURRENT_CONTEXT(ctx);
1675    if (MESA_VERBOSE & VERBOSE_API)
1676       _mesa_debug(ctx, "glCreateProgram\n");
1677    return create_shader_program(ctx);
1678 }
1679 
1680 
1681 GLhandleARB GLAPIENTRY
_mesa_CreateProgramObjectARB(void)1682 _mesa_CreateProgramObjectARB(void)
1683 {
1684    GET_CURRENT_CONTEXT(ctx);
1685    return create_shader_program(ctx);
1686 }
1687 
1688 
1689 void GLAPIENTRY
_mesa_DeleteObjectARB(GLhandleARB obj)1690 _mesa_DeleteObjectARB(GLhandleARB obj)
1691 {
1692    if (MESA_VERBOSE & VERBOSE_API) {
1693       GET_CURRENT_CONTEXT(ctx);
1694       _mesa_debug(ctx, "glDeleteObjectARB(%lu)\n", (unsigned long)obj);
1695    }
1696 
1697    if (obj) {
1698       GET_CURRENT_CONTEXT(ctx);
1699       FLUSH_VERTICES(ctx, 0, 0);
1700       if (is_program(ctx, obj)) {
1701          delete_shader_program(ctx, obj);
1702       }
1703       else if (is_shader(ctx, obj)) {
1704          delete_shader(ctx, obj);
1705       }
1706       else {
1707          _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteObjectARB");
1708       }
1709    }
1710 }
1711 
1712 
1713 void GLAPIENTRY
_mesa_DeleteProgram(GLuint name)1714 _mesa_DeleteProgram(GLuint name)
1715 {
1716    if (name) {
1717       GET_CURRENT_CONTEXT(ctx);
1718       FLUSH_VERTICES(ctx, 0, 0);
1719       delete_shader_program(ctx, name);
1720    }
1721 }
1722 
1723 
1724 void GLAPIENTRY
_mesa_DeleteShader(GLuint name)1725 _mesa_DeleteShader(GLuint name)
1726 {
1727    if (name) {
1728       GET_CURRENT_CONTEXT(ctx);
1729       FLUSH_VERTICES(ctx, 0, 0);
1730       delete_shader(ctx, name);
1731    }
1732 }
1733 
1734 
1735 void GLAPIENTRY
_mesa_DetachObjectARB_no_error(GLhandleARB program,GLhandleARB shader)1736 _mesa_DetachObjectARB_no_error(GLhandleARB program, GLhandleARB shader)
1737 {
1738    GET_CURRENT_CONTEXT(ctx);
1739    detach_shader_no_error(ctx, program, shader);
1740 }
1741 
1742 
1743 void GLAPIENTRY
_mesa_DetachObjectARB(GLhandleARB program,GLhandleARB shader)1744 _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1745 {
1746    GET_CURRENT_CONTEXT(ctx);
1747    detach_shader_error(ctx, program, shader);
1748 }
1749 
1750 
1751 void GLAPIENTRY
_mesa_DetachShader_no_error(GLuint program,GLuint shader)1752 _mesa_DetachShader_no_error(GLuint program, GLuint shader)
1753 {
1754    GET_CURRENT_CONTEXT(ctx);
1755    detach_shader_no_error(ctx, program, shader);
1756 }
1757 
1758 
1759 void GLAPIENTRY
_mesa_DetachShader(GLuint program,GLuint shader)1760 _mesa_DetachShader(GLuint program, GLuint shader)
1761 {
1762    GET_CURRENT_CONTEXT(ctx);
1763    detach_shader_error(ctx, program, shader);
1764 }
1765 
1766 
1767 void GLAPIENTRY
_mesa_GetAttachedObjectsARB(GLhandleARB container,GLsizei maxCount,GLsizei * count,GLhandleARB * obj)1768 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1769                             GLsizei * count, GLhandleARB * obj)
1770 {
1771    GET_CURRENT_CONTEXT(ctx);
1772    get_attached_shaders(ctx, (GLuint)container, maxCount, count, NULL, obj);
1773 }
1774 
1775 
1776 void GLAPIENTRY
_mesa_GetAttachedShaders(GLuint program,GLsizei maxCount,GLsizei * count,GLuint * obj)1777 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1778                          GLsizei *count, GLuint *obj)
1779 {
1780    GET_CURRENT_CONTEXT(ctx);
1781    get_attached_shaders(ctx, program, maxCount, count, obj, NULL);
1782 }
1783 
1784 
1785 void GLAPIENTRY
_mesa_GetInfoLogARB(GLhandleARB object,GLsizei maxLength,GLsizei * length,GLcharARB * infoLog)1786 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1787                     GLcharARB * infoLog)
1788 {
1789    GET_CURRENT_CONTEXT(ctx);
1790    if (is_program(ctx, object)) {
1791       get_program_info_log(ctx, object, maxLength, length, infoLog);
1792    }
1793    else if (is_shader(ctx, object)) {
1794       get_shader_info_log(ctx, object, maxLength, length, infoLog);
1795    }
1796    else {
1797       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1798    }
1799 }
1800 
1801 
1802 void GLAPIENTRY
_mesa_GetObjectParameterivARB(GLhandleARB object,GLenum pname,GLint * params)1803 _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1804 {
1805    GET_CURRENT_CONTEXT(ctx);
1806    /* Implement in terms of GetProgramiv, GetShaderiv */
1807    if (is_program(ctx, object)) {
1808       if (pname == GL_OBJECT_TYPE_ARB) {
1809 	 *params = GL_PROGRAM_OBJECT_ARB;
1810       }
1811       else {
1812 	 get_programiv(ctx, object, pname, params);
1813       }
1814    }
1815    else if (is_shader(ctx, object)) {
1816       if (pname == GL_OBJECT_TYPE_ARB) {
1817 	 *params = GL_SHADER_OBJECT_ARB;
1818       }
1819       else {
1820 	 get_shaderiv(ctx, object, pname, params);
1821       }
1822    }
1823    else {
1824       _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1825    }
1826 }
1827 
1828 
1829 void GLAPIENTRY
_mesa_GetObjectParameterfvARB(GLhandleARB object,GLenum pname,GLfloat * params)1830 _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1831                               GLfloat *params)
1832 {
1833    GLint iparams[1] = {0};  /* XXX is one element enough? */
1834    _mesa_GetObjectParameterivARB(object, pname, iparams);
1835    params[0] = (GLfloat) iparams[0];
1836 }
1837 
1838 
1839 void GLAPIENTRY
_mesa_GetProgramiv(GLuint program,GLenum pname,GLint * params)1840 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1841 {
1842    GET_CURRENT_CONTEXT(ctx);
1843    get_programiv(ctx, program, pname, params);
1844 }
1845 
1846 
1847 void GLAPIENTRY
_mesa_GetShaderiv(GLuint shader,GLenum pname,GLint * params)1848 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1849 {
1850    GET_CURRENT_CONTEXT(ctx);
1851    get_shaderiv(ctx, shader, pname, params);
1852 }
1853 
1854 
1855 void GLAPIENTRY
_mesa_GetProgramInfoLog(GLuint program,GLsizei bufSize,GLsizei * length,GLchar * infoLog)1856 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1857                         GLsizei *length, GLchar *infoLog)
1858 {
1859    GET_CURRENT_CONTEXT(ctx);
1860    get_program_info_log(ctx, program, bufSize, length, infoLog);
1861 }
1862 
1863 
1864 void GLAPIENTRY
_mesa_GetShaderInfoLog(GLuint shader,GLsizei bufSize,GLsizei * length,GLchar * infoLog)1865 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1866                        GLsizei *length, GLchar *infoLog)
1867 {
1868    GET_CURRENT_CONTEXT(ctx);
1869    get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1870 }
1871 
1872 
1873 void GLAPIENTRY
_mesa_GetShaderSource(GLuint shader,GLsizei maxLength,GLsizei * length,GLchar * sourceOut)1874 _mesa_GetShaderSource(GLuint shader, GLsizei maxLength,
1875                       GLsizei *length, GLchar *sourceOut)
1876 {
1877    GET_CURRENT_CONTEXT(ctx);
1878    get_shader_source(ctx, shader, maxLength, length, sourceOut);
1879 }
1880 
1881 
1882 GLhandleARB GLAPIENTRY
_mesa_GetHandleARB(GLenum pname)1883 _mesa_GetHandleARB(GLenum pname)
1884 {
1885    GET_CURRENT_CONTEXT(ctx);
1886    return get_handle(ctx, pname);
1887 }
1888 
1889 
1890 GLboolean GLAPIENTRY
_mesa_IsProgram(GLuint name)1891 _mesa_IsProgram(GLuint name)
1892 {
1893    GET_CURRENT_CONTEXT(ctx);
1894    return is_program(ctx, name);
1895 }
1896 
1897 
1898 GLboolean GLAPIENTRY
_mesa_IsShader(GLuint name)1899 _mesa_IsShader(GLuint name)
1900 {
1901    GET_CURRENT_CONTEXT(ctx);
1902    return is_shader(ctx, name);
1903 }
1904 
1905 
1906 void GLAPIENTRY
_mesa_LinkProgram_no_error(GLuint programObj)1907 _mesa_LinkProgram_no_error(GLuint programObj)
1908 {
1909    GET_CURRENT_CONTEXT(ctx);
1910 
1911    struct gl_shader_program *shProg =
1912       _mesa_lookup_shader_program(ctx, programObj);
1913    link_program_no_error(ctx, shProg);
1914 }
1915 
1916 
1917 void GLAPIENTRY
_mesa_LinkProgram(GLuint programObj)1918 _mesa_LinkProgram(GLuint programObj)
1919 {
1920    GET_CURRENT_CONTEXT(ctx);
1921 
1922    if (MESA_VERBOSE & VERBOSE_API)
1923       _mesa_debug(ctx, "glLinkProgram %u\n", programObj);
1924 
1925    struct gl_shader_program *shProg =
1926       _mesa_lookup_shader_program_err(ctx, programObj, "glLinkProgram");
1927    link_program_error(ctx, shProg);
1928 }
1929 
1930 #ifdef ENABLE_SHADER_CACHE
1931 
1932 /**
1933  * Construct a full path for shader replacement functionality using
1934  * following format:
1935  *
1936  * <path>/<stage prefix>_<CHECKSUM>.glsl
1937  * <path>/<stage prefix>_<CHECKSUM>.arb
1938  */
1939 static char *
construct_name(const gl_shader_stage stage,const char * sha,const char * source,const char * path)1940 construct_name(const gl_shader_stage stage, const char *sha,
1941                const char *source, const char *path)
1942 {
1943    static const char *types[] = {
1944       "VS", "TC", "TE", "GS", "FS", "CS",
1945    };
1946 
1947    const char *format = strncmp(source, "!!ARB", 5) ? "glsl" : "arb";
1948 
1949    return ralloc_asprintf(NULL, "%s/%s_%s.%s", path, types[stage], sha, format);
1950 }
1951 
1952 /**
1953  * Write given shader source to a file in MESA_SHADER_DUMP_PATH.
1954  */
1955 void
_mesa_dump_shader_source(const gl_shader_stage stage,const char * source,const uint8_t sha1[SHA1_DIGEST_LENGTH])1956 _mesa_dump_shader_source(const gl_shader_stage stage, const char *source,
1957                          const uint8_t sha1[SHA1_DIGEST_LENGTH])
1958 {
1959 #ifndef CUSTOM_SHADER_REPLACEMENT
1960    static bool path_exists = true;
1961    char *dump_path;
1962    FILE *f;
1963    char sha[64];
1964 
1965    if (!path_exists)
1966       return;
1967 
1968    dump_path = getenv("MESA_SHADER_DUMP_PATH");
1969    if (!dump_path) {
1970       path_exists = false;
1971       return;
1972    }
1973 
1974    _mesa_sha1_format(sha, sha1);
1975    char *name = construct_name(stage, sha, source, dump_path);
1976 
1977    f = fopen(name, "w");
1978    if (f) {
1979       fputs(source, f);
1980       fclose(f);
1981    } else {
1982       GET_CURRENT_CONTEXT(ctx);
1983       _mesa_warning(ctx, "could not open %s for dumping shader (%s)", name,
1984                     strerror(errno));
1985    }
1986    ralloc_free(name);
1987 #endif
1988 }
1989 
1990 /**
1991  * Read shader source code from a file.
1992  * Useful for debugging to override an app's shader.
1993  */
1994 GLcharARB *
_mesa_read_shader_source(const gl_shader_stage stage,const char * source,const uint8_t sha1[SHA1_DIGEST_LENGTH])1995 _mesa_read_shader_source(const gl_shader_stage stage, const char *source,
1996                          const uint8_t sha1[SHA1_DIGEST_LENGTH])
1997 {
1998    char *read_path;
1999    static bool path_exists = true;
2000    int len, shader_size = 0;
2001    GLcharARB *buffer;
2002    FILE *f;
2003    char sha[64];
2004 
2005    _mesa_sha1_format(sha, sha1);
2006 
2007    if (!debug_get_bool_option("MESA_NO_SHADER_REPLACEMENT", false)) {
2008       const char *process_name = util_get_process_name();
2009 
2010       char *new_source = try_direct_replace(process_name, source);
2011       if (new_source)
2012          return new_source;
2013 
2014       for (size_t i = 0; i < ARRAY_SIZE(shader_replacements); i++) {
2015          if (stage != shader_replacements[i].stage)
2016             continue;
2017 
2018          if (shader_replacements[i].app &&
2019              strcmp(process_name, shader_replacements[i].app) != 0)
2020             continue;
2021 
2022          if (memcmp(sha, shader_replacements[i].sha1, 40) != 0)
2023             continue;
2024 
2025          return load_shader_replacement(&shader_replacements[i]);
2026       }
2027    }
2028 
2029    if (!path_exists)
2030       return NULL;
2031 
2032    read_path = getenv("MESA_SHADER_READ_PATH");
2033    if (!read_path) {
2034       path_exists = false;
2035       return NULL;
2036    }
2037 
2038    char *name = construct_name(stage, sha, source, read_path);
2039    f = fopen(name, "r");
2040    ralloc_free(name);
2041    if (!f)
2042       return NULL;
2043 
2044    /* allocate enough room for the entire shader */
2045    fseek(f, 0, SEEK_END);
2046    shader_size = ftell(f);
2047    rewind(f);
2048    assert(shader_size);
2049 
2050    /* add one for terminating zero */
2051    shader_size++;
2052 
2053    buffer = malloc(shader_size);
2054    assert(buffer);
2055 
2056    len = fread(buffer, 1, shader_size, f);
2057    buffer[len] = 0;
2058 
2059    fclose(f);
2060 
2061    return buffer;
2062 }
2063 
2064 #endif /* ENABLE_SHADER_CACHE */
2065 
2066 /**
2067  * Called via glShaderSource() and glShaderSourceARB() API functions.
2068  * Basically, concatenate the source code strings into one long string
2069  * and pass it to _mesa_shader_source().
2070  */
2071 static ALWAYS_INLINE void
shader_source(struct gl_context * ctx,GLuint shaderObj,GLsizei count,const GLchar * const * string,const GLint * length,bool no_error)2072 shader_source(struct gl_context *ctx, GLuint shaderObj, GLsizei count,
2073               const GLchar *const *string, const GLint *length, bool no_error)
2074 {
2075    GLint *offsets;
2076    GLsizei i, totalLength;
2077    GLcharARB *source;
2078    struct gl_shader *sh;
2079 
2080    if (!no_error) {
2081       sh = _mesa_lookup_shader_err(ctx, shaderObj, "glShaderSourceARB");
2082       if (!sh)
2083          return;
2084 
2085       if (string == NULL || count < 0) {
2086          _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
2087          return;
2088       }
2089    } else {
2090       sh = _mesa_lookup_shader(ctx, shaderObj);
2091    }
2092 
2093    /* Return silently the spec doesn't define this as an error */
2094    if (count == 0)
2095       return;
2096 
2097    /*
2098     * This array holds offsets of where the appropriate string ends, thus the
2099     * last element will be set to the total length of the source code.
2100     */
2101    offsets = calloc(count, sizeof(GLint));
2102    if (offsets == NULL) {
2103       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
2104       return;
2105    }
2106 
2107    for (i = 0; i < count; i++) {
2108       if (!no_error && string[i] == NULL) {
2109          free((GLvoid *) offsets);
2110          _mesa_error(ctx, GL_INVALID_OPERATION,
2111                      "glShaderSourceARB(null string)");
2112          return;
2113       }
2114       if (length == NULL || length[i] < 0)
2115          offsets[i] = strlen(string[i]);
2116       else
2117          offsets[i] = length[i];
2118       /* accumulate string lengths */
2119       if (i > 0)
2120          offsets[i] += offsets[i - 1];
2121    }
2122 
2123    /* Total length of source string is sum off all strings plus two.
2124     * One extra byte for terminating zero, another extra byte to silence
2125     * valgrind warnings in the parser/grammer code.
2126     */
2127    totalLength = offsets[count - 1] + 2;
2128    source = malloc(totalLength * sizeof(GLcharARB));
2129    if (source == NULL) {
2130       free((GLvoid *) offsets);
2131       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
2132       return;
2133    }
2134 
2135    for (i = 0; i < count; i++) {
2136       GLint start = (i > 0) ? offsets[i - 1] : 0;
2137       memcpy(source + start, string[i],
2138              (offsets[i] - start) * sizeof(GLcharARB));
2139    }
2140    source[totalLength - 1] = '\0';
2141    source[totalLength - 2] = '\0';
2142 
2143    /* Compute the original source sha1 before shader replacement. */
2144    uint8_t original_sha1[SHA1_DIGEST_LENGTH];
2145    _mesa_sha1_compute(source, strlen(source), original_sha1);
2146 
2147 #ifdef ENABLE_SHADER_CACHE
2148    GLcharARB *replacement;
2149 
2150    /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
2151     * if corresponding entry found from MESA_SHADER_READ_PATH.
2152     */
2153    _mesa_dump_shader_source(sh->Stage, source, original_sha1);
2154 
2155    replacement = _mesa_read_shader_source(sh->Stage, source, original_sha1);
2156    if (replacement) {
2157       free(source);
2158       source = replacement;
2159    }
2160 #endif /* ENABLE_SHADER_CACHE */
2161 
2162    set_shader_source(sh, source, original_sha1);
2163 
2164    free(offsets);
2165 }
2166 
2167 
2168 void GLAPIENTRY
_mesa_ShaderSource_no_error(GLuint shaderObj,GLsizei count,const GLchar * const * string,const GLint * length)2169 _mesa_ShaderSource_no_error(GLuint shaderObj, GLsizei count,
2170                             const GLchar *const *string, const GLint *length)
2171 {
2172    GET_CURRENT_CONTEXT(ctx);
2173    shader_source(ctx, shaderObj, count, string, length, true);
2174 }
2175 
2176 
2177 void GLAPIENTRY
_mesa_ShaderSource(GLuint shaderObj,GLsizei count,const GLchar * const * string,const GLint * length)2178 _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
2179                    const GLchar *const *string, const GLint *length)
2180 {
2181    GET_CURRENT_CONTEXT(ctx);
2182    shader_source(ctx, shaderObj, count, string, length, false);
2183 }
2184 
2185 
2186 static ALWAYS_INLINE void
use_program(GLuint program,bool no_error)2187 use_program(GLuint program, bool no_error)
2188 {
2189    GET_CURRENT_CONTEXT(ctx);
2190    struct gl_shader_program *shProg = NULL;
2191 
2192    if (MESA_VERBOSE & VERBOSE_API)
2193       _mesa_debug(ctx, "glUseProgram %u\n", program);
2194 
2195    if (no_error) {
2196       if (program) {
2197          shProg = _mesa_lookup_shader_program(ctx, program);
2198       }
2199    } else {
2200       if (_mesa_is_xfb_active_and_unpaused(ctx)) {
2201          _mesa_error(ctx, GL_INVALID_OPERATION,
2202                      "glUseProgram(transform feedback active)");
2203          return;
2204       }
2205 
2206       if (program) {
2207          shProg =
2208             _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
2209          if (!shProg)
2210             return;
2211 
2212          if (!shProg->data->LinkStatus) {
2213             _mesa_error(ctx, GL_INVALID_OPERATION,
2214                         "glUseProgram(program %u not linked)", program);
2215             return;
2216          }
2217 
2218          /* debug code */
2219          if (ctx->_Shader->Flags & GLSL_USE_PROG) {
2220             print_shader_info(shProg);
2221          }
2222       }
2223    }
2224 
2225    /* The ARB_separate_shader_object spec says:
2226     *
2227     *     "The executable code for an individual shader stage is taken from
2228     *     the current program for that stage.  If there is a current program
2229     *     object established by UseProgram, that program is considered current
2230     *     for all stages.  Otherwise, if there is a bound program pipeline
2231     *     object (section 2.14.PPO), the program bound to the appropriate
2232     *     stage of the pipeline object is considered current."
2233     */
2234    if (shProg) {
2235       /* Attach shader state to the binding point */
2236       _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
2237       /* Update the program */
2238       _mesa_use_shader_program(ctx, shProg);
2239    } else {
2240       /* Must be done first: detach the progam */
2241       _mesa_use_shader_program(ctx, shProg);
2242       /* Unattach shader_state binding point */
2243       _mesa_reference_pipeline_object(ctx, &ctx->_Shader,
2244                                       ctx->Pipeline.Default);
2245       /* If a pipeline was bound, rebind it */
2246       if (ctx->Pipeline.Current) {
2247          if (no_error)
2248             _mesa_BindProgramPipeline_no_error(ctx->Pipeline.Current->Name);
2249          else
2250             _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
2251       }
2252    }
2253 
2254    _mesa_update_vertex_processing_mode(ctx);
2255 }
2256 
2257 
2258 void GLAPIENTRY
_mesa_UseProgram_no_error(GLuint program)2259 _mesa_UseProgram_no_error(GLuint program)
2260 {
2261    use_program(program, true);
2262 }
2263 
2264 
2265 void GLAPIENTRY
_mesa_UseProgram(GLuint program)2266 _mesa_UseProgram(GLuint program)
2267 {
2268    use_program(program, false);
2269 }
2270 
2271 
2272 void GLAPIENTRY
_mesa_ValidateProgram(GLuint program)2273 _mesa_ValidateProgram(GLuint program)
2274 {
2275    GET_CURRENT_CONTEXT(ctx);
2276    validate_program(ctx, program);
2277 }
2278 
2279 
2280 /**
2281  * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
2282  */
2283 void GLAPIENTRY
_mesa_GetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)2284 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
2285                                GLint* range, GLint* precision)
2286 {
2287    const struct gl_program_constants *limits;
2288    const struct gl_precision *p;
2289    GET_CURRENT_CONTEXT(ctx);
2290 
2291    switch (shadertype) {
2292    case GL_VERTEX_SHADER:
2293       limits = &ctx->Const.Program[MESA_SHADER_VERTEX];
2294       break;
2295    case GL_FRAGMENT_SHADER:
2296       limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT];
2297       break;
2298    default:
2299       _mesa_error(ctx, GL_INVALID_ENUM,
2300                   "glGetShaderPrecisionFormat(shadertype)");
2301       return;
2302    }
2303 
2304    switch (precisiontype) {
2305    case GL_LOW_FLOAT:
2306       p = &limits->LowFloat;
2307       break;
2308    case GL_MEDIUM_FLOAT:
2309       p = &limits->MediumFloat;
2310       break;
2311    case GL_HIGH_FLOAT:
2312       p = &limits->HighFloat;
2313       break;
2314    case GL_LOW_INT:
2315       p = &limits->LowInt;
2316       break;
2317    case GL_MEDIUM_INT:
2318       p = &limits->MediumInt;
2319       break;
2320    case GL_HIGH_INT:
2321       p = &limits->HighInt;
2322       break;
2323    default:
2324       _mesa_error(ctx, GL_INVALID_ENUM,
2325                   "glGetShaderPrecisionFormat(precisiontype)");
2326       return;
2327    }
2328 
2329    range[0] = p->RangeMin;
2330    range[1] = p->RangeMax;
2331    precision[0] = p->Precision;
2332 }
2333 
2334 
2335 /**
2336  * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
2337  */
2338 void GLAPIENTRY
_mesa_ReleaseShaderCompiler(void)2339 _mesa_ReleaseShaderCompiler(void)
2340 {
2341    GET_CURRENT_CONTEXT(ctx);
2342 
2343    if (ctx->shader_builtin_ref) {
2344       _mesa_glsl_builtin_functions_decref();
2345       ctx->shader_builtin_ref = false;
2346    }
2347 }
2348 
2349 
2350 /**
2351  * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
2352  */
2353 void GLAPIENTRY
_mesa_ShaderBinary(GLint n,const GLuint * shaders,GLenum binaryformat,const void * binary,GLint length)2354 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
2355                    const void* binary, GLint length)
2356 {
2357    GET_CURRENT_CONTEXT(ctx);
2358    struct gl_shader **sh;
2359 
2360    /* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and
2361     * page 88 of the OpenGL 4.5 specs state:
2362     *
2363     *     "An INVALID_VALUE error is generated if count or length is negative.
2364     *      An INVALID_ENUM error is generated if binaryformat is not a supported
2365     *      format returned in SHADER_BINARY_FORMATS."
2366     */
2367    if (n < 0 || length < 0) {
2368       _mesa_error(ctx, GL_INVALID_VALUE, "glShaderBinary(count or length < 0)");
2369       return;
2370    }
2371 
2372    /* Get all shader objects at once so we can make the operation
2373     * all-or-nothing.
2374     */
2375    if (n > SIZE_MAX / sizeof(*sh)) {
2376       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary(count)");
2377       return;
2378    }
2379 
2380    sh = alloca(sizeof(*sh) * (size_t)n);
2381    if (!sh) {
2382       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary");
2383       return;
2384    }
2385 
2386    for (int i = 0; i < n; ++i) {
2387       sh[i] = _mesa_lookup_shader_err(ctx, shaders[i], "glShaderBinary");
2388       if (!sh[i])
2389          return;
2390    }
2391 
2392    if (binaryformat == GL_SHADER_BINARY_FORMAT_SPIR_V_ARB) {
2393       if (!ctx->Extensions.ARB_gl_spirv) {
2394          _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary(SPIR-V)");
2395       } else if (n > 0) {
2396          _mesa_spirv_shader_binary(ctx, (unsigned) n, sh, binary,
2397                                    (size_t) length);
2398       }
2399 
2400       return;
2401    }
2402 
2403    _mesa_error(ctx, GL_INVALID_ENUM, "glShaderBinary(format)");
2404 }
2405 
2406 
2407 void GLAPIENTRY
_mesa_GetProgramBinary(GLuint program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,GLvoid * binary)2408 _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
2409                        GLenum *binaryFormat, GLvoid *binary)
2410 {
2411    struct gl_shader_program *shProg;
2412    GLsizei length_dummy;
2413    GET_CURRENT_CONTEXT(ctx);
2414 
2415    if (bufSize < 0){
2416       _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
2417       return;
2418    }
2419 
2420    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
2421    if (!shProg)
2422       return;
2423 
2424    /* The ARB_get_program_binary spec says:
2425     *
2426     *     "If <length> is NULL, then no length is returned."
2427     *
2428     * Ensure that length always points to valid storage to avoid multiple NULL
2429     * pointer checks below.
2430     */
2431    if (length == NULL)
2432       length = &length_dummy;
2433 
2434 
2435    /* The ARB_get_program_binary spec says:
2436     *
2437     *     "When a program object's LINK_STATUS is FALSE, its program binary
2438     *     length is zero, and a call to GetProgramBinary will generate an
2439     *     INVALID_OPERATION error.
2440     */
2441    if (!shProg->data->LinkStatus) {
2442       _mesa_error(ctx, GL_INVALID_OPERATION,
2443                   "glGetProgramBinary(program %u not linked)",
2444                   shProg->Name);
2445       *length = 0;
2446       return;
2447    }
2448 
2449    if (ctx->Const.NumProgramBinaryFormats == 0) {
2450       *length = 0;
2451       _mesa_error(ctx, GL_INVALID_OPERATION,
2452                   "glGetProgramBinary(driver supports zero binary formats)");
2453    } else {
2454       _mesa_get_program_binary(ctx, shProg, bufSize, length, binaryFormat,
2455                                binary);
2456       assert(*length == 0 || *binaryFormat == GL_PROGRAM_BINARY_FORMAT_MESA);
2457    }
2458 }
2459 
2460 void GLAPIENTRY
_mesa_ProgramBinary(GLuint program,GLenum binaryFormat,const GLvoid * binary,GLsizei length)2461 _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
2462                     const GLvoid *binary, GLsizei length)
2463 {
2464    struct gl_shader_program *shProg;
2465    GET_CURRENT_CONTEXT(ctx);
2466 
2467    shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary");
2468    if (!shProg)
2469       return;
2470 
2471    _mesa_clear_shader_program_data(ctx, shProg);
2472    shProg->data = _mesa_create_shader_program_data();
2473 
2474    /* Section 2.3.1 (Errors) of the OpenGL 4.5 spec says:
2475     *
2476     *     "If a negative number is provided where an argument of type sizei or
2477     *     sizeiptr is specified, an INVALID_VALUE error is generated."
2478     */
2479    if (length < 0) {
2480       _mesa_error(ctx, GL_INVALID_VALUE, "glProgramBinary(length < 0)");
2481       return;
2482    }
2483 
2484    if (ctx->Const.NumProgramBinaryFormats == 0 ||
2485        binaryFormat != GL_PROGRAM_BINARY_FORMAT_MESA) {
2486       /* The ARB_get_program_binary spec says:
2487        *
2488        *     "<binaryFormat> and <binary> must be those returned by a previous
2489        *     call to GetProgramBinary, and <length> must be the length of the
2490        *     program binary as returned by GetProgramBinary or GetProgramiv with
2491        *     <pname> PROGRAM_BINARY_LENGTH. Loading the program binary will fail,
2492        *     setting the LINK_STATUS of <program> to FALSE, if these conditions
2493        *     are not met."
2494        *
2495        * Since any value of binaryFormat passed "is not one of those specified as
2496        * allowable for [this] command, an INVALID_ENUM error is generated."
2497        */
2498       shProg->data->LinkStatus = LINKING_FAILURE;
2499       _mesa_error(ctx, GL_INVALID_ENUM, "glProgramBinary");
2500    } else {
2501       _mesa_program_binary(ctx, shProg, binaryFormat, binary, length);
2502    }
2503 }
2504 
2505 
2506 static ALWAYS_INLINE void
program_parameteri(struct gl_context * ctx,struct gl_shader_program * shProg,GLuint pname,GLint value,bool no_error)2507 program_parameteri(struct gl_context *ctx, struct gl_shader_program *shProg,
2508                    GLuint pname, GLint value, bool no_error)
2509 {
2510    switch (pname) {
2511    case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
2512       /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
2513        * is part of OpenGL ES 3.0.  For the ES2 case, this function shouldn't
2514        * even be in the dispatch table, so we shouldn't need to expclicitly
2515        * check here.
2516        *
2517        * On desktop, we ignore the 3.0+ requirement because it is silly.
2518        */
2519 
2520       /* The ARB_get_program_binary extension spec says:
2521        *
2522        *     "An INVALID_VALUE error is generated if the <value> argument to
2523        *     ProgramParameteri is not TRUE or FALSE."
2524        */
2525       if (!no_error && value != GL_TRUE && value != GL_FALSE) {
2526          goto invalid_value;
2527       }
2528 
2529       /* No need to notify the driver.  Any changes will actually take effect
2530        * the next time the shader is linked.
2531        *
2532        * The ARB_get_program_binary extension spec says:
2533        *
2534        *     "To indicate that a program binary is likely to be retrieved,
2535        *     ProgramParameteri should be called with <pname>
2536        *     PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
2537        *     will not be in effect until the next time LinkProgram or
2538        *     ProgramBinary has been called successfully."
2539        *
2540        * The resolution of issue 9 in the extension spec also says:
2541        *
2542        *     "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
2543        *     to indicate to the GL implementation that this program will
2544        *     likely be saved with GetProgramBinary at some point. This will
2545        *     give the GL implementation the opportunity to track any state
2546        *     changes made to the program before being saved such that when it
2547        *     is loaded again a recompile can be avoided."
2548        */
2549       shProg->BinaryRetrievableHintPending = value;
2550       return;
2551 
2552    case GL_PROGRAM_SEPARABLE:
2553       /* Spec imply that the behavior is the same as ARB_get_program_binary
2554        * Chapter 7.3 Program Objects
2555        */
2556       if (!no_error && value != GL_TRUE && value != GL_FALSE) {
2557          goto invalid_value;
2558       }
2559       shProg->SeparateShader = value;
2560       return;
2561 
2562    default:
2563       if (!no_error) {
2564          _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
2565                      _mesa_enum_to_string(pname));
2566       }
2567       return;
2568    }
2569 
2570 invalid_value:
2571    _mesa_error(ctx, GL_INVALID_VALUE,
2572                "glProgramParameteri(pname=%s, value=%d): "
2573                "value must be 0 or 1.",
2574                _mesa_enum_to_string(pname),
2575                value);
2576 }
2577 
2578 
2579 void GLAPIENTRY
_mesa_ProgramParameteri_no_error(GLuint program,GLenum pname,GLint value)2580 _mesa_ProgramParameteri_no_error(GLuint program, GLenum pname, GLint value)
2581 {
2582    GET_CURRENT_CONTEXT(ctx);
2583 
2584    struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program);
2585    program_parameteri(ctx, shProg, pname, value, true);
2586 }
2587 
2588 
2589 void GLAPIENTRY
_mesa_ProgramParameteri(GLuint program,GLenum pname,GLint value)2590 _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
2591 {
2592    struct gl_shader_program *shProg;
2593    GET_CURRENT_CONTEXT(ctx);
2594 
2595    shProg = _mesa_lookup_shader_program_err(ctx, program,
2596                                             "glProgramParameteri");
2597    if (!shProg)
2598       return;
2599 
2600    program_parameteri(ctx, shProg, pname, value, false);
2601 }
2602 
2603 
2604 void
_mesa_use_program(struct gl_context * ctx,gl_shader_stage stage,struct gl_shader_program * shProg,struct gl_program * prog,struct gl_pipeline_object * shTarget)2605 _mesa_use_program(struct gl_context *ctx, gl_shader_stage stage,
2606                   struct gl_shader_program *shProg, struct gl_program *prog,
2607                   struct gl_pipeline_object *shTarget)
2608 {
2609    struct gl_program **target;
2610 
2611    target = &shTarget->CurrentProgram[stage];
2612    if (prog) {
2613       _mesa_program_init_subroutine_defaults(ctx, prog);
2614    }
2615 
2616    if (*target != prog) {
2617       /* Program is current, flush it */
2618       if (shTarget == ctx->_Shader) {
2619          FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS, 0);
2620       }
2621 
2622       _mesa_reference_shader_program(ctx,
2623                                      &shTarget->ReferencedPrograms[stage],
2624                                      shProg);
2625       _mesa_reference_program(ctx, target, prog);
2626       _mesa_update_allow_draw_out_of_order(ctx);
2627       _mesa_update_valid_to_render_state(ctx);
2628       if (stage == MESA_SHADER_VERTEX)
2629          _mesa_update_vertex_processing_mode(ctx);
2630       return;
2631    }
2632 
2633 }
2634 
2635 
2636 /**
2637  * Copy program-specific data generated by linking from the gl_shader_program
2638  * object to the gl_program object referred to by the gl_linked_shader.
2639  *
2640  * This function expects _mesa_reference_program() to have been previously
2641  * called setting the gl_linked_shaders program reference.
2642  */
2643 void
_mesa_copy_linked_program_data(const struct gl_shader_program * src,struct gl_linked_shader * dst_sh)2644 _mesa_copy_linked_program_data(const struct gl_shader_program *src,
2645                                struct gl_linked_shader *dst_sh)
2646 {
2647    assert(dst_sh->Program);
2648 
2649    struct gl_program *dst = dst_sh->Program;
2650 
2651    dst->info.separate_shader = src->SeparateShader;
2652 
2653    switch (dst_sh->Stage) {
2654    case MESA_SHADER_GEOMETRY: {
2655       dst->info.gs.vertices_in = src->Geom.VerticesIn;
2656       dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive;
2657       dst->info.gs.active_stream_mask = src->Geom.ActiveStreamMask;
2658       break;
2659    }
2660    case MESA_SHADER_FRAGMENT: {
2661       dst->info.fs.depth_layout = src->FragDepthLayout;
2662       break;
2663    }
2664    default:
2665       break;
2666    }
2667 }
2668 
2669 /**
2670  * ARB_separate_shader_objects: Compile & Link Program
2671  */
2672 GLuint GLAPIENTRY
_mesa_CreateShaderProgramv(GLenum type,GLsizei count,const GLchar * const * strings)2673 _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
2674                            const GLchar* const *strings)
2675 {
2676    GET_CURRENT_CONTEXT(ctx);
2677 
2678    const GLuint shader = create_shader_err(ctx, type, "glCreateShaderProgramv");
2679    GLuint program = 0;
2680 
2681    /*
2682     * According to OpenGL 4.5 and OpenGL ES 3.1 standards, section 7.3:
2683     * GL_INVALID_VALUE should be generated if count < 0
2684     */
2685    if (count < 0) {
2686       _mesa_error(ctx, GL_INVALID_VALUE, "glCreateShaderProgram (count < 0)");
2687       return program;
2688    }
2689 
2690    if (shader) {
2691       struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
2692 
2693       _mesa_ShaderSource(shader, count, strings, NULL);
2694       _mesa_compile_shader(ctx, sh);
2695 
2696       program = create_shader_program(ctx);
2697       if (program) {
2698 	 struct gl_shader_program *shProg;
2699 	 GLint compiled = GL_FALSE;
2700 
2701 	 shProg = _mesa_lookup_shader_program(ctx, program);
2702 
2703 	 shProg->SeparateShader = GL_TRUE;
2704 
2705 	 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
2706 	 if (compiled) {
2707 	    attach_shader_err(ctx, program, shader, "glCreateShaderProgramv");
2708 	    _mesa_link_program(ctx, shProg);
2709 	    detach_shader_error(ctx, program, shader);
2710 
2711 #if 0
2712 	    /* Possibly... */
2713 	    if (active-user-defined-varyings-in-linked-program) {
2714 	       append-error-to-info-log;
2715                shProg->data->LinkStatus = LINKING_FAILURE;
2716 	    }
2717 #endif
2718 	 }
2719          if (sh->InfoLog)
2720             ralloc_strcat(&shProg->data->InfoLog, sh->InfoLog);
2721       }
2722 
2723       delete_shader(ctx, shader);
2724    }
2725 
2726    return program;
2727 }
2728 
2729 
2730 static void
set_patch_vertices(struct gl_context * ctx,GLint value)2731 set_patch_vertices(struct gl_context *ctx, GLint value)
2732 {
2733    if (ctx->TessCtrlProgram.patch_vertices != value) {
2734       FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT);
2735       ctx->NewDriverState |= ST_NEW_TESS_STATE;
2736       ctx->TessCtrlProgram.patch_vertices = value;
2737    }
2738 }
2739 
2740 /**
2741  * For GL_ARB_tessellation_shader
2742  */
2743 void GLAPIENTRY
_mesa_PatchParameteri_no_error(GLenum pname,GLint value)2744 _mesa_PatchParameteri_no_error(GLenum pname, GLint value)
2745 {
2746    GET_CURRENT_CONTEXT(ctx);
2747 
2748    set_patch_vertices(ctx, value);
2749 }
2750 
2751 
2752 extern void GLAPIENTRY
_mesa_PatchParameteri(GLenum pname,GLint value)2753 _mesa_PatchParameteri(GLenum pname, GLint value)
2754 {
2755    GET_CURRENT_CONTEXT(ctx);
2756 
2757    if (!_mesa_has_tessellation(ctx)) {
2758       _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameteri");
2759       return;
2760    }
2761 
2762    if (pname != GL_PATCH_VERTICES) {
2763       _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameteri");
2764       return;
2765    }
2766 
2767    if (value <= 0 || value > ctx->Const.MaxPatchVertices) {
2768       _mesa_error(ctx, GL_INVALID_VALUE, "glPatchParameteri");
2769       return;
2770    }
2771 
2772    set_patch_vertices(ctx, value);
2773 }
2774 
2775 
2776 extern void GLAPIENTRY
_mesa_PatchParameterfv(GLenum pname,const GLfloat * values)2777 _mesa_PatchParameterfv(GLenum pname, const GLfloat *values)
2778 {
2779    GET_CURRENT_CONTEXT(ctx);
2780 
2781    if (!_mesa_has_tessellation(ctx)) {
2782       _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameterfv");
2783       return;
2784    }
2785 
2786    switch(pname) {
2787    case GL_PATCH_DEFAULT_OUTER_LEVEL:
2788       FLUSH_VERTICES(ctx, 0, 0);
2789       memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values,
2790              4 * sizeof(GLfloat));
2791       ctx->NewDriverState |= ST_NEW_TESS_STATE;
2792       return;
2793    case GL_PATCH_DEFAULT_INNER_LEVEL:
2794       FLUSH_VERTICES(ctx, 0, 0);
2795       memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values,
2796              2 * sizeof(GLfloat));
2797       ctx->NewDriverState |= ST_NEW_TESS_STATE;
2798       return;
2799    default:
2800       _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv");
2801       return;
2802    }
2803 }
2804 
2805 /**
2806  * ARB_shader_subroutine
2807  */
2808 GLint GLAPIENTRY
_mesa_GetSubroutineUniformLocation(GLuint program,GLenum shadertype,const GLchar * name)2809 _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
2810                                    const GLchar *name)
2811 {
2812    GET_CURRENT_CONTEXT(ctx);
2813    const char *api_name = "glGetSubroutineUniformLocation";
2814    struct gl_shader_program *shProg;
2815    GLenum resource_type;
2816    gl_shader_stage stage;
2817 
2818    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2819       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2820       return -1;
2821    }
2822 
2823    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2824    if (!shProg)
2825       return -1;
2826 
2827    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2828    if (!shProg->_LinkedShaders[stage]) {
2829       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2830       return -1;
2831    }
2832 
2833    resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2834    return _mesa_program_resource_location(shProg, resource_type, name);
2835 }
2836 
2837 GLuint GLAPIENTRY
_mesa_GetSubroutineIndex(GLuint program,GLenum shadertype,const GLchar * name)2838 _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
2839                          const GLchar *name)
2840 {
2841    GET_CURRENT_CONTEXT(ctx);
2842    const char *api_name = "glGetSubroutineIndex";
2843    struct gl_shader_program *shProg;
2844    struct gl_program_resource *res;
2845    GLenum resource_type;
2846    gl_shader_stage stage;
2847 
2848    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2849       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2850       return -1;
2851    }
2852 
2853    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2854    if (!shProg)
2855       return -1;
2856 
2857    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2858    if (!shProg->_LinkedShaders[stage]) {
2859       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2860       return -1;
2861    }
2862 
2863    resource_type = _mesa_shader_stage_to_subroutine(stage);
2864    res = _mesa_program_resource_find_name(shProg, resource_type, name, NULL);
2865    if (!res) {
2866      return -1;
2867    }
2868 
2869    return _mesa_program_resource_index(shProg, res);
2870 }
2871 
2872 
2873 GLvoid GLAPIENTRY
_mesa_GetActiveSubroutineUniformiv(GLuint program,GLenum shadertype,GLuint index,GLenum pname,GLint * values)2874 _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
2875                                    GLuint index, GLenum pname, GLint *values)
2876 {
2877    GET_CURRENT_CONTEXT(ctx);
2878    const char *api_name = "glGetActiveSubroutineUniformiv";
2879    struct gl_shader_program *shProg;
2880    struct gl_linked_shader *sh;
2881    gl_shader_stage stage;
2882    struct gl_program_resource *res;
2883    const struct gl_uniform_storage *uni;
2884    GLenum resource_type;
2885    int count, i, j;
2886 
2887    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2888       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2889       return;
2890    }
2891 
2892    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2893    if (!shProg)
2894       return;
2895 
2896    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2897    resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2898 
2899    sh = shProg->_LinkedShaders[stage];
2900    if (!sh) {
2901       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2902       return;
2903    }
2904 
2905    struct gl_program *p = shProg->_LinkedShaders[stage]->Program;
2906    if (index >= p->sh.NumSubroutineUniforms) {
2907       _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name);
2908       return;
2909    }
2910 
2911    switch (pname) {
2912    case GL_NUM_COMPATIBLE_SUBROUTINES: {
2913       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2914       if (res) {
2915          uni = res->Data;
2916          values[0] = uni->num_compatible_subroutines;
2917       }
2918       break;
2919    }
2920    case GL_COMPATIBLE_SUBROUTINES: {
2921       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2922       if (res) {
2923          uni = res->Data;
2924          count = 0;
2925          for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
2926             struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
2927             for (j = 0; j < fn->num_compat_types; j++) {
2928                if (fn->types[j] == uni->type) {
2929                   values[count++] = i;
2930                   break;
2931                }
2932             }
2933          }
2934       }
2935       break;
2936    }
2937    case GL_UNIFORM_SIZE:
2938       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2939       if (res) {
2940          uni = res->Data;
2941          values[0] = uni->array_elements ? uni->array_elements : 1;
2942       }
2943       break;
2944    case GL_UNIFORM_NAME_LENGTH:
2945       res = _mesa_program_resource_find_index(shProg, resource_type, index);
2946       if (res) {
2947          values[0] = _mesa_program_resource_name_length(res) + 1
2948             + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
2949       }
2950       break;
2951    default:
2952       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2953       return;
2954    }
2955 }
2956 
2957 
2958 GLvoid GLAPIENTRY
_mesa_GetActiveSubroutineUniformName(GLuint program,GLenum shadertype,GLuint index,GLsizei bufsize,GLsizei * length,GLchar * name)2959 _mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype,
2960                                      GLuint index, GLsizei bufsize,
2961                                      GLsizei *length, GLchar *name)
2962 {
2963    GET_CURRENT_CONTEXT(ctx);
2964    const char *api_name = "glGetActiveSubroutineUniformName";
2965    struct gl_shader_program *shProg;
2966    GLenum resource_type;
2967    gl_shader_stage stage;
2968 
2969    if (!_mesa_validate_shader_target(ctx, shadertype)) {
2970       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2971       return;
2972    }
2973 
2974    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2975    if (!shProg)
2976       return;
2977 
2978    stage = _mesa_shader_enum_to_shader_stage(shadertype);
2979    if (!shProg->_LinkedShaders[stage]) {
2980       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2981       return;
2982    }
2983 
2984    resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2985    /* get program resource name */
2986    _mesa_get_program_resource_name(shProg, resource_type,
2987                                    index, bufsize,
2988                                    length, name, false, api_name);
2989 }
2990 
2991 
2992 GLvoid GLAPIENTRY
_mesa_GetActiveSubroutineName(GLuint program,GLenum shadertype,GLuint index,GLsizei bufsize,GLsizei * length,GLchar * name)2993 _mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype,
2994                               GLuint index, GLsizei bufsize,
2995                               GLsizei *length, GLchar *name)
2996 {
2997    GET_CURRENT_CONTEXT(ctx);
2998    const char *api_name = "glGetActiveSubroutineName";
2999    struct gl_shader_program *shProg;
3000    GLenum resource_type;
3001    gl_shader_stage stage;
3002 
3003    if (!_mesa_validate_shader_target(ctx, shadertype)) {
3004       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3005       return;
3006    }
3007 
3008    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
3009    if (!shProg)
3010       return;
3011 
3012    stage = _mesa_shader_enum_to_shader_stage(shadertype);
3013    if (!shProg->_LinkedShaders[stage]) {
3014       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3015       return;
3016    }
3017    resource_type = _mesa_shader_stage_to_subroutine(stage);
3018    _mesa_get_program_resource_name(shProg, resource_type,
3019                                    index, bufsize,
3020                                    length, name, false, api_name);
3021 }
3022 
3023 GLvoid GLAPIENTRY
_mesa_UniformSubroutinesuiv(GLenum shadertype,GLsizei count,const GLuint * indices)3024 _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
3025                             const GLuint *indices)
3026 {
3027    GET_CURRENT_CONTEXT(ctx);
3028    const char *api_name = "glUniformSubroutinesuiv";
3029    gl_shader_stage stage;
3030    int i;
3031 
3032    if (!_mesa_validate_shader_target(ctx, shadertype)) {
3033       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3034       return;
3035    }
3036 
3037    stage = _mesa_shader_enum_to_shader_stage(shadertype);
3038    struct gl_program *p = ctx->_Shader->CurrentProgram[stage];
3039    if (!p) {
3040       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3041       return;
3042    }
3043 
3044    if (count != p->sh.NumSubroutineUniformRemapTable) {
3045       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
3046       return;
3047    }
3048 
3049    i = 0;
3050    bool flushed = false;
3051    do {
3052       struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
3053       if (uni == NULL) {
3054          i++;
3055          continue;
3056       }
3057 
3058       if (!flushed) {
3059          _mesa_flush_vertices_for_uniforms(ctx, uni);
3060          flushed = true;
3061       }
3062 
3063       int uni_count = uni->array_elements ? uni->array_elements : 1;
3064       int j, k, f;
3065 
3066       for (j = i; j < i + uni_count; j++) {
3067          struct gl_subroutine_function *subfn = NULL;
3068          if (indices[j] > p->sh.MaxSubroutineFunctionIndex) {
3069             _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
3070             return;
3071          }
3072 
3073          for (f = 0; f < p->sh.NumSubroutineFunctions; f++) {
3074             if (p->sh.SubroutineFunctions[f].index == indices[j])
3075                subfn = &p->sh.SubroutineFunctions[f];
3076          }
3077 
3078          if (!subfn) {
3079             continue;
3080          }
3081 
3082          for (k = 0; k < subfn->num_compat_types; k++) {
3083             if (subfn->types[k] == uni->type)
3084                break;
3085          }
3086          if (k == subfn->num_compat_types) {
3087             _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3088             return;
3089          }
3090 
3091          ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j];
3092       }
3093       i += uni_count;
3094    } while(i < count);
3095 }
3096 
3097 
3098 GLvoid GLAPIENTRY
_mesa_GetUniformSubroutineuiv(GLenum shadertype,GLint location,GLuint * params)3099 _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
3100                               GLuint *params)
3101 {
3102    GET_CURRENT_CONTEXT(ctx);
3103    const char *api_name = "glGetUniformSubroutineuiv";
3104    gl_shader_stage stage;
3105 
3106    if (!_mesa_validate_shader_target(ctx, shadertype)) {
3107       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3108       return;
3109    }
3110 
3111    stage = _mesa_shader_enum_to_shader_stage(shadertype);
3112    struct gl_program *p = ctx->_Shader->CurrentProgram[stage];
3113    if (!p) {
3114       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3115       return;
3116    }
3117 
3118    if (location >= p->sh.NumSubroutineUniformRemapTable) {
3119       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
3120       return;
3121    }
3122 
3123    *params = ctx->SubroutineIndex[p->info.stage].IndexPtr[location];
3124 }
3125 
3126 
3127 GLvoid GLAPIENTRY
_mesa_GetProgramStageiv(GLuint program,GLenum shadertype,GLenum pname,GLint * values)3128 _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
3129                         GLenum pname, GLint *values)
3130 {
3131    GET_CURRENT_CONTEXT(ctx);
3132    const char *api_name = "glGetProgramStageiv";
3133    struct gl_shader_program *shProg;
3134    struct gl_linked_shader *sh;
3135    gl_shader_stage stage;
3136 
3137    if (!_mesa_validate_shader_target(ctx, shadertype)) {
3138       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3139       return;
3140    }
3141 
3142    shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
3143    if (!shProg)
3144       return;
3145 
3146    stage = _mesa_shader_enum_to_shader_stage(shadertype);
3147    sh = shProg->_LinkedShaders[stage];
3148 
3149    /* ARB_shader_subroutine doesn't ask the program to be linked, or list any
3150     * INVALID_OPERATION in the case of not be linked.
3151     *
3152     * And for some pnames, like GL_ACTIVE_SUBROUTINE_UNIFORMS, you can ask the
3153     * same info using other specs (ARB_program_interface_query), without the
3154     * need of the program to be linked, being the value for that case 0.
3155     *
3156     * But at the same time, some other methods require the program to be
3157     * linked for pname related to locations, so it would be inconsistent to
3158     * not do the same here. So we are:
3159     *   * Return GL_INVALID_OPERATION if not linked only for locations.
3160     *   * Setting a default value of 0, to be returned if not linked.
3161     */
3162    if (!sh) {
3163       values[0] = 0;
3164       if (pname == GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS) {
3165          _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
3166       }
3167       return;
3168    }
3169 
3170    struct gl_program *p = sh->Program;
3171    switch (pname) {
3172    case GL_ACTIVE_SUBROUTINES:
3173       values[0] = p->sh.NumSubroutineFunctions;
3174       break;
3175    case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS:
3176       values[0] = p->sh.NumSubroutineUniformRemapTable;
3177       break;
3178    case GL_ACTIVE_SUBROUTINE_UNIFORMS:
3179       values[0] = p->sh.NumSubroutineUniforms;
3180       break;
3181    case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
3182    {
3183       unsigned i;
3184       GLint max_len = 0;
3185       GLenum resource_type;
3186       struct gl_program_resource *res;
3187 
3188       resource_type = _mesa_shader_stage_to_subroutine(stage);
3189       for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
3190          res = _mesa_program_resource_find_index(shProg, resource_type, i);
3191          if (res) {
3192             const GLint len = _mesa_program_resource_name_length(res) + 1;
3193             if (len > max_len)
3194                max_len = len;
3195          }
3196       }
3197       values[0] = max_len;
3198       break;
3199    }
3200    case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH:
3201    {
3202       unsigned i;
3203       GLint max_len = 0;
3204       GLenum resource_type;
3205       struct gl_program_resource *res;
3206 
3207       resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
3208       for (i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) {
3209          res = _mesa_program_resource_find_index(shProg, resource_type, i);
3210          if (res) {
3211             const GLint len = _mesa_program_resource_name_length(res) + 1
3212                + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
3213 
3214             if (len > max_len)
3215                max_len = len;
3216          }
3217       }
3218       values[0] = max_len;
3219       break;
3220    }
3221    default:
3222       _mesa_error(ctx, GL_INVALID_ENUM, "%s", api_name);
3223       values[0] = -1;
3224       break;
3225    }
3226 }
3227 
3228 /* This is simple list entry that will be used to hold a list of string
3229  * tokens of a parsed shader include path.
3230  */
3231 struct sh_incl_path_entry
3232 {
3233    struct list_head list;
3234 
3235    char *path;
3236 };
3237 
3238 /* Nodes of the shader include tree */
3239 struct sh_incl_path_ht_entry
3240 {
3241    struct hash_table *path;
3242    char *shader_source;
3243 };
3244 
3245 struct shader_includes {
3246    /* Array to hold include paths given to glCompileShaderIncludeARB() */
3247    struct sh_incl_path_entry **include_paths;
3248    size_t num_include_paths;
3249    size_t relative_path_cursor;
3250 
3251    /* Root hash table holding the shader include tree */
3252    struct hash_table *shader_include_tree;
3253 };
3254 
3255 void
_mesa_init_shader_includes(struct gl_shared_state * shared)3256 _mesa_init_shader_includes(struct gl_shared_state *shared)
3257 {
3258    shared->ShaderIncludes = calloc(1, sizeof(struct shader_includes));
3259    shared->ShaderIncludes->shader_include_tree =
3260       _mesa_hash_table_create(NULL, _mesa_hash_string,
3261                               _mesa_key_string_equal);
3262 }
3263 
3264 size_t
_mesa_get_shader_include_cursor(struct gl_shared_state * shared)3265 _mesa_get_shader_include_cursor(struct gl_shared_state *shared)
3266 {
3267    return shared->ShaderIncludes->relative_path_cursor;
3268 }
3269 
3270 void
_mesa_set_shader_include_cursor(struct gl_shared_state * shared,size_t cursor)3271 _mesa_set_shader_include_cursor(struct gl_shared_state *shared, size_t cursor)
3272 {
3273    shared->ShaderIncludes->relative_path_cursor = cursor;
3274 }
3275 
3276 static void
destroy_shader_include(struct hash_entry * entry)3277 destroy_shader_include(struct hash_entry *entry)
3278 {
3279    struct sh_incl_path_ht_entry *sh_incl_ht_entry =
3280       (struct sh_incl_path_ht_entry *) entry->data;
3281 
3282    _mesa_hash_table_destroy(sh_incl_ht_entry->path, destroy_shader_include);
3283    free(sh_incl_ht_entry->shader_source);
3284    free(sh_incl_ht_entry);
3285 }
3286 
3287 void
_mesa_destroy_shader_includes(struct gl_shared_state * shared)3288 _mesa_destroy_shader_includes(struct gl_shared_state *shared)
3289 {
3290    _mesa_hash_table_destroy(shared->ShaderIncludes->shader_include_tree,
3291                             destroy_shader_include);
3292    free(shared->ShaderIncludes);
3293 }
3294 
3295 static bool
valid_path_format(const char * str,bool relative_path)3296 valid_path_format(const char *str, bool relative_path)
3297 {
3298    int i = 0;
3299 
3300    if (!str[i] || (!relative_path && str[i] != '/'))
3301       return false;
3302 
3303    i++;
3304 
3305    while (str[i]) {
3306       const char c = str[i++];
3307       if (('A' <= c && c <= 'Z') ||
3308           ('a' <= c && c <= 'z') ||
3309           ('0' <= c && c <= '9'))
3310          continue;
3311 
3312       if (c == '/') {
3313          if (str[i - 2] == '/')
3314             return false;
3315 
3316          continue;
3317       }
3318 
3319       if (strchr("^. _+*%[](){}|&~=!:;,?-", c) == NULL)
3320          return false;
3321   }
3322 
3323   if (str[i - 1] == '/')
3324      return false;
3325 
3326   return true;
3327 }
3328 
3329 
3330 static bool
validate_and_tokenise_sh_incl(struct gl_context * ctx,void * mem_ctx,struct sh_incl_path_entry ** path_list,char * full_path,bool error_check)3331 validate_and_tokenise_sh_incl(struct gl_context *ctx,
3332                               void *mem_ctx,
3333                               struct sh_incl_path_entry **path_list,
3334                               char *full_path, bool error_check)
3335 {
3336    bool relative_path = ctx->Shared->ShaderIncludes->num_include_paths;
3337 
3338    if (!valid_path_format(full_path, relative_path)) {
3339       if (error_check) {
3340          _mesa_error(ctx, GL_INVALID_VALUE,
3341                      "glNamedStringARB(invalid name %s)", full_path);
3342       }
3343       return false;
3344    }
3345 
3346    char *save_ptr = NULL;
3347    char *path_str = strtok_r(full_path, "/", &save_ptr);
3348 
3349    *path_list = rzalloc(mem_ctx, struct sh_incl_path_entry);
3350    struct sh_incl_path_entry * list = *path_list;
3351    list_inithead(&list->list);
3352 
3353    while (path_str != NULL) {
3354       if (strlen(path_str) == 0) {
3355          if (error_check) {
3356             _mesa_error(ctx, GL_INVALID_VALUE,
3357                         "glNamedStringARB(invalid name %s)", full_path);
3358          }
3359 
3360          return false;
3361       }
3362 
3363       if (strcmp(path_str, ".") == 0) {
3364          /* Do nothing */
3365       } else if (strcmp(path_str, "..") == 0) {
3366          list_del(list->list.prev);
3367       } else {
3368          struct sh_incl_path_entry *path =
3369             rzalloc(mem_ctx, struct sh_incl_path_entry);
3370 
3371          path->path = strdup(path_str);
3372          list_addtail(&path->list, &list->list);
3373       }
3374 
3375       path_str = strtok_r(NULL, "/", &save_ptr);
3376    }
3377 
3378    return true;
3379 }
3380 
3381 static struct sh_incl_path_ht_entry *
lookup_shader_include(struct gl_context * ctx,char * path,bool error_check)3382 lookup_shader_include(struct gl_context *ctx, char *path,
3383                       bool error_check)
3384 {
3385    void *mem_ctx = ralloc_context(NULL);
3386    struct sh_incl_path_entry *path_list;
3387 
3388    if (!validate_and_tokenise_sh_incl(ctx, mem_ctx, &path_list, path,
3389                                       error_check)) {
3390       ralloc_free(mem_ctx);
3391       return NULL;
3392    }
3393 
3394    struct sh_incl_path_ht_entry *sh_incl_ht_entry = NULL;
3395    struct hash_table *path_ht =
3396       ctx->Shared->ShaderIncludes->shader_include_tree;
3397 
3398    size_t count = ctx->Shared->ShaderIncludes->num_include_paths;
3399    bool relative_path = path[0] != '/';
3400 
3401    size_t i = ctx->Shared->ShaderIncludes->relative_path_cursor;
3402    bool use_cursor = ctx->Shared->ShaderIncludes->relative_path_cursor;
3403 
3404    do {
3405       struct sh_incl_path_entry *entry;
3406 
3407       if (relative_path) {
3408 next_relative_path:
3409          {
3410             struct sh_incl_path_entry *rel_path_list =
3411                ctx->Shared->ShaderIncludes->include_paths[i];
3412             LIST_FOR_EACH_ENTRY(entry, &rel_path_list->list, list) {
3413                struct hash_entry *ht_entry =
3414                   _mesa_hash_table_search(path_ht, entry->path);
3415 
3416                if (!ht_entry) {
3417                   /* Reset search path and skip to the next include path */
3418                   path_ht = ctx->Shared->ShaderIncludes->shader_include_tree;
3419                   sh_incl_ht_entry = NULL;
3420                   if (use_cursor) {
3421                      i = 0;
3422                      use_cursor = false;
3423 
3424                      goto next_relative_path;
3425                   }
3426                   i++;
3427                   if (i < count)
3428                      goto next_relative_path;
3429                   else
3430                      break;
3431                } else {
3432                   sh_incl_ht_entry =
3433                     (struct sh_incl_path_ht_entry *) ht_entry->data;
3434                }
3435 
3436                path_ht = sh_incl_ht_entry->path;
3437             }
3438          }
3439       }
3440 
3441       LIST_FOR_EACH_ENTRY(entry, &path_list->list, list) {
3442          struct hash_entry *ht_entry =
3443             _mesa_hash_table_search(path_ht, entry->path);
3444 
3445          if (!ht_entry) {
3446             /* Reset search path and skip to the next include path */
3447             path_ht = ctx->Shared->ShaderIncludes->shader_include_tree;
3448             sh_incl_ht_entry = NULL;
3449             if (use_cursor) {
3450                i = 0;
3451                use_cursor = false;
3452 
3453                break;
3454             }
3455             i++;
3456             break;
3457          } else {
3458 
3459             sh_incl_ht_entry =
3460                (struct sh_incl_path_ht_entry *) ht_entry->data;
3461          }
3462 
3463          path_ht = sh_incl_ht_entry->path;
3464       }
3465 
3466       if (i < count &&
3467           (sh_incl_ht_entry == NULL || !sh_incl_ht_entry->shader_source))
3468          continue;
3469 
3470       /* If we get here then we have found a matching path or exahusted our
3471        * relative search paths.
3472        */
3473       ctx->Shared->ShaderIncludes->relative_path_cursor = i;
3474       break;
3475    } while (i < count);
3476 
3477    ralloc_free(mem_ctx);
3478 
3479    return sh_incl_ht_entry;
3480 }
3481 
3482 const char *
_mesa_lookup_shader_include(struct gl_context * ctx,char * path,bool error_check)3483 _mesa_lookup_shader_include(struct gl_context *ctx, char *path,
3484                             bool error_check)
3485 {
3486    struct sh_incl_path_ht_entry *shader_include =
3487       lookup_shader_include(ctx, path, error_check);
3488 
3489    return shader_include ? shader_include->shader_source : NULL;
3490 }
3491 
3492 static char *
copy_string(struct gl_context * ctx,const char * str,int str_len,const char * caller)3493 copy_string(struct gl_context *ctx, const char *str, int str_len,
3494             const char *caller)
3495 {
3496    if (!str) {
3497       _mesa_error(ctx, GL_INVALID_VALUE, "%s(NULL string)", caller);
3498       return NULL;
3499    }
3500 
3501    char *cp;
3502    if (str_len == -1)
3503       cp = strdup(str);
3504    else {
3505       cp = calloc(sizeof(char), str_len + 1);
3506       memcpy(cp, str, str_len);
3507    }
3508 
3509    return cp;
3510 }
3511 
3512 GLvoid GLAPIENTRY
_mesa_NamedStringARB(GLenum type,GLint namelen,const GLchar * name,GLint stringlen,const GLchar * string)3513 _mesa_NamedStringARB(GLenum type, GLint namelen, const GLchar *name,
3514                      GLint stringlen, const GLchar *string)
3515 {
3516    GET_CURRENT_CONTEXT(ctx);
3517    const char *caller = "glNamedStringARB";
3518 
3519    if (type != GL_SHADER_INCLUDE_ARB) {
3520       _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid type)", caller);
3521       return;
3522    }
3523 
3524    char *name_cp = copy_string(ctx, name, namelen, caller);
3525    char *string_cp = copy_string(ctx, string, stringlen, caller);
3526    if (!name_cp || !string_cp) {
3527       free(string_cp);
3528       free(name_cp);
3529       return;
3530    }
3531 
3532    void *mem_ctx = ralloc_context(NULL);
3533    struct sh_incl_path_entry *path_list;
3534 
3535    if (!validate_and_tokenise_sh_incl(ctx, mem_ctx, &path_list, name_cp,
3536                                       true)) {
3537       free(string_cp);
3538       free(name_cp);
3539       ralloc_free(mem_ctx);
3540       return;
3541    }
3542 
3543    simple_mtx_lock(&ctx->Shared->ShaderIncludeMutex);
3544 
3545    struct hash_table *path_ht =
3546       ctx->Shared->ShaderIncludes->shader_include_tree;
3547 
3548    struct sh_incl_path_entry *entry;
3549    LIST_FOR_EACH_ENTRY(entry, &path_list->list, list) {
3550       struct hash_entry *ht_entry =
3551          _mesa_hash_table_search(path_ht, entry->path);
3552 
3553       struct sh_incl_path_ht_entry *sh_incl_ht_entry;
3554       if (!ht_entry) {
3555          sh_incl_ht_entry = calloc(1, sizeof(struct sh_incl_path_ht_entry));
3556          sh_incl_ht_entry->path =
3557             _mesa_hash_table_create(NULL, _mesa_hash_string,
3558                                     _mesa_key_string_equal);
3559          _mesa_hash_table_insert(path_ht, entry->path, sh_incl_ht_entry);
3560       } else {
3561          sh_incl_ht_entry = (struct sh_incl_path_ht_entry *) ht_entry->data;
3562       }
3563 
3564       path_ht = sh_incl_ht_entry->path;
3565 
3566       if (list_last_entry(&path_list->list, struct sh_incl_path_entry, list) == entry) {
3567          free(sh_incl_ht_entry->shader_source);
3568          sh_incl_ht_entry->shader_source = string_cp;
3569       }
3570    }
3571 
3572    simple_mtx_unlock(&ctx->Shared->ShaderIncludeMutex);
3573 
3574    free(name_cp);
3575    ralloc_free(mem_ctx);
3576 }
3577 
3578 GLvoid GLAPIENTRY
_mesa_DeleteNamedStringARB(GLint namelen,const GLchar * name)3579 _mesa_DeleteNamedStringARB(GLint namelen, const GLchar *name)
3580 {
3581    GET_CURRENT_CONTEXT(ctx);
3582    const char *caller = "glDeleteNamedStringARB";
3583 
3584    char *name_cp = copy_string(ctx, name, namelen, caller);
3585    if (!name_cp)
3586       return;
3587 
3588    struct sh_incl_path_ht_entry *shader_include =
3589       lookup_shader_include(ctx, name_cp, true);
3590 
3591    if (!shader_include) {
3592       _mesa_error(ctx, GL_INVALID_OPERATION,
3593                   "%s(no string associated with path %s)", caller, name_cp);
3594       free(name_cp);
3595       return;
3596    }
3597 
3598    simple_mtx_lock(&ctx->Shared->ShaderIncludeMutex);
3599 
3600    free(shader_include->shader_source);
3601    shader_include->shader_source = NULL;
3602 
3603    simple_mtx_unlock(&ctx->Shared->ShaderIncludeMutex);
3604 
3605    free(name_cp);
3606 }
3607 
3608 GLvoid GLAPIENTRY
_mesa_CompileShaderIncludeARB(GLuint shader,GLsizei count,const GLchar * const * path,const GLint * length)3609 _mesa_CompileShaderIncludeARB(GLuint shader, GLsizei count,
3610                               const GLchar* const *path, const GLint *length)
3611 {
3612    GET_CURRENT_CONTEXT(ctx);
3613    const char *caller = "glCompileShaderIncludeARB";
3614 
3615    if (count > 0 && path == NULL) {
3616       _mesa_error(ctx, GL_INVALID_VALUE, "%s(count > 0 && path == NULL)",
3617                   caller);
3618       return;
3619    }
3620 
3621    void *mem_ctx = ralloc_context(NULL);
3622 
3623    simple_mtx_lock(&ctx->Shared->ShaderIncludeMutex);
3624 
3625    ctx->Shared->ShaderIncludes->include_paths =
3626       ralloc_array_size(mem_ctx, sizeof(struct sh_incl_path_entry *), count);
3627 
3628    for (size_t i = 0; i < count; i++) {
3629       char *path_cp = copy_string(ctx, path[i], length ? length[i] : -1,
3630                                   caller);
3631       if (!path_cp) {
3632          goto exit;
3633       }
3634 
3635       struct sh_incl_path_entry *path_list;
3636 
3637       if (!validate_and_tokenise_sh_incl(ctx, mem_ctx, &path_list, path_cp,
3638                                          true)) {
3639          free(path_cp);
3640          goto exit;
3641       }
3642 
3643       ctx->Shared->ShaderIncludes->include_paths[i] = path_list;
3644 
3645       free(path_cp);
3646    }
3647 
3648    /* We must set this *after* all calls to validate_and_tokenise_sh_incl()
3649     * are done as we use this to decide if we need to check the start of the
3650     * path for a '/'
3651     */
3652    ctx->Shared->ShaderIncludes->num_include_paths = count;
3653 
3654    struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
3655    if (!sh) {
3656       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(shader)", caller);
3657       goto exit;
3658    }
3659 
3660    _mesa_compile_shader(ctx, sh);
3661 
3662 exit:
3663    ctx->Shared->ShaderIncludes->num_include_paths = 0;
3664    ctx->Shared->ShaderIncludes->relative_path_cursor = 0;
3665    ctx->Shared->ShaderIncludes->include_paths = NULL;
3666 
3667    simple_mtx_unlock(&ctx->Shared->ShaderIncludeMutex);
3668 
3669    ralloc_free(mem_ctx);
3670 }
3671 
3672 GLboolean GLAPIENTRY
_mesa_IsNamedStringARB(GLint namelen,const GLchar * name)3673 _mesa_IsNamedStringARB(GLint namelen, const GLchar *name)
3674 {
3675    GET_CURRENT_CONTEXT(ctx);
3676 
3677    if (!name)
3678       return false;
3679 
3680    char *name_cp = copy_string(ctx, name, namelen, "");
3681 
3682    const char *source = _mesa_lookup_shader_include(ctx, name_cp, false);
3683    free(name_cp);
3684 
3685    if (!source)
3686       return false;
3687 
3688    return true;
3689 }
3690 
3691 GLvoid GLAPIENTRY
_mesa_GetNamedStringARB(GLint namelen,const GLchar * name,GLsizei bufSize,GLint * stringlen,GLchar * string)3692 _mesa_GetNamedStringARB(GLint namelen, const GLchar *name, GLsizei bufSize,
3693                         GLint *stringlen, GLchar *string)
3694 {
3695    GET_CURRENT_CONTEXT(ctx);
3696    const char *caller = "glGetNamedStringARB";
3697 
3698    char *name_cp = copy_string(ctx, name, namelen, caller);
3699    if (!name_cp)
3700       return;
3701 
3702    const char *source = _mesa_lookup_shader_include(ctx, name_cp, true);
3703    if (!source) {
3704       _mesa_error(ctx, GL_INVALID_OPERATION,
3705                   "%s(no string associated with path %s)", caller, name_cp);
3706       free(name_cp);
3707       return;
3708    }
3709 
3710    size_t size = MIN2(strlen(source), bufSize - 1);
3711    memcpy(string, source, size);
3712    string[size] = '\0';
3713 
3714    *stringlen = size;
3715 
3716    free(name_cp);
3717 }
3718 
3719 GLvoid GLAPIENTRY
_mesa_GetNamedStringivARB(GLint namelen,const GLchar * name,GLenum pname,GLint * params)3720 _mesa_GetNamedStringivARB(GLint namelen, const GLchar *name,
3721                           GLenum pname, GLint *params)
3722 {
3723    GET_CURRENT_CONTEXT(ctx);
3724    const char *caller = "glGetNamedStringivARB";
3725 
3726    char *name_cp = copy_string(ctx, name, namelen, caller);
3727    if (!name_cp)
3728       return;
3729 
3730    const char *source = _mesa_lookup_shader_include(ctx, name_cp, true);
3731    if (!source) {
3732       _mesa_error(ctx, GL_INVALID_OPERATION,
3733                   "%s(no string associated with path %s)", caller, name_cp);
3734       free(name_cp);
3735       return;
3736    }
3737 
3738    switch (pname) {
3739    case GL_NAMED_STRING_LENGTH_ARB:
3740       *params = strlen(source) + 1;
3741       break;
3742    case GL_NAMED_STRING_TYPE_ARB:
3743       *params = GL_SHADER_INCLUDE_ARB;
3744       break;
3745    default:
3746       _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname)", caller);
3747       break;
3748    }
3749 
3750    free(name_cp);
3751 }
3752 
3753 static int
find_compat_subroutine(struct gl_program * p,const struct glsl_type * type)3754 find_compat_subroutine(struct gl_program *p, const struct glsl_type *type)
3755 {
3756    int i, j;
3757 
3758    for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
3759       struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
3760       for (j = 0; j < fn->num_compat_types; j++) {
3761          if (fn->types[j] == type)
3762             return i;
3763       }
3764    }
3765    return 0;
3766 }
3767 
3768 static void
_mesa_shader_write_subroutine_index(struct gl_context * ctx,struct gl_program * p)3769 _mesa_shader_write_subroutine_index(struct gl_context *ctx,
3770                                     struct gl_program *p)
3771 {
3772    int i, j;
3773 
3774    if (p->sh.NumSubroutineUniformRemapTable == 0)
3775       return;
3776 
3777    i = 0;
3778    do {
3779       struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
3780       int uni_count;
3781       int val;
3782 
3783       if (!uni) {
3784          i++;
3785          continue;
3786       }
3787 
3788       uni_count = uni->array_elements ? uni->array_elements : 1;
3789       for (j = 0; j < uni_count; j++) {
3790          val = ctx->SubroutineIndex[p->info.stage].IndexPtr[i + j];
3791          memcpy(&uni->storage[j], &val, sizeof(int));
3792       }
3793 
3794       _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
3795       i += uni_count;
3796    } while(i < p->sh.NumSubroutineUniformRemapTable);
3797 }
3798 
3799 void
_mesa_shader_write_subroutine_indices(struct gl_context * ctx,gl_shader_stage stage)3800 _mesa_shader_write_subroutine_indices(struct gl_context *ctx,
3801                                       gl_shader_stage stage)
3802 {
3803    if (ctx->_Shader->CurrentProgram[stage])
3804       _mesa_shader_write_subroutine_index(ctx,
3805                                           ctx->_Shader->CurrentProgram[stage]);
3806 }
3807 
3808 void
_mesa_program_init_subroutine_defaults(struct gl_context * ctx,struct gl_program * p)3809 _mesa_program_init_subroutine_defaults(struct gl_context *ctx,
3810                                        struct gl_program *p)
3811 {
3812    assert(p);
3813 
3814    struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[p->info.stage];
3815    if (binding->NumIndex != p->sh.NumSubroutineUniformRemapTable) {
3816       binding->IndexPtr = realloc(binding->IndexPtr,
3817                                   p->sh.NumSubroutineUniformRemapTable * (sizeof(GLuint)));
3818       binding->NumIndex = p->sh.NumSubroutineUniformRemapTable;
3819    }
3820 
3821    for (int i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) {
3822       struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
3823 
3824       if (!uni)
3825          continue;
3826 
3827       binding->IndexPtr[i] = find_compat_subroutine(p, uni->type);
3828    }
3829 }
3830