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