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 ¶ms);
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