• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
_mesa_glsl_parse_state(struct gl_context * _ctx,GLenum target,void * mem_ctx)40 _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
41 					       GLenum target, void *mem_ctx)
42  : ctx(_ctx)
43 {
44    switch (target) {
45    case GL_VERTEX_SHADER:   this->target = vertex_shader; break;
46    case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
47    case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
48    }
49 
50    this->scanner = NULL;
51    this->translation_unit.make_empty();
52    this->symbols = new(mem_ctx) glsl_symbol_table;
53    this->info_log = ralloc_strdup(mem_ctx, "");
54    this->error = false;
55    this->loop_nesting_ast = NULL;
56    this->switch_state.switch_nesting_ast = NULL;
57 
58    this->num_builtins_to_link = 0;
59 
60    /* Set default language version and extensions */
61    this->language_version = 110;
62    this->es_shader = false;
63    this->ARB_texture_rectangle_enable = true;
64 
65    /* OpenGL ES 2.0 has different defaults from desktop GL. */
66    if (ctx->API == API_OPENGLES2) {
67       this->language_version = 100;
68       this->es_shader = true;
69       this->ARB_texture_rectangle_enable = false;
70    }
71 
72    this->extensions = &ctx->Extensions;
73 
74    this->Const.MaxLights = ctx->Const.MaxLights;
75    this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
76    this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
77    this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
78    this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs;
79    this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents;
80    this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4;
81    this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits;
82    this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
83    this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
84    this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
85 
86    this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
87 
88    const unsigned lowest_version =
89       (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility
90       ? 100 : 110;
91    const unsigned highest_version =
92       _mesa_is_desktop_gl(ctx) ? ctx->Const.GLSLVersion : 100;
93    char *supported = ralloc_strdup(this, "");
94 
95    for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) {
96       const char *const prefix = (ver == lowest_version)
97 	 ? ""
98 	 : ((ver == highest_version) ? ", and " : ", ");
99 
100       ralloc_asprintf_append(& supported, "%s%d.%02d%s",
101 			     prefix,
102 			     ver / 100, ver % 100,
103 			     (ver == 100) ? " ES" : "");
104    }
105 
106    this->supported_version_string = supported;
107 
108    if (ctx->Const.ForceGLSLExtensionsWarn)
109       _mesa_glsl_process_extension("all", NULL, "warn", NULL, this);
110 
111    this->default_uniform_qualifier = new(this) ast_type_qualifier();
112    this->default_uniform_qualifier->flags.q.shared = 1;
113    this->default_uniform_qualifier->flags.q.column_major = 1;
114 }
115 
116 const char *
_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)117 _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
118 {
119    switch (target) {
120    case vertex_shader:   return "vertex";
121    case fragment_shader: return "fragment";
122    case geometry_shader: return "geometry";
123    }
124 
125    assert(!"Should not get here.");
126    return "unknown";
127 }
128 
129 /* This helper function will append the given message to the shader's
130    info log and report it via GL_ARB_debug_output. Per that extension,
131    'type' is one of the enum values classifying the message, and
132    'id' is the implementation-defined ID of the given message. */
133 static void
_mesa_glsl_msg(const YYLTYPE * locp,_mesa_glsl_parse_state * state,GLenum type,GLuint id,const char * fmt,va_list ap)134 _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
135                GLenum type, GLuint id, const char *fmt, va_list ap)
136 {
137    bool error = (type == GL_DEBUG_TYPE_ERROR_ARB);
138 
139    assert(state->info_log != NULL);
140 
141    /* Get the offset that the new message will be written to. */
142    int msg_offset = strlen(state->info_log);
143 
144    ralloc_asprintf_append(&state->info_log, "%u:%u(%u): %s: ",
145 					    locp->source,
146 					    locp->first_line,
147 					    locp->first_column,
148 					    error ? "error" : "warning");
149    ralloc_vasprintf_append(&state->info_log, fmt, ap);
150 
151    const char *const msg = &state->info_log[msg_offset];
152    struct gl_context *ctx = state->ctx;
153    /* Report the error via GL_ARB_debug_output. */
154    if (error)
155       _mesa_shader_debug(ctx, type, id, msg, strlen(msg));
156 
157    ralloc_strcat(&state->info_log, "\n");
158 }
159 
160 void
_mesa_glsl_error(YYLTYPE * locp,_mesa_glsl_parse_state * state,const char * fmt,...)161 _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
162 		 const char *fmt, ...)
163 {
164    va_list ap;
165    GLenum type = GL_DEBUG_TYPE_ERROR_ARB;
166 
167    state->error = true;
168 
169    va_start(ap, fmt);
170    _mesa_glsl_msg(locp, state, type, SHADER_ERROR_UNKNOWN, fmt, ap);
171    va_end(ap);
172 }
173 
174 
175 void
_mesa_glsl_warning(const YYLTYPE * locp,_mesa_glsl_parse_state * state,const char * fmt,...)176 _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
177 		   const char *fmt, ...)
178 {
179    va_list ap;
180    GLenum type = GL_DEBUG_TYPE_OTHER_ARB;
181 
182    va_start(ap, fmt);
183    _mesa_glsl_msg(locp, state, type, 0, fmt, ap);
184    va_end(ap);
185 }
186 
187 
188 /**
189  * Enum representing the possible behaviors that can be specified in
190  * an #extension directive.
191  */
192 enum ext_behavior {
193    extension_disable,
194    extension_enable,
195    extension_require,
196    extension_warn
197 };
198 
199 /**
200  * Element type for _mesa_glsl_supported_extensions
201  */
202 struct _mesa_glsl_extension {
203    /**
204     * Name of the extension when referred to in a GLSL extension
205     * statement
206     */
207    const char *name;
208 
209    /** True if this extension is available to vertex shaders */
210    bool avail_in_VS;
211 
212    /** True if this extension is available to geometry shaders */
213    bool avail_in_GS;
214 
215    /** True if this extension is available to fragment shaders */
216    bool avail_in_FS;
217 
218    /** True if this extension is available to desktop GL shaders */
219    bool avail_in_GL;
220 
221    /** True if this extension is available to GLES shaders */
222    bool avail_in_ES;
223 
224    /**
225     * Flag in the gl_extensions struct indicating whether this
226     * extension is supported by the driver, or
227     * &gl_extensions::dummy_true if supported by all drivers.
228     *
229     * Note: the type (GLboolean gl_extensions::*) is a "pointer to
230     * member" type, the type-safe alternative to the "offsetof" macro.
231     * In a nutshell:
232     *
233     * - foo bar::* p declares p to be an "offset" to a field of type
234     *   foo that exists within struct bar
235     * - &bar::baz computes the "offset" of field baz within struct bar
236     * - x.*p accesses the field of x that exists at "offset" p
237     * - x->*p is equivalent to (*x).*p
238     */
239    const GLboolean gl_extensions::* supported_flag;
240 
241    /**
242     * Flag in the _mesa_glsl_parse_state struct that should be set
243     * when this extension is enabled.
244     *
245     * See note in _mesa_glsl_extension::supported_flag about "pointer
246     * to member" types.
247     */
248    bool _mesa_glsl_parse_state::* enable_flag;
249 
250    /**
251     * Flag in the _mesa_glsl_parse_state struct that should be set
252     * when the shader requests "warn" behavior for this extension.
253     *
254     * See note in _mesa_glsl_extension::supported_flag about "pointer
255     * to member" types.
256     */
257    bool _mesa_glsl_parse_state::* warn_flag;
258 
259 
260    bool compatible_with_state(const _mesa_glsl_parse_state *state) const;
261    void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
262 };
263 
264 #define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG)                   \
265    { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG,   \
266          &_mesa_glsl_parse_state::NAME##_enable,                        \
267          &_mesa_glsl_parse_state::NAME##_warn }
268 
269 /**
270  * Table of extensions that can be enabled/disabled within a shader,
271  * and the conditions under which they are supported.
272  */
273 static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
274    /*                                  target availability  API availability */
275    /* name                             VS     GS     FS     GL     ES         supported flag */
276    EXT(ARB_conservative_depth,         false, false, true,  true,  false,     ARB_conservative_depth),
277    EXT(ARB_draw_buffers,               false, false, true,  true,  false,     dummy_true),
278    EXT(ARB_draw_instanced,             true,  false, false, true,  false,     ARB_draw_instanced),
279    EXT(ARB_explicit_attrib_location,   true,  false, true,  true,  false,     ARB_explicit_attrib_location),
280    EXT(ARB_fragment_coord_conventions, true,  false, true,  true,  false,     ARB_fragment_coord_conventions),
281    EXT(ARB_texture_rectangle,          true,  false, true,  true,  false,     dummy_true),
282    EXT(EXT_texture_array,              true,  false, true,  true,  false,     EXT_texture_array),
283    EXT(ARB_shader_texture_lod,         true,  false, true,  true,  false,     ARB_shader_texture_lod),
284    EXT(ARB_shader_stencil_export,      false, false, true,  true,  false,     ARB_shader_stencil_export),
285    EXT(AMD_conservative_depth,         false, false, true,  true,  false,     ARB_conservative_depth),
286    EXT(AMD_shader_stencil_export,      false, false, true,  true,  false,     ARB_shader_stencil_export),
287    EXT(OES_texture_3D,                 true,  false, true,  false, true,      EXT_texture3D),
288    EXT(OES_EGL_image_external,         true,  false, true,  false, true,      OES_EGL_image_external),
289    EXT(ARB_shader_bit_encoding,        true,  true,  true,  true,  false,     ARB_shader_bit_encoding),
290    EXT(ARB_uniform_buffer_object,      true,  false, true,  true,  false,     ARB_uniform_buffer_object),
291    EXT(OES_standard_derivatives,       false, false, true,  false,  true,     OES_standard_derivatives),
292 };
293 
294 #undef EXT
295 
296 
297 /**
298  * Determine whether a given extension is compatible with the target,
299  * API, and extension information in the current parser state.
300  */
compatible_with_state(const _mesa_glsl_parse_state * state) const301 bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state *
302                                                  state) const
303 {
304    /* Check that this extension matches the type of shader we are
305     * compiling to.
306     */
307    switch (state->target) {
308    case vertex_shader:
309       if (!this->avail_in_VS) {
310          return false;
311       }
312       break;
313    case geometry_shader:
314       if (!this->avail_in_GS) {
315          return false;
316       }
317       break;
318    case fragment_shader:
319       if (!this->avail_in_FS) {
320          return false;
321       }
322       break;
323    default:
324       assert (!"Unrecognized shader target");
325       return false;
326    }
327 
328    /* Check that this extension matches whether we are compiling
329     * for desktop GL or GLES.
330     */
331    if (state->es_shader) {
332       if (!this->avail_in_ES) return false;
333    } else {
334       if (!this->avail_in_GL) return false;
335    }
336 
337    /* Check that this extension is supported by the OpenGL
338     * implementation.
339     *
340     * Note: the ->* operator indexes into state->extensions by the
341     * offset this->supported_flag.  See
342     * _mesa_glsl_extension::supported_flag for more info.
343     */
344    return state->extensions->*(this->supported_flag);
345 }
346 
347 /**
348  * Set the appropriate flags in the parser state to establish the
349  * given behavior for this extension.
350  */
set_flags(_mesa_glsl_parse_state * state,ext_behavior behavior) const351 void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state,
352                                      ext_behavior behavior) const
353 {
354    /* Note: the ->* operator indexes into state by the
355     * offsets this->enable_flag and this->warn_flag.  See
356     * _mesa_glsl_extension::supported_flag for more info.
357     */
358    state->*(this->enable_flag) = (behavior != extension_disable);
359    state->*(this->warn_flag)   = (behavior == extension_warn);
360 }
361 
362 /**
363  * Find an extension by name in _mesa_glsl_supported_extensions.  If
364  * the name is not found, return NULL.
365  */
find_extension(const char * name)366 static const _mesa_glsl_extension *find_extension(const char *name)
367 {
368    for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) {
369       if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) {
370          return &_mesa_glsl_supported_extensions[i];
371       }
372    }
373    return NULL;
374 }
375 
376 
377 bool
_mesa_glsl_process_extension(const char * name,YYLTYPE * name_locp,const char * behavior_string,YYLTYPE * behavior_locp,_mesa_glsl_parse_state * state)378 _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
379 			     const char *behavior_string, YYLTYPE *behavior_locp,
380 			     _mesa_glsl_parse_state *state)
381 {
382    ext_behavior behavior;
383    if (strcmp(behavior_string, "warn") == 0) {
384       behavior = extension_warn;
385    } else if (strcmp(behavior_string, "require") == 0) {
386       behavior = extension_require;
387    } else if (strcmp(behavior_string, "enable") == 0) {
388       behavior = extension_enable;
389    } else if (strcmp(behavior_string, "disable") == 0) {
390       behavior = extension_disable;
391    } else {
392       _mesa_glsl_error(behavior_locp, state,
393 		       "Unknown extension behavior `%s'",
394 		       behavior_string);
395       return false;
396    }
397 
398    if (strcmp(name, "all") == 0) {
399       if ((behavior == extension_enable) || (behavior == extension_require)) {
400 	 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
401 			  (behavior == extension_enable)
402 			  ? "enable" : "require");
403 	 return false;
404       } else {
405          for (unsigned i = 0;
406               i < Elements(_mesa_glsl_supported_extensions); ++i) {
407             const _mesa_glsl_extension *extension
408                = &_mesa_glsl_supported_extensions[i];
409             if (extension->compatible_with_state(state)) {
410                _mesa_glsl_supported_extensions[i].set_flags(state, behavior);
411             }
412          }
413       }
414    } else {
415       const _mesa_glsl_extension *extension = find_extension(name);
416       if (extension && extension->compatible_with_state(state)) {
417          extension->set_flags(state, behavior);
418       } else {
419          static const char *const fmt = "extension `%s' unsupported in %s shader";
420 
421          if (behavior == extension_require) {
422             _mesa_glsl_error(name_locp, state, fmt,
423                              name, _mesa_glsl_shader_target_name(state->target));
424             return false;
425          } else {
426             _mesa_glsl_warning(name_locp, state, fmt,
427                                name, _mesa_glsl_shader_target_name(state->target));
428          }
429       }
430    }
431 
432    return true;
433 }
434 
435 void
_mesa_ast_type_qualifier_print(const struct ast_type_qualifier * q)436 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
437 {
438    if (q->flags.q.constant)
439       printf("const ");
440 
441    if (q->flags.q.invariant)
442       printf("invariant ");
443 
444    if (q->flags.q.attribute)
445       printf("attribute ");
446 
447    if (q->flags.q.varying)
448       printf("varying ");
449 
450    if (q->flags.q.in && q->flags.q.out)
451       printf("inout ");
452    else {
453       if (q->flags.q.in)
454 	 printf("in ");
455 
456       if (q->flags.q.out)
457 	 printf("out ");
458    }
459 
460    if (q->flags.q.centroid)
461       printf("centroid ");
462    if (q->flags.q.uniform)
463       printf("uniform ");
464    if (q->flags.q.smooth)
465       printf("smooth ");
466    if (q->flags.q.flat)
467       printf("flat ");
468    if (q->flags.q.noperspective)
469       printf("noperspective ");
470 }
471 
472 
473 void
print(void) const474 ast_node::print(void) const
475 {
476    printf("unhandled node ");
477 }
478 
479 
ast_node(void)480 ast_node::ast_node(void)
481 {
482    this->location.source = 0;
483    this->location.line = 0;
484    this->location.column = 0;
485 }
486 
487 
488 static void
ast_opt_array_size_print(bool is_array,const ast_expression * array_size)489 ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
490 {
491    if (is_array) {
492       printf("[ ");
493 
494       if (array_size)
495 	 array_size->print();
496 
497       printf("] ");
498    }
499 }
500 
501 
502 void
print(void) const503 ast_compound_statement::print(void) const
504 {
505    printf("{\n");
506 
507    foreach_list_const(n, &this->statements) {
508       ast_node *ast = exec_node_data(ast_node, n, link);
509       ast->print();
510    }
511 
512    printf("}\n");
513 }
514 
515 
ast_compound_statement(int new_scope,ast_node * statements)516 ast_compound_statement::ast_compound_statement(int new_scope,
517 					       ast_node *statements)
518 {
519    this->new_scope = new_scope;
520 
521    if (statements != NULL) {
522       this->statements.push_degenerate_list_at_head(&statements->link);
523    }
524 }
525 
526 
527 void
print(void) const528 ast_expression::print(void) const
529 {
530    switch (oper) {
531    case ast_assign:
532    case ast_mul_assign:
533    case ast_div_assign:
534    case ast_mod_assign:
535    case ast_add_assign:
536    case ast_sub_assign:
537    case ast_ls_assign:
538    case ast_rs_assign:
539    case ast_and_assign:
540    case ast_xor_assign:
541    case ast_or_assign:
542       subexpressions[0]->print();
543       printf("%s ", operator_string(oper));
544       subexpressions[1]->print();
545       break;
546 
547    case ast_field_selection:
548       subexpressions[0]->print();
549       printf(". %s ", primary_expression.identifier);
550       break;
551 
552    case ast_plus:
553    case ast_neg:
554    case ast_bit_not:
555    case ast_logic_not:
556    case ast_pre_inc:
557    case ast_pre_dec:
558       printf("%s ", operator_string(oper));
559       subexpressions[0]->print();
560       break;
561 
562    case ast_post_inc:
563    case ast_post_dec:
564       subexpressions[0]->print();
565       printf("%s ", operator_string(oper));
566       break;
567 
568    case ast_conditional:
569       subexpressions[0]->print();
570       printf("? ");
571       subexpressions[1]->print();
572       printf(": ");
573       subexpressions[2]->print();
574       break;
575 
576    case ast_array_index:
577       subexpressions[0]->print();
578       printf("[ ");
579       subexpressions[1]->print();
580       printf("] ");
581       break;
582 
583    case ast_function_call: {
584       subexpressions[0]->print();
585       printf("( ");
586 
587       foreach_list_const (n, &this->expressions) {
588 	 if (n != this->expressions.get_head())
589 	    printf(", ");
590 
591 	 ast_node *ast = exec_node_data(ast_node, n, link);
592 	 ast->print();
593       }
594 
595       printf(") ");
596       break;
597    }
598 
599    case ast_identifier:
600       printf("%s ", primary_expression.identifier);
601       break;
602 
603    case ast_int_constant:
604       printf("%d ", primary_expression.int_constant);
605       break;
606 
607    case ast_uint_constant:
608       printf("%u ", primary_expression.uint_constant);
609       break;
610 
611    case ast_float_constant:
612       printf("%f ", primary_expression.float_constant);
613       break;
614 
615    case ast_bool_constant:
616       printf("%s ",
617 	     primary_expression.bool_constant
618 	     ? "true" : "false");
619       break;
620 
621    case ast_sequence: {
622       printf("( ");
623       foreach_list_const(n, & this->expressions) {
624 	 if (n != this->expressions.get_head())
625 	    printf(", ");
626 
627 	 ast_node *ast = exec_node_data(ast_node, n, link);
628 	 ast->print();
629       }
630       printf(") ");
631       break;
632    }
633 
634    default:
635       assert(0);
636       break;
637    }
638 }
639 
ast_expression(int oper,ast_expression * ex0,ast_expression * ex1,ast_expression * ex2)640 ast_expression::ast_expression(int oper,
641 			       ast_expression *ex0,
642 			       ast_expression *ex1,
643 			       ast_expression *ex2)
644 {
645    this->oper = ast_operators(oper);
646    this->subexpressions[0] = ex0;
647    this->subexpressions[1] = ex1;
648    this->subexpressions[2] = ex2;
649    this->non_lvalue_description = NULL;
650 }
651 
652 
653 void
print(void) const654 ast_expression_statement::print(void) const
655 {
656    if (expression)
657       expression->print();
658 
659    printf("; ");
660 }
661 
662 
ast_expression_statement(ast_expression * ex)663 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
664    expression(ex)
665 {
666    /* empty */
667 }
668 
669 
670 void
print(void) const671 ast_function::print(void) const
672 {
673    return_type->print();
674    printf(" %s (", identifier);
675 
676    foreach_list_const(n, & this->parameters) {
677       ast_node *ast = exec_node_data(ast_node, n, link);
678       ast->print();
679    }
680 
681    printf(")");
682 }
683 
684 
ast_function(void)685 ast_function::ast_function(void)
686    : is_definition(false), signature(NULL)
687 {
688    /* empty */
689 }
690 
691 
692 void
print(void) const693 ast_fully_specified_type::print(void) const
694 {
695    _mesa_ast_type_qualifier_print(& qualifier);
696    specifier->print();
697 }
698 
699 
700 void
print(void) const701 ast_parameter_declarator::print(void) const
702 {
703    type->print();
704    if (identifier)
705       printf("%s ", identifier);
706    ast_opt_array_size_print(is_array, array_size);
707 }
708 
709 
710 void
print(void) const711 ast_function_definition::print(void) const
712 {
713    prototype->print();
714    body->print();
715 }
716 
717 
718 void
print(void) const719 ast_declaration::print(void) const
720 {
721    printf("%s ", identifier);
722    ast_opt_array_size_print(is_array, array_size);
723 
724    if (initializer) {
725       printf("= ");
726       initializer->print();
727    }
728 }
729 
730 
ast_declaration(const char * identifier,int is_array,ast_expression * array_size,ast_expression * initializer)731 ast_declaration::ast_declaration(const char *identifier, int is_array,
732 				 ast_expression *array_size,
733 				 ast_expression *initializer)
734 {
735    this->identifier = identifier;
736    this->is_array = is_array;
737    this->array_size = array_size;
738    this->initializer = initializer;
739 }
740 
741 
742 void
print(void) const743 ast_declarator_list::print(void) const
744 {
745    assert(type || invariant);
746 
747    if (type)
748       type->print();
749    else
750       printf("invariant ");
751 
752    foreach_list_const (ptr, & this->declarations) {
753       if (ptr != this->declarations.get_head())
754 	 printf(", ");
755 
756       ast_node *ast = exec_node_data(ast_node, ptr, link);
757       ast->print();
758    }
759 
760    printf("; ");
761 }
762 
763 
ast_declarator_list(ast_fully_specified_type * type)764 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
765 {
766    this->type = type;
767    this->invariant = false;
768    this->ubo_qualifiers_valid = false;
769 }
770 
771 void
print(void) const772 ast_jump_statement::print(void) const
773 {
774    switch (mode) {
775    case ast_continue:
776       printf("continue; ");
777       break;
778    case ast_break:
779       printf("break; ");
780       break;
781    case ast_return:
782       printf("return ");
783       if (opt_return_value)
784 	 opt_return_value->print();
785 
786       printf("; ");
787       break;
788    case ast_discard:
789       printf("discard; ");
790       break;
791    }
792 }
793 
794 
ast_jump_statement(int mode,ast_expression * return_value)795 ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
796 {
797    this->mode = ast_jump_modes(mode);
798 
799    if (mode == ast_return)
800       opt_return_value = return_value;
801 }
802 
803 
804 void
print(void) const805 ast_selection_statement::print(void) const
806 {
807    printf("if ( ");
808    condition->print();
809    printf(") ");
810 
811    then_statement->print();
812 
813    if (else_statement) {
814       printf("else ");
815       else_statement->print();
816    }
817 
818 }
819 
820 
ast_selection_statement(ast_expression * condition,ast_node * then_statement,ast_node * else_statement)821 ast_selection_statement::ast_selection_statement(ast_expression *condition,
822 						 ast_node *then_statement,
823 						 ast_node *else_statement)
824 {
825    this->condition = condition;
826    this->then_statement = then_statement;
827    this->else_statement = else_statement;
828 }
829 
830 
831 void
print(void) const832 ast_switch_statement::print(void) const
833 {
834    printf("switch ( ");
835    test_expression->print();
836    printf(") ");
837 
838    body->print();
839 }
840 
841 
ast_switch_statement(ast_expression * test_expression,ast_node * body)842 ast_switch_statement::ast_switch_statement(ast_expression *test_expression,
843 					   ast_node *body)
844 {
845    this->test_expression = test_expression;
846    this->body = body;
847 }
848 
849 
850 void
print(void) const851 ast_switch_body::print(void) const
852 {
853    printf("{\n");
854    if (stmts != NULL) {
855       stmts->print();
856    }
857    printf("}\n");
858 }
859 
860 
ast_switch_body(ast_case_statement_list * stmts)861 ast_switch_body::ast_switch_body(ast_case_statement_list *stmts)
862 {
863    this->stmts = stmts;
864 }
865 
866 
print(void) const867 void ast_case_label::print(void) const
868 {
869    if (test_value != NULL) {
870       printf("case ");
871       test_value->print();
872       printf(": ");
873    } else {
874       printf("default: ");
875    }
876 }
877 
878 
ast_case_label(ast_expression * test_value)879 ast_case_label::ast_case_label(ast_expression *test_value)
880 {
881    this->test_value = test_value;
882 }
883 
884 
print(void) const885 void ast_case_label_list::print(void) const
886 {
887    foreach_list_const(n, & this->labels) {
888       ast_node *ast = exec_node_data(ast_node, n, link);
889       ast->print();
890    }
891    printf("\n");
892 }
893 
894 
ast_case_label_list(void)895 ast_case_label_list::ast_case_label_list(void)
896 {
897 }
898 
899 
print(void) const900 void ast_case_statement::print(void) const
901 {
902    labels->print();
903    foreach_list_const(n, & this->stmts) {
904       ast_node *ast = exec_node_data(ast_node, n, link);
905       ast->print();
906       printf("\n");
907    }
908 }
909 
910 
ast_case_statement(ast_case_label_list * labels)911 ast_case_statement::ast_case_statement(ast_case_label_list *labels)
912 {
913    this->labels = labels;
914 }
915 
916 
print(void) const917 void ast_case_statement_list::print(void) const
918 {
919    foreach_list_const(n, & this->cases) {
920       ast_node *ast = exec_node_data(ast_node, n, link);
921       ast->print();
922    }
923 }
924 
925 
ast_case_statement_list(void)926 ast_case_statement_list::ast_case_statement_list(void)
927 {
928 }
929 
930 
931 void
print(void) const932 ast_iteration_statement::print(void) const
933 {
934    switch (mode) {
935    case ast_for:
936       printf("for( ");
937       if (init_statement)
938 	 init_statement->print();
939       printf("; ");
940 
941       if (condition)
942 	 condition->print();
943       printf("; ");
944 
945       if (rest_expression)
946 	 rest_expression->print();
947       printf(") ");
948 
949       body->print();
950       break;
951 
952    case ast_while:
953       printf("while ( ");
954       if (condition)
955 	 condition->print();
956       printf(") ");
957       body->print();
958       break;
959 
960    case ast_do_while:
961       printf("do ");
962       body->print();
963       printf("while ( ");
964       if (condition)
965 	 condition->print();
966       printf("); ");
967       break;
968    }
969 }
970 
971 
ast_iteration_statement(int mode,ast_node * init,ast_node * condition,ast_expression * rest_expression,ast_node * body)972 ast_iteration_statement::ast_iteration_statement(int mode,
973 						 ast_node *init,
974 						 ast_node *condition,
975 						 ast_expression *rest_expression,
976 						 ast_node *body)
977 {
978    this->mode = ast_iteration_modes(mode);
979    this->init_statement = init;
980    this->condition = condition;
981    this->rest_expression = rest_expression;
982    this->body = body;
983 }
984 
985 
986 void
print(void) const987 ast_struct_specifier::print(void) const
988 {
989    printf("struct %s { ", name);
990    foreach_list_const(n, &this->declarations) {
991       ast_node *ast = exec_node_data(ast_node, n, link);
992       ast->print();
993    }
994    printf("} ");
995 }
996 
997 
ast_struct_specifier(const char * identifier,ast_declarator_list * declarator_list)998 ast_struct_specifier::ast_struct_specifier(const char *identifier,
999 					   ast_declarator_list *declarator_list)
1000 {
1001    if (identifier == NULL) {
1002       static unsigned anon_count = 1;
1003       identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count);
1004       anon_count++;
1005    }
1006    name = identifier;
1007    this->declarations.push_degenerate_list_at_head(&declarator_list->link);
1008 }
1009 
1010 /**
1011  * Do the set of common optimizations passes
1012  *
1013  * \param ir                          List of instructions to be optimized
1014  * \param linked                      Is the shader linked?  This enables
1015  *                                    optimizations passes that remove code at
1016  *                                    global scope and could cause linking to
1017  *                                    fail.
1018  * \param uniform_locations_assigned  Have locations already been assigned for
1019  *                                    uniforms?  This prevents the declarations
1020  *                                    of unused uniforms from being removed.
1021  *                                    The setting of this flag only matters if
1022  *                                    \c linked is \c true.
1023  * \param max_unroll_iterations       Maximum number of loop iterations to be
1024  *                                    unrolled.  Setting to 0 forces all loops
1025  *                                    to be unrolled.
1026  */
1027 bool
do_common_optimization(exec_list * ir,bool linked,bool uniform_locations_assigned,unsigned max_unroll_iterations)1028 do_common_optimization(exec_list *ir, bool linked,
1029 		       bool uniform_locations_assigned,
1030 		       unsigned max_unroll_iterations)
1031 {
1032    GLboolean progress = GL_FALSE;
1033 
1034    progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
1035 
1036    if (linked) {
1037       progress = do_function_inlining(ir) || progress;
1038       progress = do_dead_functions(ir) || progress;
1039       progress = do_structure_splitting(ir) || progress;
1040    }
1041    progress = do_if_simplification(ir) || progress;
1042    progress = do_copy_propagation(ir) || progress;
1043    progress = do_copy_propagation_elements(ir) || progress;
1044    if (linked)
1045       progress = do_dead_code(ir, uniform_locations_assigned) || progress;
1046    else
1047       progress = do_dead_code_unlinked(ir) || progress;
1048    progress = do_dead_code_local(ir) || progress;
1049    progress = do_tree_grafting(ir) || progress;
1050    progress = do_constant_propagation(ir) || progress;
1051    if (linked)
1052       progress = do_constant_variable(ir) || progress;
1053    else
1054       progress = do_constant_variable_unlinked(ir) || progress;
1055    progress = do_constant_folding(ir) || progress;
1056    progress = do_algebraic(ir) || progress;
1057    progress = do_lower_jumps(ir) || progress;
1058    progress = do_vec_index_to_swizzle(ir) || progress;
1059    progress = do_swizzle_swizzle(ir) || progress;
1060    progress = do_noop_swizzle(ir) || progress;
1061 
1062    progress = optimize_split_arrays(ir, linked) || progress;
1063    progress = optimize_redundant_jumps(ir) || progress;
1064 
1065    loop_state *ls = analyze_loop_variables(ir);
1066    if (ls->loop_found) {
1067       progress = set_loop_controls(ir, ls) || progress;
1068       progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
1069    }
1070    delete ls;
1071 
1072    return progress;
1073 }
1074 
1075 extern "C" {
1076 
1077 /**
1078  * To be called at GL teardown time, this frees compiler datastructures.
1079  *
1080  * After calling this, any previously compiled shaders and shader
1081  * programs would be invalid.  So this should happen at approximately
1082  * program exit.
1083  */
1084 void
_mesa_destroy_shader_compiler(void)1085 _mesa_destroy_shader_compiler(void)
1086 {
1087    _mesa_destroy_shader_compiler_caches();
1088 
1089    _mesa_glsl_release_types();
1090 }
1091 
1092 /**
1093  * Releases compiler caches to trade off performance for memory.
1094  *
1095  * Intended to be used with glReleaseShaderCompiler().
1096  */
1097 void
_mesa_destroy_shader_compiler_caches(void)1098 _mesa_destroy_shader_compiler_caches(void)
1099 {
1100    _mesa_glsl_release_functions();
1101 }
1102 
1103 }
1104