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