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