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