c05da10be6c39379609e7823ae22b2a5d2d62493
[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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file shaderapi.c
27 * \author Brian Paul
28 *
29 * Implementation of GLSL-related API functions.
30 * The glUniform* functions are in uniforms.c
31 *
32 *
33 * XXX things to do:
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
36 */
37
38
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/dispatch.h"
42 #include "main/enums.h"
43 #include "main/hash.h"
44 #include "main/mfeatures.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 const char *s;
820 switch (shProg->Shaders[i]->Type) {
821 case GL_VERTEX_SHADER:
822 s = "vertex";
823 break;
824 case GL_FRAGMENT_SHADER:
825 s = "fragment";
826 break;
827 case GL_GEOMETRY_SHADER:
828 s = "geometry";
829 break;
830 default:
831 s = "";
832 }
833 printf(" %s shader %u, checksum %u\n", s,
834 shProg->Shaders[i]->Name,
835 shProg->Shaders[i]->SourceChecksum);
836 }
837 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
838 printf(" vert prog %u\n",
839 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
840 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
841 printf(" frag prog %u\n",
842 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
843 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
844 printf(" geom prog %u\n",
845 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
846 }
847
848
849 /**
850 * Use the named shader program for subsequent glUniform calls
851 */
852 void
853 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
854 const char *caller)
855 {
856 if ((shProg != NULL) && !shProg->LinkStatus) {
857 _mesa_error(ctx, GL_INVALID_OPERATION,
858 "%s(program %u not linked)", caller, shProg->Name);
859 return;
860 }
861
862 if (ctx->Shader.ActiveProgram != shProg) {
863 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
864 }
865 }
866
867 /**
868 */
869 static bool
870 use_shader_program(struct gl_context *ctx, GLenum type,
871 struct gl_shader_program *shProg)
872 {
873 struct gl_shader_program **target;
874
875 switch (type) {
876 case GL_VERTEX_SHADER:
877 target = &ctx->Shader.CurrentVertexProgram;
878 if ((shProg == NULL)
879 || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) {
880 shProg = NULL;
881 }
882 break;
883 case GL_GEOMETRY_SHADER_ARB:
884 target = &ctx->Shader.CurrentGeometryProgram;
885 if ((shProg == NULL)
886 || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) {
887 shProg = NULL;
888 }
889 break;
890 case GL_FRAGMENT_SHADER:
891 target = &ctx->Shader.CurrentFragmentProgram;
892 if ((shProg == NULL)
893 || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) {
894 shProg = NULL;
895 }
896 break;
897 default:
898 return false;
899 }
900
901 if (*target != shProg) {
902 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
903
904 /* If the shader is also bound as the current rendering shader, unbind
905 * it from that binding point as well. This ensures that the correct
906 * semantics of glDeleteProgram are maintained.
907 */
908 switch (type) {
909 case GL_VERTEX_SHADER:
910 /* Empty for now. */
911 break;
912 case GL_GEOMETRY_SHADER_ARB:
913 /* Empty for now. */
914 break;
915 case GL_FRAGMENT_SHADER:
916 if (*target == ctx->Shader._CurrentFragmentProgram) {
917 _mesa_reference_shader_program(ctx,
918 &ctx->Shader._CurrentFragmentProgram,
919 NULL);
920 }
921 break;
922 }
923
924 _mesa_reference_shader_program(ctx, target, shProg);
925 return true;
926 }
927
928 return false;
929 }
930
931 /**
932 * Use the named shader program for subsequent rendering.
933 */
934 void
935 _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
936 {
937 use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
938 use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg);
939 use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg);
940 _mesa_active_program(ctx, shProg, "glUseProgram");
941
942 if (ctx->Driver.UseProgram)
943 ctx->Driver.UseProgram(ctx, shProg);
944 }
945
946
947 /**
948 * Do validation of the given shader program.
949 * \param errMsg returns error message if validation fails.
950 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
951 */
952 static GLboolean
953 validate_shader_program(const struct gl_shader_program *shProg,
954 char *errMsg)
955 {
956 if (!shProg->LinkStatus) {
957 return GL_FALSE;
958 }
959
960 /* From the GL spec, a program is invalid if any of these are true:
961
962 any two active samplers in the current program object are of
963 different types, but refer to the same texture image unit,
964
965 any active sampler in the current program object refers to a texture
966 image unit where fixed-function fragment processing accesses a
967 texture target that does not match the sampler type, or
968
969 the sum of the number of active samplers in the program and the
970 number of texture image units enabled for fixed-function fragment
971 processing exceeds the combined limit on the total number of texture
972 image units allowed.
973 */
974
975
976 /*
977 * Check: any two active samplers in the current program object are of
978 * different types, but refer to the same texture image unit,
979 */
980 if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
981 return GL_FALSE;
982
983 return GL_TRUE;
984 }
985
986
987 /**
988 * Called via glValidateProgram()
989 */
990 static void
991 validate_program(struct gl_context *ctx, GLuint program)
992 {
993 struct gl_shader_program *shProg;
994 char errMsg[100] = "";
995
996 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
997 if (!shProg) {
998 return;
999 }
1000
1001 shProg->Validated = validate_shader_program(shProg, errMsg);
1002 if (!shProg->Validated) {
1003 /* update info log */
1004 if (shProg->InfoLog) {
1005 ralloc_free(shProg->InfoLog);
1006 }
1007 shProg->InfoLog = ralloc_strdup(shProg, errMsg);
1008 }
1009 }
1010
1011
1012
1013 void GLAPIENTRY
1014 _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1015 {
1016 GET_CURRENT_CONTEXT(ctx);
1017 attach_shader(ctx, program, shader);
1018 }
1019
1020
1021 void GLAPIENTRY
1022 _mesa_AttachShader(GLuint program, GLuint shader)
1023 {
1024 GET_CURRENT_CONTEXT(ctx);
1025 attach_shader(ctx, program, shader);
1026 }
1027
1028
1029 void GLAPIENTRY
1030 _mesa_CompileShader(GLhandleARB shaderObj)
1031 {
1032 GET_CURRENT_CONTEXT(ctx);
1033 if (MESA_VERBOSE & VERBOSE_API)
1034 _mesa_debug(ctx, "glCompileShader %u\n", shaderObj);
1035 compile_shader(ctx, shaderObj);
1036 }
1037
1038
1039 GLuint GLAPIENTRY
1040 _mesa_CreateShader(GLenum type)
1041 {
1042 GET_CURRENT_CONTEXT(ctx);
1043 if (MESA_VERBOSE & VERBOSE_API)
1044 _mesa_debug(ctx, "glCreateShader %s\n", _mesa_lookup_enum_by_nr(type));
1045 return create_shader(ctx, type);
1046 }
1047
1048
1049 GLhandleARB GLAPIENTRY
1050 _mesa_CreateShaderObjectARB(GLenum type)
1051 {
1052 GET_CURRENT_CONTEXT(ctx);
1053 return create_shader(ctx, type);
1054 }
1055
1056
1057 GLuint GLAPIENTRY
1058 _mesa_CreateProgram(void)
1059 {
1060 GET_CURRENT_CONTEXT(ctx);
1061 if (MESA_VERBOSE & VERBOSE_API)
1062 _mesa_debug(ctx, "glCreateProgram\n");
1063 return create_shader_program(ctx);
1064 }
1065
1066
1067 GLhandleARB GLAPIENTRY
1068 _mesa_CreateProgramObjectARB(void)
1069 {
1070 GET_CURRENT_CONTEXT(ctx);
1071 return create_shader_program(ctx);
1072 }
1073
1074
1075 void GLAPIENTRY
1076 _mesa_DeleteObjectARB(GLhandleARB obj)
1077 {
1078 if (MESA_VERBOSE & VERBOSE_API) {
1079 GET_CURRENT_CONTEXT(ctx);
1080 _mesa_debug(ctx, "glDeleteObjectARB(%u)\n", obj);
1081 }
1082
1083 if (obj) {
1084 GET_CURRENT_CONTEXT(ctx);
1085 FLUSH_VERTICES(ctx, 0);
1086 if (is_program(ctx, obj)) {
1087 delete_shader_program(ctx, obj);
1088 }
1089 else if (is_shader(ctx, obj)) {
1090 delete_shader(ctx, obj);
1091 }
1092 else {
1093 /* error? */
1094 }
1095 }
1096 }
1097
1098
1099 void GLAPIENTRY
1100 _mesa_DeleteProgram(GLuint name)
1101 {
1102 if (name) {
1103 GET_CURRENT_CONTEXT(ctx);
1104 FLUSH_VERTICES(ctx, 0);
1105 delete_shader_program(ctx, name);
1106 }
1107 }
1108
1109
1110 void GLAPIENTRY
1111 _mesa_DeleteShader(GLuint name)
1112 {
1113 if (name) {
1114 GET_CURRENT_CONTEXT(ctx);
1115 FLUSH_VERTICES(ctx, 0);
1116 delete_shader(ctx, name);
1117 }
1118 }
1119
1120
1121 void GLAPIENTRY
1122 _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1123 {
1124 GET_CURRENT_CONTEXT(ctx);
1125 detach_shader(ctx, program, shader);
1126 }
1127
1128
1129 void GLAPIENTRY
1130 _mesa_DetachShader(GLuint program, GLuint shader)
1131 {
1132 GET_CURRENT_CONTEXT(ctx);
1133 detach_shader(ctx, program, shader);
1134 }
1135
1136
1137 void GLAPIENTRY
1138 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1139 GLsizei * count, GLhandleARB * obj)
1140 {
1141 GET_CURRENT_CONTEXT(ctx);
1142 get_attached_shaders(ctx, container, maxCount, count, obj);
1143 }
1144
1145
1146 void GLAPIENTRY
1147 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1148 GLsizei *count, GLuint *obj)
1149 {
1150 GET_CURRENT_CONTEXT(ctx);
1151 get_attached_shaders(ctx, program, maxCount, count, obj);
1152 }
1153
1154
1155 void GLAPIENTRY
1156 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1157 GLcharARB * infoLog)
1158 {
1159 GET_CURRENT_CONTEXT(ctx);
1160 if (is_program(ctx, object)) {
1161 get_program_info_log(ctx, object, maxLength, length, infoLog);
1162 }
1163 else if (is_shader(ctx, object)) {
1164 get_shader_info_log(ctx, object, maxLength, length, infoLog);
1165 }
1166 else {
1167 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1168 }
1169 }
1170
1171
1172 void GLAPIENTRY
1173 _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1174 {
1175 GET_CURRENT_CONTEXT(ctx);
1176 /* Implement in terms of GetProgramiv, GetShaderiv */
1177 if (is_program(ctx, object)) {
1178 if (pname == GL_OBJECT_TYPE_ARB) {
1179 *params = GL_PROGRAM_OBJECT_ARB;
1180 }
1181 else {
1182 get_programiv(ctx, object, pname, params);
1183 }
1184 }
1185 else if (is_shader(ctx, object)) {
1186 if (pname == GL_OBJECT_TYPE_ARB) {
1187 *params = GL_SHADER_OBJECT_ARB;
1188 }
1189 else {
1190 get_shaderiv(ctx, object, pname, params);
1191 }
1192 }
1193 else {
1194 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1195 }
1196 }
1197
1198
1199 void GLAPIENTRY
1200 _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1201 GLfloat *params)
1202 {
1203 GLint iparams[1]; /* XXX is one element enough? */
1204 _mesa_GetObjectParameterivARB(object, pname, iparams);
1205 params[0] = (GLfloat) iparams[0];
1206 }
1207
1208
1209 void GLAPIENTRY
1210 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1211 {
1212 GET_CURRENT_CONTEXT(ctx);
1213 get_programiv(ctx, program, pname, params);
1214 }
1215
1216
1217 void GLAPIENTRY
1218 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1219 {
1220 GET_CURRENT_CONTEXT(ctx);
1221 get_shaderiv(ctx, shader, pname, params);
1222 }
1223
1224
1225 void GLAPIENTRY
1226 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1227 GLsizei *length, GLchar *infoLog)
1228 {
1229 GET_CURRENT_CONTEXT(ctx);
1230 get_program_info_log(ctx, program, bufSize, length, infoLog);
1231 }
1232
1233
1234 void GLAPIENTRY
1235 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1236 GLsizei *length, GLchar *infoLog)
1237 {
1238 GET_CURRENT_CONTEXT(ctx);
1239 get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1240 }
1241
1242
1243 void GLAPIENTRY
1244 _mesa_GetShaderSource(GLhandleARB shader, GLsizei maxLength,
1245 GLsizei *length, GLcharARB *sourceOut)
1246 {
1247 GET_CURRENT_CONTEXT(ctx);
1248 get_shader_source(ctx, shader, maxLength, length, sourceOut);
1249 }
1250
1251
1252 GLhandleARB GLAPIENTRY
1253 _mesa_GetHandleARB(GLenum pname)
1254 {
1255 GET_CURRENT_CONTEXT(ctx);
1256 return get_handle(ctx, pname);
1257 }
1258
1259
1260 GLboolean GLAPIENTRY
1261 _mesa_IsProgram(GLuint name)
1262 {
1263 GET_CURRENT_CONTEXT(ctx);
1264 return is_program(ctx, name);
1265 }
1266
1267
1268 GLboolean GLAPIENTRY
1269 _mesa_IsShader(GLuint name)
1270 {
1271 GET_CURRENT_CONTEXT(ctx);
1272 return is_shader(ctx, name);
1273 }
1274
1275
1276 void GLAPIENTRY
1277 _mesa_LinkProgram(GLhandleARB programObj)
1278 {
1279 GET_CURRENT_CONTEXT(ctx);
1280 link_program(ctx, programObj);
1281 }
1282
1283
1284
1285 /**
1286 * Read shader source code from a file.
1287 * Useful for debugging to override an app's shader.
1288 */
1289 static GLcharARB *
1290 read_shader(const char *fname)
1291 {
1292 const int max = 50*1000;
1293 FILE *f = fopen(fname, "r");
1294 GLcharARB *buffer, *shader;
1295 int len;
1296
1297 if (!f) {
1298 return NULL;
1299 }
1300
1301 buffer = malloc(max);
1302 len = fread(buffer, 1, max, f);
1303 buffer[len] = 0;
1304
1305 fclose(f);
1306
1307 shader = _mesa_strdup(buffer);
1308 free(buffer);
1309
1310 return shader;
1311 }
1312
1313
1314 /**
1315 * Called via glShaderSource() and glShaderSourceARB() API functions.
1316 * Basically, concatenate the source code strings into one long string
1317 * and pass it to _mesa_shader_source().
1318 */
1319 void GLAPIENTRY
1320 _mesa_ShaderSource(GLhandleARB shaderObj, GLsizei count,
1321 const GLcharARB * const * string, const GLint * length)
1322 {
1323 GET_CURRENT_CONTEXT(ctx);
1324 GLint *offsets;
1325 GLsizei i, totalLength;
1326 GLcharARB *source;
1327 GLuint checksum;
1328
1329 if (!shaderObj || string == NULL) {
1330 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
1331 return;
1332 }
1333
1334 /*
1335 * This array holds offsets of where the appropriate string ends, thus the
1336 * last element will be set to the total length of the source code.
1337 */
1338 offsets = malloc(count * sizeof(GLint));
1339 if (offsets == NULL) {
1340 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1341 return;
1342 }
1343
1344 for (i = 0; i < count; i++) {
1345 if (string[i] == NULL) {
1346 free((GLvoid *) offsets);
1347 _mesa_error(ctx, GL_INVALID_OPERATION,
1348 "glShaderSourceARB(null string)");
1349 return;
1350 }
1351 if (length == NULL || length[i] < 0)
1352 offsets[i] = strlen(string[i]);
1353 else
1354 offsets[i] = length[i];
1355 /* accumulate string lengths */
1356 if (i > 0)
1357 offsets[i] += offsets[i - 1];
1358 }
1359
1360 /* Total length of source string is sum off all strings plus two.
1361 * One extra byte for terminating zero, another extra byte to silence
1362 * valgrind warnings in the parser/grammer code.
1363 */
1364 totalLength = offsets[count - 1] + 2;
1365 source = malloc(totalLength * sizeof(GLcharARB));
1366 if (source == NULL) {
1367 free((GLvoid *) offsets);
1368 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1369 return;
1370 }
1371
1372 for (i = 0; i < count; i++) {
1373 GLint start = (i > 0) ? offsets[i - 1] : 0;
1374 memcpy(source + start, string[i],
1375 (offsets[i] - start) * sizeof(GLcharARB));
1376 }
1377 source[totalLength - 1] = '\0';
1378 source[totalLength - 2] = '\0';
1379
1380 if (SHADER_SUBST) {
1381 /* Compute the shader's source code checksum then try to open a file
1382 * named newshader_<CHECKSUM>. If it exists, use it in place of the
1383 * original shader source code. For debugging.
1384 */
1385 char filename[100];
1386 GLcharARB *newSource;
1387
1388 checksum = _mesa_str_checksum(source);
1389
1390 _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
1391
1392 newSource = read_shader(filename);
1393 if (newSource) {
1394 fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
1395 shaderObj, checksum, filename);
1396 free(source);
1397 source = newSource;
1398 }
1399 }
1400
1401 shader_source(ctx, shaderObj, source);
1402
1403 if (SHADER_SUBST) {
1404 struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
1405 if (sh)
1406 sh->SourceChecksum = checksum; /* save original checksum */
1407 }
1408
1409 free(offsets);
1410 }
1411
1412
1413 void GLAPIENTRY
1414 _mesa_UseProgram(GLhandleARB program)
1415 {
1416 GET_CURRENT_CONTEXT(ctx);
1417 struct gl_shader_program *shProg;
1418
1419 if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1420 _mesa_error(ctx, GL_INVALID_OPERATION,
1421 "glUseProgram(transform feedback active)");
1422 return;
1423 }
1424
1425 if (program) {
1426 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1427 if (!shProg) {
1428 return;
1429 }
1430 if (!shProg->LinkStatus) {
1431 _mesa_error(ctx, GL_INVALID_OPERATION,
1432 "glUseProgram(program %u not linked)", program);
1433 return;
1434 }
1435
1436 /* debug code */
1437 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1438 print_shader_info(shProg);
1439 }
1440 }
1441 else {
1442 shProg = NULL;
1443 }
1444
1445 _mesa_use_program(ctx, shProg);
1446 }
1447
1448
1449 void GLAPIENTRY
1450 _mesa_ValidateProgram(GLhandleARB program)
1451 {
1452 GET_CURRENT_CONTEXT(ctx);
1453 validate_program(ctx, program);
1454 }
1455
1456
1457 /**
1458 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1459 */
1460 void GLAPIENTRY
1461 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1462 GLint* range, GLint* precision)
1463 {
1464 const struct gl_program_constants *limits;
1465 const struct gl_precision *p;
1466 GET_CURRENT_CONTEXT(ctx);
1467
1468 switch (shadertype) {
1469 case GL_VERTEX_SHADER:
1470 limits = &ctx->Const.VertexProgram;
1471 break;
1472 case GL_FRAGMENT_SHADER:
1473 limits = &ctx->Const.FragmentProgram;
1474 break;
1475 default:
1476 _mesa_error(ctx, GL_INVALID_ENUM,
1477 "glGetShaderPrecisionFormat(shadertype)");
1478 return;
1479 }
1480
1481 switch (precisiontype) {
1482 case GL_LOW_FLOAT:
1483 p = &limits->LowFloat;
1484 break;
1485 case GL_MEDIUM_FLOAT:
1486 p = &limits->MediumFloat;
1487 break;
1488 case GL_HIGH_FLOAT:
1489 p = &limits->HighFloat;
1490 break;
1491 case GL_LOW_INT:
1492 p = &limits->LowInt;
1493 break;
1494 case GL_MEDIUM_INT:
1495 p = &limits->MediumInt;
1496 break;
1497 case GL_HIGH_INT:
1498 p = &limits->HighInt;
1499 break;
1500 default:
1501 _mesa_error(ctx, GL_INVALID_ENUM,
1502 "glGetShaderPrecisionFormat(precisiontype)");
1503 return;
1504 }
1505
1506 range[0] = p->RangeMin;
1507 range[1] = p->RangeMax;
1508 precision[0] = p->Precision;
1509 }
1510
1511
1512 /**
1513 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1514 */
1515 void GLAPIENTRY
1516 _mesa_ReleaseShaderCompiler(void)
1517 {
1518 _mesa_destroy_shader_compiler_caches();
1519 }
1520
1521
1522 /**
1523 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1524 */
1525 void GLAPIENTRY
1526 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1527 const void* binary, GLint length)
1528 {
1529 GET_CURRENT_CONTEXT(ctx);
1530 (void) n;
1531 (void) shaders;
1532 (void) binaryformat;
1533 (void) binary;
1534 (void) length;
1535 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1536 }
1537
1538
1539 void GLAPIENTRY
1540 _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
1541 GLenum *binaryFormat, GLvoid *binary)
1542 {
1543 struct gl_shader_program *shProg;
1544 GET_CURRENT_CONTEXT(ctx);
1545
1546 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
1547 if (!shProg)
1548 return;
1549
1550 if (!shProg->LinkStatus) {
1551 _mesa_error(ctx, GL_INVALID_OPERATION,
1552 "glGetProgramBinary(program %u not linked)",
1553 shProg->Name);
1554 return;
1555 }
1556
1557 if (bufSize < 0){
1558 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
1559 return;
1560 }
1561
1562 /* The ARB_get_program_binary spec says:
1563 *
1564 * "If <length> is NULL, then no length is returned."
1565 */
1566 if (length != NULL)
1567 *length = 0;
1568
1569 (void) binaryFormat;
1570 (void) binary;
1571 }
1572
1573 void GLAPIENTRY
1574 _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
1575 const GLvoid *binary, GLsizei length)
1576 {
1577 struct gl_shader_program *shProg;
1578 GET_CURRENT_CONTEXT(ctx);
1579
1580 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary");
1581 if (!shProg)
1582 return;
1583
1584 (void) binaryFormat;
1585 (void) binary;
1586 (void) length;
1587 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1588 }
1589
1590
1591 void GLAPIENTRY
1592 _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
1593 {
1594 struct gl_shader_program *shProg;
1595 GET_CURRENT_CONTEXT(ctx);
1596
1597 shProg = _mesa_lookup_shader_program_err(ctx, program,
1598 "glProgramParameteri");
1599 if (!shProg)
1600 return;
1601
1602 switch (pname) {
1603 case GL_GEOMETRY_VERTICES_OUT_ARB:
1604 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1605 break;
1606
1607 if (value < 1 ||
1608 (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
1609 _mesa_error(ctx, GL_INVALID_VALUE,
1610 "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
1611 value);
1612 return;
1613 }
1614 shProg->Geom.VerticesOut = value;
1615 return;
1616 case GL_GEOMETRY_INPUT_TYPE_ARB:
1617 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1618 break;
1619
1620 switch (value) {
1621 case GL_POINTS:
1622 case GL_LINES:
1623 case GL_LINES_ADJACENCY_ARB:
1624 case GL_TRIANGLES:
1625 case GL_TRIANGLES_ADJACENCY_ARB:
1626 shProg->Geom.InputType = value;
1627 break;
1628 default:
1629 _mesa_error(ctx, GL_INVALID_VALUE,
1630 "glProgramParameteri(geometry input type = %s",
1631 _mesa_lookup_enum_by_nr(value));
1632 return;
1633 }
1634 return;
1635 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
1636 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1637 break;
1638
1639 switch (value) {
1640 case GL_POINTS:
1641 case GL_LINE_STRIP:
1642 case GL_TRIANGLE_STRIP:
1643 shProg->Geom.OutputType = value;
1644 break;
1645 default:
1646 _mesa_error(ctx, GL_INVALID_VALUE,
1647 "glProgramParameteri(geometry output type = %s",
1648 _mesa_lookup_enum_by_nr(value));
1649 return;
1650 }
1651 return;
1652 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1653 /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
1654 * is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't
1655 * even be in the dispatch table, so we shouldn't need to expclicitly
1656 * check here.
1657 *
1658 * On desktop, we ignore the 3.0+ requirement because it is silly.
1659 */
1660
1661 /* The ARB_get_program_binary extension spec says:
1662 *
1663 * "An INVALID_VALUE error is generated if the <value> argument to
1664 * ProgramParameteri is not TRUE or FALSE."
1665 */
1666 if (value != GL_TRUE && value != GL_FALSE) {
1667 _mesa_error(ctx, GL_INVALID_VALUE,
1668 "glProgramParameteri(pname=%s, value=%d): "
1669 "value must be 0 or 1.",
1670 _mesa_lookup_enum_by_nr(pname),
1671 value);
1672 return;
1673 }
1674
1675 /* No need to notify the driver. Any changes will actually take effect
1676 * the next time the shader is linked.
1677 *
1678 * The ARB_get_program_binary extension spec says:
1679 *
1680 * "To indicate that a program binary is likely to be retrieved,
1681 * ProgramParameteri should be called with <pname>
1682 * PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
1683 * will not be in effect until the next time LinkProgram or
1684 * ProgramBinary has been called successfully."
1685 *
1686 * The resloution of issue 9 in the extension spec also says:
1687 *
1688 * "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
1689 * to indicate to the GL implementation that this program will
1690 * likely be saved with GetProgramBinary at some point. This will
1691 * give the GL implementation the opportunity to track any state
1692 * changes made to the program before being saved such that when it
1693 * is loaded again a recompile can be avoided."
1694 */
1695 shProg->BinaryRetreivableHint = value;
1696 return;
1697 default:
1698 break;
1699 }
1700
1701 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
1702 _mesa_lookup_enum_by_nr(pname));
1703 }
1704
1705 void
1706 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
1707 struct gl_shader_program *shProg)
1708 {
1709 use_shader_program(ctx, type, shProg);
1710
1711 if (ctx->Driver.UseProgram)
1712 ctx->Driver.UseProgram(ctx, shProg);
1713 }
1714
1715
1716 /**
1717 * For GL_EXT_separate_shader_objects
1718 */
1719 void GLAPIENTRY
1720 _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
1721 {
1722 GET_CURRENT_CONTEXT(ctx);
1723 struct gl_shader_program *shProg = NULL;
1724
1725 if (!validate_shader_target(ctx, type)) {
1726 _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
1727 return;
1728 }
1729
1730 if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1731 _mesa_error(ctx, GL_INVALID_OPERATION,
1732 "glUseShaderProgramEXT(transform feedback is active)");
1733 return;
1734 }
1735
1736 if (program) {
1737 shProg = _mesa_lookup_shader_program_err(ctx, program,
1738 "glUseShaderProgramEXT");
1739 if (shProg == NULL)
1740 return;
1741
1742 if (!shProg->LinkStatus) {
1743 _mesa_error(ctx, GL_INVALID_OPERATION,
1744 "glUseShaderProgramEXT(program not linked)");
1745 return;
1746 }
1747 }
1748
1749 _mesa_use_shader_program(ctx, type, shProg);
1750 }
1751
1752
1753 /**
1754 * For GL_EXT_separate_shader_objects
1755 */
1756 void GLAPIENTRY
1757 _mesa_ActiveProgramEXT(GLuint program)
1758 {
1759 GET_CURRENT_CONTEXT(ctx);
1760 struct gl_shader_program *shProg = (program != 0)
1761 ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
1762 : NULL;
1763
1764 _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
1765 return;
1766 }
1767
1768
1769 /**
1770 * For GL_EXT_separate_shader_objects
1771 */
1772 GLuint GLAPIENTRY
1773 _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
1774 {
1775 GET_CURRENT_CONTEXT(ctx);
1776 const GLuint shader = create_shader(ctx, type);
1777 GLuint program = 0;
1778
1779 if (shader) {
1780 shader_source(ctx, shader, _mesa_strdup(string));
1781 compile_shader(ctx, shader);
1782
1783 program = create_shader_program(ctx);
1784 if (program) {
1785 struct gl_shader_program *shProg;
1786 struct gl_shader *sh;
1787 GLint compiled = GL_FALSE;
1788
1789 shProg = _mesa_lookup_shader_program(ctx, program);
1790 sh = _mesa_lookup_shader(ctx, shader);
1791
1792 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
1793 if (compiled) {
1794 attach_shader(ctx, program, shader);
1795 link_program(ctx, program);
1796 detach_shader(ctx, program, shader);
1797
1798 #if 0
1799 /* Possibly... */
1800 if (active-user-defined-varyings-in-linked-program) {
1801 append-error-to-info-log;
1802 shProg->LinkStatus = GL_FALSE;
1803 }
1804 #endif
1805 }
1806
1807 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
1808 }
1809
1810 delete_shader(ctx, shader);
1811 }
1812
1813 return program;
1814 }