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