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