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