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