mesa: Use shared code for converting shader targets to short strings.
[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 "main/glheader.h"
41 #include "main/context.h"
42 #include "main/dispatch.h"
43 #include "main/enums.h"
44 #include "main/hash.h"
45 #include "main/mtypes.h"
46 #include "main/shaderapi.h"
47 #include "main/shaderobj.h"
48 #include "main/transformfeedback.h"
49 #include "main/uniforms.h"
50 #include "program/program.h"
51 #include "program/prog_parameter.h"
52 #include "ralloc.h"
53 #include <stdbool.h>
54 #include "../glsl/glsl_parser_extras.h"
55 #include "../glsl/ir_uniform.h"
56
57 /** Define this to enable shader substitution (see below) */
58 #define SHADER_SUBST 0
59
60
61 /**
62 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
63 */
64 static GLbitfield
65 get_shader_flags(void)
66 {
67 GLbitfield flags = 0x0;
68 const char *env = _mesa_getenv("MESA_GLSL");
69
70 if (env) {
71 if (strstr(env, "dump"))
72 flags |= GLSL_DUMP;
73 if (strstr(env, "log"))
74 flags |= GLSL_LOG;
75 if (strstr(env, "nopvert"))
76 flags |= GLSL_NOP_VERT;
77 if (strstr(env, "nopfrag"))
78 flags |= GLSL_NOP_FRAG;
79 if (strstr(env, "nopt"))
80 flags |= GLSL_NO_OPT;
81 else if (strstr(env, "opt"))
82 flags |= GLSL_OPT;
83 if (strstr(env, "uniform"))
84 flags |= GLSL_UNIFORMS;
85 if (strstr(env, "useprog"))
86 flags |= GLSL_USE_PROG;
87 if (strstr(env, "errors"))
88 flags |= GLSL_REPORT_ERRORS;
89 }
90
91 return flags;
92 }
93
94
95 /**
96 * Initialize context's shader state.
97 */
98 void
99 _mesa_init_shader_state(struct gl_context *ctx)
100 {
101 /* Device drivers may override these to control what kind of instructions
102 * are generated by the GLSL compiler.
103 */
104 struct gl_shader_compiler_options options;
105 gl_shader_type sh;
106
107 memset(&options, 0, sizeof(options));
108 options.MaxUnrollIterations = 32;
109 options.MaxIfDepth = UINT_MAX;
110
111 /* Default pragma settings */
112 options.DefaultPragmas.Optimize = GL_TRUE;
113
114 for (sh = 0; sh < MESA_SHADER_TYPES; ++sh)
115 memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
116
117 ctx->Shader.Flags = get_shader_flags();
118 }
119
120
121 /**
122 * Free the per-context shader-related state.
123 */
124 void
125 _mesa_free_shader_state(struct gl_context *ctx)
126 {
127 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentVertexProgram, NULL);
128 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentGeometryProgram,
129 NULL);
130 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
131 NULL);
132 _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
133 NULL);
134 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
135 }
136
137
138 /**
139 * Copy string from <src> to <dst>, up to maxLength characters, returning
140 * length of <dst> in <length>.
141 * \param src the strings source
142 * \param maxLength max chars to copy
143 * \param length returns number of chars copied
144 * \param dst the string destination
145 */
146 void
147 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
148 GLsizei *length, const GLchar *src)
149 {
150 GLsizei len;
151 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
152 dst[len] = src[len];
153 if (maxLength > 0)
154 dst[len] = 0;
155 if (length)
156 *length = len;
157 }
158
159
160
161 /**
162 * Confirm that the a shader type is valid and supported by the implementation
163 *
164 * \param ctx Current GL context
165 * \param type Shader target
166 *
167 */
168 static bool
169 validate_shader_target(const struct gl_context *ctx, GLenum type)
170 {
171 switch (type) {
172 case GL_FRAGMENT_SHADER:
173 return ctx->Extensions.ARB_fragment_shader;
174 case GL_VERTEX_SHADER:
175 return ctx->Extensions.ARB_vertex_shader;
176 case GL_GEOMETRY_SHADER_ARB:
177 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
178 default:
179 return false;
180 }
181 }
182
183
184 static GLboolean
185 is_program(struct gl_context *ctx, GLuint name)
186 {
187 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
188 return shProg ? GL_TRUE : GL_FALSE;
189 }
190
191
192 static GLboolean
193 is_shader(struct gl_context *ctx, GLuint name)
194 {
195 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
196 return shader ? GL_TRUE : GL_FALSE;
197 }
198
199
200 /**
201 * Attach shader to a shader program.
202 */
203 static void
204 attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
205 {
206 struct gl_shader_program *shProg;
207 struct gl_shader *sh;
208 GLuint i, n;
209
210 const bool same_type_disallowed = _mesa_is_gles(ctx);
211
212 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
213 if (!shProg)
214 return;
215
216 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
217 if (!sh) {
218 return;
219 }
220
221 n = shProg->NumShaders;
222 for (i = 0; i < n; i++) {
223 if (shProg->Shaders[i] == sh) {
224 /* The shader is already attched to this program. The
225 * GL_ARB_shader_objects spec says:
226 *
227 * "The error INVALID_OPERATION is generated by AttachObjectARB
228 * if <obj> is already attached to <containerObj>."
229 */
230 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
231 return;
232 } else if (same_type_disallowed &&
233 shProg->Shaders[i]->Type == sh->Type) {
234 /* Shader with the same type is already attached to this program,
235 * OpenGL ES 2.0 and 3.0 specs say:
236 *
237 * "Multiple shader objects of the same type may not be attached
238 * to a single program object. [...] The error INVALID_OPERATION
239 * is generated if [...] another shader object of the same type
240 * as shader is already attached to program."
241 */
242 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
243 return;
244 }
245 }
246
247 /* grow list */
248 shProg->Shaders = (struct gl_shader **)
249 _mesa_realloc(shProg->Shaders,
250 n * sizeof(struct gl_shader *),
251 (n + 1) * sizeof(struct gl_shader *));
252 if (!shProg->Shaders) {
253 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
254 return;
255 }
256
257 /* append */
258 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
259 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
260 shProg->NumShaders++;
261 }
262
263
264 static GLuint
265 create_shader(struct gl_context *ctx, GLenum type)
266 {
267 struct gl_shader *sh;
268 GLuint name;
269
270 if (!validate_shader_target(ctx, type)) {
271 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
272 return 0;
273 }
274
275 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
276 sh = ctx->Driver.NewShader(ctx, name, type);
277 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
278
279 return name;
280 }
281
282
283 static GLuint
284 create_shader_program(struct gl_context *ctx)
285 {
286 GLuint name;
287 struct gl_shader_program *shProg;
288
289 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
290
291 shProg = ctx->Driver.NewShaderProgram(ctx, name);
292
293 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
294
295 assert(shProg->RefCount == 1);
296
297 return name;
298 }
299
300
301 /**
302 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
303 * DeleteProgramARB.
304 */
305 static void
306 delete_shader_program(struct gl_context *ctx, GLuint name)
307 {
308 /*
309 * NOTE: deleting shaders/programs works a bit differently than
310 * texture objects (and buffer objects, etc). Shader/program
311 * handles/IDs exist in the hash table until the object is really
312 * deleted (refcount==0). With texture objects, the handle/ID is
313 * removed from the hash table in glDeleteTextures() while the tex
314 * object itself might linger until its refcount goes to zero.
315 */
316 struct gl_shader_program *shProg;
317
318 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
319 if (!shProg)
320 return;
321
322 if (!shProg->DeletePending) {
323 shProg->DeletePending = GL_TRUE;
324
325 /* effectively, decr shProg's refcount */
326 _mesa_reference_shader_program(ctx, &shProg, NULL);
327 }
328 }
329
330
331 static void
332 delete_shader(struct gl_context *ctx, GLuint shader)
333 {
334 struct gl_shader *sh;
335
336 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
337 if (!sh)
338 return;
339
340 if (!sh->DeletePending) {
341 sh->DeletePending = GL_TRUE;
342
343 /* effectively, decr sh's refcount */
344 _mesa_reference_shader(ctx, &sh, NULL);
345 }
346 }
347
348
349 static void
350 detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
351 {
352 struct gl_shader_program *shProg;
353 GLuint n;
354 GLuint i, j;
355
356 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
357 if (!shProg)
358 return;
359
360 n = shProg->NumShaders;
361
362 for (i = 0; i < n; i++) {
363 if (shProg->Shaders[i]->Name == shader) {
364 /* found it */
365 struct gl_shader **newList;
366
367 /* release */
368 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
369
370 /* alloc new, smaller array */
371 newList =
372 malloc((n - 1) * sizeof(struct gl_shader *));
373 if (!newList) {
374 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
375 return;
376 }
377 for (j = 0; j < i; j++) {
378 newList[j] = shProg->Shaders[j];
379 }
380 while (++i < n)
381 newList[j++] = shProg->Shaders[i];
382 free(shProg->Shaders);
383
384 shProg->Shaders = newList;
385 shProg->NumShaders = n - 1;
386
387 #ifdef DEBUG
388 /* sanity check */
389 {
390 for (j = 0; j < shProg->NumShaders; j++) {
391 assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
392 shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
393 assert(shProg->Shaders[j]->RefCount > 0);
394 }
395 }
396 #endif
397
398 return;
399 }
400 }
401
402 /* not found */
403 {
404 GLenum err;
405 if (is_shader(ctx, shader))
406 err = GL_INVALID_OPERATION;
407 else if (is_program(ctx, shader))
408 err = GL_INVALID_OPERATION;
409 else
410 err = GL_INVALID_VALUE;
411 _mesa_error(ctx, err, "glDetachProgram(shader)");
412 return;
413 }
414 }
415
416
417 /**
418 * Return list of shaders attached to shader program.
419 */
420 static void
421 get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
422 GLsizei *count, GLuint *obj)
423 {
424 struct gl_shader_program *shProg =
425 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
426 if (shProg) {
427 GLuint i;
428 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
429 obj[i] = shProg->Shaders[i]->Name;
430 }
431 if (count)
432 *count = i;
433 }
434 }
435
436
437 /**
438 * glGetHandleARB() - return ID/name of currently bound shader program.
439 */
440 static GLuint
441 get_handle(struct gl_context *ctx, GLenum pname)
442 {
443 if (pname == GL_PROGRAM_OBJECT_ARB) {
444 if (ctx->Shader.ActiveProgram)
445 return ctx->Shader.ActiveProgram->Name;
446 else
447 return 0;
448 }
449 else {
450 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
451 return 0;
452 }
453 }
454
455
456 /**
457 * glGetProgramiv() - get shader program state.
458 * Note that this is for GLSL shader programs, not ARB vertex/fragment
459 * programs (see glGetProgramivARB).
460 */
461 static void
462 get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params)
463 {
464 struct gl_shader_program *shProg
465 = _mesa_lookup_shader_program(ctx, program);
466
467 /* Is transform feedback available in this context?
468 */
469 const bool has_xfb =
470 (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback)
471 || ctx->API == API_OPENGL_CORE
472 || _mesa_is_gles3(ctx);
473
474 /* Are geometry shaders available in this context?
475 */
476 const bool has_gs =
477 _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
478
479 /* Are uniform buffer objects available in this context?
480 */
481 const bool has_ubo =
482 (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_uniform_buffer_object)
483 || ctx->API == API_OPENGL_CORE
484 || _mesa_is_gles3(ctx);
485
486 if (!shProg) {
487 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
488 return;
489 }
490
491 switch (pname) {
492 case GL_DELETE_STATUS:
493 *params = shProg->DeletePending;
494 return;
495 case GL_LINK_STATUS:
496 *params = shProg->LinkStatus;
497 return;
498 case GL_VALIDATE_STATUS:
499 *params = shProg->Validated;
500 return;
501 case GL_INFO_LOG_LENGTH:
502 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
503 return;
504 case GL_ATTACHED_SHADERS:
505 *params = shProg->NumShaders;
506 return;
507 case GL_ACTIVE_ATTRIBUTES:
508 *params = _mesa_count_active_attribs(shProg);
509 return;
510 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
511 *params = _mesa_longest_attribute_name_length(shProg);
512 return;
513 case GL_ACTIVE_UNIFORMS:
514 *params = shProg->NumUserUniformStorage;
515 return;
516 case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
517 unsigned i;
518 GLint max_len = 0;
519
520 for (i = 0; i < shProg->NumUserUniformStorage; i++) {
521 /* Add one for the terminating NUL character for a non-array, and
522 * 4 for the "[0]" and the NUL for an array.
523 */
524 const GLint len = strlen(shProg->UniformStorage[i].name) + 1 +
525 ((shProg->UniformStorage[i].array_elements != 0) ? 3 : 0);
526
527 if (len > max_len)
528 max_len = len;
529 }
530
531 *params = max_len;
532 return;
533 }
534 case GL_TRANSFORM_FEEDBACK_VARYINGS:
535 if (!has_xfb)
536 break;
537 *params = shProg->TransformFeedback.NumVarying;
538 return;
539 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: {
540 unsigned i;
541 GLint max_len = 0;
542 if (!has_xfb)
543 break;
544
545 for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
546 /* Add one for the terminating NUL character.
547 */
548 const GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]) + 1;
549
550 if (len > max_len)
551 max_len = len;
552 }
553
554 *params = max_len;
555 return;
556 }
557 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
558 if (!has_xfb)
559 break;
560 *params = shProg->TransformFeedback.BufferMode;
561 return;
562 case GL_GEOMETRY_VERTICES_OUT_ARB:
563 if (!has_gs)
564 break;
565 *params = shProg->Geom.VerticesOut;
566 return;
567 case GL_GEOMETRY_INPUT_TYPE_ARB:
568 if (!has_gs)
569 break;
570 *params = shProg->Geom.InputType;
571 return;
572 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
573 if (!has_gs)
574 break;
575 *params = shProg->Geom.OutputType;
576 return;
577 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
578 unsigned i;
579 GLint max_len = 0;
580
581 if (!has_ubo)
582 break;
583
584 for (i = 0; i < shProg->NumUniformBlocks; i++) {
585 /* Add one for the terminating NUL character.
586 */
587 const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;
588
589 if (len > max_len)
590 max_len = len;
591 }
592
593 *params = max_len;
594 return;
595 }
596 case GL_ACTIVE_UNIFORM_BLOCKS:
597 if (!has_ubo)
598 break;
599
600 *params = shProg->NumUniformBlocks;
601 return;
602 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
603 /* This enum isn't part of the OES extension for OpenGL ES 2.0. It is
604 * only available with desktop OpenGL 3.0+ with the
605 * GL_ARB_get_program_binary extension or OpenGL ES 3.0.
606 *
607 * On desktop, we ignore the 3.0+ requirement because it is silly.
608 */
609 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
610 break;
611
612 *params = shProg->BinaryRetreivableHint;
613 return;
614 case GL_PROGRAM_BINARY_LENGTH:
615 *params = 0;
616 return;
617 default:
618 break;
619 }
620
621 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)",
622 _mesa_lookup_enum_by_nr(pname));
623 }
624
625
626 /**
627 * glGetShaderiv() - get GLSL shader state
628 */
629 static void
630 get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
631 {
632 struct gl_shader *shader =
633 _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
634
635 if (!shader) {
636 return;
637 }
638
639 switch (pname) {
640 case GL_SHADER_TYPE:
641 *params = shader->Type;
642 break;
643 case GL_DELETE_STATUS:
644 *params = shader->DeletePending;
645 break;
646 case GL_COMPILE_STATUS:
647 *params = shader->CompileStatus;
648 break;
649 case GL_INFO_LOG_LENGTH:
650 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
651 break;
652 case GL_SHADER_SOURCE_LENGTH:
653 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
654 break;
655 default:
656 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
657 return;
658 }
659 }
660
661
662 static void
663 get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
664 GLsizei *length, GLchar *infoLog)
665 {
666 struct gl_shader_program *shProg
667 = _mesa_lookup_shader_program(ctx, program);
668 if (!shProg) {
669 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
670 return;
671 }
672 _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
673 }
674
675
676 static void
677 get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
678 GLsizei *length, GLchar *infoLog)
679 {
680 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
681 if (!sh) {
682 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
683 return;
684 }
685 _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
686 }
687
688
689 /**
690 * Return shader source code.
691 */
692 static void
693 get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
694 GLsizei *length, GLchar *sourceOut)
695 {
696 struct gl_shader *sh;
697 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
698 if (!sh) {
699 return;
700 }
701 _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
702 }
703
704
705 /**
706 * Set/replace shader source code. A helper function used by
707 * glShaderSource[ARB] and glCreateShaderProgramEXT.
708 */
709 static void
710 shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
711 {
712 struct gl_shader *sh;
713
714 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
715 if (!sh)
716 return;
717
718 /* free old shader source string and install new one */
719 free((void *)sh->Source);
720 sh->Source = source;
721 sh->CompileStatus = GL_FALSE;
722 #ifdef DEBUG
723 sh->SourceChecksum = _mesa_str_checksum(sh->Source);
724 #endif
725 }
726
727
728 /**
729 * Compile a shader.
730 */
731 static void
732 compile_shader(struct gl_context *ctx, GLuint shaderObj)
733 {
734 struct gl_shader *sh;
735 struct gl_shader_compiler_options *options;
736
737 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
738 if (!sh)
739 return;
740
741 options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)];
742
743 /* set default pragma state for shader */
744 sh->Pragmas = options->DefaultPragmas;
745
746 /* this call will set the sh->CompileStatus field to indicate if
747 * compilation was successful.
748 */
749 _mesa_glsl_compile_shader(ctx, sh);
750
751 if (sh->CompileStatus == GL_FALSE &&
752 (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
753 _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
754 sh->Name, sh->InfoLog);
755 }
756 }
757
758
759 /**
760 * Link a program's shaders.
761 */
762 static void
763 link_program(struct gl_context *ctx, GLuint program)
764 {
765 struct gl_shader_program *shProg;
766 struct gl_transform_feedback_object *obj =
767 ctx->TransformFeedback.CurrentObject;
768
769 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
770 if (!shProg)
771 return;
772
773 if (obj->Active
774 && (shProg == ctx->Shader.CurrentVertexProgram
775 || shProg == ctx->Shader.CurrentGeometryProgram
776 || shProg == ctx->Shader.CurrentFragmentProgram)) {
777 _mesa_error(ctx, GL_INVALID_OPERATION,
778 "glLinkProgram(transform feedback active)");
779 return;
780 }
781
782 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
783
784 _mesa_glsl_link_shader(ctx, shProg);
785
786 if (shProg->LinkStatus == GL_FALSE &&
787 (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
788 _mesa_debug(ctx, "Error linking program %u:\n%s\n",
789 shProg->Name, shProg->InfoLog);
790 }
791
792 /* debug code */
793 if (0) {
794 GLuint i;
795
796 printf("Link %u shaders in program %u: %s\n",
797 shProg->NumShaders, shProg->Name,
798 shProg->LinkStatus ? "Success" : "Failed");
799
800 for (i = 0; i < shProg->NumShaders; i++) {
801 printf(" shader %u, type 0x%x\n",
802 shProg->Shaders[i]->Name,
803 shProg->Shaders[i]->Type);
804 }
805 }
806 }
807
808
809 /**
810 * Print basic shader info (for debug).
811 */
812 static void
813 print_shader_info(const struct gl_shader_program *shProg)
814 {
815 GLuint i;
816
817 printf("Mesa: glUseProgram(%u)\n", shProg->Name);
818 for (i = 0; i < shProg->NumShaders; i++) {
819 printf(" %s shader %u, checksum %u\n",
820 _mesa_glsl_shader_target_name(shProg->Shaders[i]->Type),
821 shProg->Shaders[i]->Name,
822 shProg->Shaders[i]->SourceChecksum);
823 }
824 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
825 printf(" vert prog %u\n",
826 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
827 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
828 printf(" frag prog %u\n",
829 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
830 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
831 printf(" geom prog %u\n",
832 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
833 }
834
835
836 /**
837 * Use the named shader program for subsequent glUniform calls
838 */
839 void
840 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
841 const char *caller)
842 {
843 if ((shProg != NULL) && !shProg->LinkStatus) {
844 _mesa_error(ctx, GL_INVALID_OPERATION,
845 "%s(program %u not linked)", caller, shProg->Name);
846 return;
847 }
848
849 if (ctx->Shader.ActiveProgram != shProg) {
850 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
851 }
852 }
853
854 /**
855 */
856 static bool
857 use_shader_program(struct gl_context *ctx, GLenum type,
858 struct gl_shader_program *shProg)
859 {
860 struct gl_shader_program **target;
861
862 switch (type) {
863 case GL_VERTEX_SHADER:
864 target = &ctx->Shader.CurrentVertexProgram;
865 if ((shProg == NULL)
866 || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) {
867 shProg = NULL;
868 }
869 break;
870 case GL_GEOMETRY_SHADER_ARB:
871 target = &ctx->Shader.CurrentGeometryProgram;
872 if ((shProg == NULL)
873 || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) {
874 shProg = NULL;
875 }
876 break;
877 case GL_FRAGMENT_SHADER:
878 target = &ctx->Shader.CurrentFragmentProgram;
879 if ((shProg == NULL)
880 || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) {
881 shProg = NULL;
882 }
883 break;
884 default:
885 return false;
886 }
887
888 if (*target != shProg) {
889 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
890
891 /* If the shader is also bound as the current rendering shader, unbind
892 * it from that binding point as well. This ensures that the correct
893 * semantics of glDeleteProgram are maintained.
894 */
895 switch (type) {
896 case GL_VERTEX_SHADER:
897 /* Empty for now. */
898 break;
899 case GL_GEOMETRY_SHADER_ARB:
900 /* Empty for now. */
901 break;
902 case GL_FRAGMENT_SHADER:
903 if (*target == ctx->Shader._CurrentFragmentProgram) {
904 _mesa_reference_shader_program(ctx,
905 &ctx->Shader._CurrentFragmentProgram,
906 NULL);
907 }
908 break;
909 }
910
911 _mesa_reference_shader_program(ctx, target, shProg);
912 return true;
913 }
914
915 return false;
916 }
917
918 /**
919 * Use the named shader program for subsequent rendering.
920 */
921 void
922 _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
923 {
924 use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
925 use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg);
926 use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg);
927 _mesa_active_program(ctx, shProg, "glUseProgram");
928
929 if (ctx->Driver.UseProgram)
930 ctx->Driver.UseProgram(ctx, shProg);
931 }
932
933
934 /**
935 * Do validation of the given shader program.
936 * \param errMsg returns error message if validation fails.
937 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
938 */
939 static GLboolean
940 validate_shader_program(const struct gl_shader_program *shProg,
941 char *errMsg)
942 {
943 if (!shProg->LinkStatus) {
944 return GL_FALSE;
945 }
946
947 /* From the GL spec, a program is invalid if any of these are true:
948
949 any two active samplers in the current program object are of
950 different types, but refer to the same texture image unit,
951
952 any active sampler in the current program object refers to a texture
953 image unit where fixed-function fragment processing accesses a
954 texture target that does not match the sampler type, or
955
956 the sum of the number of active samplers in the program and the
957 number of texture image units enabled for fixed-function fragment
958 processing exceeds the combined limit on the total number of texture
959 image units allowed.
960 */
961
962
963 /*
964 * Check: any two active samplers in the current program object are of
965 * different types, but refer to the same texture image unit,
966 */
967 if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
968 return GL_FALSE;
969
970 return GL_TRUE;
971 }
972
973
974 /**
975 * Called via glValidateProgram()
976 */
977 static void
978 validate_program(struct gl_context *ctx, GLuint program)
979 {
980 struct gl_shader_program *shProg;
981 char errMsg[100] = "";
982
983 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
984 if (!shProg) {
985 return;
986 }
987
988 shProg->Validated = validate_shader_program(shProg, errMsg);
989 if (!shProg->Validated) {
990 /* update info log */
991 if (shProg->InfoLog) {
992 ralloc_free(shProg->InfoLog);
993 }
994 shProg->InfoLog = ralloc_strdup(shProg, errMsg);
995 }
996 }
997
998
999
1000 void GLAPIENTRY
1001 _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1002 {
1003 GET_CURRENT_CONTEXT(ctx);
1004 attach_shader(ctx, program, shader);
1005 }
1006
1007
1008 void GLAPIENTRY
1009 _mesa_AttachShader(GLuint program, GLuint shader)
1010 {
1011 GET_CURRENT_CONTEXT(ctx);
1012 attach_shader(ctx, program, shader);
1013 }
1014
1015
1016 void GLAPIENTRY
1017 _mesa_CompileShader(GLhandleARB shaderObj)
1018 {
1019 GET_CURRENT_CONTEXT(ctx);
1020 if (MESA_VERBOSE & VERBOSE_API)
1021 _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
1022 compile_shader(ctx, shaderObj);
1023 }
1024
1025
1026 GLuint GLAPIENTRY
1027 _mesa_CreateShader(GLenum type)
1028 {
1029 GET_CURRENT_CONTEXT(ctx);
1030 if (MESA_VERBOSE & VERBOSE_API)
1031 _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type));
1032 return create_shader(ctx, type);
1033 }
1034
1035
1036 GLhandleARB GLAPIENTRY
1037 _mesa_CreateShaderObjectARB(GLenum type)
1038 {
1039 GET_CURRENT_CONTEXT(ctx);
1040 return create_shader(ctx, type);
1041 }
1042
1043
1044 GLuint GLAPIENTRY
1045 _mesa_CreateProgram(void)
1046 {
1047 GET_CURRENT_CONTEXT(ctx);
1048 if (MESA_VERBOSE & VERBOSE_API)
1049 _mesa_debug(ctx, "glCreateProgram\n");
1050 return create_shader_program(ctx);
1051 }
1052
1053
1054 GLhandleARB GLAPIENTRY
1055 _mesa_CreateProgramObjectARB(void)
1056 {
1057 GET_CURRENT_CONTEXT(ctx);
1058 return create_shader_program(ctx);
1059 }
1060
1061
1062 void GLAPIENTRY
1063 _mesa_DeleteObjectARB(GLhandleARB obj)
1064 {
1065 if (MESA_VERBOSE & VERBOSE_API) {
1066 GET_CURRENT_CONTEXT(ctx);
1067 _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj);
1068 }
1069
1070 if (obj) {
1071 GET_CURRENT_CONTEXT(ctx);
1072 FLUSH_VERTICES(ctx, 0);
1073 if (is_program(ctx, obj)) {
1074 delete_shader_program(ctx, obj);
1075 }
1076 else if (is_shader(ctx, obj)) {
1077 delete_shader(ctx, obj);
1078 }
1079 else {
1080 /* error? */
1081 }
1082 }
1083 }
1084
1085
1086 void GLAPIENTRY
1087 _mesa_DeleteProgram(GLuint name)
1088 {
1089 if (name) {
1090 GET_CURRENT_CONTEXT(ctx);
1091 FLUSH_VERTICES(ctx, 0);
1092 delete_shader_program(ctx, name);
1093 }
1094 }
1095
1096
1097 void GLAPIENTRY
1098 _mesa_DeleteShader(GLuint name)
1099 {
1100 if (name) {
1101 GET_CURRENT_CONTEXT(ctx);
1102 FLUSH_VERTICES(ctx, 0);
1103 delete_shader(ctx, name);
1104 }
1105 }
1106
1107
1108 void GLAPIENTRY
1109 _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1110 {
1111 GET_CURRENT_CONTEXT(ctx);
1112 detach_shader(ctx, program, shader);
1113 }
1114
1115
1116 void GLAPIENTRY
1117 _mesa_DetachShader(GLuint program, GLuint shader)
1118 {
1119 GET_CURRENT_CONTEXT(ctx);
1120 detach_shader(ctx, program, shader);
1121 }
1122
1123
1124 void GLAPIENTRY
1125 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1126 GLsizei * count, GLhandleARB * obj)
1127 {
1128 GET_CURRENT_CONTEXT(ctx);
1129 get_attached_shaders(ctx, container, maxCount, count, obj);
1130 }
1131
1132
1133 void GLAPIENTRY
1134 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1135 GLsizei *count, GLuint *obj)
1136 {
1137 GET_CURRENT_CONTEXT(ctx);
1138 get_attached_shaders(ctx, program, maxCount, count, obj);
1139 }
1140
1141
1142 void GLAPIENTRY
1143 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1144 GLcharARB * infoLog)
1145 {
1146 GET_CURRENT_CONTEXT(ctx);
1147 if (is_program(ctx, object)) {
1148 get_program_info_log(ctx, object, maxLength, length, infoLog);
1149 }
1150 else if (is_shader(ctx, object)) {
1151 get_shader_info_log(ctx, object, maxLength, length, infoLog);
1152 }
1153 else {
1154 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1155 }
1156 }
1157
1158
1159 void GLAPIENTRY
1160 _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1161 {
1162 GET_CURRENT_CONTEXT(ctx);
1163 /* Implement in terms of GetProgramiv, GetShaderiv */
1164 if (is_program(ctx, object)) {
1165 if (pname == GL_OBJECT_TYPE_ARB) {
1166 *params = GL_PROGRAM_OBJECT_ARB;
1167 }
1168 else {
1169 get_programiv(ctx, object, pname, params);
1170 }
1171 }
1172 else if (is_shader(ctx, object)) {
1173 if (pname == GL_OBJECT_TYPE_ARB) {
1174 *params = GL_SHADER_OBJECT_ARB;
1175 }
1176 else {
1177 get_shaderiv(ctx, object, pname, params);
1178 }
1179 }
1180 else {
1181 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1182 }
1183 }
1184
1185
1186 void GLAPIENTRY
1187 _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1188 GLfloat *params)
1189 {
1190 GLint iparams[1]; /* XXX is one element enough? */
1191 _mesa_GetObjectParameterivARB(object, pname, iparams);
1192 params[0] = (GLfloat) iparams[0];
1193 }
1194
1195
1196 void GLAPIENTRY
1197 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1198 {
1199 GET_CURRENT_CONTEXT(ctx);
1200 get_programiv(ctx, program, pname, params);
1201 }
1202
1203
1204 void GLAPIENTRY
1205 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1206 {
1207 GET_CURRENT_CONTEXT(ctx);
1208 get_shaderiv(ctx, shader, pname, params);
1209 }
1210
1211
1212 void GLAPIENTRY
1213 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1214 GLsizei *length, GLchar *infoLog)
1215 {
1216 GET_CURRENT_CONTEXT(ctx);
1217 get_program_info_log(ctx, program, bufSize, length, infoLog);
1218 }
1219
1220
1221 void GLAPIENTRY
1222 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1223 GLsizei *length, GLchar *infoLog)
1224 {
1225 GET_CURRENT_CONTEXT(ctx);
1226 get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1227 }
1228
1229
1230 void GLAPIENTRY
1231 _mesa_GetShaderSource(GLhandleARB shader, GLsizei maxLength,
1232 GLsizei *length, GLcharARB *sourceOut)
1233 {
1234 GET_CURRENT_CONTEXT(ctx);
1235 get_shader_source(ctx, shader, maxLength, length, sourceOut);
1236 }
1237
1238
1239 GLhandleARB GLAPIENTRY
1240 _mesa_GetHandleARB(GLenum pname)
1241 {
1242 GET_CURRENT_CONTEXT(ctx);
1243 return get_handle(ctx, pname);
1244 }
1245
1246
1247 GLboolean GLAPIENTRY
1248 _mesa_IsProgram(GLuint name)
1249 {
1250 GET_CURRENT_CONTEXT(ctx);
1251 return is_program(ctx, name);
1252 }
1253
1254
1255 GLboolean GLAPIENTRY
1256 _mesa_IsShader(GLuint name)
1257 {
1258 GET_CURRENT_CONTEXT(ctx);
1259 return is_shader(ctx, name);
1260 }
1261
1262
1263 void GLAPIENTRY
1264 _mesa_LinkProgram(GLhandleARB programObj)
1265 {
1266 GET_CURRENT_CONTEXT(ctx);
1267 link_program(ctx, programObj);
1268 }
1269
1270
1271
1272 /**
1273 * Read shader source code from a file.
1274 * Useful for debugging to override an app's shader.
1275 */
1276 static GLcharARB *
1277 read_shader(const char *fname)
1278 {
1279 const int max = 50*1000;
1280 FILE *f = fopen(fname, "r");
1281 GLcharARB *buffer, *shader;
1282 int len;
1283
1284 if (!f) {
1285 return NULL;
1286 }
1287
1288 buffer = malloc(max);
1289 len = fread(buffer, 1, max, f);
1290 buffer[len] = 0;
1291
1292 fclose(f);
1293
1294 shader = _mesa_strdup(buffer);
1295 free(buffer);
1296
1297 return shader;
1298 }
1299
1300
1301 /**
1302 * Called via glShaderSource() and glShaderSourceARB() API functions.
1303 * Basically, concatenate the source code strings into one long string
1304 * and pass it to _mesa_shader_source().
1305 */
1306 void GLAPIENTRY
1307 _mesa_ShaderSource(GLhandleARB shaderObj, GLsizei count,
1308 const GLcharARB * const * string, const GLint * length)
1309 {
1310 GET_CURRENT_CONTEXT(ctx);
1311 GLint *offsets;
1312 GLsizei i, totalLength;
1313 GLcharARB *source;
1314 GLuint checksum;
1315
1316 if (!shaderObj || string == NULL) {
1317 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
1318 return;
1319 }
1320
1321 /*
1322 * This array holds offsets of where the appropriate string ends, thus the
1323 * last element will be set to the total length of the source code.
1324 */
1325 offsets = malloc(count * sizeof(GLint));
1326 if (offsets == NULL) {
1327 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1328 return;
1329 }
1330
1331 for (i = 0; i < count; i++) {
1332 if (string[i] == NULL) {
1333 free((GLvoid *) offsets);
1334 _mesa_error(ctx, GL_INVALID_OPERATION,
1335 "glShaderSourceARB(null string)");
1336 return;
1337 }
1338 if (length == NULL || length[i] < 0)
1339 offsets[i] = strlen(string[i]);
1340 else
1341 offsets[i] = length[i];
1342 /* accumulate string lengths */
1343 if (i > 0)
1344 offsets[i] += offsets[i - 1];
1345 }
1346
1347 /* Total length of source string is sum off all strings plus two.
1348 * One extra byte for terminating zero, another extra byte to silence
1349 * valgrind warnings in the parser/grammer code.
1350 */
1351 totalLength = offsets[count - 1] + 2;
1352 source = malloc(totalLength * sizeof(GLcharARB));
1353 if (source == NULL) {
1354 free((GLvoid *) offsets);
1355 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1356 return;
1357 }
1358
1359 for (i = 0; i < count; i++) {
1360 GLint start = (i > 0) ? offsets[i - 1] : 0;
1361 memcpy(source + start, string[i],
1362 (offsets[i] - start) * sizeof(GLcharARB));
1363 }
1364 source[totalLength - 1] = '\0';
1365 source[totalLength - 2] = '\0';
1366
1367 if (SHADER_SUBST) {
1368 /* Compute the shader's source code checksum then try to open a file
1369 * named newshader_<CHECKSUM>. If it exists, use it in place of the
1370 * original shader source code. For debugging.
1371 */
1372 char filename[100];
1373 GLcharARB *newSource;
1374
1375 checksum = _mesa_str_checksum(source);
1376
1377 _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
1378
1379 newSource = read_shader(filename);
1380 if (newSource) {
1381 fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
1382 shaderObj, checksum, filename);
1383 free(source);
1384 source = newSource;
1385 }
1386 }
1387
1388 shader_source(ctx, shaderObj, source);
1389
1390 if (SHADER_SUBST) {
1391 struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
1392 if (sh)
1393 sh->SourceChecksum = checksum; /* save original checksum */
1394 }
1395
1396 free(offsets);
1397 }
1398
1399
1400 void GLAPIENTRY
1401 _mesa_UseProgram(GLhandleARB program)
1402 {
1403 GET_CURRENT_CONTEXT(ctx);
1404 struct gl_shader_program *shProg;
1405
1406 if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1407 _mesa_error(ctx, GL_INVALID_OPERATION,
1408 "glUseProgram(transform feedback active)");
1409 return;
1410 }
1411
1412 if (program) {
1413 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1414 if (!shProg) {
1415 return;
1416 }
1417 if (!shProg->LinkStatus) {
1418 _mesa_error(ctx, GL_INVALID_OPERATION,
1419 "glUseProgram(program %u not linked)", program);
1420 return;
1421 }
1422
1423 /* debug code */
1424 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1425 print_shader_info(shProg);
1426 }
1427 }
1428 else {
1429 shProg = NULL;
1430 }
1431
1432 _mesa_use_program(ctx, shProg);
1433 }
1434
1435
1436 void GLAPIENTRY
1437 _mesa_ValidateProgram(GLhandleARB program)
1438 {
1439 GET_CURRENT_CONTEXT(ctx);
1440 validate_program(ctx, program);
1441 }
1442
1443
1444 /**
1445 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1446 */
1447 void GLAPIENTRY
1448 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1449 GLint* range, GLint* precision)
1450 {
1451 const struct gl_program_constants *limits;
1452 const struct gl_precision *p;
1453 GET_CURRENT_CONTEXT(ctx);
1454
1455 switch (shadertype) {
1456 case GL_VERTEX_SHADER:
1457 limits = &ctx->Const.VertexProgram;
1458 break;
1459 case GL_FRAGMENT_SHADER:
1460 limits = &ctx->Const.FragmentProgram;
1461 break;
1462 default:
1463 _mesa_error(ctx, GL_INVALID_ENUM,
1464 "glGetShaderPrecisionFormat(shadertype)");
1465 return;
1466 }
1467
1468 switch (precisiontype) {
1469 case GL_LOW_FLOAT:
1470 p = &limits->LowFloat;
1471 break;
1472 case GL_MEDIUM_FLOAT:
1473 p = &limits->MediumFloat;
1474 break;
1475 case GL_HIGH_FLOAT:
1476 p = &limits->HighFloat;
1477 break;
1478 case GL_LOW_INT:
1479 p = &limits->LowInt;
1480 break;
1481 case GL_MEDIUM_INT:
1482 p = &limits->MediumInt;
1483 break;
1484 case GL_HIGH_INT:
1485 p = &limits->HighInt;
1486 break;
1487 default:
1488 _mesa_error(ctx, GL_INVALID_ENUM,
1489 "glGetShaderPrecisionFormat(precisiontype)");
1490 return;
1491 }
1492
1493 range[0] = p->RangeMin;
1494 range[1] = p->RangeMax;
1495 precision[0] = p->Precision;
1496 }
1497
1498
1499 /**
1500 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1501 */
1502 void GLAPIENTRY
1503 _mesa_ReleaseShaderCompiler(void)
1504 {
1505 _mesa_destroy_shader_compiler_caches();
1506 }
1507
1508
1509 /**
1510 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1511 */
1512 void GLAPIENTRY
1513 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1514 const void* binary, GLint length)
1515 {
1516 GET_CURRENT_CONTEXT(ctx);
1517 (void) n;
1518 (void) shaders;
1519 (void) binaryformat;
1520 (void) binary;
1521 (void) length;
1522 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1523 }
1524
1525
1526 void GLAPIENTRY
1527 _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
1528 GLenum *binaryFormat, GLvoid *binary)
1529 {
1530 struct gl_shader_program *shProg;
1531 GET_CURRENT_CONTEXT(ctx);
1532
1533 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
1534 if (!shProg)
1535 return;
1536
1537 if (!shProg->LinkStatus) {
1538 _mesa_error(ctx, GL_INVALID_OPERATION,
1539 "glGetProgramBinary(program %u not linked)",
1540 shProg->Name);
1541 return;
1542 }
1543
1544 if (bufSize < 0){
1545 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
1546 return;
1547 }
1548
1549 /* The ARB_get_program_binary spec says:
1550 *
1551 * "If <length> is NULL, then no length is returned."
1552 */
1553 if (length != NULL)
1554 *length = 0;
1555
1556 (void) binaryFormat;
1557 (void) binary;
1558 }
1559
1560 void GLAPIENTRY
1561 _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
1562 const GLvoid *binary, GLsizei length)
1563 {
1564 struct gl_shader_program *shProg;
1565 GET_CURRENT_CONTEXT(ctx);
1566
1567 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary");
1568 if (!shProg)
1569 return;
1570
1571 (void) binaryFormat;
1572 (void) binary;
1573 (void) length;
1574 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1575 }
1576
1577
1578 void GLAPIENTRY
1579 _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
1580 {
1581 struct gl_shader_program *shProg;
1582 GET_CURRENT_CONTEXT(ctx);
1583
1584 shProg = _mesa_lookup_shader_program_err(ctx, program,
1585 "glProgramParameteri");
1586 if (!shProg)
1587 return;
1588
1589 switch (pname) {
1590 case GL_GEOMETRY_VERTICES_OUT_ARB:
1591 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1592 break;
1593
1594 if (value < 1 ||
1595 (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
1596 _mesa_error(ctx, GL_INVALID_VALUE,
1597 "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
1598 value);
1599 return;
1600 }
1601 shProg->Geom.VerticesOut = value;
1602 return;
1603 case GL_GEOMETRY_INPUT_TYPE_ARB:
1604 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1605 break;
1606
1607 switch (value) {
1608 case GL_POINTS:
1609 case GL_LINES:
1610 case GL_LINES_ADJACENCY_ARB:
1611 case GL_TRIANGLES:
1612 case GL_TRIANGLES_ADJACENCY_ARB:
1613 shProg->Geom.InputType = value;
1614 break;
1615 default:
1616 _mesa_error(ctx, GL_INVALID_VALUE,
1617 "glProgramParameteri(geometry input type = %s",
1618 _mesa_lookup_enum_by_nr(value));
1619 return;
1620 }
1621 return;
1622 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
1623 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1624 break;
1625
1626 switch (value) {
1627 case GL_POINTS:
1628 case GL_LINE_STRIP:
1629 case GL_TRIANGLE_STRIP:
1630 shProg->Geom.OutputType = value;
1631 break;
1632 default:
1633 _mesa_error(ctx, GL_INVALID_VALUE,
1634 "glProgramParameteri(geometry output type = %s",
1635 _mesa_lookup_enum_by_nr(value));
1636 return;
1637 }
1638 return;
1639 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1640 /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
1641 * is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't
1642 * even be in the dispatch table, so we shouldn't need to expclicitly
1643 * check here.
1644 *
1645 * On desktop, we ignore the 3.0+ requirement because it is silly.
1646 */
1647
1648 /* The ARB_get_program_binary extension spec says:
1649 *
1650 * "An INVALID_VALUE error is generated if the <value> argument to
1651 * ProgramParameteri is not TRUE or FALSE."
1652 */
1653 if (value != GL_TRUE && value != GL_FALSE) {
1654 _mesa_error(ctx, GL_INVALID_VALUE,
1655 "glProgramParameteri(pname=%s, value=%d): "
1656 "value must be 0 or 1.",
1657 _mesa_lookup_enum_by_nr(pname),
1658 value);
1659 return;
1660 }
1661
1662 /* No need to notify the driver. Any changes will actually take effect
1663 * the next time the shader is linked.
1664 *
1665 * The ARB_get_program_binary extension spec says:
1666 *
1667 * "To indicate that a program binary is likely to be retrieved,
1668 * ProgramParameteri should be called with <pname>
1669 * PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
1670 * will not be in effect until the next time LinkProgram or
1671 * ProgramBinary has been called successfully."
1672 *
1673 * The resloution of issue 9 in the extension spec also says:
1674 *
1675 * "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
1676 * to indicate to the GL implementation that this program will
1677 * likely be saved with GetProgramBinary at some point. This will
1678 * give the GL implementation the opportunity to track any state
1679 * changes made to the program before being saved such that when it
1680 * is loaded again a recompile can be avoided."
1681 */
1682 shProg->BinaryRetreivableHint = value;
1683 return;
1684 default:
1685 break;
1686 }
1687
1688 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
1689 _mesa_lookup_enum_by_nr(pname));
1690 }
1691
1692 void
1693 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
1694 struct gl_shader_program *shProg)
1695 {
1696 use_shader_program(ctx, type, shProg);
1697
1698 if (ctx->Driver.UseProgram)
1699 ctx->Driver.UseProgram(ctx, shProg);
1700 }
1701
1702
1703 /**
1704 * For GL_EXT_separate_shader_objects
1705 */
1706 void GLAPIENTRY
1707 _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
1708 {
1709 GET_CURRENT_CONTEXT(ctx);
1710 struct gl_shader_program *shProg = NULL;
1711
1712 if (!validate_shader_target(ctx, type)) {
1713 _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
1714 return;
1715 }
1716
1717 if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1718 _mesa_error(ctx, GL_INVALID_OPERATION,
1719 "glUseShaderProgramEXT(transform feedback is active)");
1720 return;
1721 }
1722
1723 if (program) {
1724 shProg = _mesa_lookup_shader_program_err(ctx, program,
1725 "glUseShaderProgramEXT");
1726 if (shProg == NULL)
1727 return;
1728
1729 if (!shProg->LinkStatus) {
1730 _mesa_error(ctx, GL_INVALID_OPERATION,
1731 "glUseShaderProgramEXT(program not linked)");
1732 return;
1733 }
1734 }
1735
1736 _mesa_use_shader_program(ctx, type, shProg);
1737 }
1738
1739
1740 /**
1741 * For GL_EXT_separate_shader_objects
1742 */
1743 void GLAPIENTRY
1744 _mesa_ActiveProgramEXT(GLuint program)
1745 {
1746 GET_CURRENT_CONTEXT(ctx);
1747 struct gl_shader_program *shProg = (program != 0)
1748 ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
1749 : NULL;
1750
1751 _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
1752 return;
1753 }
1754
1755
1756 /**
1757 * For GL_EXT_separate_shader_objects
1758 */
1759 GLuint GLAPIENTRY
1760 _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
1761 {
1762 GET_CURRENT_CONTEXT(ctx);
1763 const GLuint shader = create_shader(ctx, type);
1764 GLuint program = 0;
1765
1766 if (shader) {
1767 shader_source(ctx, shader, _mesa_strdup(string));
1768 compile_shader(ctx, shader);
1769
1770 program = create_shader_program(ctx);
1771 if (program) {
1772 struct gl_shader_program *shProg;
1773 struct gl_shader *sh;
1774 GLint compiled = GL_FALSE;
1775
1776 shProg = _mesa_lookup_shader_program(ctx, program);
1777 sh = _mesa_lookup_shader(ctx, shader);
1778
1779 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
1780 if (compiled) {
1781 attach_shader(ctx, program, shader);
1782 link_program(ctx, program);
1783 detach_shader(ctx, program, shader);
1784
1785 #if 0
1786 /* Possibly... */
1787 if (active-user-defined-varyings-in-linked-program) {
1788 append-error-to-info-log;
1789 shProg->LinkStatus = GL_FALSE;
1790 }
1791 #endif
1792 }
1793
1794 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
1795 }
1796
1797 delete_shader(ctx, shader);
1798 }
1799
1800 return program;
1801 }