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