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