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