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