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