glsl_parser_extras.cpp revision 9a1d063c6d679c2155f5eb80f1cb94368d36bf2c
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
28extern "C" {
29#include <talloc.h>
30#include "main/core.h" /* for struct gl_context */
31}
32
33#include "ast.h"
34#include "glsl_parser_extras.h"
35#include "glsl_parser.h"
36#include "ir_optimization.h"
37#include "loop_analysis.h"
38
39_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *ctx,
40					       GLenum target, void *mem_ctx)
41{
42   switch (target) {
43   case GL_VERTEX_SHADER:   this->target = vertex_shader; break;
44   case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
45   case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
46   }
47
48   this->scanner = NULL;
49   this->translation_unit.make_empty();
50   this->symbols = new(mem_ctx) glsl_symbol_table;
51   this->info_log = talloc_strdup(mem_ctx, "");
52   this->error = false;
53   this->loop_or_switch_nesting = NULL;
54
55   /* Set default language version and extensions */
56   this->language_version = 110;
57   this->es_shader = false;
58   this->ARB_texture_rectangle_enable = true;
59
60   /* OpenGL ES 2.0 has different defaults from desktop GL. */
61   if (ctx->API == API_OPENGLES2) {
62      this->language_version = 100;
63      this->es_shader = true;
64      this->ARB_texture_rectangle_enable = false;
65   }
66
67   this->extensions = &ctx->Extensions;
68
69   this->Const.MaxLights = ctx->Const.MaxLights;
70   this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
71   this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
72   this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
73   this->Const.MaxVertexAttribs = ctx->Const.VertexProgram.MaxAttribs;
74   this->Const.MaxVertexUniformComponents = ctx->Const.VertexProgram.MaxUniformComponents;
75   this->Const.MaxVaryingFloats = ctx->Const.MaxVarying * 4;
76   this->Const.MaxVertexTextureImageUnits = ctx->Const.MaxVertexTextureImageUnits;
77   this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
78   this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
79   this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents;
80
81   this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
82}
83
84const char *
85_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
86{
87   switch (target) {
88   case vertex_shader:   return "vertex";
89   case fragment_shader: return "fragment";
90   case geometry_shader: return "geometry";
91   }
92
93   assert(!"Should not get here.");
94   return "unknown";
95}
96
97
98void
99_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
100		 const char *fmt, ...)
101{
102   va_list ap;
103
104   state->error = true;
105
106   assert(state->info_log != NULL);
107   state->info_log = talloc_asprintf_append(state->info_log,
108					    "%u:%u(%u): error: ",
109					    locp->source,
110					    locp->first_line,
111					    locp->first_column);
112   va_start(ap, fmt);
113   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
114   va_end(ap);
115   state->info_log = talloc_strdup_append(state->info_log, "\n");
116}
117
118
119void
120_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
121		   const char *fmt, ...)
122{
123   va_list ap;
124
125   assert(state->info_log != NULL);
126   state->info_log = talloc_asprintf_append(state->info_log,
127					    "%u:%u(%u): warning: ",
128					    locp->source,
129					    locp->first_line,
130					    locp->first_column);
131   va_start(ap, fmt);
132   state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap);
133   va_end(ap);
134   state->info_log = talloc_strdup_append(state->info_log, "\n");
135}
136
137
138bool
139_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
140			     const char *behavior, YYLTYPE *behavior_locp,
141			     _mesa_glsl_parse_state *state)
142{
143   enum {
144      extension_disable,
145      extension_enable,
146      extension_require,
147      extension_warn
148   } ext_mode;
149
150   if (strcmp(behavior, "warn") == 0) {
151      ext_mode = extension_warn;
152   } else if (strcmp(behavior, "require") == 0) {
153      ext_mode = extension_require;
154   } else if (strcmp(behavior, "enable") == 0) {
155      ext_mode = extension_enable;
156   } else if (strcmp(behavior, "disable") == 0) {
157      ext_mode = extension_disable;
158   } else {
159      _mesa_glsl_error(behavior_locp, state,
160		       "Unknown extension behavior `%s'",
161		       behavior);
162      return false;
163   }
164
165   bool unsupported = false;
166
167   if (strcmp(name, "all") == 0) {
168      if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
169	 _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
170			  (ext_mode == extension_enable)
171			  ? "enable" : "require");
172	 return false;
173      }
174   } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
175      /* This extension is only supported in fragment shaders.
176       */
177      if (state->target != fragment_shader) {
178	 unsupported = true;
179      } else {
180	 state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
181	 state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
182      }
183   } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
184      state->ARB_explicit_attrib_location_enable =
185	 (ext_mode != extension_disable);
186      state->ARB_explicit_attrib_location_warn =
187	 (ext_mode == extension_warn);
188
189      unsupported = !state->extensions->ARB_explicit_attrib_location;
190   } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) {
191      state->ARB_fragment_coord_conventions_enable =
192	 (ext_mode != extension_disable);
193      state->ARB_fragment_coord_conventions_warn =
194	 (ext_mode == extension_warn);
195
196      unsupported = !state->extensions->ARB_fragment_coord_conventions;
197   } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
198      state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
199      state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
200   } else if (strcmp(name, "GL_EXT_texture_array") == 0) {
201      state->EXT_texture_array_enable = (ext_mode != extension_disable);
202      state->EXT_texture_array_warn = (ext_mode == extension_warn);
203
204      unsupported = !state->extensions->EXT_texture_array;
205   } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) {
206      if (state->target != fragment_shader) {
207	 unsupported = true;
208      } else {
209	 state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable);
210	 state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn);
211	 unsupported = !state->extensions->ARB_shader_stencil_export;
212      }
213   } else {
214      unsupported = true;
215   }
216
217   if (unsupported) {
218      static const char *const fmt = "extension `%s' unsupported in %s shader";
219
220      if (ext_mode == extension_require) {
221	 _mesa_glsl_error(name_locp, state, fmt,
222			  name, _mesa_glsl_shader_target_name(state->target));
223	 return false;
224      } else {
225	 _mesa_glsl_warning(name_locp, state, fmt,
226			    name, _mesa_glsl_shader_target_name(state->target));
227      }
228   }
229
230   return true;
231}
232
233void
234_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
235{
236   if (q->flags.q.constant)
237      printf("const ");
238
239   if (q->flags.q.invariant)
240      printf("invariant ");
241
242   if (q->flags.q.attribute)
243      printf("attribute ");
244
245   if (q->flags.q.varying)
246      printf("varying ");
247
248   if (q->flags.q.in && q->flags.q.out)
249      printf("inout ");
250   else {
251      if (q->flags.q.in)
252	 printf("in ");
253
254      if (q->flags.q.out)
255	 printf("out ");
256   }
257
258   if (q->flags.q.centroid)
259      printf("centroid ");
260   if (q->flags.q.uniform)
261      printf("uniform ");
262   if (q->flags.q.smooth)
263      printf("smooth ");
264   if (q->flags.q.flat)
265      printf("flat ");
266   if (q->flags.q.noperspective)
267      printf("noperspective ");
268}
269
270
271void
272ast_node::print(void) const
273{
274   printf("unhandled node ");
275}
276
277
278ast_node::ast_node(void)
279{
280   this->location.source = 0;
281   this->location.line = 0;
282   this->location.column = 0;
283}
284
285
286static void
287ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
288{
289   if (is_array) {
290      printf("[ ");
291
292      if (array_size)
293	 array_size->print();
294
295      printf("] ");
296   }
297}
298
299
300void
301ast_compound_statement::print(void) const
302{
303   printf("{\n");
304
305   foreach_list_const(n, &this->statements) {
306      ast_node *ast = exec_node_data(ast_node, n, link);
307      ast->print();
308   }
309
310   printf("}\n");
311}
312
313
314ast_compound_statement::ast_compound_statement(int new_scope,
315					       ast_node *statements)
316{
317   this->new_scope = new_scope;
318
319   if (statements != NULL) {
320      this->statements.push_degenerate_list_at_head(&statements->link);
321   }
322}
323
324
325void
326ast_expression::print(void) const
327{
328   switch (oper) {
329   case ast_assign:
330   case ast_mul_assign:
331   case ast_div_assign:
332   case ast_mod_assign:
333   case ast_add_assign:
334   case ast_sub_assign:
335   case ast_ls_assign:
336   case ast_rs_assign:
337   case ast_and_assign:
338   case ast_xor_assign:
339   case ast_or_assign:
340      subexpressions[0]->print();
341      printf("%s ", operator_string(oper));
342      subexpressions[1]->print();
343      break;
344
345   case ast_field_selection:
346      subexpressions[0]->print();
347      printf(". %s ", primary_expression.identifier);
348      break;
349
350   case ast_plus:
351   case ast_neg:
352   case ast_bit_not:
353   case ast_logic_not:
354   case ast_pre_inc:
355   case ast_pre_dec:
356      printf("%s ", operator_string(oper));
357      subexpressions[0]->print();
358      break;
359
360   case ast_post_inc:
361   case ast_post_dec:
362      subexpressions[0]->print();
363      printf("%s ", operator_string(oper));
364      break;
365
366   case ast_conditional:
367      subexpressions[0]->print();
368      printf("? ");
369      subexpressions[1]->print();
370      printf(": ");
371      subexpressions[1]->print();
372      break;
373
374   case ast_array_index:
375      subexpressions[0]->print();
376      printf("[ ");
377      subexpressions[1]->print();
378      printf("] ");
379      break;
380
381   case ast_function_call: {
382      subexpressions[0]->print();
383      printf("( ");
384
385      foreach_list_const (n, &this->expressions) {
386	 if (n != this->expressions.get_head())
387	    printf(", ");
388
389	 ast_node *ast = exec_node_data(ast_node, n, link);
390	 ast->print();
391      }
392
393      printf(") ");
394      break;
395   }
396
397   case ast_identifier:
398      printf("%s ", primary_expression.identifier);
399      break;
400
401   case ast_int_constant:
402      printf("%d ", primary_expression.int_constant);
403      break;
404
405   case ast_uint_constant:
406      printf("%u ", primary_expression.uint_constant);
407      break;
408
409   case ast_float_constant:
410      printf("%f ", primary_expression.float_constant);
411      break;
412
413   case ast_bool_constant:
414      printf("%s ",
415	     primary_expression.bool_constant
416	     ? "true" : "false");
417      break;
418
419   case ast_sequence: {
420      printf("( ");
421      foreach_list_const(n, & this->expressions) {
422	 if (n != this->expressions.get_head())
423	    printf(", ");
424
425	 ast_node *ast = exec_node_data(ast_node, n, link);
426	 ast->print();
427      }
428      printf(") ");
429      break;
430   }
431
432   default:
433      assert(0);
434      break;
435   }
436}
437
438ast_expression::ast_expression(int oper,
439			       ast_expression *ex0,
440			       ast_expression *ex1,
441			       ast_expression *ex2)
442{
443   this->oper = ast_operators(oper);
444   this->subexpressions[0] = ex0;
445   this->subexpressions[1] = ex1;
446   this->subexpressions[2] = ex2;
447}
448
449
450void
451ast_expression_statement::print(void) const
452{
453   if (expression)
454      expression->print();
455
456   printf("; ");
457}
458
459
460ast_expression_statement::ast_expression_statement(ast_expression *ex) :
461   expression(ex)
462{
463   /* empty */
464}
465
466
467void
468ast_function::print(void) const
469{
470   return_type->print();
471   printf(" %s (", identifier);
472
473   foreach_list_const(n, & this->parameters) {
474      ast_node *ast = exec_node_data(ast_node, n, link);
475      ast->print();
476   }
477
478   printf(")");
479}
480
481
482ast_function::ast_function(void)
483   : is_definition(false), signature(NULL)
484{
485   /* empty */
486}
487
488
489void
490ast_fully_specified_type::print(void) const
491{
492   _mesa_ast_type_qualifier_print(& qualifier);
493   specifier->print();
494}
495
496
497void
498ast_parameter_declarator::print(void) const
499{
500   type->print();
501   if (identifier)
502      printf("%s ", identifier);
503   ast_opt_array_size_print(is_array, array_size);
504}
505
506
507void
508ast_function_definition::print(void) const
509{
510   prototype->print();
511   body->print();
512}
513
514
515void
516ast_declaration::print(void) const
517{
518   printf("%s ", identifier);
519   ast_opt_array_size_print(is_array, array_size);
520
521   if (initializer) {
522      printf("= ");
523      initializer->print();
524   }
525}
526
527
528ast_declaration::ast_declaration(char *identifier, int is_array,
529				 ast_expression *array_size,
530				 ast_expression *initializer)
531{
532   this->identifier = identifier;
533   this->is_array = is_array;
534   this->array_size = array_size;
535   this->initializer = initializer;
536}
537
538
539void
540ast_declarator_list::print(void) const
541{
542   assert(type || invariant);
543
544   if (type)
545      type->print();
546   else
547      printf("invariant ");
548
549   foreach_list_const (ptr, & this->declarations) {
550      if (ptr != this->declarations.get_head())
551	 printf(", ");
552
553      ast_node *ast = exec_node_data(ast_node, ptr, link);
554      ast->print();
555   }
556
557   printf("; ");
558}
559
560
561ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
562{
563   this->type = type;
564   this->invariant = false;
565}
566
567void
568ast_jump_statement::print(void) const
569{
570   switch (mode) {
571   case ast_continue:
572      printf("continue; ");
573      break;
574   case ast_break:
575      printf("break; ");
576      break;
577   case ast_return:
578      printf("return ");
579      if (opt_return_value)
580	 opt_return_value->print();
581
582      printf("; ");
583      break;
584   case ast_discard:
585      printf("discard; ");
586      break;
587   }
588}
589
590
591ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
592{
593   this->mode = ast_jump_modes(mode);
594
595   if (mode == ast_return)
596      opt_return_value = return_value;
597}
598
599
600void
601ast_selection_statement::print(void) const
602{
603   printf("if ( ");
604   condition->print();
605   printf(") ");
606
607   then_statement->print();
608
609   if (else_statement) {
610      printf("else ");
611      else_statement->print();
612   }
613
614}
615
616
617ast_selection_statement::ast_selection_statement(ast_expression *condition,
618						 ast_node *then_statement,
619						 ast_node *else_statement)
620{
621   this->condition = condition;
622   this->then_statement = then_statement;
623   this->else_statement = else_statement;
624}
625
626
627void
628ast_iteration_statement::print(void) const
629{
630   switch (mode) {
631   case ast_for:
632      printf("for( ");
633      if (init_statement)
634	 init_statement->print();
635      printf("; ");
636
637      if (condition)
638	 condition->print();
639      printf("; ");
640
641      if (rest_expression)
642	 rest_expression->print();
643      printf(") ");
644
645      body->print();
646      break;
647
648   case ast_while:
649      printf("while ( ");
650      if (condition)
651	 condition->print();
652      printf(") ");
653      body->print();
654      break;
655
656   case ast_do_while:
657      printf("do ");
658      body->print();
659      printf("while ( ");
660      if (condition)
661	 condition->print();
662      printf("); ");
663      break;
664   }
665}
666
667
668ast_iteration_statement::ast_iteration_statement(int mode,
669						 ast_node *init,
670						 ast_node *condition,
671						 ast_expression *rest_expression,
672						 ast_node *body)
673{
674   this->mode = ast_iteration_modes(mode);
675   this->init_statement = init;
676   this->condition = condition;
677   this->rest_expression = rest_expression;
678   this->body = body;
679}
680
681
682void
683ast_struct_specifier::print(void) const
684{
685   printf("struct %s { ", name);
686   foreach_list_const(n, &this->declarations) {
687      ast_node *ast = exec_node_data(ast_node, n, link);
688      ast->print();
689   }
690   printf("} ");
691}
692
693
694ast_struct_specifier::ast_struct_specifier(char *identifier,
695					   ast_node *declarator_list)
696{
697   if (identifier == NULL) {
698      static unsigned anon_count = 1;
699      identifier = talloc_asprintf(this, "#anon_struct_%04x", anon_count);
700      anon_count++;
701   }
702   name = identifier;
703   this->declarations.push_degenerate_list_at_head(&declarator_list->link);
704}
705
706bool
707do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
708{
709   GLboolean progress = GL_FALSE;
710
711   progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
712
713   if (linked) {
714      progress = do_function_inlining(ir) || progress;
715      progress = do_dead_functions(ir) || progress;
716   }
717   progress = do_structure_splitting(ir) || progress;
718   progress = do_if_simplification(ir) || progress;
719   progress = do_discard_simplification(ir) || progress;
720   progress = do_copy_propagation(ir) || progress;
721   if (linked)
722      progress = do_dead_code(ir) || progress;
723   else
724      progress = do_dead_code_unlinked(ir) || progress;
725   progress = do_dead_code_local(ir) || progress;
726   progress = do_tree_grafting(ir) || progress;
727   progress = do_constant_propagation(ir) || progress;
728   if (linked)
729      progress = do_constant_variable(ir) || progress;
730   else
731      progress = do_constant_variable_unlinked(ir) || progress;
732   progress = do_constant_folding(ir) || progress;
733   progress = do_algebraic(ir) || progress;
734   progress = do_lower_jumps(ir) || progress;
735   progress = do_vec_index_to_swizzle(ir) || progress;
736   progress = do_swizzle_swizzle(ir) || progress;
737   progress = do_noop_swizzle(ir) || progress;
738
739   progress = optimize_redundant_jumps(ir) || progress;
740
741   loop_state *ls = analyze_loop_variables(ir);
742   progress = set_loop_controls(ir, ls) || progress;
743   progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
744   delete ls;
745
746   return progress;
747}
748
749extern "C" {
750
751/**
752 * To be called at GL teardown time, this frees compiler datastructures.
753 *
754 * After calling this, any previously compiled shaders and shader
755 * programs would be invalid.  So this should happen at approximately
756 * program exit.
757 */
758void
759_mesa_destroy_shader_compiler(void)
760{
761   _mesa_destroy_shader_compiler_caches();
762
763   _mesa_glsl_release_types();
764}
765
766/**
767 * Releases compiler caches to trade off performance for memory.
768 *
769 * Intended to be used with glReleaseShaderCompiler().
770 */
771void
772_mesa_destroy_shader_compiler_caches(void)
773{
774   _mesa_glsl_release_functions();
775}
776
777}
778