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