Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

glsl_parser_extras.cpp 16KB

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