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