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