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