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