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