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