OSDN Git Service

38dee95c359bd6a3accf42b3b3ade1faa32dce5d
[android-x86/external-mesa.git] / 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 <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28     
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33
34 #include "ast.h"
35 #include "glsl_parser_extras.h"
36 #include "glsl_parser.h"
37 #include "ir_constant_folding.h"
38 #include "ir_function_inlining.h"
39 #include "ir_print_visitor.h"
40
41 const char *
42 _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
43 {
44    switch (target) {
45    case vertex_shader:   return "vertex";
46    case fragment_shader: return "fragment";
47    case geometry_shader: return "geometry";
48    }
49
50    assert(!"Should not get here.");
51 }
52
53
54 void
55 _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
56                  const char *fmt, ...)
57 {
58    char buf[1024];
59    int len;
60    va_list ap;
61
62    state->error = true;
63
64    len = snprintf(buf, sizeof(buf), "%u:%u(%u): error: ",
65                   locp->source, locp->first_line, locp->first_column);
66
67    va_start(ap, fmt);
68    vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
69    va_end(ap);
70
71    printf("%s\n", buf);
72 }
73
74
75 void
76 _mesa_glsl_warning(const YYLTYPE *locp, const _mesa_glsl_parse_state *state,
77                    const char *fmt, ...)
78 {
79    char buf[1024];
80    int len;
81    va_list ap;
82
83    len = snprintf(buf, sizeof(buf), "%u:%u(%u): warning: ",
84                   locp->source, locp->first_line, locp->first_column);
85
86    va_start(ap, fmt);
87    vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
88    va_end(ap);
89
90    printf("%s\n", buf);
91 }
92
93
94 bool
95 _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
96                              const char *behavior, YYLTYPE *behavior_locp,
97                              _mesa_glsl_parse_state *state)
98 {
99    enum {
100       extension_disable,
101       extension_enable,
102       extension_require,
103       extension_warn
104    } ext_mode;
105
106    if (strcmp(behavior, "warn") == 0) {
107       ext_mode = extension_warn;
108    } else if (strcmp(behavior, "require") == 0) {
109       ext_mode = extension_require;
110    } else if (strcmp(behavior, "enable") == 0) {
111       ext_mode = extension_enable;
112    } else if (strcmp(behavior, "disable") == 0) {
113       ext_mode = extension_disable;
114    } else {
115       _mesa_glsl_error(behavior_locp, state,
116                        "Unknown extension behavior `%s'",
117                        behavior);
118       return false;
119    }
120
121    bool unsupported = false;
122
123    if (strcmp(name, "all") == 0) {
124       if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
125          _mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
126                           (ext_mode == extension_enable)
127                           ? "enable" : "require");
128          return false;
129       }
130    } if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
131       /* This extension is only supported in fragment shaders.
132        */
133       if (state->target != fragment_shader) {
134          unsupported = true;
135       } else {
136          state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
137          state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
138       }
139    } if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
140       state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
141       state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
142    } else {
143       unsupported = true;
144    }
145
146    if (unsupported) {
147       static const char *const fmt = "extension `%s' unsupported in %s shader";
148
149       if (ext_mode == extension_require) {
150          _mesa_glsl_error(name_locp, state, fmt,
151                           name, _mesa_glsl_shader_target_name(state->target));
152          return false;
153       } else {
154          _mesa_glsl_warning(name_locp, state, fmt,
155                             name, _mesa_glsl_shader_target_name(state->target));
156       }
157    }
158
159    return true;
160 }
161
162
163 ast_node::~ast_node()
164 {
165    /* empty */
166 }
167
168
169 void
170 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
171 {
172    if (q->constant)
173       printf("const ");
174
175    if (q->invariant)
176       printf("invariant ");
177
178    if (q->attribute)
179       printf("attribute ");
180
181    if (q->varying)
182       printf("varying ");
183
184    if (q->in && q->out) 
185       printf("inout ");
186    else {
187       if (q->in)
188          printf("in ");
189
190       if (q->out)
191          printf("out ");
192    }
193
194    if (q->centroid)
195       printf("centroid ");
196    if (q->uniform)
197       printf("uniform ");
198    if (q->smooth)
199       printf("smooth ");
200    if (q->flat)
201       printf("flat ");
202    if (q->noperspective)
203       printf("noperspective ");
204 }
205
206
207 void
208 ast_node::print(void) const
209 {
210    printf("unhandled node ");
211 }
212
213
214 ast_node::ast_node(void)
215 {
216    make_empty_list(this);
217 }
218
219
220 static void
221 ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
222 {
223    if (is_array) {
224       printf("[ ");
225
226       if (array_size)
227          array_size->print();
228
229       printf("] ");
230    }
231 }
232
233
234 void
235 ast_compound_statement::print(void) const
236 {
237    const struct simple_node *ptr;
238
239    printf("{\n");
240    
241    foreach(ptr, & statements) {
242       ((ast_node *)ptr)->print();
243    }
244
245    printf("}\n");
246 }
247
248
249 ast_compound_statement::ast_compound_statement(int new_scope,
250                                                ast_node *statements)
251 {
252    this->new_scope = new_scope;
253    make_empty_list(& this->statements);
254
255    if (statements != NULL) {
256       /* This seems odd, but it works.  The simple_list is,
257        * basically, a circular list.  insert_at_tail adds
258        * the specified node to the list before the current
259        * head.
260        */
261       insert_at_tail((struct simple_node *) statements,
262                      & this->statements);
263    }
264 }
265
266
267 void
268 ast_expression::print(void) const
269 {
270    switch (oper) {
271    case ast_assign:
272    case ast_mul_assign:
273    case ast_div_assign:
274    case ast_mod_assign:
275    case ast_add_assign:
276    case ast_sub_assign:
277    case ast_ls_assign:
278    case ast_rs_assign:
279    case ast_and_assign:
280    case ast_xor_assign:
281    case ast_or_assign:
282       subexpressions[0]->print();
283       printf("%s ", operator_string(oper));
284       subexpressions[1]->print();
285       break;
286
287    case ast_field_selection:
288       subexpressions[0]->print();
289       printf(". %s ", primary_expression.identifier);
290       break;
291
292    case ast_plus:
293    case ast_neg:
294    case ast_bit_not:
295    case ast_logic_not:
296    case ast_pre_inc:
297    case ast_pre_dec:
298       printf("%s ", operator_string(oper));
299       subexpressions[0]->print();
300       break;
301
302    case ast_post_inc:
303    case ast_post_dec:
304       subexpressions[0]->print();
305       printf("%s ", operator_string(oper));
306       break;
307
308    case ast_conditional:
309       subexpressions[0]->print();
310       printf("? ");
311       subexpressions[1]->print();
312       printf(": ");
313       subexpressions[1]->print();
314       break;
315
316    case ast_array_index:
317       subexpressions[0]->print();
318       printf("[ ");
319       subexpressions[1]->print();
320       printf("] ");
321       break;
322
323    case ast_function_call: {
324       ast_expression *parameters = subexpressions[1];
325
326       subexpressions[0]->print();
327       printf("( ");
328
329       if (parameters != NULL) {
330          struct simple_node *ptr;
331
332          parameters->print();
333          foreach (ptr, (struct simple_node *) parameters) {
334             printf(", ");
335             ((ast_node *)ptr)->print();
336          }
337       }
338
339       printf(") ");
340       break;
341    }
342
343    case ast_identifier:
344       printf("%s ", primary_expression.identifier);
345       break;
346
347    case ast_int_constant:
348       printf("%d ", primary_expression.int_constant);
349       break;
350
351    case ast_uint_constant:
352       printf("%u ", primary_expression.uint_constant);
353       break;
354
355    case ast_float_constant:
356       printf("%f ", primary_expression.float_constant);
357       break;
358
359    case ast_bool_constant:
360       printf("%s ",
361              primary_expression.bool_constant
362              ? "true" : "false");
363       break;
364
365    case ast_sequence: {
366       struct simple_node *ptr;
367       struct simple_node *const head = first_elem(& expressions);
368       
369       printf("( ");
370       foreach (ptr, & expressions) {
371          if (ptr != head)
372             printf(", ");
373
374          ((ast_node *)ptr)->print();
375       }
376       printf(") ");
377       break;
378    }
379
380    default:
381       assert(0);
382       break;
383    }
384 }
385
386 ast_expression::ast_expression(int oper,
387                                ast_expression *ex0,
388                                ast_expression *ex1,
389                                ast_expression *ex2)
390 {
391    this->oper = ast_operators(oper);
392    this->subexpressions[0] = ex0;
393    this->subexpressions[1] = ex1;
394    this->subexpressions[2] = ex2;
395    make_empty_list(& expressions);
396 }
397
398
399 void
400 ast_expression_statement::print(void) const
401 {
402    if (expression)
403       expression->print();
404
405    printf("; ");
406 }
407
408
409 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
410    expression(ex)
411 {
412    /* empty */
413 }
414
415
416 void
417 ast_function::print(void) const
418 {
419    struct simple_node *ptr;
420
421    return_type->print();
422    printf(" %s (", identifier);
423
424    foreach(ptr, & parameters) {
425       ((ast_node *)ptr)->print();
426    }
427
428    printf(")");
429 }
430
431
432 ast_function::ast_function(void)
433    : is_definition(false), signature(NULL)
434 {
435    make_empty_list(& parameters);
436 }
437
438
439 void
440 ast_fully_specified_type::print(void) const
441 {
442    _mesa_ast_type_qualifier_print(& qualifier);
443    specifier->print();
444 }
445
446
447 void
448 ast_parameter_declarator::print(void) const
449 {
450    type->print();
451    if (identifier)
452       printf("%s ", identifier);
453    ast_opt_array_size_print(is_array, array_size);
454 }
455
456
457 void
458 ast_function_definition::print(void) const
459 {
460    prototype->print();
461    body->print();
462 }
463
464
465 void
466 ast_declaration::print(void) const
467 {
468    printf("%s ", identifier);
469    ast_opt_array_size_print(is_array, array_size);
470
471    if (initializer) {
472       printf("= ");
473       initializer->print();
474    }
475 }
476
477
478 ast_declaration::ast_declaration(char *identifier, int is_array,
479                                  ast_expression *array_size,
480                                  ast_expression *initializer)
481 {
482    this->identifier = identifier;
483    this->is_array = is_array;
484    this->array_size = array_size;
485    this->initializer = initializer;
486 }
487
488
489 void
490 ast_declarator_list::print(void) const
491 {
492    struct simple_node *head;
493    struct simple_node *ptr;
494
495    assert(type || invariant);
496
497    if (type)
498       type->print();
499    else
500       printf("invariant ");
501
502    head = first_elem(& declarations);
503    foreach (ptr, & declarations) {
504       if (ptr != head)
505          printf(", ");
506
507       ((ast_node *)ptr)->print();
508    }
509
510    printf("; ");
511 }
512
513
514 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
515 {
516    this->type = type;
517    make_empty_list(& this->declarations);
518 }
519
520 void
521 ast_jump_statement::print(void) const
522 {
523    switch (mode) {
524    case ast_continue:
525       printf("continue; ");
526       break;
527    case ast_break:
528       printf("break; ");
529       break;
530    case ast_return:
531       printf("return ");
532       if (opt_return_value)
533          opt_return_value->print();
534
535       printf("; ");
536       break;
537    case ast_discard:
538       printf("discard; ");
539       break;
540    }
541 }
542
543
544 ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
545 {
546    this->mode = ast_jump_modes(mode);
547
548    if (mode == ast_return)
549       opt_return_value = return_value;
550 }
551
552
553 void
554 ast_selection_statement::print(void) const
555 {
556    printf("if ( ");
557    condition->print();
558    printf(") ");
559
560    then_statement->print();
561
562    if (else_statement) {
563       printf("else ");
564       else_statement->print();
565    }
566    
567 }
568
569
570 ast_selection_statement::ast_selection_statement(ast_expression *condition,
571                                                  ast_node *then_statement,
572                                                  ast_node *else_statement)
573 {
574    this->condition = condition;
575    this->then_statement = then_statement;
576    this->else_statement = else_statement;
577 }
578
579
580 void
581 ast_iteration_statement::print(void) const
582 {
583    switch (mode) {
584    case ast_for:
585       printf("for( ");
586       if (init_statement)
587          init_statement->print();
588       printf("; ");
589
590       if (condition)
591          condition->print();
592       printf("; ");
593
594       if (rest_expression)
595          rest_expression->print();
596       printf(") ");
597
598       body->print();
599       break;
600
601    case ast_while:
602       printf("while ( ");
603       if (condition)
604          condition->print();
605       printf(") ");
606       body->print();
607       break;
608
609    case ast_do_while:
610       printf("do ");
611       body->print();
612       printf("while ( ");
613       if (condition)
614          condition->print();
615       printf("); ");
616       break;
617    }
618 }
619
620
621 ast_iteration_statement::ast_iteration_statement(int mode,
622                                                  ast_node *init,
623                                                  ast_node *condition,
624                                                  ast_expression *rest_expression,
625                                                  ast_node *body)
626 {
627    this->mode = ast_iteration_modes(mode);
628    this->init_statement = init;
629    this->condition = condition;
630    this->rest_expression = rest_expression;
631    this->body = body;
632 }
633
634
635 void
636 ast_struct_specifier::print(void) const
637 {
638    struct simple_node *ptr;
639
640    printf("struct %s { ", name);
641    foreach (ptr, & declarations) {
642       ((ast_node *)ptr)->print();
643    }
644    printf("} ");
645 }
646
647
648 ast_struct_specifier::ast_struct_specifier(char *identifier,
649                                            ast_node *declarator_list)
650 {
651    name = identifier;
652
653    /* This seems odd, but it works.  The simple_list is,
654     * basically, a circular list.  insert_at_tail adds
655     * the specified node to the list before the current
656     * head.
657     */
658    insert_at_tail((struct simple_node *) declarator_list,
659                   & declarations);
660 }
661
662
663 static char *
664 load_text_file(const char *file_name, size_t *size)
665 {
666         char *text = NULL;
667         struct stat st;
668         ssize_t total_read = 0;
669         int fd = open(file_name, O_RDONLY);
670
671         *size = 0;
672         if (fd < 0) {
673                 return NULL;
674         }
675
676         if (fstat(fd, & st) == 0) {
677            text = (char *) malloc(st.st_size + 1);
678                 if (text != NULL) {
679                         do {
680                                 ssize_t bytes = read(fd, text + total_read,
681                                                      st.st_size - total_read);
682                                 if (bytes < 0) {
683                                         free(text);
684                                         text = NULL;
685                                         break;
686                                 }
687
688                                 if (bytes == 0) {
689                                         break;
690                                 }
691
692                                 total_read += bytes;
693                         } while (total_read < st.st_size);
694
695                         text[total_read] = '\0';
696                         *size = total_read;
697                 }
698         }
699
700         close(fd);
701
702         return text;
703 }
704
705
706 int
707 main(int argc, char **argv)
708 {
709    struct _mesa_glsl_parse_state state;
710    char *shader;
711    size_t shader_len;
712    struct simple_node *ptr;
713    exec_list instructions;
714
715    if (argc < 3) {
716       printf("Usage: %s [v|g|f] <shader_file>\n", argv[0]);
717       return EXIT_FAILURE;
718    }
719
720    switch (argv[1][0]) {
721    case 'v':
722       state.target = vertex_shader;
723       break;
724    case 'g':
725       state.target = geometry_shader;
726       break;
727    case 'f':
728       state.target = fragment_shader;
729       break;
730    default:
731       printf("Usage: %s [v|g|f] <shader_file>\n", argv[0]);
732       return EXIT_FAILURE;
733    }
734
735    shader = load_text_file(argv[2], & shader_len);
736
737    state.scanner = NULL;
738    make_empty_list(& state.translation_unit);
739    state.symbols = new glsl_symbol_table;
740    state.error = false;
741    state.temp_index = 0;
742    state.loop_or_switch_nesting = NULL;
743    state.ARB_texture_rectangle_enable = true;
744
745    _mesa_glsl_lexer_ctor(& state, shader, shader_len);
746    _mesa_glsl_parse(& state);
747    _mesa_glsl_lexer_dtor(& state);
748
749    foreach (ptr, & state.translation_unit) {
750       ((ast_node *)ptr)->print();
751    }
752
753    _mesa_ast_to_hir(&instructions, &state);
754
755    /* Optimization passes */
756    if (!state.error) {
757       bool progress;
758       do {
759          progress = false;
760
761          progress = do_function_inlining(&instructions) || progress;
762
763          /* Constant folding */
764          ir_constant_folding_visitor constant_folding;
765          visit_exec_list(&instructions, &constant_folding);
766       } while (progress);
767    }
768
769    /* Print out the resulting IR */
770    printf("\n\n");
771
772    if (!state.error) {
773       foreach_iter(exec_list_iterator, iter, instructions) {
774          ir_print_visitor v;
775
776          ((ir_instruction *)iter.get())->accept(& v);
777          printf("\n");
778       }
779    }
780
781    delete state.symbols;
782
783    return state.error != 0;
784 }