mesa: add support for using API_OPENGL_CORE
[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 "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 if (strstr(env, "errors"))
87 flags |= GLSL_REPORT_ERRORS;
88 }
89
90 return flags;
91 }
92
93
94 /**
95 * Initialize context's shader state.
96 */
97 void
98 _mesa_init_shader_state(struct gl_context *ctx)
99 {
100 /* Device drivers may override these to control what kind of instructions
101 * are generated by the GLSL compiler.
102 */
103 struct gl_shader_compiler_options options;
104 gl_shader_type sh;
105
106 memset(&options, 0, sizeof(options));
107 options.MaxUnrollIterations = 32;
108
109 /* Default pragma settings */
110 options.DefaultPragmas.Optimize = GL_TRUE;
111
112 for (sh = 0; sh < MESA_SHADER_TYPES; ++sh)
113 memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
114
115 ctx->Shader.Flags = get_shader_flags();
116 }
117
118
119 /**
120 * Free the per-context shader-related state.
121 */
122 void
123 _mesa_free_shader_state(struct gl_context *ctx)
124 {
125 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentVertexProgram, NULL);
126 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentGeometryProgram,
127 NULL);
128 _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
129 NULL);
130 _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
131 NULL);
132 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
133 }
134
135
136 /**
137 * Copy string from <src> to <dst>, up to maxLength characters, returning
138 * length of <dst> in <length>.
139 * \param src the strings source
140 * \param maxLength max chars to copy
141 * \param length returns number of chars copied
142 * \param dst the string destination
143 */
144 void
145 _mesa_copy_string(GLchar *dst, GLsizei maxLength,
146 GLsizei *length, const GLchar *src)
147 {
148 GLsizei len;
149 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
150 dst[len] = src[len];
151 if (maxLength > 0)
152 dst[len] = 0;
153 if (length)
154 *length = len;
155 }
156
157
158
159 /**
160 * Confirm that the a shader type is valid and supported by the implementation
161 *
162 * \param ctx Current GL context
163 * \param type Shader target
164 *
165 */
166 static bool
167 validate_shader_target(const struct gl_context *ctx, GLenum type)
168 {
169 switch (type) {
170 #if FEATURE_ARB_fragment_shader
171 case GL_FRAGMENT_SHADER:
172 return ctx->Extensions.ARB_fragment_shader;
173 #endif
174 #if FEATURE_ARB_vertex_shader
175 case GL_VERTEX_SHADER:
176 return ctx->Extensions.ARB_vertex_shader;
177 #endif
178 #if FEATURE_ARB_geometry_shader4
179 case GL_GEOMETRY_SHADER_ARB:
180 return ctx->Extensions.ARB_geometry_shader4;
181 #endif
182 default:
183 return false;
184 }
185 }
186
187
188 /**
189 * Find the length of the longest transform feedback varying name
190 * which was specified with glTransformFeedbackVaryings().
191 */
192 static GLint
193 longest_feedback_varying_name(const struct gl_shader_program *shProg)
194 {
195 GLuint i;
196 GLint max = 0;
197 for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
198 GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
199 if (len > max)
200 max = len;
201 }
202 return max;
203 }
204
205
206
207 static GLboolean
208 is_program(struct gl_context *ctx, GLuint name)
209 {
210 struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
211 return shProg ? GL_TRUE : GL_FALSE;
212 }
213
214
215 static GLboolean
216 is_shader(struct gl_context *ctx, GLuint name)
217 {
218 struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
219 return shader ? GL_TRUE : GL_FALSE;
220 }
221
222
223 /**
224 * Attach shader to a shader program.
225 */
226 static void
227 attach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
228 {
229 struct gl_shader_program *shProg;
230 struct gl_shader *sh;
231 GLuint i, n;
232
233 shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
234 if (!shProg)
235 return;
236
237 sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
238 if (!sh) {
239 return;
240 }
241
242 n = shProg->NumShaders;
243 for (i = 0; i < n; i++) {
244 if (shProg->Shaders[i] == sh) {
245 /* The shader is already attched to this program. The
246 * GL_ARB_shader_objects spec says:
247 *
248 * "The error INVALID_OPERATION is generated by AttachObjectARB
249 * if <obj> is already attached to <containerObj>."
250 */
251 _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
252 return;
253 }
254 }
255
256 /* grow list */
257 shProg->Shaders = (struct gl_shader **)
258 _mesa_realloc(shProg->Shaders,
259 n * sizeof(struct gl_shader *),
260 (n + 1) * sizeof(struct gl_shader *));
261 if (!shProg->Shaders) {
262 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
263 return;
264 }
265
266 /* append */
267 shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
268 _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
269 shProg->NumShaders++;
270 }
271
272
273 static GLuint
274 create_shader(struct gl_context *ctx, GLenum type)
275 {
276 struct gl_shader *sh;
277 GLuint name;
278
279 if (!validate_shader_target(ctx, type)) {
280 _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
281 return 0;
282 }
283
284 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
285 sh = ctx->Driver.NewShader(ctx, name, type);
286 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
287
288 return name;
289 }
290
291
292 static GLuint
293 create_shader_program(struct gl_context *ctx)
294 {
295 GLuint name;
296 struct gl_shader_program *shProg;
297
298 name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
299
300 shProg = ctx->Driver.NewShaderProgram(ctx, name);
301
302 _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
303
304 assert(shProg->RefCount == 1);
305
306 return name;
307 }
308
309
310 /**
311 * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
312 * DeleteProgramARB.
313 */
314 static void
315 delete_shader_program(struct gl_context *ctx, GLuint name)
316 {
317 /*
318 * NOTE: deleting shaders/programs works a bit differently than
319 * texture objects (and buffer objects, etc). Shader/program
320 * handles/IDs exist in the hash table until the object is really
321 * deleted (refcount==0). With texture objects, the handle/ID is
322 * removed from the hash table in glDeleteTextures() while the tex
323 * object itself might linger until its refcount goes to zero.
324 */
325 struct gl_shader_program *shProg;
326
327 shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
328 if (!shProg)
329 return;
330
331 if (!shProg->DeletePending) {
332 shProg->DeletePending = GL_TRUE;
333
334 /* effectively, decr shProg's refcount */
335 _mesa_reference_shader_program(ctx, &shProg, NULL);
336 }
337 }
338
339
340 static void
341 delete_shader(struct gl_context *ctx, GLuint shader)
342 {
343 struct gl_shader *sh;
344
345 sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
346 if (!sh)
347 return;
348
349 if (!sh->DeletePending) {
350 sh->DeletePending = GL_TRUE;
351
352 /* effectively, decr sh's refcount */
353 _mesa_reference_shader(ctx, &sh, NULL);
354 }
355 }
356
357
358 static void
359 detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
360 {
361 struct gl_shader_program *shProg;
362 GLuint n;
363 GLuint i, j;
364
365 shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
366 if (!shProg)
367 return;
368
369 n = shProg->NumShaders;
370
371 for (i = 0; i < n; i++) {
372 if (shProg->Shaders[i]->Name == shader) {
373 /* found it */
374 struct gl_shader **newList;
375
376 /* release */
377 _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
378
379 /* alloc new, smaller array */
380 newList = (struct gl_shader **)
381 malloc((n - 1) * sizeof(struct gl_shader *));
382 if (!newList) {
383 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
384 return;
385 }
386 for (j = 0; j < i; j++) {
387 newList[j] = shProg->Shaders[j];
388 }
389 while (++i < n)
390 newList[j++] = shProg->Shaders[i];
391 free(shProg->Shaders);
392
393 shProg->Shaders = newList;
394 shProg->NumShaders = n - 1;
395
396 #ifdef DEBUG
397 /* sanity check */
398 {
399 for (j = 0; j < shProg->NumShaders; j++) {
400 assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
401 shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
402 assert(shProg->Shaders[j]->RefCount > 0);
403 }
404 }
405 #endif
406
407 return;
408 }
409 }
410
411 /* not found */
412 {
413 GLenum err;
414 if (is_shader(ctx, shader))
415 err = GL_INVALID_OPERATION;
416 else if (is_program(ctx, shader))
417 err = GL_INVALID_OPERATION;
418 else
419 err = GL_INVALID_VALUE;
420 _mesa_error(ctx, err, "glDetachProgram(shader)");
421 return;
422 }
423 }
424
425
426 /**
427 * Return list of shaders attached to shader program.
428 */
429 static void
430 get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount,
431 GLsizei *count, GLuint *obj)
432 {
433 struct gl_shader_program *shProg =
434 _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
435 if (shProg) {
436 GLuint i;
437 for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
438 obj[i] = shProg->Shaders[i]->Name;
439 }
440 if (count)
441 *count = i;
442 }
443 }
444
445
446 /**
447 * glGetHandleARB() - return ID/name of currently bound shader program.
448 */
449 static GLuint
450 get_handle(struct gl_context *ctx, GLenum pname)
451 {
452 if (pname == GL_PROGRAM_OBJECT_ARB) {
453 if (ctx->Shader.ActiveProgram)
454 return ctx->Shader.ActiveProgram->Name;
455 else
456 return 0;
457 }
458 else {
459 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
460 return 0;
461 }
462 }
463
464
465 /**
466 * glGetProgramiv() - get shader program state.
467 * Note that this is for GLSL shader programs, not ARB vertex/fragment
468 * programs (see glGetProgramivARB).
469 */
470 static void
471 get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params)
472 {
473 struct gl_shader_program *shProg
474 = _mesa_lookup_shader_program(ctx, program);
475
476 if (!shProg) {
477 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
478 return;
479 }
480
481 switch (pname) {
482 case GL_DELETE_STATUS:
483 *params = shProg->DeletePending;
484 break;
485 case GL_LINK_STATUS:
486 *params = shProg->LinkStatus;
487 break;
488 case GL_VALIDATE_STATUS:
489 *params = shProg->Validated;
490 break;
491 case GL_INFO_LOG_LENGTH:
492 *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
493 break;
494 case GL_ATTACHED_SHADERS:
495 *params = shProg->NumShaders;
496 break;
497 case GL_ACTIVE_ATTRIBUTES:
498 *params = _mesa_count_active_attribs(shProg);
499 break;
500 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
501 *params = _mesa_longest_attribute_name_length(shProg);
502 break;
503 case GL_ACTIVE_UNIFORMS:
504 *params = shProg->NumUserUniformStorage;
505 break;
506 case GL_ACTIVE_UNIFORM_MAX_LENGTH: {
507 unsigned i;
508 GLint max_len = 0;
509
510 for (i = 0; i < shProg->NumUserUniformStorage; i++) {
511 /* Add one for the terminating NUL character.
512 */
513 const GLint len = strlen(shProg->UniformStorage[i].name) + 1;
514
515 if (len > max_len)
516 max_len = len;
517 }
518
519 *params = max_len;
520 break;
521 }
522 case GL_PROGRAM_BINARY_LENGTH_OES:
523 *params = 0;
524 break;
525 #if FEATURE_EXT_transform_feedback
526 case GL_TRANSFORM_FEEDBACK_VARYINGS:
527 *params = shProg->TransformFeedback.NumVarying;
528 break;
529 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
530 *params = longest_feedback_varying_name(shProg) + 1;
531 break;
532 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
533 *params = shProg->TransformFeedback.BufferMode;
534 break;
535 #endif
536 #if FEATURE_ARB_geometry_shader4
537 case GL_GEOMETRY_VERTICES_OUT_ARB:
538 *params = shProg->Geom.VerticesOut;
539 break;
540 case GL_GEOMETRY_INPUT_TYPE_ARB:
541 *params = shProg->Geom.InputType;
542 break;
543 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
544 *params = shProg->Geom.OutputType;
545 break;
546 #endif
547 default:
548 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
549 return;
550 }
551 }
552
553
554 /**
555 * glGetShaderiv() - get GLSL shader state
556 */
557 static void
558 get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
559 {
560 struct gl_shader *shader =
561 _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
562
563 if (!shader) {
564 return;
565 }
566
567 switch (pname) {
568 case GL_SHADER_TYPE:
569 *params = shader->Type;
570 break;
571 case GL_DELETE_STATUS:
572 *params = shader->DeletePending;
573 break;
574 case GL_COMPILE_STATUS:
575 *params = shader->CompileStatus;
576 break;
577 case GL_INFO_LOG_LENGTH:
578 *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
579 break;
580 case GL_SHADER_SOURCE_LENGTH:
581 *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
582 break;
583 default:
584 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
585 return;
586 }
587 }
588
589
590 static void
591 get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize,
592 GLsizei *length, GLchar *infoLog)
593 {
594 struct gl_shader_program *shProg
595 = _mesa_lookup_shader_program(ctx, program);
596 if (!shProg) {
597 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
598 return;
599 }
600 _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
601 }
602
603
604 static void
605 get_shader_info_log(struct gl_context *ctx, GLuint shader, GLsizei bufSize,
606 GLsizei *length, GLchar *infoLog)
607 {
608 struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
609 if (!sh) {
610 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
611 return;
612 }
613 _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
614 }
615
616
617 /**
618 * Return shader source code.
619 */
620 static void
621 get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength,
622 GLsizei *length, GLchar *sourceOut)
623 {
624 struct gl_shader *sh;
625 sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
626 if (!sh) {
627 return;
628 }
629 _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
630 }
631
632
633 /**
634 * Set/replace shader source code. A helper function used by
635 * glShaderSource[ARB] and glCreateShaderProgramEXT.
636 */
637 static void
638 shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
639 {
640 struct gl_shader *sh;
641
642 sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
643 if (!sh)
644 return;
645
646 /* free old shader source string and install new one */
647 if (sh->Source) {
648 free((void *) sh->Source);
649 }
650 sh->Source = source;
651 sh->CompileStatus = GL_FALSE;
652 #ifdef DEBUG
653 sh->SourceChecksum = _mesa_str_checksum(sh->Source);
654 #endif
655 }
656
657
658 /**
659 * Compile a shader.
660 */
661 static void
662 compile_shader(struct gl_context *ctx, GLuint shaderObj)
663 {
664 struct gl_shader *sh;
665 struct gl_shader_compiler_options *options;
666
667 sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
668 if (!sh)
669 return;
670
671 options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)];
672
673 /* set default pragma state for shader */
674 sh->Pragmas = options->DefaultPragmas;
675
676 /* this call will set the sh->CompileStatus field to indicate if
677 * compilation was successful.
678 */
679 _mesa_glsl_compile_shader(ctx, sh);
680
681 if (sh->CompileStatus == GL_FALSE &&
682 (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
683 _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
684 sh->Name, sh->InfoLog);
685 }
686 }
687
688
689 /**
690 * Link a program's shaders.
691 */
692 static void
693 link_program(struct gl_context *ctx, GLuint program)
694 {
695 struct gl_shader_program *shProg;
696 struct gl_transform_feedback_object *obj =
697 ctx->TransformFeedback.CurrentObject;
698
699 shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
700 if (!shProg)
701 return;
702
703 if (obj->Active
704 && (shProg == ctx->Shader.CurrentVertexProgram
705 || shProg == ctx->Shader.CurrentGeometryProgram
706 || shProg == ctx->Shader.CurrentFragmentProgram)) {
707 _mesa_error(ctx, GL_INVALID_OPERATION,
708 "glLinkProgram(transform feedback active)");
709 return;
710 }
711
712 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
713
714 _mesa_glsl_link_shader(ctx, shProg);
715
716 if (shProg->LinkStatus == GL_FALSE &&
717 (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
718 _mesa_debug(ctx, "Error linking program %u:\n%s\n",
719 shProg->Name, shProg->InfoLog);
720 }
721
722 /* debug code */
723 if (0) {
724 GLuint i;
725
726 printf("Link %u shaders in program %u: %s\n",
727 shProg->NumShaders, shProg->Name,
728 shProg->LinkStatus ? "Success" : "Failed");
729
730 for (i = 0; i < shProg->NumShaders; i++) {
731 printf(" shader %u, type 0x%x\n",
732 shProg->Shaders[i]->Name,
733 shProg->Shaders[i]->Type);
734 }
735 }
736 }
737
738
739 /**
740 * Print basic shader info (for debug).
741 */
742 static void
743 print_shader_info(const struct gl_shader_program *shProg)
744 {
745 GLuint i;
746
747 printf("Mesa: glUseProgram(%u)\n", shProg->Name);
748 for (i = 0; i < shProg->NumShaders; i++) {
749 const char *s;
750 switch (shProg->Shaders[i]->Type) {
751 case GL_VERTEX_SHADER:
752 s = "vertex";
753 break;
754 case GL_FRAGMENT_SHADER:
755 s = "fragment";
756 break;
757 case GL_GEOMETRY_SHADER:
758 s = "geometry";
759 break;
760 default:
761 s = "";
762 }
763 printf(" %s shader %u, checksum %u\n", s,
764 shProg->Shaders[i]->Name,
765 shProg->Shaders[i]->SourceChecksum);
766 }
767 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX])
768 printf(" vert prog %u\n",
769 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id);
770 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT])
771 printf(" frag prog %u\n",
772 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id);
773 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY])
774 printf(" geom prog %u\n",
775 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id);
776 }
777
778
779 /**
780 * Use the named shader program for subsequent glUniform calls
781 */
782 void
783 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
784 const char *caller)
785 {
786 if ((shProg != NULL) && !shProg->LinkStatus) {
787 _mesa_error(ctx, GL_INVALID_OPERATION,
788 "%s(program %u not linked)", caller, shProg->Name);
789 return;
790 }
791
792 if (ctx->Shader.ActiveProgram != shProg) {
793 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, shProg);
794 }
795 }
796
797 /**
798 */
799 static bool
800 use_shader_program(struct gl_context *ctx, GLenum type,
801 struct gl_shader_program *shProg)
802 {
803 struct gl_shader_program **target;
804
805 switch (type) {
806 #if FEATURE_ARB_vertex_shader
807 case GL_VERTEX_SHADER:
808 target = &ctx->Shader.CurrentVertexProgram;
809 if ((shProg == NULL)
810 || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) {
811 shProg = NULL;
812 }
813 break;
814 #endif
815 #if FEATURE_ARB_geometry_shader4
816 case GL_GEOMETRY_SHADER_ARB:
817 target = &ctx->Shader.CurrentGeometryProgram;
818 if ((shProg == NULL)
819 || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) {
820 shProg = NULL;
821 }
822 break;
823 #endif
824 #if FEATURE_ARB_fragment_shader
825 case GL_FRAGMENT_SHADER:
826 target = &ctx->Shader.CurrentFragmentProgram;
827 if ((shProg == NULL)
828 || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) {
829 shProg = NULL;
830 }
831 break;
832 #endif
833 default:
834 return false;
835 }
836
837 if (*target != shProg) {
838 FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
839
840 /* If the shader is also bound as the current rendering shader, unbind
841 * it from that binding point as well. This ensures that the correct
842 * semantics of glDeleteProgram are maintained.
843 */
844 switch (type) {
845 #if FEATURE_ARB_vertex_shader
846 case GL_VERTEX_SHADER:
847 /* Empty for now. */
848 break;
849 #endif
850 #if FEATURE_ARB_geometry_shader4
851 case GL_GEOMETRY_SHADER_ARB:
852 /* Empty for now. */
853 break;
854 #endif
855 #if FEATURE_ARB_fragment_shader
856 case GL_FRAGMENT_SHADER:
857 if (*target == ctx->Shader._CurrentFragmentProgram) {
858 _mesa_reference_shader_program(ctx,
859 &ctx->Shader._CurrentFragmentProgram,
860 NULL);
861 }
862 break;
863 #endif
864 }
865
866 _mesa_reference_shader_program(ctx, target, shProg);
867 return true;
868 }
869
870 return false;
871 }
872
873 /**
874 * Use the named shader program for subsequent rendering.
875 */
876 void
877 _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
878 {
879 use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
880 use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg);
881 use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg);
882 _mesa_active_program(ctx, shProg, "glUseProgram");
883
884 if (ctx->Driver.UseProgram)
885 ctx->Driver.UseProgram(ctx, shProg);
886 }
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 struct gl_transform_feedback_object *obj =
1361 ctx->TransformFeedback.CurrentObject;
1362
1363 ASSERT_OUTSIDE_BEGIN_END(ctx);
1364
1365 if (obj->Active && !obj->Paused) {
1366 _mesa_error(ctx, GL_INVALID_OPERATION,
1367 "glUseProgram(transform feedback active)");
1368 return;
1369 }
1370
1371 if (program) {
1372 shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
1373 if (!shProg) {
1374 return;
1375 }
1376 if (!shProg->LinkStatus) {
1377 _mesa_error(ctx, GL_INVALID_OPERATION,
1378 "glUseProgram(program %u not linked)", program);
1379 return;
1380 }
1381
1382 /* debug code */
1383 if (ctx->Shader.Flags & GLSL_USE_PROG) {
1384 print_shader_info(shProg);
1385 }
1386 }
1387 else {
1388 shProg = NULL;
1389 }
1390
1391 _mesa_use_program(ctx, shProg);
1392 }
1393
1394
1395 void GLAPIENTRY
1396 _mesa_ValidateProgramARB(GLhandleARB program)
1397 {
1398 GET_CURRENT_CONTEXT(ctx);
1399 validate_program(ctx, program);
1400 }
1401
1402 #ifdef FEATURE_ES2
1403
1404 void GLAPIENTRY
1405 _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1406 GLint* range, GLint* precision)
1407 {
1408 const struct gl_program_constants *limits;
1409 const struct gl_precision *p;
1410 GET_CURRENT_CONTEXT(ctx);
1411
1412 switch (shadertype) {
1413 case GL_VERTEX_SHADER:
1414 limits = &ctx->Const.VertexProgram;
1415 break;
1416 case GL_FRAGMENT_SHADER:
1417 limits = &ctx->Const.FragmentProgram;
1418 break;
1419 default:
1420 _mesa_error(ctx, GL_INVALID_ENUM,
1421 "glGetShaderPrecisionFormat(shadertype)");
1422 return;
1423 }
1424
1425 switch (precisiontype) {
1426 case GL_LOW_FLOAT:
1427 p = &limits->LowFloat;
1428 break;
1429 case GL_MEDIUM_FLOAT:
1430 p = &limits->MediumFloat;
1431 break;
1432 case GL_HIGH_FLOAT:
1433 p = &limits->HighFloat;
1434 break;
1435 case GL_LOW_INT:
1436 p = &limits->LowInt;
1437 break;
1438 case GL_MEDIUM_INT:
1439 p = &limits->MediumInt;
1440 break;
1441 case GL_HIGH_INT:
1442 p = &limits->HighInt;
1443 break;
1444 default:
1445 _mesa_error(ctx, GL_INVALID_ENUM,
1446 "glGetShaderPrecisionFormat(precisiontype)");
1447 return;
1448 }
1449
1450 range[0] = p->RangeMin;
1451 range[1] = p->RangeMax;
1452 precision[0] = p->Precision;
1453 }
1454
1455
1456 void GLAPIENTRY
1457 _mesa_ReleaseShaderCompiler(void)
1458 {
1459 _mesa_destroy_shader_compiler_caches();
1460 }
1461
1462
1463 void GLAPIENTRY
1464 _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
1465 const void* binary, GLint length)
1466 {
1467 GET_CURRENT_CONTEXT(ctx);
1468 (void) n;
1469 (void) shaders;
1470 (void) binaryformat;
1471 (void) binary;
1472 (void) length;
1473 _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
1474 }
1475
1476 #endif /* FEATURE_ES2 */
1477
1478
1479 #if FEATURE_ARB_geometry_shader4
1480
1481 void GLAPIENTRY
1482 _mesa_ProgramParameteriARB(GLuint program, GLenum pname, GLint value)
1483 {
1484 struct gl_shader_program *shProg;
1485 GET_CURRENT_CONTEXT(ctx);
1486
1487 ASSERT_OUTSIDE_BEGIN_END(ctx);
1488
1489 shProg = _mesa_lookup_shader_program_err(ctx, program,
1490 "glProgramParameteri");
1491 if (!shProg)
1492 return;
1493
1494 switch (pname) {
1495 case GL_GEOMETRY_VERTICES_OUT_ARB:
1496 if (value < 1 ||
1497 (unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
1498 _mesa_error(ctx, GL_INVALID_VALUE,
1499 "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
1500 value);
1501 return;
1502 }
1503 shProg->Geom.VerticesOut = value;
1504 break;
1505 case GL_GEOMETRY_INPUT_TYPE_ARB:
1506 switch (value) {
1507 case GL_POINTS:
1508 case GL_LINES:
1509 case GL_LINES_ADJACENCY_ARB:
1510 case GL_TRIANGLES:
1511 case GL_TRIANGLES_ADJACENCY_ARB:
1512 shProg->Geom.InputType = value;
1513 break;
1514 default:
1515 _mesa_error(ctx, GL_INVALID_VALUE,
1516 "glProgramParameteri(geometry input type = %s",
1517 _mesa_lookup_enum_by_nr(value));
1518 return;
1519 }
1520 break;
1521 case GL_GEOMETRY_OUTPUT_TYPE_ARB:
1522 switch (value) {
1523 case GL_POINTS:
1524 case GL_LINE_STRIP:
1525 case GL_TRIANGLE_STRIP:
1526 shProg->Geom.OutputType = value;
1527 break;
1528 default:
1529 _mesa_error(ctx, GL_INVALID_VALUE,
1530 "glProgramParameteri(geometry output type = %s",
1531 _mesa_lookup_enum_by_nr(value));
1532 return;
1533 }
1534 break;
1535 default:
1536 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)",
1537 _mesa_lookup_enum_by_nr(pname));
1538 break;
1539 }
1540 }
1541
1542 #endif
1543
1544 void
1545 _mesa_use_shader_program(struct gl_context *ctx, GLenum type,
1546 struct gl_shader_program *shProg)
1547 {
1548 use_shader_program(ctx, type, shProg);
1549
1550 if (ctx->Driver.UseProgram)
1551 ctx->Driver.UseProgram(ctx, shProg);
1552 }
1553
1554
1555 /**
1556 * For GL_EXT_separate_shader_objects
1557 */
1558 void GLAPIENTRY
1559 _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
1560 {
1561 GET_CURRENT_CONTEXT(ctx);
1562 struct gl_shader_program *shProg = NULL;
1563
1564 ASSERT_OUTSIDE_BEGIN_END(ctx);
1565
1566 if (!validate_shader_target(ctx, type)) {
1567 _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
1568 return;
1569 }
1570
1571 if (ctx->TransformFeedback.CurrentObject->Active &&
1572 !ctx->TransformFeedback.CurrentObject->Paused) {
1573 _mesa_error(ctx, GL_INVALID_OPERATION,
1574 "glUseShaderProgramEXT(transform feedback is active)");
1575 return;
1576 }
1577
1578 if (program) {
1579 shProg = _mesa_lookup_shader_program_err(ctx, program,
1580 "glUseShaderProgramEXT");
1581 if (shProg == NULL)
1582 return;
1583
1584 if (!shProg->LinkStatus) {
1585 _mesa_error(ctx, GL_INVALID_OPERATION,
1586 "glUseShaderProgramEXT(program not linked)");
1587 return;
1588 }
1589 }
1590
1591 _mesa_use_shader_program(ctx, type, shProg);
1592 }
1593
1594
1595 /**
1596 * For GL_EXT_separate_shader_objects
1597 */
1598 void GLAPIENTRY
1599 _mesa_ActiveProgramEXT(GLuint program)
1600 {
1601 GET_CURRENT_CONTEXT(ctx);
1602 struct gl_shader_program *shProg = (program != 0)
1603 ? _mesa_lookup_shader_program_err(ctx, program, "glActiveProgramEXT")
1604 : NULL;
1605
1606 _mesa_active_program(ctx, shProg, "glActiveProgramEXT");
1607 return;
1608 }
1609
1610
1611 /**
1612 * For GL_EXT_separate_shader_objects
1613 */
1614 GLuint GLAPIENTRY
1615 _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
1616 {
1617 GET_CURRENT_CONTEXT(ctx);
1618 const GLuint shader = create_shader(ctx, type);
1619 GLuint program = 0;
1620
1621 if (shader) {
1622 shader_source(ctx, shader, _mesa_strdup(string));
1623 compile_shader(ctx, shader);
1624
1625 program = create_shader_program(ctx);
1626 if (program) {
1627 struct gl_shader_program *shProg;
1628 struct gl_shader *sh;
1629 GLint compiled = GL_FALSE;
1630
1631 shProg = _mesa_lookup_shader_program(ctx, program);
1632 sh = _mesa_lookup_shader(ctx, shader);
1633
1634 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
1635 if (compiled) {
1636 attach_shader(ctx, program, shader);
1637 link_program(ctx, program);
1638 detach_shader(ctx, program, shader);
1639
1640 #if 0
1641 /* Possibly... */
1642 if (active-user-defined-varyings-in-linked-program) {
1643 append-error-to-info-log;
1644 shProg->LinkStatus = GL_FALSE;
1645 }
1646 #endif
1647 }
1648
1649 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
1650 }
1651
1652 delete_shader(ctx, shader);
1653 }
1654
1655 return program;
1656 }
1657
1658 /**
1659 * Plug in shader-related functions into API dispatch table.
1660 */
1661 void
1662 _mesa_init_shader_dispatch(struct _glapi_table *exec)
1663 {
1664 #if FEATURE_GL
1665 /* GL_ARB_vertex/fragment_shader */
1666 SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
1667 SET_GetHandleARB(exec, _mesa_GetHandleARB);
1668 SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
1669 SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
1670 SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
1671 SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
1672 SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
1673 SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
1674 SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
1675 SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
1676 SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
1677 SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
1678 SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
1679 SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
1680 SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
1681 SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
1682
1683 /* OpenGL 2.0 */
1684 SET_AttachShader(exec, _mesa_AttachShader);
1685 SET_CreateProgram(exec, _mesa_CreateProgram);
1686 SET_CreateShader(exec, _mesa_CreateShader);
1687 SET_DeleteProgram(exec, _mesa_DeleteProgram);
1688 SET_DeleteShader(exec, _mesa_DeleteShader);
1689 SET_DetachShader(exec, _mesa_DetachShader);
1690 SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
1691 SET_GetProgramiv(exec, _mesa_GetProgramiv);
1692 SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
1693 SET_GetShaderiv(exec, _mesa_GetShaderiv);
1694 SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
1695 SET_IsProgram(exec, _mesa_IsProgram);
1696 SET_IsShader(exec, _mesa_IsShader);
1697
1698 #if FEATURE_ARB_vertex_shader
1699 SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
1700 SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
1701 SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
1702 #endif
1703
1704 #if FEATURE_ARB_geometry_shader4
1705 SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB);
1706 #endif
1707
1708 SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT);
1709 SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT);
1710 SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT);
1711
1712 /* GL_EXT_gpu_shader4 / GL 3.0 */
1713 SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation);
1714 SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation);
1715
1716 /* GL_ARB_ES2_compatibility */
1717 SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler);
1718 SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat);
1719
1720 /* GL_ARB_blend_func_extended */
1721 SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed);
1722 SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex);
1723 #endif /* FEATURE_GL */
1724 }
1725