mesa: Drop PATH_MAX usage.
[mesa.git] / src / mesa / main / shaderapi.c
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 * XXX things to do:
35 * 1. Check that the right error code is generated for all _mesa_error() calls.
36 * 2. Insert FLUSH_VERTICES calls in various places
37 */
38
39
40 #include <stdbool.h>
41 #include "main/glheader.h"
42 #include "main/context.h"
43 #include "main/dispatch.h"
44 #include "main/enums.h"
45 #include "main/hash.h"
46 #include "main/mtypes.h"
47 #include "main/pipelineobj.h"
48 #include "main/shaderapi.h"
49 #include "main/shaderobj.h"
50 #include "main/transformfeedback.h"
51 #include "main/uniforms.h"
52 #include "compiler/glsl/glsl_parser_extras.h"
53 #include "compiler/glsl/ir.h"
54 #include "compiler/glsl/ir_uniform.h"
55 #include "compiler/glsl/program.h"
56 #include "program/program.h"
57 #include "program/prog_print.h"
58 #include "program/prog_parameter.h"
59 #include "util/ralloc.h"
60 #include "util/hash_table.h"
61 #include "util/mesa-sha1.h"
62
63 /**
64 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
65 */
66 GLbitfield
67 _mesa_get_shader_flags(void)
68 {
69 GLbitfield flags = 0x0;
70 const char *env = getenv("MESA_GLSL");
71
72 if (env) {
73 if (strstr(env, "dump_on_error"))
74 flags |= GLSL_DUMP_ON_ERROR;
75 else if (strstr(env, "dump"))
76 flags |= GLSL_DUMP;
77 if (strstr(env, "log"))
78 flags |= GLSL_LOG;
79 if (strstr(env, "nopvert"))
80 flags |= GLSL_NOP_VERT;
81 if (strstr(env, "nopfrag"))
82 flags |= GLSL_NOP_FRAG;
83 if (strstr(env, "nopt"))
84 flags |= GLSL_NO_OPT;
85 else if (strstr(env, "opt"))
86 flags |= GLSL_OPT;
87 if (strstr(env, "uniform"))
88 flags |= GLSL_UNIFORMS;
89 if (strstr(env, "useprog"))
90 flags |= GLSL_USE_PROG;
91 if (strstr(env, "errors"))
92 flags |= GLSL_REPORT_ERRORS;
93 }
94
95 return flags;
96 }
97
98 /**
99 * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH").
100 */
101 const char *
102 _mesa_get_shader_capture_path(void)
103 {
104 static bool read_env_var = false;
105 static const char *path = NULL;
106
107 if (!read_env_var) {
108 path = getenv("MESA_SHADER_CAPTURE_PATH");
109 read_env_var = true;
110 }
111
112 return path;
113 }
114
115 /**
116 * Initialize context's shader state.
117 */
118 void
119 _mesa_init_shader_state(struct gl_context *ctx)
120 {
121 /* Device drivers may override these to control what kind of instructions
122 * are generated by the GLSL compiler.
123 */
124 struct gl_shader_compiler_options options;
125 gl_shader_stage sh;
126 int i;
127
128 memset(&options, 0, sizeof(options));
129 options.MaxUnrollIterations = 32;
130 options.MaxIfDepth = UINT_MAX;
131
132 for (sh = 0; sh < MESA_SHADER_STAGES; ++sh)
133 memcpy(&ctx->Const.ShaderCompilerOptions[sh], &options, sizeof(options));
134
135 ctx->Shader.Flags = _mesa_get_shader_flags();
136
137 if (ctx->Shader.Flags != 0)
138 ctx->Const.GenerateTemporaryNames = true;
139
140 /* Extended for ARB_separate_shader_objects */
141 ctx->Shader.RefCount = 1;
142 mtx_init(&ctx->Shader.Mutex, mtx_plain);
143
144 ctx->TessCtrlProgram.patch_vertices = 3;
145 for (i = 0; i < 4; ++i)
146 ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0;
147 for (i = 0; i < 2; ++i)
148 ctx->TessCtrlProgram.patch_default_inner_level[i] = 1.0;
149 }
150
151
152 /**
153 * Free the per-context shader-related state.
154 */
155 void
156 _mesa_free_shader_state(struct gl_context *ctx)
157 {
158 int i;
159 for (i = 0; i < MESA_SHADER_STAGES; i++) {
160 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram[i],
161 NULL);
162 }
163 _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
164 NULL);
165 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
166
167 /* Extended for ARB_separate_shader_objects */
168 _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);
169
170 assert(ctx->Shader.RefCount == 1);
171 mtx_destroy(&ctx->Shader.Mutex);
172 }
173
174
175 /**
176 * Copy string from <src> to <dst>, up to maxLength characters, returning
177 * length of <dst> in <length>.
178 * \param src the strings source
179 * \param maxLength max chars to copy
180 * \param length returns number of chars copied
181 * \param dst the string destination
182 */
183 void
184 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
185 GLsizei *length, const GLchar *src)
186 {
187 GLsizei len;
188 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
189 dst[len] = src[len];
190 if (maxLength > 0)
191 dst[len] = 0;
192 if (length)
193 *length = len;
194 }
195
196
197
198 /**
199 * Confirm that the a shader type is valid and supported by the implementation
200 *
201 * \param ctx Current GL context
202 * \param type Shader target
203 *
204 */
205 bool
206 _mesa_validate_shader_target(const struct gl_context *ctx, GLenum type)
207 {
208 /* Note: when building built-in GLSL functions, this function may be
209 * invoked with ctx == NULL. In that case, we can only validate that it's
210 * a shader target we recognize, not that it's supported in the current
211 * context. But that's fine--we don't need any further validation than
212 * that when building built-in GLSL functions.
213 */
214
215 switch (type) {
216 case GL_FRAGMENT_SHADER:
217 return ctx == NULL || ctx->Extensions.ARB_fragment_shader;
218 case GL_VERTEX_SHADER:
219 return ctx == NULL || ctx->Extensions.ARB_vertex_shader;
220 case GL_GEOMETRY_SHADER_ARB:
221 return ctx == NULL || _mesa_has_geometry_shaders(ctx);
222 case GL_TESS_CONTROL_SHADER:
223 case GL_TESS_EVALUATION_SHADER:
224 return ctx == NULL || _mesa_has_tessellation(ctx);
225 case GL_COMPUTE_SHADER:
226 return ctx == NULL || _mesa_has_compute_shaders(ctx);
227 default:
228 return false;
229 }
230 }
231
232
233 static GLboolean
234 is_program(struct gl_context *ctx, GLuint name)
235 {
236 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
237 return shProg ? GL_TRUE : GL_FALSE;
238 }
239
240
241 static GLboolean
242 is_shader(struct gl_context *ctx, GLuint name)
243 {
244 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
245 return shader ? GL_TRUE : GL_FALSE;
246 }
247
248
249 /**
250 * Attach shader to a shader program.
251 */
252 static void
253 attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
254 {
255 struct gl_shader_program *shProg;
256 struct gl_shader *sh;
257 GLuint i, n;
258
259 const bool same_type_disallowed = _mesa_is_gles(ctx);
260
261 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
262 if (!shProg)
263 return;
264
265 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
266 if (!sh) {
267 return;
268 }
269
270 n = shProg->NumShaders;
271 for (i = 0; i < n; i++) {
272 if (shProg->Shaders[i] == sh) {
273 /* The shader is already attched to this program. The
274 * GL_ARB_shader_objects spec says:
275 *
276 * "The error INVALID_OPERATION is generated by AttachObjectARB
277 * if <obj> is already attached to <containerObj>."
278 */
279 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
280 return;
281 } else if (same_type_disallowed &&
282 shProg->Shaders[i]->Stage == sh->Stage) {
283 /* Shader with the same type is already attached to this program,
284 * OpenGL ES 2.0 and 3.0 specs say:
285 *
286 * "Multiple shader objects of the same type may not be attached
287 * to a single program object. [...] The error INVALID_OPERATION
288 * is generated if [...] another shader object of the same type
289 * as shader is already attached to program."
290 */
291 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
292 return;
293 }
294 }
295
296 /* grow list */
297 shProg->Shaders = realloc(shProg->Shaders,
298 (n + 1) * sizeof(struct gl_shader *));
299 if (!shProg->Shaders) {
300 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
301 return;
302 }
303
304 /* append */
305 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
306 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
307 shProg->NumShaders++;
308 }
309
310
311 static GLuint
312 create_shader(struct gl_context *ctx, GLenum type)
313 {
314 struct gl_shader *sh;
315 GLuint name;
316
317 if (!_mesa_validate_shader_target(ctx, type)) {
318 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(%s)",
319 _mesa_enum_to_string(type));
320 return 0;
321 }
322
323 _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
324 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
325 sh = _mesa_new_shader(name, _mesa_shader_enum_to_shader_stage(type));
326 sh->Type = type;
327 _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh);
328 _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
329
330 return name;
331 }
332
333
334 static GLuint
335 create_shader_program(struct gl_context *ctx)
336 {
337 GLuint name;
338 struct gl_shader_program *shProg;
339
340 _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
341
342 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
343
344 shProg = _mesa_new_shader_program(name);
345
346 _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg);
347
348 assert(shProg->RefCount == 1);
349
350 _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
351
352 return name;
353 }
354
355
356 /**
357 * Delete a shader program. Actually, just decrement the program's
358 * reference count and mark it as DeletePending.
359 * Used to implement glDeleteProgram() and glDeleteObjectARB().
360 */
361 static void
362 delete_shader_program(struct gl_context *ctx, GLuint name)
363 {
364 /*
365 * NOTE: deleting shaders/programs works a bit differently than
366 * texture objects (and buffer objects, etc). Shader/program
367 * handles/IDs exist in the hash table until the object is really
368 * deleted (refcount==0). With texture objects, the handle/ID is
369 * removed from the hash table in glDeleteTextures() while the tex
370 * object itself might linger until its refcount goes to zero.
371 */
372 struct gl_shader_program *shProg;
373
374 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
375 if (!shProg)
376 return;
377
378 if (!shProg->DeletePending) {
379 shProg->DeletePending = GL_TRUE;
380
381 /* effectively, decr shProg's refcount */
382 _mesa_reference_shader_program(ctx, &shProg, NULL);
383 }
384 }
385
386
387 static void
388 delete_shader(struct gl_context *ctx, GLuint shader)
389 {
390 struct gl_shader *sh;
391
392 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
393 if (!sh)
394 return;
395
396 if (!sh->DeletePending) {
397 sh->DeletePending = GL_TRUE;
398
399 /* effectively, decr sh's refcount */
400 _mesa_reference_shader(ctx, &sh, NULL);
401 }
402 }
403
404
405 static void
406 detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
407 {
408 struct gl_shader_program *shProg;
409 GLuint n;
410 GLuint i, j;
411
412 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
413 if (!shProg)
414 return;
415
416 n = shProg->NumShaders;
417
418 for (i = 0; i < n; i++) {
419 if (shProg->Shaders[i]->Name == shader) {
420 /* found it */
421 struct gl_shader **newList;
422
423 /* release */
424 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
425
426 /* alloc new, smaller array */
427 newList = malloc((n - 1) * sizeof(struct gl_shader *));
428 if (!newList) {
429 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
430 return;
431 }
432 /* Copy old list entries to new list, skipping removed entry at [i] */
433 for (j = 0; j < i; j++) {
434 newList[j] = shProg->Shaders[j];
435 }
436 while (++i < n) {
437 newList[j++] = shProg->Shaders[i];
438 }
439
440 /* Free old list and install new one */
441 free(shProg->Shaders);
442 shProg->Shaders = newList;
443 shProg->NumShaders = n - 1;
444
445 #ifdef DEBUG
446 /* sanity check - make sure the new list's entries are sensible */
447 for (j = 0; j < shProg->NumShaders; j++) {
448 assert(shProg->Shaders[j]->Stage == MESA_SHADER_VERTEX ||
449 shProg->Shaders[j]->Stage == MESA_SHADER_TESS_CTRL ||
450 shProg->Shaders[j]->Stage == MESA_SHADER_TESS_EVAL ||
451 shProg->Shaders[j]->Stage == MESA_SHADER_GEOMETRY ||
452 shProg->Shaders[j]->Stage == MESA_SHADER_FRAGMENT);
453 assert(shProg->Shaders[j]->RefCount > 0);
454 }
455 #endif
456
457 return;
458 }
459 }
460
461 /* not found */
462 {
463 GLenum err;
464 if (is_shader(ctx, shader) || is_program(ctx, shader))
465 err = GL_INVALID_OPERATION;
466 else
467 err = GL_INVALID_VALUE;
468 _mesa_error(ctx, err, "glDetachShader(shader)");
469 return;
470 }
471 }
472
473
474 /**
475 * Return list of shaders attached to shader program.
476 */
477 static void
478 get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
479 GLsizei *count, GLuint *obj)
480 {
481 struct gl_shader_program *shProg;
482
483 if (maxCount < 0) {
484 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders(maxCount < 0)");
485 return;
486 }
487
488 shProg =
489 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
490
491 if (shProg) {
492 GLuint i;
493 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
494 obj[i] = shProg->Shaders[i]->Name;
495 }
496 if (count)
497 *count = i;
498 }
499 }
500
501
502 /**
503 * glGetHandleARB() - return ID/name of currently bound shader program.
504 */
505 static GLuint
506 get_handle(struct gl_context *ctx, GLenum pname)
507 {
508 if (pname == GL_PROGRAM_OBJECT_ARB) {
509 if (ctx->_Shader->ActiveProgram)
510 return ctx->_Shader->ActiveProgram->Name;
511 else
512 return 0;
513 }
514 else {
515 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
516 return 0;
517 }
518 }
519
520
521 /**
522 * Check if a geometry shader query is valid at this time. If not, report an
523 * error and return false.
524 *
525 * From GL 3.2 section 6.1.16 (Shader and Program Queries):
526 *
527 * "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE
528 * are queried for a program which has not been linked successfully, or
529 * which does not contain objects to form a geometry shader, then an
530 * INVALID_OPERATION error is generated."
531 */
532 static bool
533 check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
534 {
535 if (shProg->LinkStatus &&
536 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
537 return true;
538 }
539
540 _mesa_error(ctx, GL_INVALID_OPERATION,
541 "glGetProgramv(linked geometry shader required)");
542 return false;
543 }
544
545
546 /**
547 * Check if a tessellation control shader query is valid at this time.
548 * If not, report an error and return false.
549 *
550 * From GL 4.0 section 6.1.12 (Shader and Program Queries):
551 *
552 * "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has
553 * not been linked successfully, or which does not contain objects to
554 * form a tessellation control shader, then an INVALID_OPERATION error is
555 * generated."
556 */
557 static bool
558 check_tcs_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
559 {
560 if (shProg->LinkStatus &&
561 shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL] != NULL) {
562 return true;
563 }
564
565 _mesa_error(ctx, GL_INVALID_OPERATION,
566 "glGetProgramv(linked tessellation control shader required)");
567 return false;
568 }
569
570
571 /**
572 * Check if a tessellation evaluation shader query is valid at this time.
573 * If not, report an error and return false.
574 *
575 * From GL 4.0 section 6.1.12 (Shader and Program Queries):
576 *
577 * "If any of the pname values in this paragraph are queried for a program
578 * which has not been linked successfully, or which does not contain
579 * objects to form a tessellation evaluation shader, then an
580 * INVALID_OPERATION error is generated."
581 *
582 */
583 static bool
584 check_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg)
585 {
586 if (shProg->LinkStatus &&
587 shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL] != NULL) {
588 return true;
589 }
590
591 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramv(linked tessellation "
592 "evaluation shader required)");
593 return false;
594 }
595
596
597 /**
598 * glGetProgramiv() - get shader program state.
599 * Note that this is for GLSL shader programs, not ARB vertex/fragment
600 * programs (see glGetProgramivARB).
601 */
602 static void
603 get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
604 GLint *params)
605 {
606 struct gl_shader_program *shProg
607 = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramiv(program)");
608
609 /* Is transform feedback available in this context?
610 */
611 const bool has_xfb =
612 (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback)
613 || ctx->API == API_OPENGL_CORE
614 || _mesa_is_gles3(ctx);
615
616 /* True if geometry shaders (of the form that was adopted into GLSL 1.50
617 * and GL 3.2) are available in this context
618 */
619 const bool has_core_gs = _mesa_has_geometry_shaders(ctx);
620 const bool has_tess = _mesa_has_tessellation(ctx);
621
622 /* Are uniform buffer objects available in this context?
623 */
624 const bool has_ubo =
625 (ctx->API == API_OPENGL_COMPAT &&
626 ctx->Extensions.ARB_uniform_buffer_object)
627 || ctx->API == API_OPENGL_CORE
628 || _mesa_is_gles3(ctx);
629
630 if (!shProg) {
631 return;
632 }
633
634 switch (pname) {
635 case GL_DELETE_STATUS:
636 *params = shProg->DeletePending;
637 return;
638 case GL_LINK_STATUS:
639 *params = shProg->LinkStatus;
640 return;
641 case GL_VALIDATE_STATUS:
642 *params = shProg->Validated;
643 return;
644 case GL_INFO_LOG_LENGTH:
645 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
646 return;
647 case GL_ATTACHED_SHADERS:
648 *params = shProg->NumShaders;
649 return;
650 case GL_ACTIVE_ATTRIBUTES:
651 *params = _mesa_count_active_attribs(shProg);
652 return;
653 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
654 *params = _mesa_longest_attribute_name_length(shProg);
655 return;
656 case GL_ACTIVE_UNIFORMS: {
657 unsigned i;
658 const unsigned num_uniforms =
659 shProg->NumUniformStorage - shProg->NumHiddenUniforms;
660 for (*params = 0, i = 0; i < num_uniforms; i++) {
661 if (!shProg->UniformStorage[i].is_shader_storage)
662 (*params)++;
663 }
664 return;
665 }
666 case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
667 unsigned i;
668 GLint max_len = 0;
669 const unsigned num_uniforms =
670 shProg->NumUniformStorage - shProg->NumHiddenUniforms;
671
672 for (i = 0; i < num_uniforms; i++) {
673 if (shProg->UniformStorage[i].is_shader_storage)
674 continue;
675
676 /* Add one for the terminating NUL character for a non-array, and
677 * 4 for the "[0]" and the NUL for an array.
678 */
679 const GLint len = strlen(shProg->UniformStorage[i].name) + 1 +
680 ((shProg->UniformStorage[i].array_elements != 0) ? 3 : 0);
681
682 if (len > max_len)
683 max_len = len;
684 }
685
686 *params = max_len;
687 return;
688 }
689 case GL_TRANSFORM_FEEDBACK_VARYINGS:
690 if (!has_xfb)
691 break;
692 *params = shProg->TransformFeedback.NumVarying;
693 return;
694 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: {
695 unsigned i;
696 GLint max_len = 0;
697 if (!has_xfb)
698 break;
699
700 for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
701 /* Add one for the terminating NUL character.
702 */
703 const GLint len =
704 strlen(shProg->TransformFeedback.VaryingNames[i]) + 1;
705
706 if (len > max_len)
707 max_len = len;
708 }
709
710 *params = max_len;
711 return;
712 }
713 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
714 if (!has_xfb)
715 break;
716 *params = shProg->TransformFeedback.BufferMode;
717 return;
718 case GL_GEOMETRY_VERTICES_OUT:
719 if (!has_core_gs)
720 break;
721 if (check_gs_query(ctx, shProg)) {
722 *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
723 info.Geom.VerticesOut;
724 }
725 return;
726 case GL_GEOMETRY_SHADER_INVOCATIONS:
727 if (!has_core_gs || !ctx->Extensions.ARB_gpu_shader5)
728 break;
729 if (check_gs_query(ctx, shProg)) {
730 *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
731 info.Geom.Invocations;
732 }
733 return;
734 case GL_GEOMETRY_INPUT_TYPE:
735 if (!has_core_gs)
736 break;
737 if (check_gs_query(ctx, shProg)) {
738 *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
739 info.Geom.InputType;
740 }
741 return;
742 case GL_GEOMETRY_OUTPUT_TYPE:
743 if (!has_core_gs)
744 break;
745 if (check_gs_query(ctx, shProg)) {
746 *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
747 info.Geom.OutputType;
748 }
749 return;
750 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
751 unsigned i;
752 GLint max_len = 0;
753
754 if (!has_ubo)
755 break;
756
757 for (i = 0; i < shProg->NumUniformBlocks; i++) {
758 /* Add one for the terminating NUL character.
759 */
760 const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;
761
762 if (len > max_len)
763 max_len = len;
764 }
765
766 *params = max_len;
767 return;
768 }
769 case GL_ACTIVE_UNIFORM_BLOCKS:
770 if (!has_ubo)
771 break;
772
773 *params = shProg->NumUniformBlocks;
774 return;
775 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
776 /* This enum isn't part of the OES extension for OpenGL ES 2.0. It is
777 * only available with desktop OpenGL 3.0+ with the
778 * GL_ARB_get_program_binary extension or OpenGL ES 3.0.
779 *
780 * On desktop, we ignore the 3.0+ requirement because it is silly.
781 */
782 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
783 break;
784
785 *params = shProg->BinaryRetreivableHint;
786 return;
787 case GL_PROGRAM_BINARY_LENGTH:
788 *params = 0;
789 return;
790 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
791 if (!ctx->Extensions.ARB_shader_atomic_counters)
792 break;
793
794 *params = shProg->NumAtomicBuffers;
795 return;
796 case GL_COMPUTE_WORK_GROUP_SIZE: {
797 int i;
798 if (!_mesa_has_compute_shaders(ctx))
799 break;
800 if (!shProg->LinkStatus) {
801 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(program not "
802 "linked)");
803 return;
804 }
805 if (shProg->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) {
806 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramiv(no compute "
807 "shaders)");
808 return;
809 }
810 for (i = 0; i < 3; i++)
811 params[i] = shProg->Comp.LocalSize[i];
812 return;
813 }
814 case GL_PROGRAM_SEPARABLE:
815 /* If the program has not been linked, return initial value 0. */
816 *params = (shProg->LinkStatus == GL_FALSE) ? 0 : shProg->SeparateShader;
817 return;
818
819 /* ARB_tessellation_shader */
820 case GL_TESS_CONTROL_OUTPUT_VERTICES:
821 if (!has_tess)
822 break;
823 if (check_tcs_query(ctx, shProg)) {
824 *params = shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->
825 info.TessCtrl.VerticesOut;
826 }
827 return;
828 case GL_TESS_GEN_MODE:
829 if (!has_tess)
830 break;
831 if (check_tes_query(ctx, shProg)) {
832 *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
833 info.TessEval.PrimitiveMode;
834 }
835 return;
836 case GL_TESS_GEN_SPACING:
837 if (!has_tess)
838 break;
839 if (check_tes_query(ctx, shProg)) {
840 *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
841 info.TessEval.Spacing;
842 }
843 return;
844 case GL_TESS_GEN_VERTEX_ORDER:
845 if (!has_tess)
846 break;
847 if (check_tes_query(ctx, shProg)) {
848 *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
849 info.TessEval.VertexOrder;
850 }
851 return;
852 case GL_TESS_GEN_POINT_MODE:
853 if (!has_tess)
854 break;
855 if (check_tes_query(ctx, shProg)) {
856 *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
857 info.TessEval.PointMode;
858 }
859 return;
860 default:
861 break;
862 }
863
864 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
865 _mesa_enum_to_string(pname));
866 }
867
868
869 /**
870 * glGetShaderiv() - get GLSL shader state
871 */
872 static void
873 get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
874 {
875 struct gl_shader *shader =
876 _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
877
878 if (!shader) {
879 return;
880 }
881
882 switch (pname) {
883 case GL_SHADER_TYPE:
884 *params = shader->Type;
885 break;
886 case GL_DELETE_STATUS:
887 *params = shader->DeletePending;
888 break;
889 case GL_COMPILE_STATUS:
890 *params = shader->CompileStatus;
891 break;
892 case GL_INFO_LOG_LENGTH:
893 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
894 break;
895 case GL_SHADER_SOURCE_LENGTH:
896 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
897 break;
898 default:
899 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
900 return;
901 }
902 }
903
904
905 static void
906 get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
907 GLsizei *length, GLchar *infoLog)
908 {
909 struct gl_shader_program *shProg;
910
911 /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
912 * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
913 *
914 * "If a negative number is provided where an argument of type sizei or
915 * sizeiptr is specified, an INVALID_VALUE error is generated."
916 */
917 if (bufSize < 0) {
918 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(bufSize < 0)");
919 return;
920 }
921
922 shProg = _mesa_lookup_shader_program_err(ctx, program,
923 "glGetProgramInfoLog(program)");
924 if (!shProg) {
925 return;
926 }
927
928 _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
929 }
930
931
932 static void
933 get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
934 GLsizei *length, GLchar *infoLog)
935 {
936 struct gl_shader *sh;
937
938 /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
939 * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
940 *
941 * "If a negative number is provided where an argument of type sizei or
942 * sizeiptr is specified, an INVALID_VALUE error is generated."
943 */
944 if (bufSize < 0) {
945 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(bufSize < 0)");
946 return;
947 }
948
949 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderInfoLog(shader)");
950 if (!sh) {
951 return;
952 }
953
954 _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
955 }
956
957
958 /**
959 * Return shader source code.
960 */
961 static void
962 get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
963 GLsizei *length, GLchar *sourceOut)
964 {
965 struct gl_shader *sh;
966
967 if (maxLength < 0) {
968 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(bufSize < 0)");
969 return;
970 }
971
972 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
973 if (!sh) {
974 return;
975 }
976 _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
977 }
978
979
980 /**
981 * Set/replace shader source code. A helper function used by
982 * glShaderSource[ARB].
983 */
984 static void
985 shader_source(struct gl_shader *sh, const GLchar *source)
986 {
987 assert(sh);
988
989 /* free old shader source string and install new one */
990 free((void *)sh->Source);
991 sh->Source = source;
992 #ifdef DEBUG
993 sh->SourceChecksum = _mesa_str_checksum(sh->Source);
994 #endif
995 }
996
997
998 /**
999 * Compile a shader.
1000 */
1001 void
1002 _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh)
1003 {
1004 if (!sh)
1005 return;
1006
1007 if (!sh->Source) {
1008 /* If the user called glCompileShader without first calling
1009 * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
1010 */
1011 sh->CompileStatus = GL_FALSE;
1012 } else {
1013 if (ctx->_Shader->Flags & GLSL_DUMP) {
1014 _mesa_log("GLSL source for %s shader %d:\n",
1015 _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1016 _mesa_log("%s\n", sh->Source);
1017 }
1018
1019 /* this call will set the shader->CompileStatus field to indicate if
1020 * compilation was successful.
1021 */
1022 _mesa_glsl_compile_shader(ctx, sh, false, false);
1023
1024 if (ctx->_Shader->Flags & GLSL_LOG) {
1025 _mesa_write_shader_to_file(sh);
1026 }
1027
1028 if (ctx->_Shader->Flags & GLSL_DUMP) {
1029 if (sh->CompileStatus) {
1030 if (sh->ir) {
1031 _mesa_log("GLSL IR for shader %d:\n", sh->Name);
1032 _mesa_print_ir(_mesa_get_log_file(), sh->ir, NULL);
1033 } else {
1034 _mesa_log("No GLSL IR for shader %d (shader may be from "
1035 "cache)\n", sh->Name);
1036 }
1037 _mesa_log("\n\n");
1038 } else {
1039 _mesa_log("GLSL shader %d failed to compile.\n", sh->Name);
1040 }
1041 if (sh->InfoLog && sh->InfoLog[0] != 0) {
1042 _mesa_log("GLSL shader %d info log:\n", sh->Name);
1043 _mesa_log("%s\n", sh->InfoLog);
1044 }
1045 }
1046 }
1047
1048 if (!sh->CompileStatus) {
1049 if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) {
1050 _mesa_log("GLSL source for %s shader %d:\n",
1051 _mesa_shader_stage_to_string(sh->Stage), sh->Name);
1052 _mesa_log("%s\n", sh->Source);
1053 _mesa_log("Info Log:\n%s\n", sh->InfoLog);
1054 }
1055
1056 if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) {
1057 _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
1058 sh->Name, sh->InfoLog);
1059 }
1060 }
1061 }
1062
1063
1064 /**
1065 * Link a program's shaders.
1066 */
1067 void
1068 _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
1069 {
1070 if (!shProg)
1071 return;
1072
1073 /* From the ARB_transform_feedback2 specification:
1074 * "The error INVALID_OPERATION is generated by LinkProgram if <program> is
1075 * the name of a program being used by one or more transform feedback
1076 * objects, even if the objects are not currently bound or are paused."
1077 */
1078 if (_mesa_transform_feedback_is_using_program(ctx, shProg)) {
1079 _mesa_error(ctx, GL_INVALID_OPERATION,
1080 "glLinkProgram(transform feedback is using the program)");
1081 return;
1082 }
1083
1084 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1085
1086 _mesa_glsl_link_shader(ctx, shProg);
1087
1088 /* Capture .shader_test files. */
1089 const char *capture_path = _mesa_get_shader_capture_path();
1090 if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
1091 FILE *file;
1092 char *filename = ralloc_asprintf(NULL, "%s/%u.shader_test",
1093 capture_path, shProg->Name);
1094 file = fopen(filename, "w");
1095 if (file) {
1096 fprintf(file, "[require]\nGLSL%s >= %u.%02u\n",
1097 shProg->IsES ? " ES" : "",
1098 shProg->Version / 100, shProg->Version % 100);
1099 if (shProg->SeparateShader)
1100 fprintf(file, "GL_ARB_separate_shader_objects\nSSO ENABLED\n");
1101 fprintf(file, "\n");
1102
1103 for (unsigned i = 0; i < shProg->NumShaders; i++) {
1104 fprintf(file, "[%s shader]\n%s\n",
1105 _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
1106 shProg->Shaders[i]->Source);
1107 }
1108 fclose(file);
1109 } else {
1110 _mesa_warning(ctx, "Failed to open %s", filename);
1111 }
1112
1113 ralloc_free(filename);
1114 }
1115
1116 if (shProg->LinkStatus == GL_FALSE &&
1117 (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
1118 _mesa_debug(ctx, "Error linking program %u:\n%s\n",
1119 shProg->Name, shProg->InfoLog);
1120 }
1121
1122 /* debug code */
1123 if (0) {
1124 GLuint i;
1125
1126 printf("Link %u shaders in program %u: %s\n",
1127 shProg->NumShaders, shProg->Name,
1128 shProg->LinkStatus ? "Success" : "Failed");
1129
1130 for (i = 0; i < shProg->NumShaders; i++) {
1131 printf(" shader %u, stage %u\n",
1132 shProg->Shaders[i]->Name,
1133 shProg->Shaders[i]->Stage);
1134 }
1135 }
1136 }
1137
1138
1139 /**
1140 * Print basic shader info (for debug).
1141 */
1142 static void
1143 print_shader_info(const struct gl_shader_program *shProg)
1144 {
1145 GLuint i;
1146
1147 printf("Mesa: glUseProgram(%u)\n", shProg->Name);
1148 for (i = 0; i < shProg->NumShaders; i++) {
1149 printf(" %s shader %u, checksum %u\n",
1150 _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage),
1151 shProg->Shaders[i]->Name,
1152 shProg->Shaders[i]->SourceChecksum);
1153 }
1154 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
1155 printf(" vert prog %u\n",
1156 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
1157 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
1158 printf(" frag prog %u\n",
1159 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
1160 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
1161 printf(" geom prog %u\n",
1162 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
1163 if (shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL])
1164 printf(" tesc prog %u\n",
1165 shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program->Id);
1166 if (shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL])
1167 printf(" tese prog %u\n",
1168 shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program->Id);
1169 }
1170
1171
1172 /**
1173 * Use the named shader program for subsequent glUniform calls
1174 */
1175 void
1176 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
1177 const char *caller)
1178 {
1179 if ((shProg != NULL) && !shProg->LinkStatus) {
1180 _mesa_error(ctx, GL_INVALID_OPERATION,
1181 "%s(program %u not linked)", caller, shProg->Name);
1182 return;
1183 }
1184
1185 if (ctx->Shader.ActiveProgram != shProg) {
1186 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
1187 }
1188 }
1189
1190
1191 static void
1192 use_shader_program(struct gl_context *ctx, gl_shader_stage stage,
1193 struct gl_shader_program *shProg,
1194 struct gl_pipeline_object *shTarget)
1195 {
1196 struct gl_shader_program **target;
1197
1198 target = &shTarget->CurrentProgram[stage];
1199 if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL))
1200 shProg = NULL;
1201
1202 if (shProg)
1203 _mesa_shader_program_init_subroutine_defaults(ctx, shProg);
1204
1205 if (*target != shProg) {
1206 /* Program is current, flush it */
1207 if (shTarget == ctx->_Shader) {
1208 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
1209 }
1210
1211 /* If the shader is also bound as the current rendering shader, unbind
1212 * it from that binding point as well. This ensures that the correct
1213 * semantics of glDeleteProgram are maintained.
1214 */
1215 switch (stage) {
1216 case MESA_SHADER_VERTEX:
1217 case MESA_SHADER_TESS_CTRL:
1218 case MESA_SHADER_TESS_EVAL:
1219 case MESA_SHADER_GEOMETRY:
1220 case MESA_SHADER_COMPUTE:
1221 /* Empty for now. */
1222 break;
1223 case MESA_SHADER_FRAGMENT:
1224 if (*target == ctx->_Shader->_CurrentFragmentProgram) {
1225 _mesa_reference_shader_program(ctx,
1226 &ctx->_Shader->_CurrentFragmentProgram,
1227 NULL);
1228 }
1229 break;
1230 }
1231
1232 _mesa_reference_shader_program(ctx, target, shProg);
1233 return;
1234 }
1235 }
1236
1237
1238 /**
1239 * Use the named shader program for subsequent rendering.
1240 */
1241 void
1242 _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
1243 {
1244 int i;
1245 for (i = 0; i < MESA_SHADER_STAGES; i++)
1246 use_shader_program(ctx, i, shProg, &ctx->Shader);
1247 _mesa_active_program(ctx, shProg, "glUseProgram");
1248 }
1249
1250
1251 /**
1252 * Do validation of the given shader program.
1253 * \param errMsg returns error message if validation fails.
1254 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
1255 */
1256 static GLboolean
1257 validate_shader_program(const struct gl_shader_program *shProg,
1258 char *errMsg)
1259 {
1260 if (!shProg->LinkStatus) {
1261 return GL_FALSE;
1262 }
1263
1264 /* From the GL spec, a program is invalid if any of these are true:
1265
1266 any two active samplers in the current program object are of
1267 different types, but refer to the same texture image unit,
1268
1269 any active sampler in the current program object refers to a texture
1270 image unit where fixed-function fragment processing accesses a
1271 texture target that does not match the sampler type, or
1272
1273 the sum of the number of active samplers in the program and the
1274 number of texture image units enabled for fixed-function fragment
1275 processing exceeds the combined limit on the total number of texture
1276 image units allowed.
1277 */
1278
1279 /*
1280 * Check: any two active samplers in the current program object are of
1281 * different types, but refer to the same texture image unit,
1282 */
1283 if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
1284 return GL_FALSE;
1285
1286 return GL_TRUE;
1287 }
1288
1289
1290 /**
1291 * Called via glValidateProgram()
1292 */
1293 static void
1294 validate_program(struct gl_context *ctx, GLuint program)
1295 {
1296 struct gl_shader_program *shProg;
1297 char errMsg[100] = "";
1298
1299 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1300 if (!shProg) {
1301 return;
1302 }
1303
1304 shProg->Validated = validate_shader_program(shProg, errMsg);
1305 if (!shProg->Validated) {
1306 /* update info log */
1307 if (shProg->InfoLog) {
1308 ralloc_free(shProg->InfoLog);
1309 }
1310 shProg->InfoLog = ralloc_strdup(shProg, errMsg);
1311 }
1312 }
1313
1314
1315
1316 void GLAPIENTRY
1317 _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1318 {
1319 GET_CURRENT_CONTEXT(ctx);
1320 attach_shader(ctx, program, shader);
1321 }
1322
1323
1324 void GLAPIENTRY
1325 _mesa_AttachShader(GLuint program, GLuint shader)
1326 {
1327 GET_CURRENT_CONTEXT(ctx);
1328 attach_shader(ctx, program, shader);
1329 }
1330
1331
1332 void GLAPIENTRY
1333 _mesa_CompileShader(GLuint shaderObj)
1334 {
1335 GET_CURRENT_CONTEXT(ctx);
1336 if (MESA_VERBOSE & VERBOSE_API)
1337 _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
1338 _mesa_compile_shader(ctx, _mesa_lookup_shader_err(ctx, shaderObj,
1339 "glCompileShader"));
1340 }
1341
1342
1343 GLuint GLAPIENTRY
1344 _mesa_CreateShader(GLenum type)
1345 {
1346 GET_CURRENT_CONTEXT(ctx);
1347 if (MESA_VERBOSE & VERBOSE_API)
1348 _mesa_debug(ctx, "glCreateShader %s\n", _mesa_enum_to_string(type));
1349 return create_shader(ctx, type);
1350 }
1351
1352
1353 GLhandleARB GLAPIENTRY
1354 _mesa_CreateShaderObjectARB(GLenum type)
1355 {
1356 GET_CURRENT_CONTEXT(ctx);
1357 return create_shader(ctx, type);
1358 }
1359
1360
1361 GLuint GLAPIENTRY
1362 _mesa_CreateProgram(void)
1363 {
1364 GET_CURRENT_CONTEXT(ctx);
1365 if (MESA_VERBOSE & VERBOSE_API)
1366 _mesa_debug(ctx, "glCreateProgram\n");
1367 return create_shader_program(ctx);
1368 }
1369
1370
1371 GLhandleARB GLAPIENTRY
1372 _mesa_CreateProgramObjectARB(void)
1373 {
1374 GET_CURRENT_CONTEXT(ctx);
1375 return create_shader_program(ctx);
1376 }
1377
1378
1379 void GLAPIENTRY
1380 _mesa_DeleteObjectARB(GLhandleARB obj)
1381 {
1382 if (MESA_VERBOSE & VERBOSE_API) {
1383 GET_CURRENT_CONTEXT(ctx);
1384 _mesa_debug(ctx, "glDeleteObjectARB(%lu)\n", (unsigned long)obj);
1385 }
1386
1387 if (obj) {
1388 GET_CURRENT_CONTEXT(ctx);
1389 FLUSH_VERTICES(ctx, 0);
1390 if (is_program(ctx, obj)) {
1391 delete_shader_program(ctx, obj);
1392 }
1393 else if (is_shader(ctx, obj)) {
1394 delete_shader(ctx, obj);
1395 }
1396 else {
1397 /* error? */
1398 }
1399 }
1400 }
1401
1402
1403 void GLAPIENTRY
1404 _mesa_DeleteProgram(GLuint name)
1405 {
1406 if (name) {
1407 GET_CURRENT_CONTEXT(ctx);
1408 FLUSH_VERTICES(ctx, 0);
1409 delete_shader_program(ctx, name);
1410 }
1411 }
1412
1413
1414 void GLAPIENTRY
1415 _mesa_DeleteShader(GLuint name)
1416 {
1417 if (name) {
1418 GET_CURRENT_CONTEXT(ctx);
1419 FLUSH_VERTICES(ctx, 0);
1420 delete_shader(ctx, name);
1421 }
1422 }
1423
1424
1425 void GLAPIENTRY
1426 _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1427 {
1428 GET_CURRENT_CONTEXT(ctx);
1429 detach_shader(ctx, program, shader);
1430 }
1431
1432
1433 void GLAPIENTRY
1434 _mesa_DetachShader(GLuint program, GLuint shader)
1435 {
1436 GET_CURRENT_CONTEXT(ctx);
1437 detach_shader(ctx, program, shader);
1438 }
1439
1440
1441 void GLAPIENTRY
1442 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1443 GLsizei * count, GLhandleARB * obj)
1444 {
1445 GET_CURRENT_CONTEXT(ctx);
1446 get_attached_shaders(ctx, container, maxCount, count, obj);
1447 }
1448
1449
1450 void GLAPIENTRY
1451 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1452 GLsizei *count, GLuint *obj)
1453 {
1454 GET_CURRENT_CONTEXT(ctx);
1455 get_attached_shaders(ctx, program, maxCount, count, obj);
1456 }
1457
1458
1459 void GLAPIENTRY
1460 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1461 GLcharARB * infoLog)
1462 {
1463 GET_CURRENT_CONTEXT(ctx);
1464 if (is_program(ctx, object)) {
1465 get_program_info_log(ctx, object, maxLength, length, infoLog);
1466 }
1467 else if (is_shader(ctx, object)) {
1468 get_shader_info_log(ctx, object, maxLength, length, infoLog);
1469 }
1470 else {
1471 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1472 }
1473 }
1474
1475
1476 void GLAPIENTRY
1477 _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1478 {
1479 GET_CURRENT_CONTEXT(ctx);
1480 /* Implement in terms of GetProgramiv, GetShaderiv */
1481 if (is_program(ctx, object)) {
1482 if (pname == GL_OBJECT_TYPE_ARB) {
1483 *params = GL_PROGRAM_OBJECT_ARB;
1484 }
1485 else {
1486 get_programiv(ctx, object, pname, params);
1487 }
1488 }
1489 else if (is_shader(ctx, object)) {
1490 if (pname == GL_OBJECT_TYPE_ARB) {
1491 *params = GL_SHADER_OBJECT_ARB;
1492 }
1493 else {
1494 get_shaderiv(ctx, object, pname, params);
1495 }
1496 }
1497 else {
1498 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1499 }
1500 }
1501
1502
1503 void GLAPIENTRY
1504 _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1505 GLfloat *params)
1506 {
1507 GLint iparams[1] = {0}; /* XXX is one element enough? */
1508 _mesa_GetObjectParameterivARB(object, pname, iparams);
1509 params[0] = (GLfloat) iparams[0];
1510 }
1511
1512
1513 void GLAPIENTRY
1514 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1515 {
1516 GET_CURRENT_CONTEXT(ctx);
1517 get_programiv(ctx, program, pname, params);
1518 }
1519
1520
1521 void GLAPIENTRY
1522 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1523 {
1524 GET_CURRENT_CONTEXT(ctx);
1525 get_shaderiv(ctx, shader, pname, params);
1526 }
1527
1528
1529 void GLAPIENTRY
1530 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1531 GLsizei *length, GLchar *infoLog)
1532 {
1533 GET_CURRENT_CONTEXT(ctx);
1534 get_program_info_log(ctx, program, bufSize, length, infoLog);
1535 }
1536
1537
1538 void GLAPIENTRY
1539 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1540 GLsizei *length, GLchar *infoLog)
1541 {
1542 GET_CURRENT_CONTEXT(ctx);
1543 get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1544 }
1545
1546
1547 void GLAPIENTRY
1548 _mesa_GetShaderSource(GLuint shader, GLsizei maxLength,
1549 GLsizei *length, GLchar *sourceOut)
1550 {
1551 GET_CURRENT_CONTEXT(ctx);
1552 get_shader_source(ctx, shader, maxLength, length, sourceOut);
1553 }
1554
1555
1556 GLhandleARB GLAPIENTRY
1557 _mesa_GetHandleARB(GLenum pname)
1558 {
1559 GET_CURRENT_CONTEXT(ctx);
1560 return get_handle(ctx, pname);
1561 }
1562
1563
1564 GLboolean GLAPIENTRY
1565 _mesa_IsProgram(GLuint name)
1566 {
1567 GET_CURRENT_CONTEXT(ctx);
1568 return is_program(ctx, name);
1569 }
1570
1571
1572 GLboolean GLAPIENTRY
1573 _mesa_IsShader(GLuint name)
1574 {
1575 GET_CURRENT_CONTEXT(ctx);
1576 return is_shader(ctx, name);
1577 }
1578
1579
1580 void GLAPIENTRY
1581 _mesa_LinkProgram(GLuint programObj)
1582 {
1583 GET_CURRENT_CONTEXT(ctx);
1584 if (MESA_VERBOSE & VERBOSE_API)
1585 _mesa_debug(ctx, "glLinkProgram %u\n", programObj);
1586 _mesa_link_program(ctx, _mesa_lookup_shader_program_err(ctx, programObj,
1587 "glLinkProgram"));
1588 }
1589
1590 #if defined(HAVE_SHA1)
1591 /**
1592 * Generate a SHA-1 hash value string for given source string.
1593 */
1594 static void
1595 generate_sha1(const char *source, char sha_str[64])
1596 {
1597 unsigned char sha[20];
1598 _mesa_sha1_compute(source, strlen(source), sha);
1599 _mesa_sha1_format(sha_str, sha);
1600 }
1601
1602 /**
1603 * Construct a full path for shader replacement functionality using
1604 * following format:
1605 *
1606 * <path>/<stage prefix>_<CHECKSUM>.glsl
1607 */
1608 static char *
1609 construct_name(const gl_shader_stage stage, const char *source,
1610 const char *path)
1611 {
1612 char sha[64];
1613 static const char *types[] = {
1614 "VS", "TC", "TE", "GS", "FS", "CS",
1615 };
1616
1617 generate_sha1(source, sha);
1618 return ralloc_asprintf(NULL, "%s/%s_%s.glsl", path, types[stage], sha);
1619 }
1620
1621 /**
1622 * Write given shader source to a file in MESA_SHADER_DUMP_PATH.
1623 */
1624 static void
1625 dump_shader(const gl_shader_stage stage, const char *source)
1626 {
1627 static bool path_exists = true;
1628 char *dump_path;
1629 FILE *f;
1630
1631 if (!path_exists)
1632 return;
1633
1634 dump_path = getenv("MESA_SHADER_DUMP_PATH");
1635 if (!dump_path) {
1636 path_exists = false;
1637 return;
1638 }
1639
1640 char *name = construct_name(stage, source, dump_path);
1641
1642 f = fopen(name, "w");
1643 if (f) {
1644 fputs(source, f);
1645 fclose(f);
1646 } else {
1647 GET_CURRENT_CONTEXT(ctx);
1648 _mesa_warning(ctx, "could not open %s for dumping shader (%s)", name,
1649 strerror(errno));
1650 }
1651 ralloc_free(name);
1652 }
1653
1654 /**
1655 * Read shader source code from a file.
1656 * Useful for debugging to override an app's shader.
1657 */
1658 static GLcharARB *
1659 read_shader(const gl_shader_stage stage, const char *source)
1660 {
1661 char *read_path;
1662 static bool path_exists = true;
1663 int len, shader_size = 0;
1664 GLcharARB *buffer;
1665 FILE *f;
1666
1667 if (!path_exists)
1668 return NULL;
1669
1670 read_path = getenv("MESA_SHADER_READ_PATH");
1671 if (!read_path) {
1672 path_exists = false;
1673 return NULL;
1674 }
1675
1676 char *name = construct_name(stage, source, read_path);
1677 f = fopen(name, "r");
1678 ralloc_free(name);
1679 if (!f)
1680 return NULL;
1681
1682 /* allocate enough room for the entire shader */
1683 fseek(f, 0, SEEK_END);
1684 shader_size = ftell(f);
1685 rewind(f);
1686 assert(shader_size);
1687
1688 /* add one for terminating zero */
1689 shader_size++;
1690
1691 buffer = malloc(shader_size);
1692 assert(buffer);
1693
1694 len = fread(buffer, 1, shader_size, f);
1695 buffer[len] = 0;
1696
1697 fclose(f);
1698
1699 return buffer;
1700 }
1701 #endif /* HAVE_SHA1 */
1702
1703 /**
1704 * Called via glShaderSource() and glShaderSourceARB() API functions.
1705 * Basically, concatenate the source code strings into one long string
1706 * and pass it to _mesa_shader_source().
1707 */
1708 void GLAPIENTRY
1709 _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
1710 const GLchar * const * string, const GLint * length)
1711 {
1712 GET_CURRENT_CONTEXT(ctx);
1713 GLint *offsets;
1714 GLsizei i, totalLength;
1715 GLcharARB *source;
1716 struct gl_shader *sh;
1717
1718 #if defined(HAVE_SHA1)
1719 GLcharARB *replacement;
1720 #endif /* HAVE_SHA1 */
1721
1722 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glShaderSourceARB");
1723 if (!sh)
1724 return;
1725
1726 if (string == NULL) {
1727 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
1728 return;
1729 }
1730
1731 /*
1732 * This array holds offsets of where the appropriate string ends, thus the
1733 * last element will be set to the total length of the source code.
1734 */
1735 offsets = malloc(count * sizeof(GLint));
1736 if (offsets == NULL) {
1737 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1738 return;
1739 }
1740
1741 for (i = 0; i < count; i++) {
1742 if (string[i] == NULL) {
1743 free((GLvoid *) offsets);
1744 _mesa_error(ctx, GL_INVALID_OPERATION,
1745 "glShaderSourceARB(null string)");
1746 return;
1747 }
1748 if (length == NULL || length[i] < 0)
1749 offsets[i] = strlen(string[i]);
1750 else
1751 offsets[i] = length[i];
1752 /* accumulate string lengths */
1753 if (i > 0)
1754 offsets[i] += offsets[i - 1];
1755 }
1756
1757 /* Total length of source string is sum off all strings plus two.
1758 * One extra byte for terminating zero, another extra byte to silence
1759 * valgrind warnings in the parser/grammer code.
1760 */
1761 totalLength = offsets[count - 1] + 2;
1762 source = malloc(totalLength * sizeof(GLcharARB));
1763 if (source == NULL) {
1764 free((GLvoid *) offsets);
1765 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1766 return;
1767 }
1768
1769 for (i = 0; i < count; i++) {
1770 GLint start = (i > 0) ? offsets[i - 1] : 0;
1771 memcpy(source + start, string[i],
1772 (offsets[i] - start) * sizeof(GLcharARB));
1773 }
1774 source[totalLength - 1] = '\0';
1775 source[totalLength - 2] = '\0';
1776
1777 #if defined(HAVE_SHA1)
1778 /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
1779 * if corresponding entry found from MESA_SHADER_READ_PATH.
1780 */
1781 dump_shader(sh->Stage, source);
1782
1783 replacement = read_shader(sh->Stage, source);
1784 if (replacement) {
1785 free(source);
1786 source = replacement;
1787 }
1788 #endif /* HAVE_SHA1 */
1789
1790 shader_source(sh, source);
1791
1792 free(offsets);
1793 }
1794
1795
1796 void GLAPIENTRY
1797 _mesa_UseProgram(GLuint program)
1798 {
1799 GET_CURRENT_CONTEXT(ctx);
1800 struct gl_shader_program *shProg;
1801
1802 if (MESA_VERBOSE & VERBOSE_API)
1803 _mesa_debug(ctx, "glUseProgram %u\n", program);
1804
1805 if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1806 _mesa_error(ctx, GL_INVALID_OPERATION,
1807 "glUseProgram(transform feedback active)");
1808 return;
1809 }
1810
1811 if (program) {
1812 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1813 if (!shProg) {
1814 return;
1815 }
1816 if (!shProg->LinkStatus) {
1817 _mesa_error(ctx, GL_INVALID_OPERATION,
1818 "glUseProgram(program %u not linked)", program);
1819 return;
1820 }
1821
1822 /* debug code */
1823 if (ctx->_Shader->Flags & GLSL_USE_PROG) {
1824 print_shader_info(shProg);
1825 }
1826 }
1827 else {
1828 shProg = NULL;
1829 }
1830
1831 /* The ARB_separate_shader_object spec says:
1832 *
1833 * "The executable code for an individual shader stage is taken from
1834 * the current program for that stage. If there is a current program
1835 * object established by UseProgram, that program is considered current
1836 * for all stages. Otherwise, if there is a bound program pipeline
1837 * object (section 2.14.PPO), the program bound to the appropriate
1838 * stage of the pipeline object is considered current."
1839 */
1840 if (program) {
1841 /* Attach shader state to the binding point */
1842 _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
1843 /* Update the program */
1844 _mesa_use_program(ctx, shProg);
1845 } else {
1846 /* Must be done first: detach the progam */
1847 _mesa_use_program(ctx, shProg);
1848 /* Unattach shader_state binding point */
1849 _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
1850 /* If a pipeline was bound, rebind it */
1851 if (ctx->Pipeline.Current) {
1852 _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
1853 }
1854 }
1855 }
1856
1857
1858 void GLAPIENTRY
1859 _mesa_ValidateProgram(GLuint program)
1860 {
1861 GET_CURRENT_CONTEXT(ctx);
1862 validate_program(ctx, program);
1863 }
1864
1865
1866 /**
1867 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1868 */
1869 void GLAPIENTRY
1870 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1871 GLint* range, GLint* precision)
1872 {
1873 const struct gl_program_constants *limits;
1874 const struct gl_precision *p;
1875 GET_CURRENT_CONTEXT(ctx);
1876
1877 switch (shadertype) {
1878 case GL_VERTEX_SHADER:
1879 limits = &ctx->Const.Program[MESA_SHADER_VERTEX];
1880 break;
1881 case GL_FRAGMENT_SHADER:
1882 limits = &ctx->Const.Program[MESA_SHADER_FRAGMENT];
1883 break;
1884 default:
1885 _mesa_error(ctx, GL_INVALID_ENUM,
1886 "glGetShaderPrecisionFormat(shadertype)");
1887 return;
1888 }
1889
1890 switch (precisiontype) {
1891 case GL_LOW_FLOAT:
1892 p = &limits->LowFloat;
1893 break;
1894 case GL_MEDIUM_FLOAT:
1895 p = &limits->MediumFloat;
1896 break;
1897 case GL_HIGH_FLOAT:
1898 p = &limits->HighFloat;
1899 break;
1900 case GL_LOW_INT:
1901 p = &limits->LowInt;
1902 break;
1903 case GL_MEDIUM_INT:
1904 p = &limits->MediumInt;
1905 break;
1906 case GL_HIGH_INT:
1907 p = &limits->HighInt;
1908 break;
1909 default:
1910 _mesa_error(ctx, GL_INVALID_ENUM,
1911 "glGetShaderPrecisionFormat(precisiontype)");
1912 return;
1913 }
1914
1915 range[0] = p->RangeMin;
1916 range[1] = p->RangeMax;
1917 precision[0] = p->Precision;
1918 }
1919
1920
1921 /**
1922 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1923 */
1924 void GLAPIENTRY
1925 _mesa_ReleaseShaderCompiler(void)
1926 {
1927 _mesa_destroy_shader_compiler_caches();
1928 }
1929
1930
1931 /**
1932 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1933 */
1934 void GLAPIENTRY
1935 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1936 const void* binary, GLint length)
1937 {
1938 GET_CURRENT_CONTEXT(ctx);
1939 (void) shaders;
1940 (void) binaryformat;
1941 (void) binary;
1942
1943 /* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and
1944 * page 88 of the OpenGL 4.5 specs state:
1945 *
1946 * "An INVALID_VALUE error is generated if count or length is negative.
1947 * An INVALID_ENUM error is generated if binaryformat is not a supported
1948 * format returned in SHADER_BINARY_FORMATS."
1949 */
1950 if (n < 0 || length < 0) {
1951 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderBinary(count or length < 0)");
1952 return;
1953 }
1954
1955 _mesa_error(ctx, GL_INVALID_ENUM, "glShaderBinary(format)");
1956 }
1957
1958
1959 void GLAPIENTRY
1960 _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
1961 GLenum *binaryFormat, GLvoid *binary)
1962 {
1963 struct gl_shader_program *shProg;
1964 GLsizei length_dummy;
1965 GET_CURRENT_CONTEXT(ctx);
1966
1967 if (bufSize < 0){
1968 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
1969 return;
1970 }
1971
1972 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
1973 if (!shProg)
1974 return;
1975
1976 /* The ARB_get_program_binary spec says:
1977 *
1978 * "If <length> is NULL, then no length is returned."
1979 *
1980 * Ensure that length always points to valid storage to avoid multiple NULL
1981 * pointer checks below.
1982 */
1983 if (length == NULL)
1984 length = &length_dummy;
1985
1986
1987 /* The ARB_get_program_binary spec says:
1988 *
1989 * "When a program object's LINK_STATUS is FALSE, its program binary
1990 * length is zero, and a call to GetProgramBinary will generate an
1991 * INVALID_OPERATION error.
1992 */
1993 if (!shProg->LinkStatus) {
1994 _mesa_error(ctx, GL_INVALID_OPERATION,
1995 "glGetProgramBinary(program %u not linked)",
1996 shProg->Name);
1997 *length = 0;
1998 return;
1999 }
2000
2001 *length = 0;
2002 _mesa_error(ctx, GL_INVALID_OPERATION,
2003 "glGetProgramBinary(driver supports zero binary formats)");
2004
2005 (void) binaryFormat;
2006 (void) binary;
2007 }
2008
2009 void GLAPIENTRY
2010 _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
2011 const GLvoid *binary, GLsizei length)
2012 {
2013 struct gl_shader_program *shProg;
2014 GET_CURRENT_CONTEXT(ctx);
2015
2016 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary");
2017 if (!shProg)
2018 return;
2019
2020 (void) binaryFormat;
2021 (void) binary;
2022
2023 /* Section 2.3.1 (Errors) of the OpenGL 4.5 spec says:
2024 *
2025 * "If a negative number is provided where an argument of type sizei or
2026 * sizeiptr is specified, an INVALID_VALUE error is generated."
2027 */
2028 if (length < 0) {
2029 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramBinary(length < 0)");
2030 return;
2031 }
2032
2033 /* The ARB_get_program_binary spec says:
2034 *
2035 * "<binaryFormat> and <binary> must be those returned by a previous
2036 * call to GetProgramBinary, and <length> must be the length of the
2037 * program binary as returned by GetProgramBinary or GetProgramiv with
2038 * <pname> PROGRAM_BINARY_LENGTH. Loading the program binary will fail,
2039 * setting the LINK_STATUS of <program> to FALSE, if these conditions
2040 * are not met."
2041 *
2042 * Since any value of binaryFormat passed "is not one of those specified as
2043 * allowable for [this] command, an INVALID_ENUM error is generated."
2044 */
2045 shProg->LinkStatus = GL_FALSE;
2046 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramBinary");
2047 }
2048
2049
2050 void GLAPIENTRY
2051 _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
2052 {
2053 struct gl_shader_program *shProg;
2054 GET_CURRENT_CONTEXT(ctx);
2055
2056 shProg = _mesa_lookup_shader_program_err(ctx, program,
2057 "glProgramParameteri");
2058 if (!shProg)
2059 return;
2060
2061 switch (pname) {
2062 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
2063 /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
2064 * is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't
2065 * even be in the dispatch table, so we shouldn't need to expclicitly
2066 * check here.
2067 *
2068 * On desktop, we ignore the 3.0+ requirement because it is silly.
2069 */
2070
2071 /* The ARB_get_program_binary extension spec says:
2072 *
2073 * "An INVALID_VALUE error is generated if the <value> argument to
2074 * ProgramParameteri is not TRUE or FALSE."
2075 */
2076 if (value != GL_TRUE && value != GL_FALSE) {
2077 goto invalid_value;
2078 }
2079
2080 /* No need to notify the driver. Any changes will actually take effect
2081 * the next time the shader is linked.
2082 *
2083 * The ARB_get_program_binary extension spec says:
2084 *
2085 * "To indicate that a program binary is likely to be retrieved,
2086 * ProgramParameteri should be called with <pname>
2087 * PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
2088 * will not be in effect until the next time LinkProgram or
2089 * ProgramBinary has been called successfully."
2090 *
2091 * The resloution of issue 9 in the extension spec also says:
2092 *
2093 * "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
2094 * to indicate to the GL implementation that this program will
2095 * likely be saved with GetProgramBinary at some point. This will
2096 * give the GL implementation the opportunity to track any state
2097 * changes made to the program before being saved such that when it
2098 * is loaded again a recompile can be avoided."
2099 */
2100 shProg->BinaryRetreivableHint = value;
2101 return;
2102
2103 case GL_PROGRAM_SEPARABLE:
2104 /* Spec imply that the behavior is the same as ARB_get_program_binary
2105 * Chapter 7.3 Program Objects
2106 */
2107 if (value != GL_TRUE && value != GL_FALSE) {
2108 goto invalid_value;
2109 }
2110 shProg->SeparateShader = value;
2111 return;
2112
2113 default:
2114 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
2115 _mesa_enum_to_string(pname));
2116 return;
2117 }
2118
2119 invalid_value:
2120 _mesa_error(ctx, GL_INVALID_VALUE,
2121 "glProgramParameteri(pname=%s, value=%d): "
2122 "value must be 0 or 1.",
2123 _mesa_enum_to_string(pname),
2124 value);
2125 }
2126
2127
2128 void
2129 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
2130 struct gl_shader_program *shProg,
2131 struct gl_pipeline_object *shTarget)
2132 {
2133 gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type);
2134 use_shader_program(ctx, stage, shProg, shTarget);
2135 }
2136
2137
2138 /**
2139 * Copy program-specific data generated by linking from the gl_shader_program
2140 * object to the gl_program object referred to by the gl_linked_shader.
2141 *
2142 * This function expects _mesa_reference_program() to have been previously
2143 * called setting the gl_linked_shaders program reference.
2144 */
2145 void
2146 _mesa_copy_linked_program_data(const struct gl_shader_program *src,
2147 struct gl_linked_shader *dst_sh)
2148 {
2149 assert(dst_sh->Program);
2150
2151 struct gl_program *dst = dst_sh->Program;
2152
2153 dst->info.num_abos = dst_sh->NumAtomicBuffers;
2154 dst->info.num_images = dst_sh->NumImages;
2155
2156 switch (dst_sh->Stage) {
2157 case MESA_SHADER_VERTEX:
2158 dst->ClipDistanceArraySize = src->Vert.ClipDistanceArraySize;
2159 dst->CullDistanceArraySize = src->Vert.CullDistanceArraySize;
2160 break;
2161 case MESA_SHADER_TESS_CTRL: {
2162 dst->info.tcs.vertices_out = dst_sh->info.TessCtrl.VerticesOut;
2163 break;
2164 }
2165 case MESA_SHADER_TESS_EVAL: {
2166 dst->info.tes.primitive_mode = dst_sh->info.TessEval.PrimitiveMode;
2167 dst->info.tes.spacing = dst_sh->info.TessEval.Spacing;
2168 dst->info.tes.vertex_order = dst_sh->info.TessEval.VertexOrder;
2169 dst->info.tes.point_mode = dst_sh->info.TessEval.PointMode;
2170 dst->ClipDistanceArraySize = src->TessEval.ClipDistanceArraySize;
2171 dst->CullDistanceArraySize = src->TessEval.CullDistanceArraySize;
2172 break;
2173 }
2174 case MESA_SHADER_GEOMETRY: {
2175 dst->info.gs.vertices_in = src->Geom.VerticesIn;
2176 dst->info.gs.vertices_out = dst_sh->info.Geom.VerticesOut;
2177 dst->info.gs.invocations = dst_sh->info.Geom.Invocations;
2178 dst->info.gs.input_primitive = dst_sh->info.Geom.InputType;
2179 dst->info.gs.output_primitive = dst_sh->info.Geom.OutputType;
2180 dst->ClipDistanceArraySize = src->Geom.ClipDistanceArraySize;
2181 dst->CullDistanceArraySize = src->Geom.CullDistanceArraySize;
2182 dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive;
2183 dst->info.gs.uses_streams = src->Geom.UsesStreams;
2184 break;
2185 }
2186 case MESA_SHADER_FRAGMENT: {
2187 dst->info.fs.depth_layout = src->FragDepthLayout;
2188 dst->info.fs.early_fragment_tests = dst_sh->info.EarlyFragmentTests;
2189 break;
2190 }
2191 case MESA_SHADER_COMPUTE: {
2192 for (int i = 0; i < 3; i++)
2193 dst->info.cs.local_size[i] = src->Comp.LocalSize[i];
2194 dst->info.cs.shared_size = src->Comp.SharedSize;
2195 break;
2196 }
2197 default:
2198 break;
2199 }
2200 }
2201
2202 /**
2203 * ARB_separate_shader_objects: Compile & Link Program
2204 */
2205 GLuint GLAPIENTRY
2206 _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
2207 const GLchar* const *strings)
2208 {
2209 GET_CURRENT_CONTEXT(ctx);
2210
2211 const GLuint shader = create_shader(ctx, type);
2212 GLuint program = 0;
2213
2214 /*
2215 * According to OpenGL 4.5 and OpenGL ES 3.1 standards, section 7.3:
2216 * GL_INVALID_VALUE should be generated if count < 0
2217 */
2218 if (count < 0) {
2219 _mesa_error(ctx, GL_INVALID_VALUE, "glCreateShaderProgram (count < 0)");
2220 return program;
2221 }
2222
2223 if (shader) {
2224 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
2225
2226 _mesa_ShaderSource(shader, count, strings, NULL);
2227 _mesa_compile_shader(ctx, sh);
2228
2229 program = create_shader_program(ctx);
2230 if (program) {
2231 struct gl_shader_program *shProg;
2232 GLint compiled = GL_FALSE;
2233
2234 shProg = _mesa_lookup_shader_program(ctx, program);
2235
2236 shProg->SeparateShader = GL_TRUE;
2237
2238 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
2239 if (compiled) {
2240 attach_shader(ctx, program, shader);
2241 _mesa_link_program(ctx, shProg);
2242 detach_shader(ctx, program, shader);
2243
2244 #if 0
2245 /* Possibly... */
2246 if (active-user-defined-varyings-in-linked-program) {
2247 append-error-to-info-log;
2248 shProg->LinkStatus = GL_FALSE;
2249 }
2250 #endif
2251 }
2252 if (sh->InfoLog)
2253 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
2254 }
2255
2256 delete_shader(ctx, shader);
2257 }
2258
2259 return program;
2260 }
2261
2262
2263 /**
2264 * For GL_ARB_tessellation_shader
2265 */
2266 extern void GLAPIENTRY
2267 _mesa_PatchParameteri(GLenum pname, GLint value)
2268 {
2269 GET_CURRENT_CONTEXT(ctx);
2270
2271 if (!_mesa_has_tessellation(ctx)) {
2272 _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameteri");
2273 return;
2274 }
2275
2276 if (pname != GL_PATCH_VERTICES) {
2277 _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameteri");
2278 return;
2279 }
2280
2281 if (value <= 0 || value > ctx->Const.MaxPatchVertices) {
2282 _mesa_error(ctx, GL_INVALID_VALUE, "glPatchParameteri");
2283 return;
2284 }
2285
2286 ctx->TessCtrlProgram.patch_vertices = value;
2287 }
2288
2289
2290 extern void GLAPIENTRY
2291 _mesa_PatchParameterfv(GLenum pname, const GLfloat *values)
2292 {
2293 GET_CURRENT_CONTEXT(ctx);
2294
2295 if (!_mesa_has_tessellation(ctx)) {
2296 _mesa_error(ctx, GL_INVALID_OPERATION, "glPatchParameterfv");
2297 return;
2298 }
2299
2300 switch(pname) {
2301 case GL_PATCH_DEFAULT_OUTER_LEVEL:
2302 FLUSH_VERTICES(ctx, 0);
2303 memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values,
2304 4 * sizeof(GLfloat));
2305 ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
2306 return;
2307 case GL_PATCH_DEFAULT_INNER_LEVEL:
2308 FLUSH_VERTICES(ctx, 0);
2309 memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values,
2310 2 * sizeof(GLfloat));
2311 ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels;
2312 return;
2313 default:
2314 _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv");
2315 return;
2316 }
2317 }
2318
2319 /**
2320 * ARB_shader_subroutine
2321 */
2322 GLint GLAPIENTRY
2323 _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
2324 const GLchar *name)
2325 {
2326 GET_CURRENT_CONTEXT(ctx);
2327 const char *api_name = "glGetSubroutineUniformLocation";
2328 struct gl_shader_program *shProg;
2329 GLenum resource_type;
2330 gl_shader_stage stage;
2331
2332 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2333 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2334 return -1;
2335 }
2336
2337 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2338 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2339 return -1;
2340 }
2341
2342 shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2343 if (!shProg)
2344 return -1;
2345
2346 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2347 if (!shProg->_LinkedShaders[stage]) {
2348 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2349 return -1;
2350 }
2351
2352 resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2353 return _mesa_program_resource_location(shProg, resource_type, name);
2354 }
2355
2356 GLuint GLAPIENTRY
2357 _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
2358 const GLchar *name)
2359 {
2360 GET_CURRENT_CONTEXT(ctx);
2361 const char *api_name = "glGetSubroutineIndex";
2362 struct gl_shader_program *shProg;
2363 struct gl_program_resource *res;
2364 GLenum resource_type;
2365 gl_shader_stage stage;
2366
2367 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2368 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2369 return -1;
2370 }
2371
2372 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2373 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2374 return -1;
2375 }
2376
2377 shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2378 if (!shProg)
2379 return -1;
2380
2381 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2382 if (!shProg->_LinkedShaders[stage]) {
2383 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2384 return -1;
2385 }
2386
2387 resource_type = _mesa_shader_stage_to_subroutine(stage);
2388 res = _mesa_program_resource_find_name(shProg, resource_type, name, NULL);
2389 if (!res) {
2390 return -1;
2391 }
2392
2393 return _mesa_program_resource_index(shProg, res);
2394 }
2395
2396
2397 GLvoid GLAPIENTRY
2398 _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
2399 GLuint index, GLenum pname, GLint *values)
2400 {
2401 GET_CURRENT_CONTEXT(ctx);
2402 const char *api_name = "glGetActiveSubroutineUniformiv";
2403 struct gl_shader_program *shProg;
2404 struct gl_linked_shader *sh;
2405 gl_shader_stage stage;
2406 struct gl_program_resource *res;
2407 const struct gl_uniform_storage *uni;
2408 GLenum resource_type;
2409 int count, i, j;
2410
2411 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2412 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2413 return;
2414 }
2415
2416 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2417 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2418 return;
2419 }
2420
2421 shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2422 if (!shProg)
2423 return;
2424
2425 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2426 resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2427
2428 sh = shProg->_LinkedShaders[stage];
2429 if (!sh) {
2430 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2431 return;
2432 }
2433
2434 if (index >= sh->NumSubroutineUniforms) {
2435 _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name);
2436 return;
2437 }
2438
2439 switch (pname) {
2440 case GL_NUM_COMPATIBLE_SUBROUTINES: {
2441 res = _mesa_program_resource_find_index(shProg, resource_type, index);
2442 if (res) {
2443 uni = res->Data;
2444 values[0] = uni->num_compatible_subroutines;
2445 }
2446 break;
2447 }
2448 case GL_COMPATIBLE_SUBROUTINES: {
2449 res = _mesa_program_resource_find_index(shProg, resource_type, index);
2450 if (res) {
2451 uni = res->Data;
2452 count = 0;
2453 for (i = 0; i < sh->NumSubroutineFunctions; i++) {
2454 struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
2455 for (j = 0; j < fn->num_compat_types; j++) {
2456 if (fn->types[j] == uni->type) {
2457 values[count++] = i;
2458 break;
2459 }
2460 }
2461 }
2462 }
2463 break;
2464 }
2465 case GL_UNIFORM_SIZE:
2466 res = _mesa_program_resource_find_index(shProg, resource_type, index);
2467 if (res) {
2468 uni = res->Data;
2469 values[0] = uni->array_elements ? uni->array_elements : 1;
2470 }
2471 break;
2472 case GL_UNIFORM_NAME_LENGTH:
2473 res = _mesa_program_resource_find_index(shProg, resource_type, index);
2474 if (res) {
2475 values[0] = strlen(_mesa_program_resource_name(res)) + 1
2476 + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
2477 }
2478 break;
2479 default:
2480 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2481 return;
2482 }
2483 }
2484
2485
2486 GLvoid GLAPIENTRY
2487 _mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype,
2488 GLuint index, GLsizei bufsize,
2489 GLsizei *length, GLchar *name)
2490 {
2491 GET_CURRENT_CONTEXT(ctx);
2492 const char *api_name = "glGetActiveSubroutineUniformName";
2493 struct gl_shader_program *shProg;
2494 GLenum resource_type;
2495 gl_shader_stage stage;
2496
2497 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2498 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2499 return;
2500 }
2501
2502 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2503 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2504 return;
2505 }
2506
2507 shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2508 if (!shProg)
2509 return;
2510
2511 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2512 if (!shProg->_LinkedShaders[stage]) {
2513 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2514 return;
2515 }
2516
2517 resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2518 /* get program resource name */
2519 _mesa_get_program_resource_name(shProg, resource_type,
2520 index, bufsize,
2521 length, name, api_name);
2522 }
2523
2524
2525 GLvoid GLAPIENTRY
2526 _mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype,
2527 GLuint index, GLsizei bufsize,
2528 GLsizei *length, GLchar *name)
2529 {
2530 GET_CURRENT_CONTEXT(ctx);
2531 const char *api_name = "glGetActiveSubroutineName";
2532 struct gl_shader_program *shProg;
2533 GLenum resource_type;
2534 gl_shader_stage stage;
2535
2536 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2537 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2538 return;
2539 }
2540
2541 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2542 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2543 return;
2544 }
2545
2546 shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2547 if (!shProg)
2548 return;
2549
2550 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2551 if (!shProg->_LinkedShaders[stage]) {
2552 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2553 return;
2554 }
2555 resource_type = _mesa_shader_stage_to_subroutine(stage);
2556 _mesa_get_program_resource_name(shProg, resource_type,
2557 index, bufsize,
2558 length, name, api_name);
2559 }
2560
2561 GLvoid GLAPIENTRY
2562 _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
2563 const GLuint *indices)
2564 {
2565 GET_CURRENT_CONTEXT(ctx);
2566 const char *api_name = "glUniformSubroutinesuiv";
2567 struct gl_shader_program *shProg;
2568 struct gl_linked_shader *sh;
2569 gl_shader_stage stage;
2570 int i;
2571
2572 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2573 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2574 return;
2575 }
2576
2577 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2578 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2579 return;
2580 }
2581
2582 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2583 shProg = ctx->_Shader->CurrentProgram[stage];
2584 if (!shProg) {
2585 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2586 return;
2587 }
2588
2589 sh = shProg->_LinkedShaders[stage];
2590 if (!sh) {
2591 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2592 return;
2593 }
2594
2595 if (count != sh->NumSubroutineUniformRemapTable) {
2596 _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
2597 return;
2598 }
2599
2600 i = 0;
2601 do {
2602 struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
2603 if (uni == NULL) {
2604 i++;
2605 continue;
2606 }
2607
2608 int uni_count = uni->array_elements ? uni->array_elements : 1;
2609 int j, k, f;
2610
2611 for (j = i; j < i + uni_count; j++) {
2612 struct gl_subroutine_function *subfn = NULL;
2613 if (indices[j] > sh->MaxSubroutineFunctionIndex) {
2614 _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
2615 return;
2616 }
2617
2618 for (f = 0; f < sh->NumSubroutineFunctions; f++) {
2619 if (sh->SubroutineFunctions[f].index == indices[j])
2620 subfn = &sh->SubroutineFunctions[f];
2621 }
2622
2623 if (!subfn) {
2624 continue;
2625 }
2626
2627 for (k = 0; k < subfn->num_compat_types; k++) {
2628 if (subfn->types[k] == uni->type)
2629 break;
2630 }
2631 if (k == subfn->num_compat_types) {
2632 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2633 return;
2634 }
2635
2636 ctx->SubroutineIndex[sh->Stage].IndexPtr[j] = indices[j];
2637 }
2638 i += uni_count;
2639 } while(i < count);
2640
2641 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
2642 }
2643
2644
2645 GLvoid GLAPIENTRY
2646 _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
2647 GLuint *params)
2648 {
2649 GET_CURRENT_CONTEXT(ctx);
2650 const char *api_name = "glGetUniformSubroutineuiv";
2651 struct gl_shader_program *shProg;
2652 struct gl_linked_shader *sh;
2653 gl_shader_stage stage;
2654
2655 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2656 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2657 return;
2658 }
2659
2660 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2661 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2662 return;
2663 }
2664
2665 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2666 shProg = ctx->_Shader->CurrentProgram[stage];
2667 if (!shProg) {
2668 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2669 return;
2670 }
2671
2672 sh = shProg->_LinkedShaders[stage];
2673 if (!sh) {
2674 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2675 return;
2676 }
2677
2678 if (location >= sh->NumSubroutineUniformRemapTable) {
2679 _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
2680 return;
2681 }
2682
2683 *params = ctx->SubroutineIndex[sh->Stage].IndexPtr[location];
2684 }
2685
2686
2687 GLvoid GLAPIENTRY
2688 _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
2689 GLenum pname, GLint *values)
2690 {
2691 GET_CURRENT_CONTEXT(ctx);
2692 const char *api_name = "glGetProgramStageiv";
2693 struct gl_shader_program *shProg;
2694 struct gl_linked_shader *sh;
2695 gl_shader_stage stage;
2696
2697 if (!_mesa_has_ARB_shader_subroutine(ctx)) {
2698 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2699 return;
2700 }
2701
2702 if (!_mesa_validate_shader_target(ctx, shadertype)) {
2703 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2704 return;
2705 }
2706
2707 shProg = _mesa_lookup_shader_program_err(ctx, program, api_name);
2708 if (!shProg)
2709 return;
2710
2711 stage = _mesa_shader_enum_to_shader_stage(shadertype);
2712 sh = shProg->_LinkedShaders[stage];
2713
2714 /* ARB_shader_subroutine doesn't ask the program to be linked, or list any
2715 * INVALID_OPERATION in the case of not be linked.
2716 *
2717 * And for some pnames, like GL_ACTIVE_SUBROUTINE_UNIFORMS, you can ask the
2718 * same info using other specs (ARB_program_interface_query), without the
2719 * need of the program to be linked, being the value for that case 0.
2720 *
2721 * But at the same time, some other methods require the program to be
2722 * linked for pname related to locations, so it would be inconsistent to
2723 * not do the same here. So we are:
2724 * * Return GL_INVALID_OPERATION if not linked only for locations.
2725 * * Setting a default value of 0, to be returned if not linked.
2726 */
2727 if (!sh) {
2728 values[0] = 0;
2729 if (pname == GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS) {
2730 _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
2731 }
2732 return;
2733 }
2734
2735 switch (pname) {
2736 case GL_ACTIVE_SUBROUTINES:
2737 values[0] = sh->NumSubroutineFunctions;
2738 break;
2739 case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS:
2740 values[0] = sh->NumSubroutineUniformRemapTable;
2741 break;
2742 case GL_ACTIVE_SUBROUTINE_UNIFORMS:
2743 values[0] = sh->NumSubroutineUniforms;
2744 break;
2745 case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
2746 {
2747 unsigned i;
2748 GLint max_len = 0;
2749 GLenum resource_type;
2750 struct gl_program_resource *res;
2751
2752 resource_type = _mesa_shader_stage_to_subroutine(stage);
2753 for (i = 0; i < sh->NumSubroutineFunctions; i++) {
2754 res = _mesa_program_resource_find_index(shProg, resource_type, i);
2755 if (res) {
2756 const GLint len = strlen(_mesa_program_resource_name(res)) + 1;
2757 if (len > max_len)
2758 max_len = len;
2759 }
2760 }
2761 values[0] = max_len;
2762 break;
2763 }
2764 case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH:
2765 {
2766 unsigned i;
2767 GLint max_len = 0;
2768 GLenum resource_type;
2769 struct gl_program_resource *res;
2770
2771 resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
2772 for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
2773 res = _mesa_program_resource_find_index(shProg, resource_type, i);
2774 if (res) {
2775 const GLint len = strlen(_mesa_program_resource_name(res)) + 1
2776 + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
2777
2778 if (len > max_len)
2779 max_len = len;
2780 }
2781 }
2782 values[0] = max_len;
2783 break;
2784 }
2785 default:
2786 _mesa_error(ctx, GL_INVALID_ENUM, "%s", api_name);
2787 values[0] = -1;
2788 break;
2789 }
2790 }
2791
2792 static int
2793 find_compat_subroutine(struct gl_linked_shader *sh,
2794 const struct glsl_type *type)
2795 {
2796 int i, j;
2797
2798 for (i = 0; i < sh->NumSubroutineFunctions; i++) {
2799 struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
2800 for (j = 0; j < fn->num_compat_types; j++) {
2801 if (fn->types[j] == type)
2802 return i;
2803 }
2804 }
2805 return 0;
2806 }
2807
2808 static void
2809 _mesa_shader_write_subroutine_index(struct gl_context *ctx,
2810 struct gl_linked_shader *sh)
2811 {
2812 int i, j;
2813
2814 if (sh->NumSubroutineUniformRemapTable == 0)
2815 return;
2816
2817 i = 0;
2818 do {
2819 struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
2820 int uni_count;
2821 int val;
2822
2823 if (!uni) {
2824 i++;
2825 continue;
2826 }
2827
2828 uni_count = uni->array_elements ? uni->array_elements : 1;
2829 for (j = 0; j < uni_count; j++) {
2830 val = ctx->SubroutineIndex[sh->Stage].IndexPtr[i + j];
2831 memcpy(&uni->storage[j], &val, sizeof(int));
2832 }
2833
2834 _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
2835 i += uni_count;
2836 } while(i < sh->NumSubroutineUniformRemapTable);
2837 }
2838
2839 void
2840 _mesa_shader_write_subroutine_indices(struct gl_context *ctx,
2841 gl_shader_stage stage)
2842 {
2843 if (ctx->_Shader->CurrentProgram[stage] &&
2844 ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage])
2845 _mesa_shader_write_subroutine_index(ctx,
2846 ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]);
2847 }
2848
2849 static void
2850 _mesa_shader_init_subroutine_defaults(struct gl_context *ctx,
2851 struct gl_linked_shader *sh)
2852 {
2853 int i;
2854 struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[sh->Stage];
2855 if (binding->NumIndex != sh->NumSubroutineUniformRemapTable) {
2856 binding->IndexPtr = realloc(binding->IndexPtr,
2857 sh->NumSubroutineUniformRemapTable * (sizeof(GLuint)));
2858 binding->NumIndex = sh->NumSubroutineUniformRemapTable;
2859 }
2860
2861 for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
2862 struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
2863
2864 if (!uni)
2865 continue;
2866
2867 binding->IndexPtr[i] = find_compat_subroutine(sh, uni->type);
2868 }
2869 }
2870
2871 void
2872 _mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
2873 struct gl_shader_program *shProg)
2874 {
2875 int i;
2876
2877 if (!shProg)
2878 return;
2879
2880 for (i = 0; i < MESA_SHADER_STAGES; i++) {
2881 if (!shProg->_LinkedShaders[i])
2882 continue;
2883
2884 _mesa_shader_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]);
2885 }
2886 }