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