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