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