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