glsl: add support for system values and GL_ARB_draw_instanced
[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 <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
84 const 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
98 void
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
119 void
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
138 bool
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_draw_instanced") == 0) {
184 /* This extension is only supported in vertex shaders.
185 */
186 if (state->target != vertex_shader) {
187 unsupported = true;
188 } else {
189 state->ARB_draw_instanced_enable = (ext_mode != extension_disable);
190 state->ARB_draw_instanced_warn = (ext_mode == extension_warn);
191 }
192 } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
193 state->ARB_explicit_attrib_location_enable =
194 (ext_mode != extension_disable);
195 state->ARB_explicit_attrib_location_warn =
196 (ext_mode == extension_warn);
197
198 unsupported = !state->extensions->ARB_explicit_attrib_location;
199 } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) {
200 state->ARB_fragment_coord_conventions_enable =
201 (ext_mode != extension_disable);
202 state->ARB_fragment_coord_conventions_warn =
203 (ext_mode == extension_warn);
204
205 unsupported = !state->extensions->ARB_fragment_coord_conventions;
206 } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
207 state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
208 state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
209 } else if (strcmp(name, "GL_EXT_texture_array") == 0) {
210 state->EXT_texture_array_enable = (ext_mode != extension_disable);
211 state->EXT_texture_array_warn = (ext_mode == extension_warn);
212
213 unsupported = !state->extensions->EXT_texture_array;
214 } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) {
215 if (state->target != fragment_shader) {
216 unsupported = true;
217 } else {
218 state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable);
219 state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn);
220 unsupported = !state->extensions->ARB_shader_stencil_export;
221 }
222 } else {
223 unsupported = true;
224 }
225
226 if (unsupported) {
227 static const char *const fmt = "extension `%s' unsupported in %s shader";
228
229 if (ext_mode == extension_require) {
230 _mesa_glsl_error(name_locp, state, fmt,
231 name, _mesa_glsl_shader_target_name(state->target));
232 return false;
233 } else {
234 _mesa_glsl_warning(name_locp, state, fmt,
235 name, _mesa_glsl_shader_target_name(state->target));
236 }
237 }
238
239 return true;
240 }
241
242 void
243 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
244 {
245 if (q->flags.q.constant)
246 printf("const ");
247
248 if (q->flags.q.invariant)
249 printf("invariant ");
250
251 if (q->flags.q.attribute)
252 printf("attribute ");
253
254 if (q->flags.q.varying)
255 printf("varying ");
256
257 if (q->flags.q.in && q->flags.q.out)
258 printf("inout ");
259 else {
260 if (q->flags.q.in)
261 printf("in ");
262
263 if (q->flags.q.out)
264 printf("out ");
265 }
266
267 if (q->flags.q.centroid)
268 printf("centroid ");
269 if (q->flags.q.uniform)
270 printf("uniform ");
271 if (q->flags.q.smooth)
272 printf("smooth ");
273 if (q->flags.q.flat)
274 printf("flat ");
275 if (q->flags.q.noperspective)
276 printf("noperspective ");
277 }
278
279
280 void
281 ast_node::print(void) const
282 {
283 printf("unhandled node ");
284 }
285
286
287 ast_node::ast_node(void)
288 {
289 this->location.source = 0;
290 this->location.line = 0;
291 this->location.column = 0;
292 }
293
294
295 static void
296 ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
297 {
298 if (is_array) {
299 printf("[ ");
300
301 if (array_size)
302 array_size->print();
303
304 printf("] ");
305 }
306 }
307
308
309 void
310 ast_compound_statement::print(void) const
311 {
312 printf("{\n");
313
314 foreach_list_const(n, &this->statements) {
315 ast_node *ast = exec_node_data(ast_node, n, link);
316 ast->print();
317 }
318
319 printf("}\n");
320 }
321
322
323 ast_compound_statement::ast_compound_statement(int new_scope,
324 ast_node *statements)
325 {
326 this->new_scope = new_scope;
327
328 if (statements != NULL) {
329 this->statements.push_degenerate_list_at_head(&statements->link);
330 }
331 }
332
333
334 void
335 ast_expression::print(void) const
336 {
337 switch (oper) {
338 case ast_assign:
339 case ast_mul_assign:
340 case ast_div_assign:
341 case ast_mod_assign:
342 case ast_add_assign:
343 case ast_sub_assign:
344 case ast_ls_assign:
345 case ast_rs_assign:
346 case ast_and_assign:
347 case ast_xor_assign:
348 case ast_or_assign:
349 subexpressions[0]->print();
350 printf("%s ", operator_string(oper));
351 subexpressions[1]->print();
352 break;
353
354 case ast_field_selection:
355 subexpressions[0]->print();
356 printf(". %s ", primary_expression.identifier);
357 break;
358
359 case ast_plus:
360 case ast_neg:
361 case ast_bit_not:
362 case ast_logic_not:
363 case ast_pre_inc:
364 case ast_pre_dec:
365 printf("%s ", operator_string(oper));
366 subexpressions[0]->print();
367 break;
368
369 case ast_post_inc:
370 case ast_post_dec:
371 subexpressions[0]->print();
372 printf("%s ", operator_string(oper));
373 break;
374
375 case ast_conditional:
376 subexpressions[0]->print();
377 printf("? ");
378 subexpressions[1]->print();
379 printf(": ");
380 subexpressions[1]->print();
381 break;
382
383 case ast_array_index:
384 subexpressions[0]->print();
385 printf("[ ");
386 subexpressions[1]->print();
387 printf("] ");
388 break;
389
390 case ast_function_call: {
391 subexpressions[0]->print();
392 printf("( ");
393
394 foreach_list_const (n, &this->expressions) {
395 if (n != this->expressions.get_head())
396 printf(", ");
397
398 ast_node *ast = exec_node_data(ast_node, n, link);
399 ast->print();
400 }
401
402 printf(") ");
403 break;
404 }
405
406 case ast_identifier:
407 printf("%s ", primary_expression.identifier);
408 break;
409
410 case ast_int_constant:
411 printf("%d ", primary_expression.int_constant);
412 break;
413
414 case ast_uint_constant:
415 printf("%u ", primary_expression.uint_constant);
416 break;
417
418 case ast_float_constant:
419 printf("%f ", primary_expression.float_constant);
420 break;
421
422 case ast_bool_constant:
423 printf("%s ",
424 primary_expression.bool_constant
425 ? "true" : "false");
426 break;
427
428 case ast_sequence: {
429 printf("( ");
430 foreach_list_const(n, & this->expressions) {
431 if (n != this->expressions.get_head())
432 printf(", ");
433
434 ast_node *ast = exec_node_data(ast_node, n, link);
435 ast->print();
436 }
437 printf(") ");
438 break;
439 }
440
441 default:
442 assert(0);
443 break;
444 }
445 }
446
447 ast_expression::ast_expression(int oper,
448 ast_expression *ex0,
449 ast_expression *ex1,
450 ast_expression *ex2)
451 {
452 this->oper = ast_operators(oper);
453 this->subexpressions[0] = ex0;
454 this->subexpressions[1] = ex1;
455 this->subexpressions[2] = ex2;
456 }
457
458
459 void
460 ast_expression_statement::print(void) const
461 {
462 if (expression)
463 expression->print();
464
465 printf("; ");
466 }
467
468
469 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
470 expression(ex)
471 {
472 /* empty */
473 }
474
475
476 void
477 ast_function::print(void) const
478 {
479 return_type->print();
480 printf(" %s (", identifier);
481
482 foreach_list_const(n, & this->parameters) {
483 ast_node *ast = exec_node_data(ast_node, n, link);
484 ast->print();
485 }
486
487 printf(")");
488 }
489
490
491 ast_function::ast_function(void)
492 : is_definition(false), signature(NULL)
493 {
494 /* empty */
495 }
496
497
498 void
499 ast_fully_specified_type::print(void) const
500 {
501 _mesa_ast_type_qualifier_print(& qualifier);
502 specifier->print();
503 }
504
505
506 void
507 ast_parameter_declarator::print(void) const
508 {
509 type->print();
510 if (identifier)
511 printf("%s ", identifier);
512 ast_opt_array_size_print(is_array, array_size);
513 }
514
515
516 void
517 ast_function_definition::print(void) const
518 {
519 prototype->print();
520 body->print();
521 }
522
523
524 void
525 ast_declaration::print(void) const
526 {
527 printf("%s ", identifier);
528 ast_opt_array_size_print(is_array, array_size);
529
530 if (initializer) {
531 printf("= ");
532 initializer->print();
533 }
534 }
535
536
537 ast_declaration::ast_declaration(char *identifier, int is_array,
538 ast_expression *array_size,
539 ast_expression *initializer)
540 {
541 this->identifier = identifier;
542 this->is_array = is_array;
543 this->array_size = array_size;
544 this->initializer = initializer;
545 }
546
547
548 void
549 ast_declarator_list::print(void) const
550 {
551 assert(type || invariant);
552
553 if (type)
554 type->print();
555 else
556 printf("invariant ");
557
558 foreach_list_const (ptr, & this->declarations) {
559 if (ptr != this->declarations.get_head())
560 printf(", ");
561
562 ast_node *ast = exec_node_data(ast_node, ptr, link);
563 ast->print();
564 }
565
566 printf("; ");
567 }
568
569
570 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
571 {
572 this->type = type;
573 this->invariant = false;
574 }
575
576 void
577 ast_jump_statement::print(void) const
578 {
579 switch (mode) {
580 case ast_continue:
581 printf("continue; ");
582 break;
583 case ast_break:
584 printf("break; ");
585 break;
586 case ast_return:
587 printf("return ");
588 if (opt_return_value)
589 opt_return_value->print();
590
591 printf("; ");
592 break;
593 case ast_discard:
594 printf("discard; ");
595 break;
596 }
597 }
598
599
600 ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
601 {
602 this->mode = ast_jump_modes(mode);
603
604 if (mode == ast_return)
605 opt_return_value = return_value;
606 }
607
608
609 void
610 ast_selection_statement::print(void) const
611 {
612 printf("if ( ");
613 condition->print();
614 printf(") ");
615
616 then_statement->print();
617
618 if (else_statement) {
619 printf("else ");
620 else_statement->print();
621 }
622
623 }
624
625
626 ast_selection_statement::ast_selection_statement(ast_expression *condition,
627 ast_node *then_statement,
628 ast_node *else_statement)
629 {
630 this->condition = condition;
631 this->then_statement = then_statement;
632 this->else_statement = else_statement;
633 }
634
635
636 void
637 ast_iteration_statement::print(void) const
638 {
639 switch (mode) {
640 case ast_for:
641 printf("for( ");
642 if (init_statement)
643 init_statement->print();
644 printf("; ");
645
646 if (condition)
647 condition->print();
648 printf("; ");
649
650 if (rest_expression)
651 rest_expression->print();
652 printf(") ");
653
654 body->print();
655 break;
656
657 case ast_while:
658 printf("while ( ");
659 if (condition)
660 condition->print();
661 printf(") ");
662 body->print();
663 break;
664
665 case ast_do_while:
666 printf("do ");
667 body->print();
668 printf("while ( ");
669 if (condition)
670 condition->print();
671 printf("); ");
672 break;
673 }
674 }
675
676
677 ast_iteration_statement::ast_iteration_statement(int mode,
678 ast_node *init,
679 ast_node *condition,
680 ast_expression *rest_expression,
681 ast_node *body)
682 {
683 this->mode = ast_iteration_modes(mode);
684 this->init_statement = init;
685 this->condition = condition;
686 this->rest_expression = rest_expression;
687 this->body = body;
688 }
689
690
691 void
692 ast_struct_specifier::print(void) const
693 {
694 printf("struct %s { ", name);
695 foreach_list_const(n, &this->declarations) {
696 ast_node *ast = exec_node_data(ast_node, n, link);
697 ast->print();
698 }
699 printf("} ");
700 }
701
702
703 ast_struct_specifier::ast_struct_specifier(char *identifier,
704 ast_node *declarator_list)
705 {
706 if (identifier == NULL) {
707 static unsigned anon_count = 1;
708 identifier = talloc_asprintf(this, "#anon_struct_%04x", anon_count);
709 anon_count++;
710 }
711 name = identifier;
712 this->declarations.push_degenerate_list_at_head(&declarator_list->link);
713 }
714
715 bool
716 do_common_optimization(exec_list *ir, bool linked, unsigned max_unroll_iterations)
717 {
718 GLboolean progress = GL_FALSE;
719
720 progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress;
721
722 if (linked) {
723 progress = do_function_inlining(ir) || progress;
724 progress = do_dead_functions(ir) || progress;
725 }
726 progress = do_structure_splitting(ir) || progress;
727 progress = do_if_simplification(ir) || progress;
728 progress = do_copy_propagation(ir) || progress;
729 if (linked)
730 progress = do_dead_code(ir) || progress;
731 else
732 progress = do_dead_code_unlinked(ir) || progress;
733 progress = do_dead_code_local(ir) || progress;
734 progress = do_tree_grafting(ir) || progress;
735 progress = do_constant_propagation(ir) || progress;
736 if (linked)
737 progress = do_constant_variable(ir) || progress;
738 else
739 progress = do_constant_variable_unlinked(ir) || progress;
740 progress = do_constant_folding(ir) || progress;
741 progress = do_algebraic(ir) || progress;
742 progress = do_lower_jumps(ir) || progress;
743 progress = do_vec_index_to_swizzle(ir) || progress;
744 progress = do_swizzle_swizzle(ir) || progress;
745 progress = do_noop_swizzle(ir) || progress;
746
747 progress = optimize_redundant_jumps(ir) || progress;
748
749 loop_state *ls = analyze_loop_variables(ir);
750 progress = set_loop_controls(ir, ls) || progress;
751 progress = unroll_loops(ir, ls, max_unroll_iterations) || progress;
752 delete ls;
753
754 return progress;
755 }
756
757 extern "C" {
758
759 /**
760 * To be called at GL teardown time, this frees compiler datastructures.
761 *
762 * After calling this, any previously compiled shaders and shader
763 * programs would be invalid. So this should happen at approximately
764 * program exit.
765 */
766 void
767 _mesa_destroy_shader_compiler(void)
768 {
769 _mesa_destroy_shader_compiler_caches();
770
771 _mesa_glsl_release_types();
772 }
773
774 /**
775 * Releases compiler caches to trade off performance for memory.
776 *
777 * Intended to be used with glReleaseShaderCompiler().
778 */
779 void
780 _mesa_destroy_shader_compiler_caches(void)
781 {
782 _mesa_glsl_release_functions();
783 }
784
785 }