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