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