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