glsl: Fix unsupported version error for GLSL ES 3.00, future proof for 3.30.
[mesa.git] / src / glsl / glsl_parser_extras.cpp
1 /*
2 * Copyright © 2008, 2009 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <assert.h>
27
28 extern "C" {
29 #include "main/core.h" /* for struct gl_context */
30 #include "main/context.h"
31 }
32
33 #include "ralloc.h"
34 #include "ast.h"
35 #include "glsl_parser_extras.h"
36 #include "glsl_parser.h"
37 #include "ir_optimization.h"
38 #include "loop_analysis.h"
39
40 /**
41 * Format a short human-readable description of the given GLSL version.
42 */
43 const char *
44 glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version)
45 {
46 return ralloc_asprintf(mem_ctx, "GLSL%s %d.%02d", is_es ? " ES" : "",
47 version / 100, version % 100);
48 }
49
50
51 static unsigned known_desktop_glsl_versions[] =
52 { 110, 120, 130, 140, 150, 330, 400, 410, 420, 430 };
53
54
55 _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
56 GLenum target, void *mem_ctx)
57 : ctx(_ctx)
58 {
59 switch (target) {
60 case GL_VERTEX_SHADER: this->target = vertex_shader; break;
61 case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
62 case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
63 }
64
65 this->scanner = NULL;
66 this->translation_unit.make_empty();
67 this->symbols = new(mem_ctx) glsl_symbol_table;
68 this->info_log = ralloc_strdup(mem_ctx, "");
69 this->error = false;
70 this->loop_nesting_ast = NULL;
71 this->switch_state.switch_nesting_ast = NULL;
72
73 this->num_builtins_to_link = 0;
74
75 /* Set default language version and extensions */
76 this->language_version = 110;
77 this->es_shader = false;
78 this->ARB_texture_rectangle_enable = true;
79
80 /* OpenGL ES 2.0 has different defaults from desktop GL. */
81 if (ctx->API == API_OPENGLES2) {
82 this->language_version = 100;
83 this->es_shader = true;
84 this->ARB_texture_rectangle_enable = false;
85 }
86
87 this->extensions = &ctx->Extensions;
88
89 this->Const.MaxLights = ctx->Const.MaxLights;
90 this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
91 this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
92 this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
93 this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs;
94 this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents;
95 this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4;
96 this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits;
97 this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
98 this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
99 this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
100 this->Const.MinProgramTexelOffset = ctx->Const.MinProgramTexelOffset;
101 this->Const.MaxProgramTexelOffset = ctx->Const.MaxProgramTexelOffset;
102
103 this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
104
105 /* Populate the list of supported GLSL versions */
106 /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or
107 * the OpenGL 3.2 Core context is supported, this logic will need
108 * change. Older versions of GLSL are no longer supported
109 * outside the compatibility contexts of 3.x.
110 */
111 this->num_supported_versions = 0;
112 if (_mesa_is_desktop_gl(ctx)) {
113 for (unsigned i = 0; i < ARRAY_SIZE(known_desktop_glsl_versions); i++) {
114 if (known_desktop_glsl_versions[i] <= ctx->Const.GLSLVersion) {
115 this->supported_versions[this->num_supported_versions].ver
116 = known_desktop_glsl_versions[i];
117 this->supported_versions[this->num_supported_versions].es = false;
118 this->num_supported_versions++;
119 }
120 }
121 }
122 if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) {
123 this->supported_versions[this->num_supported_versions].ver = 100;
124 this->supported_versions[this->num_supported_versions].es = true;
125 this->num_supported_versions++;
126 }
127 if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) {
128 this->supported_versions[this->num_supported_versions].ver = 300;
129 this->supported_versions[this->num_supported_versions].es = true;
130 this->num_supported_versions++;
131 }
132 assert(this->num_supported_versions
133 <= ARRAY_SIZE(this->supported_versions));
134
135 /* Create a string for use in error messages to tell the user which GLSL
136 * versions are supported.
137 */
138 char *supported = ralloc_strdup(this, "");
139 for (unsigned i = 0; i < this->num_supported_versions; i++) {
140 unsigned ver = this->supported_versions[i].ver;
141 const char *const prefix = (i == 0)
142 ? ""
143 : ((i == this->num_supported_versions - 1) ? ", and " : ", ");
144 const char *const suffix = (this->supported_versions[i].es) ? " ES" : "";
145
146 ralloc_asprintf_append(& supported, "%s%u.%02u%s",
147 prefix,
148 ver / 100, ver % 100,
149 suffix);
150 }
151
152 this->supported_version_string = supported;
153
154 if (ctx->Const.ForceGLSLExtensionsWarn)
155 _mesa_glsl_process_extension("all", NULL, "warn", NULL, this);
156
157 this->default_uniform_qualifier = new(this) ast_type_qualifier();
158 this->default_uniform_qualifier->flags.q.shared = 1;
159 this->default_uniform_qualifier->flags.q.column_major = 1;
160 }
161
162 /**
163 * Determine whether the current GLSL version is sufficiently high to support
164 * a certain feature, and generate an error message if it isn't.
165 *
166 * \param required_glsl_version and \c required_glsl_es_version are
167 * interpreted as they are in _mesa_glsl_parse_state::is_version().
168 *
169 * \param locp is the parser location where the error should be reported.
170 *
171 * \param fmt (and additional arguments) constitute a printf-style error
172 * message to report if the version check fails. Information about the
173 * current and required GLSL versions will be appended. So, for example, if
174 * the GLSL version being compiled is 1.20, and check_version(130, 300, locp,
175 * "foo unsupported") is called, the error message will be "foo unsupported in
176 * GLSL 1.20 (GLSL 1.30 or GLSL 3.00 ES required)".
177 */
178 bool
179 _mesa_glsl_parse_state::check_version(unsigned required_glsl_version,
180 unsigned required_glsl_es_version,
181 YYLTYPE *locp, const char *fmt, ...)
182 {
183 if (this->is_version(required_glsl_version, required_glsl_es_version))
184 return true;
185
186 va_list args;
187 va_start(args, fmt);
188 char *problem = ralloc_vasprintf(this, fmt, args);
189 va_end(args);
190 const char *glsl_version_string
191 = glsl_compute_version_string(this, false, required_glsl_version);
192 const char *glsl_es_version_string
193 = glsl_compute_version_string(this, true, required_glsl_es_version);
194 const char *requirement_string = "";
195 if (required_glsl_version && required_glsl_es_version) {
196 requirement_string = ralloc_asprintf(this, " (%s or %s required)",
197 glsl_version_string,
198 glsl_es_version_string);
199 } else if (required_glsl_version) {
200 requirement_string = ralloc_asprintf(this, " (%s required)",
201 glsl_version_string);
202 } else if (required_glsl_es_version) {
203 requirement_string = ralloc_asprintf(this, " (%s required)",
204 glsl_es_version_string);
205 }
206 _mesa_glsl_error(locp, this, "%s in %s%s.",
207 problem, this->get_version_string(),
208 requirement_string);
209
210 return false;
211 }
212
213 /**
214 * Process a GLSL #version directive.
215 *
216 * \param version is the integer that follows the #version token.
217 *
218 * \param ident is a string identifier that follows the integer, if any is
219 * present. Otherwise NULL.
220 */
221 void
222 _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
223 const char *ident)
224 {
225 bool es_token_present = false;
226 if (ident) {
227 if (strcmp(ident, "es") == 0) {
228 es_token_present = true;
229 } else {
230 _mesa_glsl_error(locp, this,
231 "Illegal text following version number\n");
232 }
233 }
234
235 this->es_shader = es_token_present;
236 if (version == 100) {
237 if (es_token_present) {
238 _mesa_glsl_error(locp, this,
239 "GLSL 1.00 ES should be selected using "
240 "`#version 100'\n");
241 } else {
242 this->es_shader = true;
243 }
244 }
245
246 this->language_version = version;
247
248 bool supported = false;
249 for (unsigned i = 0; i < this->num_supported_versions; i++) {
250 if (this->supported_versions[i].ver == (unsigned) version
251 && this->supported_versions[i].es == this->es_shader) {
252 supported = true;
253 break;
254 }
255 }
256
257 if (!supported) {
258 _mesa_glsl_error(locp, this, "%s is not supported. "
259 "Supported versions are: %s\n",
260 this->get_version_string(),
261 this->supported_version_string);
262
263 /* On exit, the language_version must be set to a valid value.
264 * Later calls to _mesa_glsl_initialize_types will misbehave if
265 * the version is invalid.
266 */
267 switch (this->ctx->API) {
268 case API_OPENGL_COMPAT:
269 case API_OPENGL_CORE:
270 this->language_version = this->ctx->Const.GLSLVersion;
271 break;
272
273 case API_OPENGLES:
274 assert(!"Should not get here.");
275 /* FALLTHROUGH */
276
277 case API_OPENGLES2:
278 this->language_version = 100;
279 break;
280 }
281 }
282
283 if (this->language_version >= 140) {
284 this->ARB_uniform_buffer_object_enable = true;
285 }
286
287 if (this->language_version == 300 && this->es_shader) {
288 this->ARB_explicit_attrib_location_enable = true;
289 }
290 }
291
292 const char *
293 _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
294 {
295 switch (target) {
296 case vertex_shader: return "vertex";
297 case fragment_shader: return "fragment";
298 case geometry_shader: return "geometry";
299 }
300
301 assert(!"Should not get here.");
302 return "unknown";
303 }
304
305 /* This helper function will append the given message to the shader's
306 info log and report it via GL_ARB_debug_output. Per that extension,
307 'type' is one of the enum values classifying the message, and
308 'id' is the implementation-defined ID of the given message. */
309 static void
310 _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
311 GLenum type, GLuint id, const char *fmt, va_list ap)
312 {
313 bool error = (type == GL_DEBUG_TYPE_ERROR_ARB);
314
315 assert(state->info_log != NULL);
316
317 /* Get the offset that the new message will be written to. */
318 int msg_offset = strlen(state->info_log);
319
320 ralloc_asprintf_append(&state->info_log, "%u:%u(%u): %s: ",
321 locp->source,
322 locp->first_line,
323 locp->first_column,
324 error ? "error" : "warning");
325 ralloc_vasprintf_append(&state->info_log, fmt, ap);
326
327 const char *const msg = &state->info_log[msg_offset];
328 struct gl_context *ctx = state->ctx;
329 /* Report the error via GL_ARB_debug_output. */
330 if (error)
331 _mesa_shader_debug(ctx, type, id, msg, strlen(msg));
332
333 ralloc_strcat(&state->info_log, "\n");
334 }
335
336 void
337 _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
338 const char *fmt, ...)
339 {
340 va_list ap;
341 GLenum type = GL_DEBUG_TYPE_ERROR_ARB;
342
343 state->error = true;
344
345 va_start(ap, fmt);
346 _mesa_glsl_msg(locp, state, type, SHADER_ERROR_UNKNOWN, fmt, ap);
347 va_end(ap);
348 }
349
350
351 void
352 _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
353 const char *fmt, ...)
354 {
355 va_list ap;
356 GLenum type = GL_DEBUG_TYPE_OTHER_ARB;
357
358 va_start(ap, fmt);
359 _mesa_glsl_msg(locp, state, type, 0, fmt, ap);
360 va_end(ap);
361 }
362
363
364 /**
365 * Enum representing the possible behaviors that can be specified in
366 * an #extension directive.
367 */
368 enum ext_behavior {
369 extension_disable,
370 extension_enable,
371 extension_require,
372 extension_warn
373 };
374
375 /**
376 * Element type for _mesa_glsl_supported_extensions
377 */
378 struct _mesa_glsl_extension {
379 /**
380 * Name of the extension when referred to in a GLSL extension
381 * statement
382 */
383 const char *name;
384
385 /** True if this extension is available to vertex shaders */
386 bool avail_in_VS;
387
388 /** True if this extension is available to geometry shaders */
389 bool avail_in_GS;
390
391 /** True if this extension is available to fragment shaders */
392 bool avail_in_FS;
393
394 /** True if this extension is available to desktop GL shaders */
395 bool avail_in_GL;
396
397 /** True if this extension is available to GLES shaders */
398 bool avail_in_ES;
399
400 /**
401 * Flag in the gl_extensions struct indicating whether this
402 * extension is supported by the driver, or
403 * &gl_extensions::dummy_true if supported by all drivers.
404 *
405 * Note: the type (GLboolean gl_extensions::*) is a "pointer to
406 * member" type, the type-safe alternative to the "offsetof" macro.
407 * In a nutshell:
408 *
409 * - foo bar::* p declares p to be an "offset" to a field of type
410 * foo that exists within struct bar
411 * - &bar::baz computes the "offset" of field baz within struct bar
412 * - x.*p accesses the field of x that exists at "offset" p
413 * - x->*p is equivalent to (*x).*p
414 */
415 const GLboolean gl_extensions::* supported_flag;
416
417 /**
418 * Flag in the _mesa_glsl_parse_state struct that should be set
419 * when this extension is enabled.
420 *
421 * See note in _mesa_glsl_extension::supported_flag about "pointer
422 * to member" types.
423 */
424 bool _mesa_glsl_parse_state::* enable_flag;
425
426 /**
427 * Flag in the _mesa_glsl_parse_state struct that should be set
428 * when the shader requests "warn" behavior for this extension.
429 *
430 * See note in _mesa_glsl_extension::supported_flag about "pointer
431 * to member" types.
432 */
433 bool _mesa_glsl_parse_state::* warn_flag;
434
435
436 bool compatible_with_state(const _mesa_glsl_parse_state *state) const;
437 void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
438 };
439
440 #define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \
441 { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \
442 &_mesa_glsl_parse_state::NAME##_enable, \
443 &_mesa_glsl_parse_state::NAME##_warn }
444
445 /**
446 * Table of extensions that can be enabled/disabled within a shader,
447 * and the conditions under which they are supported.
448 */
449 static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
450 /* target availability API availability */
451 /* name VS GS FS GL ES supported flag */
452 EXT(ARB_conservative_depth, false, false, true, true, false, ARB_conservative_depth),
453 EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true),
454 EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced),
455 EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location),
456 EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions),
457 EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true),
458 EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array),
459 EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod),
460 EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
461 EXT(AMD_conservative_depth, false, false, true, true, false, ARB_conservative_depth),
462 EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
463 EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D),
464 EXT(OES_EGL_image_external, true, false, true, false, true, OES_EGL_image_external),
465 EXT(ARB_shader_bit_encoding, true, true, true, true, false, ARB_shader_bit_encoding),
466 EXT(ARB_uniform_buffer_object, true, false, true, true, false, ARB_uniform_buffer_object),
467 EXT(OES_standard_derivatives, false, false, true, false, true, OES_standard_derivatives),
468 EXT(ARB_texture_cube_map_array, true, false, true, true, false, ARB_texture_cube_map_array),
469 EXT(ARB_shading_language_packing, true, false, true, true, false, ARB_shading_language_packing),
470 };
471
472 #undef EXT
473
474
475 /**
476 * Determine whether a given extension is compatible with the target,
477 * API, and extension information in the current parser state.
478 */
479 bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state *
480 state) const
481 {
482 /* Check that this extension matches the type of shader we are
483 * compiling to.
484 */
485 switch (state->target) {
486 case vertex_shader:
487 if (!this->avail_in_VS) {
488 return false;
489 }
490 break;
491 case geometry_shader:
492 if (!this->avail_in_GS) {
493 return false;
494 }
495 break;
496 case fragment_shader:
497 if (!this->avail_in_FS) {
498 return false;
499 }
500 break;
501 default:
502 assert (!"Unrecognized shader target");
503 return false;
504 }
505
506 /* Check that this extension matches whether we are compiling
507 * for desktop GL or GLES.
508 */
509 if (state->es_shader) {
510 if (!this->avail_in_ES) return false;
511 } else {
512 if (!this->avail_in_GL) return false;
513 }
514
515 /* Check that this extension is supported by the OpenGL
516 * implementation.
517 *
518 * Note: the ->* operator indexes into state->extensions by the
519 * offset this->supported_flag. See
520 * _mesa_glsl_extension::supported_flag for more info.
521 */
522 return state->extensions->*(this->supported_flag);
523 }
524
525 /**
526 * Set the appropriate flags in the parser state to establish the
527 * given behavior for this extension.
528 */
529 void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state,
530 ext_behavior behavior) const
531 {
532 /* Note: the ->* operator indexes into state by the
533 * offsets this->enable_flag and this->warn_flag. See
534 * _mesa_glsl_extension::supported_flag for more info.
535 */
536 state->*(this->enable_flag) = (behavior != extension_disable);
537 state->*(this->warn_flag) = (behavior == extension_warn);
538 }
539
540 /**
541 * Find an extension by name in _mesa_glsl_supported_extensions. If
542 * the name is not found, return NULL.
543 */
544 static const _mesa_glsl_extension *find_extension(const char *name)
545 {
546 for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) {
547 if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) {
548 return &_mesa_glsl_supported_extensions[i];
549 }
550 }
551 return NULL;
552 }
553
554
555 bool
556 _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
557 const char *behavior_string, YYLTYPE *behavior_locp,
558 _mesa_glsl_parse_state *state)
559 {
560 ext_behavior behavior;
561 if (strcmp(behavior_string, "warn") == 0) {
562 behavior = extension_warn;
563 } else if (strcmp(behavior_string, "require") == 0) {
564 behavior = extension_require;
565 } else if (strcmp(behavior_string, "enable") == 0) {
566 behavior = extension_enable;
567 } else if (strcmp(behavior_string, "disable") == 0) {
568 behavior = extension_disable;
569 } else {
570 _mesa_glsl_error(behavior_locp, state,
571 "Unknown extension behavior `%s'",
572 behavior_string);
573 return false;
574 }
575
576 if (strcmp(name, "all") == 0) {
577 if ((behavior == extension_enable) || (behavior == extension_require)) {
578 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
579 (behavior == extension_enable)
580 ? "enable" : "require");
581 return false;
582 } else {
583 for (unsigned i = 0;
584 i < Elements(_mesa_glsl_supported_extensions); ++i) {
585 const _mesa_glsl_extension *extension
586 = &_mesa_glsl_supported_extensions[i];
587 if (extension->compatible_with_state(state)) {
588 _mesa_glsl_supported_extensions[i].set_flags(state, behavior);
589 }
590 }
591 }
592 } else {
593 const _mesa_glsl_extension *extension = find_extension(name);
594 if (extension && extension->compatible_with_state(state)) {
595 extension->set_flags(state, behavior);
596 } else {
597 static const char *const fmt = "extension `%s' unsupported in %s shader";
598
599 if (behavior == extension_require) {
600 _mesa_glsl_error(name_locp, state, fmt,
601 name, _mesa_glsl_shader_target_name(state->target));
602 return false;
603 } else {
604 _mesa_glsl_warning(name_locp, state, fmt,
605 name, _mesa_glsl_shader_target_name(state->target));
606 }
607 }
608 }
609
610 return true;
611 }
612
613 void
614 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
615 {
616 if (q->flags.q.constant)
617 printf("const ");
618
619 if (q->flags.q.invariant)
620 printf("invariant ");
621
622 if (q->flags.q.attribute)
623 printf("attribute ");
624
625 if (q->flags.q.varying)
626 printf("varying ");
627
628 if (q->flags.q.in && q->flags.q.out)
629 printf("inout ");
630 else {
631 if (q->flags.q.in)
632 printf("in ");
633
634 if (q->flags.q.out)
635 printf("out ");
636 }
637
638 if (q->flags.q.centroid)
639 printf("centroid ");
640 if (q->flags.q.uniform)
641 printf("uniform ");
642 if (q->flags.q.smooth)
643 printf("smooth ");
644 if (q->flags.q.flat)
645 printf("flat ");
646 if (q->flags.q.noperspective)
647 printf("noperspective ");
648 }
649
650
651 void
652 ast_node::print(void) const
653 {
654 printf("unhandled node ");
655 }
656
657
658 ast_node::ast_node(void)
659 {
660 this->location.source = 0;
661 this->location.line = 0;
662 this->location.column = 0;
663 }
664
665
666 static void
667 ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
668 {
669 if (is_array) {
670 printf("[ ");
671
672 if (array_size)
673 array_size->print();
674
675 printf("] ");
676 }
677 }
678
679
680 void
681 ast_compound_statement::print(void) const
682 {
683 printf("{\n");
684
685 foreach_list_const(n, &this->statements) {
686 ast_node *ast = exec_node_data(ast_node, n, link);
687 ast->print();
688 }
689
690 printf("}\n");
691 }
692
693
694 ast_compound_statement::ast_compound_statement(int new_scope,
695 ast_node *statements)
696 {
697 this->new_scope = new_scope;
698
699 if (statements != NULL) {
700 this->statements.push_degenerate_list_at_head(&statements->link);
701 }
702 }
703
704
705 void
706 ast_expression::print(void) const
707 {
708 switch (oper) {
709 case ast_assign:
710 case ast_mul_assign:
711 case ast_div_assign:
712 case ast_mod_assign:
713 case ast_add_assign:
714 case ast_sub_assign:
715 case ast_ls_assign:
716 case ast_rs_assign:
717 case ast_and_assign:
718 case ast_xor_assign:
719 case ast_or_assign:
720 subexpressions[0]->print();
721 printf("%s ", operator_string(oper));
722 subexpressions[1]->print();
723 break;
724
725 case ast_field_selection:
726 subexpressions[0]->print();
727 printf(". %s ", primary_expression.identifier);
728 break;
729
730 case ast_plus:
731 case ast_neg:
732 case ast_bit_not:
733 case ast_logic_not:
734 case ast_pre_inc:
735 case ast_pre_dec:
736 printf("%s ", operator_string(oper));
737 subexpressions[0]->print();
738 break;
739
740 case ast_post_inc:
741 case ast_post_dec:
742 subexpressions[0]->print();
743 printf("%s ", operator_string(oper));
744 break;
745
746 case ast_conditional:
747 subexpressions[0]->print();
748 printf("? ");
749 subexpressions[1]->print();
750 printf(": ");
751 subexpressions[2]->print();
752 break;
753
754 case ast_array_index:
755 subexpressions[0]->print();
756 printf("[ ");
757 subexpressions[1]->print();
758 printf("] ");
759 break;
760
761 case ast_function_call: {
762 subexpressions[0]->print();
763 printf("( ");
764
765 foreach_list_const (n, &this->expressions) {
766 if (n != this->expressions.get_head())
767 printf(", ");
768
769 ast_node *ast = exec_node_data(ast_node, n, link);
770 ast->print();
771 }
772
773 printf(") ");
774 break;
775 }
776
777 case ast_identifier:
778 printf("%s ", primary_expression.identifier);
779 break;
780
781 case ast_int_constant:
782 printf("%d ", primary_expression.int_constant);
783 break;
784
785 case ast_uint_constant:
786 printf("%u ", primary_expression.uint_constant);
787 break;
788
789 case ast_float_constant:
790 printf("%f ", primary_expression.float_constant);
791 break;
792
793 case ast_bool_constant:
794 printf("%s ",
795 primary_expression.bool_constant
796 ? "true" : "false");
797 break;
798
799 case ast_sequence: {
800 printf("( ");
801 foreach_list_const(n, & this->expressions) {
802 if (n != this->expressions.get_head())
803 printf(", ");
804
805 ast_node *ast = exec_node_data(ast_node, n, link);
806 ast->print();
807 }
808 printf(") ");
809 break;
810 }
811
812 default:
813 assert(0);
814 break;
815 }
816 }
817
818 ast_expression::ast_expression(int oper,
819 ast_expression *ex0,
820 ast_expression *ex1,
821 ast_expression *ex2)
822 {
823 this->oper = ast_operators(oper);
824 this->subexpressions[0] = ex0;
825 this->subexpressions[1] = ex1;
826 this->subexpressions[2] = ex2;
827 this->non_lvalue_description = NULL;
828 }
829
830
831 void
832 ast_expression_statement::print(void) const
833 {
834 if (expression)
835 expression->print();
836
837 printf("; ");
838 }
839
840
841 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
842 expression(ex)
843 {
844 /* empty */
845 }
846
847
848 void
849 ast_function::print(void) const
850 {
851 return_type->print();
852 printf(" %s (", identifier);
853
854 foreach_list_const(n, & this->parameters) {
855 ast_node *ast = exec_node_data(ast_node, n, link);
856 ast->print();
857 }
858
859 printf(")");
860 }
861
862
863 ast_function::ast_function(void)
864 : is_definition(false), signature(NULL)
865 {
866 /* empty */
867 }
868
869
870 void
871 ast_fully_specified_type::print(void) const
872 {
873 _mesa_ast_type_qualifier_print(& qualifier);
874 specifier->print();
875 }
876
877
878 void
879 ast_parameter_declarator::print(void) const
880 {
881 type->print();
882 if (identifier)
883 printf("%s ", identifier);
884 ast_opt_array_size_print(is_array, array_size);
885 }
886
887
888 void
889 ast_function_definition::print(void) const
890 {
891 prototype->print();
892 body->print();
893 }
894
895
896 void
897 ast_declaration::print(void) const
898 {
899 printf("%s ", identifier);
900 ast_opt_array_size_print(is_array, array_size);
901
902 if (initializer) {
903 printf("= ");
904 initializer->print();
905 }
906 }
907
908
909 ast_declaration::ast_declaration(const char *identifier, int is_array,
910 ast_expression *array_size,
911 ast_expression *initializer)
912 {
913 this->identifier = identifier;
914 this->is_array = is_array;
915 this->array_size = array_size;
916 this->initializer = initializer;
917 }
918
919
920 void
921 ast_declarator_list::print(void) const
922 {
923 assert(type || invariant);
924
925 if (type)
926 type->print();
927 else
928 printf("invariant ");
929
930 foreach_list_const (ptr, & this->declarations) {
931 if (ptr != this->declarations.get_head())
932 printf(", ");
933
934 ast_node *ast = exec_node_data(ast_node, ptr, link);
935 ast->print();
936 }
937
938 printf("; ");
939 }
940
941
942 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
943 {
944 this->type = type;
945 this->invariant = false;
946 this->ubo_qualifiers_valid = false;
947 }
948
949 void
950 ast_jump_statement::print(void) const
951 {
952 switch (mode) {
953 case ast_continue:
954 printf("continue; ");
955 break;
956 case ast_break:
957 printf("break; ");
958 break;
959 case ast_return:
960 printf("return ");
961 if (opt_return_value)
962 opt_return_value->print();
963
964 printf("; ");
965 break;
966 case ast_discard:
967 printf("discard; ");
968 break;
969 }
970 }
971
972
973 ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
974 {
975 this->mode = ast_jump_modes(mode);
976
977 if (mode == ast_return)
978 opt_return_value = return_value;
979 }
980
981
982 void
983 ast_selection_statement::print(void) const
984 {
985 printf("if ( ");
986 condition->print();
987 printf(") ");
988
989 then_statement->print();
990
991 if (else_statement) {
992 printf("else ");
993 else_statement->print();
994 }
995
996 }
997
998
999 ast_selection_statement::ast_selection_statement(ast_expression *condition,
1000 ast_node *then_statement,
1001 ast_node *else_statement)
1002 {
1003 this->condition = condition;
1004 this->then_statement = then_statement;
1005 this->else_statement = else_statement;
1006 }
1007
1008
1009 void
1010 ast_switch_statement::print(void) const
1011 {
1012 printf("switch ( ");
1013 test_expression->print();
1014 printf(") ");
1015
1016 body->print();
1017 }
1018
1019
1020 ast_switch_statement::ast_switch_statement(ast_expression *test_expression,
1021 ast_node *body)
1022 {
1023 this->test_expression = test_expression;
1024 this->body = body;
1025 }
1026
1027
1028 void
1029 ast_switch_body::print(void) const
1030 {
1031 printf("{\n");
1032 if (stmts != NULL) {
1033 stmts->print();
1034 }
1035 printf("}\n");
1036 }
1037
1038
1039 ast_switch_body::ast_switch_body(ast_case_statement_list *stmts)
1040 {
1041 this->stmts = stmts;
1042 }
1043
1044
1045 void ast_case_label::print(void) const
1046 {
1047 if (test_value != NULL) {
1048 printf("case ");
1049 test_value->print();
1050 printf(": ");
1051 } else {
1052 printf("default: ");
1053 }
1054 }
1055
1056
1057 ast_case_label::ast_case_label(ast_expression *test_value)
1058 {
1059 this->test_value = test_value;
1060 }
1061
1062
1063 void ast_case_label_list::print(void) const
1064 {
1065 foreach_list_const(n, & this->labels) {
1066 ast_node *ast = exec_node_data(ast_node, n, link);
1067 ast->print();
1068 }
1069 printf("\n");
1070 }
1071
1072
1073 ast_case_label_list::ast_case_label_list(void)
1074 {
1075 }
1076
1077
1078 void ast_case_statement::print(void) const
1079 {
1080 labels->print();
1081 foreach_list_const(n, & this->stmts) {
1082 ast_node *ast = exec_node_data(ast_node, n, link);
1083 ast->print();
1084 printf("\n");
1085 }
1086 }
1087
1088
1089 ast_case_statement::ast_case_statement(ast_case_label_list *labels)
1090 {
1091 this->labels = labels;
1092 }
1093
1094
1095 void ast_case_statement_list::print(void) const
1096 {
1097 foreach_list_const(n, & this->cases) {
1098 ast_node *ast = exec_node_data(ast_node, n, link);
1099 ast->print();
1100 }
1101 }
1102
1103
1104 ast_case_statement_list::ast_case_statement_list(void)
1105 {
1106 }
1107
1108
1109 void
1110 ast_iteration_statement::print(void) const
1111 {
1112 switch (mode) {
1113 case ast_for:
1114 printf("for( ");
1115 if (init_statement)
1116 init_statement->print();
1117 printf("; ");
1118
1119 if (condition)
1120 condition->print();
1121 printf("; ");
1122
1123 if (rest_expression)
1124 rest_expression->print();
1125 printf(") ");
1126
1127 body->print();
1128 break;
1129
1130 case ast_while:
1131 printf("while ( ");
1132 if (condition)
1133 condition->print();
1134 printf(") ");
1135 body->print();
1136 break;
1137
1138 case ast_do_while:
1139 printf("do ");
1140 body->print();
1141 printf("while ( ");
1142 if (condition)
1143 condition->print();
1144 printf("); ");
1145 break;
1146 }
1147 }
1148
1149
1150 ast_iteration_statement::ast_iteration_statement(int mode,
1151 ast_node *init,
1152 ast_node *condition,
1153 ast_expression *rest_expression,
1154 ast_node *body)
1155 {
1156 this->mode = ast_iteration_modes(mode);
1157 this->init_statement = init;
1158 this->condition = condition;
1159 this->rest_expression = rest_expression;
1160 this->body = body;
1161 }
1162
1163
1164 void
1165 ast_struct_specifier::print(void) const
1166 {
1167 printf("struct %s { ", name);
1168 foreach_list_const(n, &this->declarations) {
1169 ast_node *ast = exec_node_data(ast_node, n, link);
1170 ast->print();
1171 }
1172 printf("} ");
1173 }
1174
1175
1176 ast_struct_specifier::ast_struct_specifier(const char *identifier,
1177 ast_declarator_list *declarator_list)
1178 {
1179 if (identifier == NULL) {
1180 static unsigned anon_count = 1;
1181 identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count);
1182 anon_count++;
1183 }
1184 name = identifier;
1185 this->declarations.push_degenerate_list_at_head(&declarator_list->link);
1186 }
1187
1188 /**
1189 * Do the set of common optimizations passes
1190 *
1191 * \param ir List of instructions to be optimized
1192 * \param linked Is the shader linked? This enables
1193 * optimizations passes that remove code at
1194 * global scope and could cause linking to
1195 * fail.
1196 * \param uniform_locations_assigned Have locations already been assigned for
1197 * uniforms? This prevents the declarations
1198 * of unused uniforms from being removed.
1199 * The setting of this flag only matters if
1200 * \c linked is \c true.
1201 * \param max_unroll_iterations Maximum number of loop iterations to be
1202 * unrolled. Setting to 0 disables loop
1203 * unrolling.
1204 */
1205 bool
1206 do_common_optimization(exec_list *ir, bool linked,
1207 bool uniform_locations_assigned,
1208 unsigned max_unroll_iterations)
1209 {
1210 GLboolean progress = GL_FALSE;
1211
1212 progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
1213
1214 if (linked) {
1215 progress = do_function_inlining(ir) || progress;
1216 progress = do_dead_functions(ir) || progress;
1217 progress = do_structure_splitting(ir) || progress;
1218 }
1219 progress = do_if_simplification(ir) || progress;
1220 progress = do_copy_propagation(ir) || progress;
1221 progress = do_copy_propagation_elements(ir) || progress;
1222 if (linked)
1223 progress = do_dead_code(ir, uniform_locations_assigned) || progress;
1224 else
1225 progress = do_dead_code_unlinked(ir) || progress;
1226 progress = do_dead_code_local(ir) || progress;
1227 progress = do_tree_grafting(ir) || progress;
1228 progress = do_constant_propagation(ir) || progress;
1229 if (linked)
1230 progress = do_constant_variable(ir) || progress;
1231 else
1232 progress = do_constant_variable_unlinked(ir) || progress;
1233 progress = do_constant_folding(ir) || progress;
1234 progress = do_algebraic(ir) || progress;
1235 progress = do_lower_jumps(ir) || progress;
1236 progress = do_vec_index_to_swizzle(ir) || progress;
1237 progress = do_swizzle_swizzle(ir) || progress;
1238 progress = do_noop_swizzle(ir) || progress;
1239
1240 progress = optimize_split_arrays(ir, linked) || progress;
1241 progress = optimize_redundant_jumps(ir) || progress;
1242
1243 loop_state *ls = analyze_loop_variables(ir);
1244 if (ls->loop_found) {
1245 progress = set_loop_controls(ir, ls) || progress;
1246 progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
1247 }
1248 delete ls;
1249
1250 return progress;
1251 }
1252
1253 extern "C" {
1254
1255 /**
1256 * To be called at GL teardown time, this frees compiler datastructures.
1257 *
1258 * After calling this, any previously compiled shaders and shader
1259 * programs would be invalid. So this should happen at approximately
1260 * program exit.
1261 */
1262 void
1263 _mesa_destroy_shader_compiler(void)
1264 {
1265 _mesa_destroy_shader_compiler_caches();
1266
1267 _mesa_glsl_release_types();
1268 }
1269
1270 /**
1271 * Releases compiler caches to trade off performance for memory.
1272 *
1273 * Intended to be used with glReleaseShaderCompiler().
1274 */
1275 void
1276 _mesa_destroy_shader_compiler_caches(void)
1277 {
1278 _mesa_glsl_release_functions();
1279 }
1280
1281 }