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