mesa: Add skeleton implementation of glGetInternalformativ
[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 ASSERT_OUTSIDE_BEGIN_END(ctx);
1404
1405 if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1406 _mesa_error(ctx, GL_INVALID_OPERATION,
1407 "glUseProgram(transform feedback active)");
1408 return;
1409 }
1410
1411 if (program) {
1412 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1413 if (!shProg) {
1414 return;
1415 }
1416 if (!shProg->LinkStatus) {
1417 _mesa_error(ctx, GL_INVALID_OPERATION,
1418 "glUseProgram(program %u not linked)", program);
1419 return;
1420 }
1421
1422 /* debug code */
1423 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1424 print_shader_info(shProg);
1425 }
1426 }
1427 else {
1428 shProg = NULL;
1429 }
1430
1431 _mesa_use_program(ctx, shProg);
1432 }
1433
1434
1435 void GLAPIENTRY
1436 _mesa_ValidateProgram(GLhandleARB program)
1437 {
1438 GET_CURRENT_CONTEXT(ctx);
1439 validate_program(ctx, program);
1440 }
1441
1442 #ifdef FEATURE_ES2
1443
1444 void GLAPIENTRY
1445 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1446 GLint* range, GLint* precision)
1447 {
1448 const struct gl_program_constants *limits;
1449 const struct gl_precision *p;
1450 GET_CURRENT_CONTEXT(ctx);
1451
1452 switch (shadertype) {
1453 case GL_VERTEX_SHADER:
1454 limits = &ctx->Const.VertexProgram;
1455 break;
1456 case GL_FRAGMENT_SHADER:
1457 limits = &ctx->Const.FragmentProgram;
1458 break;
1459 default:
1460 _mesa_error(ctx, GL_INVALID_ENUM,
1461 "glGetShaderPrecisionFormat(shadertype)");
1462 return;
1463 }
1464
1465 switch (precisiontype) {
1466 case GL_LOW_FLOAT:
1467 p = &limits->LowFloat;
1468 break;
1469 case GL_MEDIUM_FLOAT:
1470 p = &limits->MediumFloat;
1471 break;
1472 case GL_HIGH_FLOAT:
1473 p = &limits->HighFloat;
1474 break;
1475 case GL_LOW_INT:
1476 p = &limits->LowInt;
1477 break;
1478 case GL_MEDIUM_INT:
1479 p = &limits->MediumInt;
1480 break;
1481 case GL_HIGH_INT:
1482 p = &limits->HighInt;
1483 break;
1484 default:
1485 _mesa_error(ctx, GL_INVALID_ENUM,
1486 "glGetShaderPrecisionFormat(precisiontype)");
1487 return;
1488 }
1489
1490 range[0] = p->RangeMin;
1491 range[1] = p->RangeMax;
1492 precision[0] = p->Precision;
1493 }
1494
1495
1496 void GLAPIENTRY
1497 _mesa_ReleaseShaderCompiler(void)
1498 {
1499 _mesa_destroy_shader_compiler_caches();
1500 }
1501
1502
1503 void GLAPIENTRY
1504 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1505 const void* binary, GLint length)
1506 {
1507 GET_CURRENT_CONTEXT(ctx);
1508 (void) n;
1509 (void) shaders;
1510 (void) binaryformat;
1511 (void) binary;
1512 (void) length;
1513 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1514 }
1515
1516 #endif /* FEATURE_ES2 */
1517
1518 void GLAPIENTRY
1519 _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length,
1520 GLenum *binaryFormat, GLvoid *binary)
1521 {
1522 struct gl_shader_program *shProg;
1523 GET_CURRENT_CONTEXT(ctx);
1524
1525 ASSERT_OUTSIDE_BEGIN_END(ctx);
1526
1527 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary");
1528 if (!shProg)
1529 return;
1530
1531 if (!shProg->LinkStatus) {
1532 _mesa_error(ctx, GL_INVALID_OPERATION,
1533 "glGetProgramBinary(program %u not linked)",
1534 shProg->Name);
1535 return;
1536 }
1537
1538 if (bufSize < 0){
1539 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)");
1540 return;
1541 }
1542
1543 /* The ARB_get_program_binary spec says:
1544 *
1545 * "If <length> is NULL, then no length is returned."
1546 */
1547 if (length != NULL)
1548 *length = 0;
1549
1550 (void) binaryFormat;
1551 (void) binary;
1552 }
1553
1554 void GLAPIENTRY
1555 _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
1556 const GLvoid *binary, GLsizei length)
1557 {
1558 struct gl_shader_program *shProg;
1559 GET_CURRENT_CONTEXT(ctx);
1560
1561 ASSERT_OUTSIDE_BEGIN_END(ctx);
1562
1563 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramBinary");
1564 if (!shProg)
1565 return;
1566
1567 (void) binaryFormat;
1568 (void) binary;
1569 (void) length;
1570 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1571 }
1572
1573
1574 void GLAPIENTRY
1575 _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
1576 {
1577 struct gl_shader_program *shProg;
1578 GET_CURRENT_CONTEXT(ctx);
1579
1580 ASSERT_OUTSIDE_BEGIN_END(ctx);
1581
1582 shProg = _mesa_lookup_shader_program_err(ctx, program,
1583 "glProgramParameteri");
1584 if (!shProg)
1585 return;
1586
1587 switch (pname) {
1588 case GL_GEOMETRY_VERTICES_OUT_ARB:
1589 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1590 break;
1591
1592 if (value < 1 ||
1593 (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
1594 _mesa_error(ctx, GL_INVALID_VALUE,
1595 "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
1596 value);
1597 return;
1598 }
1599 shProg->Geom.VerticesOut = value;
1600 return;
1601 case GL_GEOMETRY_INPUT_TYPE_ARB:
1602 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1603 break;
1604
1605 switch (value) {
1606 case GL_POINTS:
1607 case GL_LINES:
1608 case GL_LINES_ADJACENCY_ARB:
1609 case GL_TRIANGLES:
1610 case GL_TRIANGLES_ADJACENCY_ARB:
1611 shProg->Geom.InputType = value;
1612 break;
1613 default:
1614 _mesa_error(ctx, GL_INVALID_VALUE,
1615 "glProgramParameteri(geometry input type = %s",
1616 _mesa_lookup_enum_by_nr(value));
1617 return;
1618 }
1619 return;
1620 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
1621 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
1622 break;
1623
1624 switch (value) {
1625 case GL_POINTS:
1626 case GL_LINE_STRIP:
1627 case GL_TRIANGLE_STRIP:
1628 shProg->Geom.OutputType = value;
1629 break;
1630 default:
1631 _mesa_error(ctx, GL_INVALID_VALUE,
1632 "glProgramParameteri(geometry output type = %s",
1633 _mesa_lookup_enum_by_nr(value));
1634 return;
1635 }
1636 return;
1637 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1638 /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
1639 * is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't
1640 * even be in the dispatch table, so we shouldn't need to expclicitly
1641 * check here.
1642 *
1643 * On desktop, we ignore the 3.0+ requirement because it is silly.
1644 */
1645
1646 /* The ARB_get_program_binary extension spec says:
1647 *
1648 * "An INVALID_VALUE error is generated if the <value> argument to
1649 * ProgramParameteri is not TRUE or FALSE."
1650 */
1651 if (value != GL_TRUE && value != GL_FALSE) {
1652 _mesa_error(ctx, GL_INVALID_VALUE,
1653 "glProgramParameteri(pname=%s, value=%d): "
1654 "value must be 0 or 1.",
1655 _mesa_lookup_enum_by_nr(pname),
1656 value);
1657 return;
1658 }
1659
1660 /* No need to notify the driver. Any changes will actually take effect
1661 * the next time the shader is linked.
1662 *
1663 * The ARB_get_program_binary extension spec says:
1664 *
1665 * "To indicate that a program binary is likely to be retrieved,
1666 * ProgramParameteri should be called with <pname>
1667 * PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
1668 * will not be in effect until the next time LinkProgram or
1669 * ProgramBinary has been called successfully."
1670 *
1671 * The resloution of issue 9 in the extension spec also says:
1672 *
1673 * "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
1674 * to indicate to the GL implementation that this program will
1675 * likely be saved with GetProgramBinary at some point. This will
1676 * give the GL implementation the opportunity to track any state
1677 * changes made to the program before being saved such that when it
1678 * is loaded again a recompile can be avoided."
1679 */
1680 shProg->BinaryRetreivableHint = value;
1681 return;
1682 default:
1683 break;
1684 }
1685
1686 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)",
1687 _mesa_lookup_enum_by_nr(pname));
1688 }
1689
1690 void
1691 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
1692 struct gl_shader_program *shProg)
1693 {
1694 use_shader_program(ctx, type, shProg);
1695
1696 if (ctx->Driver.UseProgram)
1697 ctx->Driver.UseProgram(ctx, shProg);
1698 }
1699
1700
1701 /**
1702 * For GL_EXT_separate_shader_objects
1703 */
1704 void GLAPIENTRY
1705 _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
1706 {
1707 GET_CURRENT_CONTEXT(ctx);
1708 struct gl_shader_program *shProg = NULL;
1709
1710 ASSERT_OUTSIDE_BEGIN_END(ctx);
1711
1712 if (!validate_shader_target(ctx, type)) {
1713 _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
1714 return;
1715 }
1716
1717 if (_mesa_is_xfb_active_and_unpaused(ctx)) {
1718 _mesa_error(ctx, GL_INVALID_OPERATION,
1719 "glUseShaderProgramEXT(transform feedback is active)");
1720 return;
1721 }
1722
1723 if (program) {
1724 shProg = _mesa_lookup_shader_program_err(ctx, program,
1725 "glUseShaderProgramEXT");
1726 if (shProg == NULL)
1727 return;
1728
1729 if (!shProg->LinkStatus) {
1730 _mesa_error(ctx, GL_INVALID_OPERATION,
1731 "glUseShaderProgramEXT(program not linked)");
1732 return;
1733 }
1734 }
1735
1736 _mesa_use_shader_program(ctx, type, shProg);
1737 }
1738
1739
1740 /**
1741 * For GL_EXT_separate_shader_objects
1742 */
1743 void GLAPIENTRY
1744 _mesa_ActiveProgramEXT(GLuint program)
1745 {
1746 GET_CURRENT_CONTEXT(ctx);
1747 struct gl_shader_program *shProg = (program != 0)
1748 ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
1749 : NULL;
1750
1751 _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
1752 return;
1753 }
1754
1755
1756 /**
1757 * For GL_EXT_separate_shader_objects
1758 */
1759 GLuint GLAPIENTRY
1760 _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
1761 {
1762 GET_CURRENT_CONTEXT(ctx);
1763 const GLuint shader = create_shader(ctx, type);
1764 GLuint program = 0;
1765
1766 if (shader) {
1767 shader_source(ctx, shader, _mesa_strdup(string));
1768 compile_shader(ctx, shader);
1769
1770 program = create_shader_program(ctx);
1771 if (program) {
1772 struct gl_shader_program *shProg;
1773 struct gl_shader *sh;
1774 GLint compiled = GL_FALSE;
1775
1776 shProg = _mesa_lookup_shader_program(ctx, program);
1777 sh = _mesa_lookup_shader(ctx, shader);
1778
1779 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
1780 if (compiled) {
1781 attach_shader(ctx, program, shader);
1782 link_program(ctx, program);
1783 detach_shader(ctx, program, shader);
1784
1785 #if 0
1786 /* Possibly... */
1787 if (active-user-defined-varyings-in-linked-program) {
1788 append-error-to-info-log;
1789 shProg->LinkStatus = GL_FALSE;
1790 }
1791 #endif
1792 }
1793
1794 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
1795 }
1796
1797 delete_shader(ctx, shader);
1798 }
1799
1800 return program;
1801 }
1802
1803 /**
1804 * Plug in shader-related functions into API dispatch table.
1805 */
1806 void
1807 _mesa_init_shader_dispatch(const struct gl_context *ctx,
1808 struct _glapi_table *exec)
1809 {
1810 #if FEATURE_GL
1811 /* GL_ARB_vertex/fragment_shader */
1812 if (_mesa_is_desktop_gl(ctx)) {
1813 SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
1814 SET_GetHandleARB(exec, _mesa_GetHandleARB);
1815 SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
1816 SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
1817 SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
1818 SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
1819 SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
1820 SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
1821 SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
1822 SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
1823 }
1824
1825 if (ctx->API != API_OPENGLES) {
1826 SET_ShaderSource(exec, _mesa_ShaderSource);
1827 SET_CompileShader(exec, _mesa_CompileShader);
1828 SET_LinkProgram(exec, _mesa_LinkProgram);
1829 SET_UseProgram(exec, _mesa_UseProgram);
1830 SET_ValidateProgram(exec, _mesa_ValidateProgram);
1831 SET_GetShaderSource(exec, _mesa_GetShaderSource);
1832
1833 /* OpenGL 2.0 */
1834 SET_AttachShader(exec, _mesa_AttachShader);
1835 SET_CreateProgram(exec, _mesa_CreateProgram);
1836 SET_CreateShader(exec, _mesa_CreateShader);
1837 SET_DeleteProgram(exec, _mesa_DeleteProgram);
1838 SET_DeleteShader(exec, _mesa_DeleteShader);
1839 SET_DetachShader(exec, _mesa_DetachShader);
1840 SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
1841 SET_GetProgramiv(exec, _mesa_GetProgramiv);
1842 SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
1843 SET_GetShaderiv(exec, _mesa_GetShaderiv);
1844 SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
1845 SET_IsProgram(exec, _mesa_IsProgram);
1846 SET_IsShader(exec, _mesa_IsShader);
1847
1848 /* GL_ARB_vertex_shader */
1849 SET_BindAttribLocation(exec, _mesa_BindAttribLocation);
1850 SET_GetActiveAttrib(exec, _mesa_GetActiveAttrib);
1851 SET_GetAttribLocation(exec, _mesa_GetAttribLocation);
1852 }
1853
1854 if (ctx->API == API_OPENGL_COMPAT) {
1855 SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT);
1856 SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT);
1857 SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT);
1858 }
1859
1860 /* GL_EXT_gpu_shader4 / GL 3.0 */
1861 if (_mesa_is_desktop_gl(ctx)) {
1862 SET_BindFragDataLocation(exec, _mesa_BindFragDataLocation);
1863 }
1864 if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
1865 SET_GetFragDataLocation(exec, _mesa_GetFragDataLocation);
1866 }
1867
1868 /* GL_ARB_ES2_compatibility */
1869 if (ctx->API != API_OPENGLES) {
1870 SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
1871 SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat);
1872 SET_ShaderBinary(exec, _mesa_ShaderBinary);
1873 }
1874
1875 /* GL_ARB_blend_func_extended */
1876 if (_mesa_is_desktop_gl(ctx)) {
1877 SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed);
1878 SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex);
1879 }
1880 #endif /* FEATURE_GL */
1881 }
1882