Merge remote branch 'origin/master' into nv50-compiler
[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 if (*params > 0)
648 (*params)++; /* add one for terminating zero */
649 break;
650 case GL_PROGRAM_BINARY_LENGTH_OES:
651 *params = 0;
652 break;
653 #if FEATURE_EXT_transform_feedback
654 case GL_TRANSFORM_FEEDBACK_VARYINGS:
655 *params = shProg->TransformFeedback.NumVarying;
656 break;
657 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
658 *params = longest_feedback_varying_name(shProg) + 1;
659 break;
660 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
661 *params = shProg->TransformFeedback.BufferMode;
662 break;
663 #endif
664 #if FEATURE_ARB_geometry_shader4
665 case GL_GEOMETRY_VERTICES_OUT_ARB:
666 *params = shProg->Geom.VerticesOut;
667 break;
668 case GL_GEOMETRY_INPUT_TYPE_ARB:
669 *params = shProg->Geom.InputType;
670 break;
671 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
672 *params = shProg->Geom.OutputType;
673 break;
674 #endif
675 default:
676 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
677 return;
678 }
679 }
680
681
682 /**
683 * glGetShaderiv() - get GLSL shader state
684 */
685 static void
686 get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
687 {
688 struct gl_shader *shader =
689 _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
690
691 if (!shader) {
692 return;
693 }
694
695 switch (pname) {
696 case GL_SHADER_TYPE:
697 *params = shader->Type;
698 break;
699 case GL_DELETE_STATUS:
700 *params = shader->DeletePending;
701 break;
702 case GL_COMPILE_STATUS:
703 *params = shader->CompileStatus;
704 break;
705 case GL_INFO_LOG_LENGTH:
706 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
707 break;
708 case GL_SHADER_SOURCE_LENGTH:
709 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
710 break;
711 default:
712 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
713 return;
714 }
715 }
716
717
718 static void
719 get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
720 GLsizei *length, GLchar *infoLog)
721 {
722 struct gl_shader_program *shProg
723 = _mesa_lookup_shader_program(ctx, program);
724 if (!shProg) {
725 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
726 return;
727 }
728 _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
729 }
730
731
732 static void
733 get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
734 GLsizei *length, GLchar *infoLog)
735 {
736 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
737 if (!sh) {
738 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
739 return;
740 }
741 _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
742 }
743
744
745 /**
746 * Return shader source code.
747 */
748 static void
749 get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
750 GLsizei *length, GLchar *sourceOut)
751 {
752 struct gl_shader *sh;
753 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
754 if (!sh) {
755 return;
756 }
757 _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
758 }
759
760
761 /**
762 * Set/replace shader source code.
763 */
764 static void
765 shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
766 {
767 struct gl_shader *sh;
768
769 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
770 if (!sh)
771 return;
772
773 /* free old shader source string and install new one */
774 if (sh->Source) {
775 free((void *) sh->Source);
776 }
777 sh->Source = source;
778 sh->CompileStatus = GL_FALSE;
779 #ifdef DEBUG
780 sh->SourceChecksum = _mesa_str_checksum(sh->Source);
781 #endif
782 }
783
784
785 /**
786 * Compile a shader.
787 */
788 static void
789 compile_shader(GLcontext *ctx, GLuint shaderObj)
790 {
791 struct gl_shader *sh;
792
793 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
794 if (!sh)
795 return;
796
797 /* set default pragma state for shader */
798 sh->Pragmas = ctx->Shader.DefaultPragmas;
799
800 /* this call will set the sh->CompileStatus field to indicate if
801 * compilation was successful.
802 */
803 _mesa_glsl_compile_shader(ctx, sh);
804 }
805
806
807 /**
808 * Link a program's shaders.
809 */
810 static void
811 link_program(GLcontext *ctx, GLuint program)
812 {
813 struct gl_shader_program *shProg;
814 struct gl_transform_feedback_object *obj =
815 ctx->TransformFeedback.CurrentObject;
816
817 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
818 if (!shProg)
819 return;
820
821 if (obj->Active && shProg == ctx->Shader.CurrentProgram) {
822 _mesa_error(ctx, GL_INVALID_OPERATION,
823 "glLinkProgram(transform feedback active");
824 return;
825 }
826
827 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
828
829 _mesa_glsl_link_shader(ctx, shProg);
830
831 /* debug code */
832 if (0) {
833 GLuint i;
834
835 printf("Link %u shaders in program %u: %s\n",
836 shProg->NumShaders, shProg->Name,
837 shProg->LinkStatus ? "Success" : "Failed");
838
839 for (i = 0; i < shProg->NumShaders; i++) {
840 printf(" shader %u, type 0x%x\n",
841 shProg->Shaders[i]->Name,
842 shProg->Shaders[i]->Type);
843 }
844 }
845 }
846
847
848 /**
849 * Print basic shader info (for debug).
850 */
851 static void
852 print_shader_info(const struct gl_shader_program *shProg)
853 {
854 GLuint i;
855
856 printf("Mesa: glUseProgram(%u)\n", shProg->Name);
857 for (i = 0; i < shProg->NumShaders; i++) {
858 const char *s;
859 switch (shProg->Shaders[i]->Type) {
860 case GL_VERTEX_SHADER:
861 s = "vertex";
862 break;
863 case GL_FRAGMENT_SHADER:
864 s = "fragment";
865 break;
866 case GL_GEOMETRY_SHADER:
867 s = "geometry";
868 break;
869 default:
870 s = "";
871 }
872 printf(" %s shader %u, checksum %u\n", s,
873 shProg->Shaders[i]->Name,
874 shProg->Shaders[i]->SourceChecksum);
875 }
876 if (shProg->VertexProgram)
877 printf(" vert prog %u\n", shProg->VertexProgram->Base.Id);
878 if (shProg->FragmentProgram)
879 printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id);
880 }
881
882
883 /**
884 * Use the named shader program for subsequent rendering.
885 */
886 void
887 _mesa_use_program(GLcontext *ctx, GLuint program)
888 {
889 struct gl_shader_program *shProg;
890 struct gl_transform_feedback_object *obj =
891 ctx->TransformFeedback.CurrentObject;
892
893 if (obj->Active) {
894 _mesa_error(ctx, GL_INVALID_OPERATION,
895 "glUseProgram(transform feedback active)");
896 return;
897 }
898
899 if (ctx->Shader.CurrentProgram &&
900 ctx->Shader.CurrentProgram->Name == program) {
901 /* no-op */
902 return;
903 }
904
905 if (program) {
906 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
907 if (!shProg) {
908 return;
909 }
910 if (!shProg->LinkStatus) {
911 _mesa_error(ctx, GL_INVALID_OPERATION,
912 "glUseProgram(program %u not linked)", program);
913 return;
914 }
915
916 /* debug code */
917 if (ctx->Shader.Flags & GLSL_USE_PROG) {
918 print_shader_info(shProg);
919 }
920 }
921 else {
922 shProg = NULL;
923 }
924
925 if (ctx->Shader.CurrentProgram != shProg) {
926 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
927 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
928 }
929
930 if (ctx->Driver.UseProgram)
931 ctx->Driver.UseProgram(ctx, shProg);
932 }
933
934
935 /**
936 * Validate a program's samplers.
937 * Specifically, check that there aren't two samplers of different types
938 * pointing to the same texture unit.
939 * \return GL_TRUE if valid, GL_FALSE if invalid
940 */
941 static GLboolean
942 validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
943 {
944 static const char *targetName[] = {
945 "TEXTURE_2D_ARRAY",
946 "TEXTURE_1D_ARRAY",
947 "TEXTURE_CUBE",
948 "TEXTURE_3D",
949 "TEXTURE_RECT",
950 "TEXTURE_2D",
951 "TEXTURE_1D",
952 };
953 GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
954 GLbitfield samplersUsed = prog->SamplersUsed;
955 GLuint i;
956
957 assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
958
959 if (samplersUsed == 0x0)
960 return GL_TRUE;
961
962 for (i = 0; i < Elements(targetUsed); i++)
963 targetUsed[i] = -1;
964
965 /* walk over bits which are set in 'samplers' */
966 while (samplersUsed) {
967 GLuint unit;
968 gl_texture_index target;
969 GLint sampler = _mesa_ffs(samplersUsed) - 1;
970 assert(sampler >= 0);
971 assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
972 unit = prog->SamplerUnits[sampler];
973 target = prog->SamplerTargets[sampler];
974 if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
975 _mesa_snprintf(errMsg, 100,
976 "Texture unit %d is accessed both as %s and %s",
977 unit, targetName[targetUsed[unit]], targetName[target]);
978 return GL_FALSE;
979 }
980 targetUsed[unit] = target;
981 samplersUsed ^= (1 << sampler);
982 }
983
984 return GL_TRUE;
985 }
986
987
988 /**
989 * Do validation of the given shader program.
990 * \param errMsg returns error message if validation fails.
991 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
992 */
993 static GLboolean
994 validate_shader_program(GLcontext *ctx,
995 const struct gl_shader_program *shProg,
996 char *errMsg)
997 {
998 const struct gl_vertex_program *vp = shProg->VertexProgram;
999 const struct gl_fragment_program *fp = shProg->FragmentProgram;
1000
1001 if (!shProg->LinkStatus) {
1002 return GL_FALSE;
1003 }
1004
1005 /* From the GL spec, a program is invalid if any of these are true:
1006
1007 any two active samplers in the current program object are of
1008 different types, but refer to the same texture image unit,
1009
1010 any active sampler in the current program object refers to a texture
1011 image unit where fixed-function fragment processing accesses a
1012 texture target that does not match the sampler type, or
1013
1014 the sum of the number of active samplers in the program and the
1015 number of texture image units enabled for fixed-function fragment
1016 processing exceeds the combined limit on the total number of texture
1017 image units allowed.
1018 */
1019
1020
1021 /*
1022 * Check: any two active samplers in the current program object are of
1023 * different types, but refer to the same texture image unit,
1024 */
1025 if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
1026 return GL_FALSE;
1027 }
1028 if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
1029 return GL_FALSE;
1030 }
1031
1032 return GL_TRUE;
1033 }
1034
1035
1036 /**
1037 * Called via glValidateProgram()
1038 */
1039 static void
1040 validate_program(GLcontext *ctx, GLuint program)
1041 {
1042 struct gl_shader_program *shProg;
1043 char errMsg[100];
1044
1045 shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
1046 if (!shProg) {
1047 return;
1048 }
1049
1050 shProg->Validated = validate_shader_program(ctx, shProg, errMsg);
1051 if (!shProg->Validated) {
1052 /* update info log */
1053 if (shProg->InfoLog) {
1054 talloc_free(shProg->InfoLog);
1055 }
1056 shProg->InfoLog = talloc_strdup(shProg, errMsg);
1057 }
1058 }
1059
1060
1061
1062 void GLAPIENTRY
1063 _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
1064 {
1065 GET_CURRENT_CONTEXT(ctx);
1066 attach_shader(ctx, program, shader);
1067 }
1068
1069
1070 void GLAPIENTRY
1071 _mesa_AttachShader(GLuint program, GLuint shader)
1072 {
1073 GET_CURRENT_CONTEXT(ctx);
1074 attach_shader(ctx, program, shader);
1075 }
1076
1077
1078 void GLAPIENTRY
1079 _mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
1080 const GLcharARB *name)
1081 {
1082 GET_CURRENT_CONTEXT(ctx);
1083 bind_attrib_location(ctx, program, index, name);
1084 }
1085
1086
1087 void GLAPIENTRY
1088 _mesa_CompileShaderARB(GLhandleARB shaderObj)
1089 {
1090 GET_CURRENT_CONTEXT(ctx);
1091 compile_shader(ctx, shaderObj);
1092 }
1093
1094
1095 GLuint GLAPIENTRY
1096 _mesa_CreateShader(GLenum type)
1097 {
1098 GET_CURRENT_CONTEXT(ctx);
1099 return create_shader(ctx, type);
1100 }
1101
1102
1103 GLhandleARB GLAPIENTRY
1104 _mesa_CreateShaderObjectARB(GLenum type)
1105 {
1106 GET_CURRENT_CONTEXT(ctx);
1107 return create_shader(ctx, type);
1108 }
1109
1110
1111 GLuint GLAPIENTRY
1112 _mesa_CreateProgram(void)
1113 {
1114 GET_CURRENT_CONTEXT(ctx);
1115 return create_shader_program(ctx);
1116 }
1117
1118
1119 GLhandleARB GLAPIENTRY
1120 _mesa_CreateProgramObjectARB(void)
1121 {
1122 GET_CURRENT_CONTEXT(ctx);
1123 return create_shader_program(ctx);
1124 }
1125
1126
1127 void GLAPIENTRY
1128 _mesa_DeleteObjectARB(GLhandleARB obj)
1129 {
1130 if (obj) {
1131 GET_CURRENT_CONTEXT(ctx);
1132 if (is_program(ctx, obj)) {
1133 delete_shader_program(ctx, obj);
1134 }
1135 else if (is_shader(ctx, obj)) {
1136 delete_shader(ctx, obj);
1137 }
1138 else {
1139 /* error? */
1140 }
1141 }
1142 }
1143
1144
1145 void GLAPIENTRY
1146 _mesa_DeleteProgram(GLuint name)
1147 {
1148 if (name) {
1149 GET_CURRENT_CONTEXT(ctx);
1150 delete_shader_program(ctx, name);
1151 }
1152 }
1153
1154
1155 void GLAPIENTRY
1156 _mesa_DeleteShader(GLuint name)
1157 {
1158 if (name) {
1159 GET_CURRENT_CONTEXT(ctx);
1160 delete_shader(ctx, name);
1161 }
1162 }
1163
1164
1165 void GLAPIENTRY
1166 _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
1167 {
1168 GET_CURRENT_CONTEXT(ctx);
1169 detach_shader(ctx, program, shader);
1170 }
1171
1172
1173 void GLAPIENTRY
1174 _mesa_DetachShader(GLuint program, GLuint shader)
1175 {
1176 GET_CURRENT_CONTEXT(ctx);
1177 detach_shader(ctx, program, shader);
1178 }
1179
1180
1181 void GLAPIENTRY
1182 _mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
1183 GLsizei maxLength, GLsizei * length, GLint * size,
1184 GLenum * type, GLcharARB * name)
1185 {
1186 GET_CURRENT_CONTEXT(ctx);
1187 get_active_attrib(ctx, program, index, maxLength, length, size, type, name);
1188 }
1189
1190
1191 void GLAPIENTRY
1192 _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
1193 GLsizei * count, GLhandleARB * obj)
1194 {
1195 GET_CURRENT_CONTEXT(ctx);
1196 get_attached_shaders(ctx, container, maxCount, count, obj);
1197 }
1198
1199
1200 void GLAPIENTRY
1201 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1202 GLsizei *count, GLuint *obj)
1203 {
1204 GET_CURRENT_CONTEXT(ctx);
1205 get_attached_shaders(ctx, program, maxCount, count, obj);
1206 }
1207
1208
1209 GLint GLAPIENTRY
1210 _mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
1211 {
1212 GET_CURRENT_CONTEXT(ctx);
1213 return get_attrib_location(ctx, program, name);
1214 }
1215
1216
1217 void GLAPIENTRY
1218 _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
1219 GLcharARB * infoLog)
1220 {
1221 GET_CURRENT_CONTEXT(ctx);
1222 if (is_program(ctx, object)) {
1223 get_program_info_log(ctx, object, maxLength, length, infoLog);
1224 }
1225 else if (is_shader(ctx, object)) {
1226 get_shader_info_log(ctx, object, maxLength, length, infoLog);
1227 }
1228 else {
1229 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
1230 }
1231 }
1232
1233
1234 void GLAPIENTRY
1235 _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
1236 {
1237 GET_CURRENT_CONTEXT(ctx);
1238 /* Implement in terms of GetProgramiv, GetShaderiv */
1239 if (is_program(ctx, object)) {
1240 if (pname == GL_OBJECT_TYPE_ARB) {
1241 *params = GL_PROGRAM_OBJECT_ARB;
1242 }
1243 else {
1244 get_programiv(ctx, object, pname, params);
1245 }
1246 }
1247 else if (is_shader(ctx, object)) {
1248 if (pname == GL_OBJECT_TYPE_ARB) {
1249 *params = GL_SHADER_OBJECT_ARB;
1250 }
1251 else {
1252 get_shaderiv(ctx, object, pname, params);
1253 }
1254 }
1255 else {
1256 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
1257 }
1258 }
1259
1260
1261 void GLAPIENTRY
1262 _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
1263 GLfloat *params)
1264 {
1265 GLint iparams[1]; /* XXX is one element enough? */
1266 _mesa_GetObjectParameterivARB(object, pname, iparams);
1267 params[0] = (GLfloat) iparams[0];
1268 }
1269
1270
1271 void GLAPIENTRY
1272 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1273 {
1274 GET_CURRENT_CONTEXT(ctx);
1275 get_programiv(ctx, program, pname, params);
1276 }
1277
1278
1279 void GLAPIENTRY
1280 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1281 {
1282 GET_CURRENT_CONTEXT(ctx);
1283 get_shaderiv(ctx, shader, pname, params);
1284 }
1285
1286
1287 void GLAPIENTRY
1288 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1289 GLsizei *length, GLchar *infoLog)
1290 {
1291 GET_CURRENT_CONTEXT(ctx);
1292 get_program_info_log(ctx, program, bufSize, length, infoLog);
1293 }
1294
1295
1296 void GLAPIENTRY
1297 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1298 GLsizei *length, GLchar *infoLog)
1299 {
1300 GET_CURRENT_CONTEXT(ctx);
1301 get_shader_info_log(ctx, shader, bufSize, length, infoLog);
1302 }
1303
1304
1305 void GLAPIENTRY
1306 _mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
1307 GLsizei *length, GLcharARB *sourceOut)
1308 {
1309 GET_CURRENT_CONTEXT(ctx);
1310 get_shader_source(ctx, shader, maxLength, length, sourceOut);
1311 }
1312
1313
1314 GLhandleARB GLAPIENTRY
1315 _mesa_GetHandleARB(GLenum pname)
1316 {
1317 GET_CURRENT_CONTEXT(ctx);
1318 return get_handle(ctx, pname);
1319 }
1320
1321
1322 GLboolean GLAPIENTRY
1323 _mesa_IsProgram(GLuint name)
1324 {
1325 GET_CURRENT_CONTEXT(ctx);
1326 return is_program(ctx, name);
1327 }
1328
1329
1330 GLboolean GLAPIENTRY
1331 _mesa_IsShader(GLuint name)
1332 {
1333 GET_CURRENT_CONTEXT(ctx);
1334 return is_shader(ctx, name);
1335 }
1336
1337
1338 void GLAPIENTRY
1339 _mesa_LinkProgramARB(GLhandleARB programObj)
1340 {
1341 GET_CURRENT_CONTEXT(ctx);
1342 link_program(ctx, programObj);
1343 }
1344
1345
1346
1347 /**
1348 * Read shader source code from a file.
1349 * Useful for debugging to override an app's shader.
1350 */
1351 static GLcharARB *
1352 read_shader(const char *fname)
1353 {
1354 const int max = 50*1000;
1355 FILE *f = fopen(fname, "r");
1356 GLcharARB *buffer, *shader;
1357 int len;
1358
1359 if (!f) {
1360 return NULL;
1361 }
1362
1363 buffer = (char *) malloc(max);
1364 len = fread(buffer, 1, max, f);
1365 buffer[len] = 0;
1366
1367 fclose(f);
1368
1369 shader = _mesa_strdup(buffer);
1370 free(buffer);
1371
1372 return shader;
1373 }
1374
1375
1376 /**
1377 * Called via glShaderSource() and glShaderSourceARB() API functions.
1378 * Basically, concatenate the source code strings into one long string
1379 * and pass it to _mesa_shader_source().
1380 */
1381 void GLAPIENTRY
1382 _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
1383 const GLcharARB ** string, const GLint * length)
1384 {
1385 GET_CURRENT_CONTEXT(ctx);
1386 GLint *offsets;
1387 GLsizei i, totalLength;
1388 GLcharARB *source;
1389 GLuint checksum;
1390
1391 if (!shaderObj || string == NULL) {
1392 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
1393 return;
1394 }
1395
1396 /*
1397 * This array holds offsets of where the appropriate string ends, thus the
1398 * last element will be set to the total length of the source code.
1399 */
1400 offsets = (GLint *) malloc(count * sizeof(GLint));
1401 if (offsets == NULL) {
1402 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1403 return;
1404 }
1405
1406 for (i = 0; i < count; i++) {
1407 if (string[i] == NULL) {
1408 free((GLvoid *) offsets);
1409 _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
1410 return;
1411 }
1412 if (length == NULL || length[i] < 0)
1413 offsets[i] = strlen(string[i]);
1414 else
1415 offsets[i] = length[i];
1416 /* accumulate string lengths */
1417 if (i > 0)
1418 offsets[i] += offsets[i - 1];
1419 }
1420
1421 /* Total length of source string is sum off all strings plus two.
1422 * One extra byte for terminating zero, another extra byte to silence
1423 * valgrind warnings in the parser/grammer code.
1424 */
1425 totalLength = offsets[count - 1] + 2;
1426 source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
1427 if (source == NULL) {
1428 free((GLvoid *) offsets);
1429 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
1430 return;
1431 }
1432
1433 for (i = 0; i < count; i++) {
1434 GLint start = (i > 0) ? offsets[i - 1] : 0;
1435 memcpy(source + start, string[i],
1436 (offsets[i] - start) * sizeof(GLcharARB));
1437 }
1438 source[totalLength - 1] = '\0';
1439 source[totalLength - 2] = '\0';
1440
1441 if (SHADER_SUBST) {
1442 /* Compute the shader's source code checksum then try to open a file
1443 * named newshader_<CHECKSUM>. If it exists, use it in place of the
1444 * original shader source code. For debugging.
1445 */
1446 char filename[100];
1447 GLcharARB *newSource;
1448
1449 checksum = _mesa_str_checksum(source);
1450
1451 _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
1452
1453 newSource = read_shader(filename);
1454 if (newSource) {
1455 fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
1456 shaderObj, checksum, filename);
1457 free(source);
1458 source = newSource;
1459 }
1460 }
1461
1462 shader_source(ctx, shaderObj, source);
1463
1464 if (SHADER_SUBST) {
1465 struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
1466 if (sh)
1467 sh->SourceChecksum = checksum; /* save original checksum */
1468 }
1469
1470 free(offsets);
1471 }
1472
1473
1474 void GLAPIENTRY
1475 _mesa_UseProgramObjectARB(GLhandleARB program)
1476 {
1477 GET_CURRENT_CONTEXT(ctx);
1478 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
1479 _mesa_use_program(ctx, program);
1480 }
1481
1482
1483 void GLAPIENTRY
1484 _mesa_ValidateProgramARB(GLhandleARB program)
1485 {
1486 GET_CURRENT_CONTEXT(ctx);
1487 validate_program(ctx, program);
1488 }
1489
1490 #ifdef FEATURE_ES2
1491
1492 void GLAPIENTRY
1493 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1494 GLint* range, GLint* precision)
1495 {
1496 GET_CURRENT_CONTEXT(ctx);
1497 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1498 }
1499
1500
1501 void GLAPIENTRY
1502 _mesa_ReleaseShaderCompiler(void)
1503 {
1504 GET_CURRENT_CONTEXT(ctx);
1505 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1506 }
1507
1508
1509 void GLAPIENTRY
1510 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1511 const void* binary, GLint length)
1512 {
1513 GET_CURRENT_CONTEXT(ctx);
1514 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1515 }
1516
1517 #endif /* FEATURE_ES2 */
1518
1519
1520 #if FEATURE_ARB_geometry_shader4
1521
1522 void GLAPIENTRY
1523 _mesa_ProgramParameteriARB(GLuint program, GLenum pname,
1524 GLint value)
1525 {
1526 struct gl_shader_program *shProg;
1527 GET_CURRENT_CONTEXT(ctx);
1528
1529 ASSERT_OUTSIDE_BEGIN_END(ctx);
1530
1531 shProg = _mesa_lookup_shader_program_err(ctx, program,
1532 "glProgramParameteri");
1533 if (!shProg)
1534 return;
1535
1536 switch (pname) {
1537 case GL_GEOMETRY_VERTICES_OUT_ARB:
1538 if (value < 1 ||
1539 value > ctx->Const.GeometryProgram.MaxGeometryOutputVertices) {
1540 _mesa_error(ctx, GL_INVALID_VALUE,
1541 "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
1542 value);
1543 return;
1544 }
1545 shProg->Geom.VerticesOut = value;
1546 break;
1547 case GL_GEOMETRY_INPUT_TYPE_ARB:
1548 switch (value) {
1549 case GL_POINTS:
1550 case GL_LINES:
1551 case GL_LINES_ADJACENCY_ARB:
1552 case GL_TRIANGLES:
1553 case GL_TRIANGLES_ADJACENCY_ARB:
1554 shProg->Geom.InputType = value;
1555 break;
1556 default:
1557 _mesa_error(ctx, GL_INVALID_VALUE,
1558 "glProgramParameteri(geometry input type = %s",
1559 _mesa_lookup_enum_by_nr(value));
1560 return;
1561 }
1562 break;
1563 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
1564 switch (value) {
1565 case GL_POINTS:
1566 case GL_LINE_STRIP:
1567 case GL_TRIANGLE_STRIP:
1568 shProg->Geom.OutputType = value;
1569 break;
1570 default:
1571 _mesa_error(ctx, GL_INVALID_VALUE,
1572 "glProgramParameteri(geometry output type = %s",
1573 _mesa_lookup_enum_by_nr(value));
1574 return;
1575 }
1576 break;
1577 default:
1578 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)",
1579 _mesa_lookup_enum_by_nr(pname));
1580 break;
1581 }
1582 }
1583
1584 #endif
1585
1586
1587 /**
1588 * Plug in shader-related functions into API dispatch table.
1589 */
1590 void
1591 _mesa_init_shader_dispatch(struct _glapi_table *exec)
1592 {
1593 #if FEATURE_GL
1594 /* GL_ARB_vertex/fragment_shader */
1595 SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
1596 SET_GetHandleARB(exec, _mesa_GetHandleARB);
1597 SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
1598 SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
1599 SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
1600 SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
1601 SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
1602 SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
1603 SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
1604 SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
1605 SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
1606 SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
1607 SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
1608 SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
1609 SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
1610 SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
1611
1612 /* OpenGL 2.0 */
1613 SET_AttachShader(exec, _mesa_AttachShader);
1614 SET_CreateProgram(exec, _mesa_CreateProgram);
1615 SET_CreateShader(exec, _mesa_CreateShader);
1616 SET_DeleteProgram(exec, _mesa_DeleteProgram);
1617 SET_DeleteShader(exec, _mesa_DeleteShader);
1618 SET_DetachShader(exec, _mesa_DetachShader);
1619 SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
1620 SET_GetProgramiv(exec, _mesa_GetProgramiv);
1621 SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
1622 SET_GetShaderiv(exec, _mesa_GetShaderiv);
1623 SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
1624 SET_IsProgram(exec, _mesa_IsProgram);
1625 SET_IsShader(exec, _mesa_IsShader);
1626
1627 #if FEATURE_ARB_vertex_shader
1628 SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
1629 SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
1630 SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
1631 #endif
1632
1633 #if FEATURE_ARB_geometry_shader4
1634 SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB);
1635 #endif
1636 #endif /* FEATURE_GL */
1637 }
1638