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