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