ir_reader.cpp revision ec7e4f0ec5c9b718bbfa33a706149030be86d2d9
1/* 2 * Copyright © 2010 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 24extern "C" { 25#include <talloc.h> 26} 27 28#include "ir_reader.h" 29#include "glsl_parser_extras.h" 30#include "glsl_types.h" 31#include "s_expression.h" 32 33const static bool debug = false; 34 35static void ir_read_error(_mesa_glsl_parse_state *, s_expression *, 36 const char *fmt, ...); 37static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *); 38 39static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *, 40 s_expression *); 41static ir_function *read_function(_mesa_glsl_parse_state *, s_expression *, 42 bool skip_body); 43static void read_function_sig(_mesa_glsl_parse_state *, ir_function *, 44 s_expression *, bool skip_body); 45 46static void read_instructions(_mesa_glsl_parse_state *, exec_list *, 47 s_expression *, ir_loop *); 48static ir_instruction *read_instruction(_mesa_glsl_parse_state *, 49 s_expression *, ir_loop *); 50static ir_variable *read_declaration(_mesa_glsl_parse_state *, s_expression *); 51static ir_if *read_if(_mesa_glsl_parse_state *, s_expression *, ir_loop *); 52static ir_loop *read_loop(_mesa_glsl_parse_state *st, s_expression *); 53static ir_return *read_return(_mesa_glsl_parse_state *, s_expression *); 54 55static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *); 56static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_expression *); 57static ir_expression *read_expression(_mesa_glsl_parse_state *, s_expression *); 58static ir_call *read_call(_mesa_glsl_parse_state *, s_expression *); 59static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_expression *); 60static ir_constant *read_constant(_mesa_glsl_parse_state *, s_expression *); 61static ir_texture *read_texture(_mesa_glsl_parse_state *, s_expression *); 62 63static ir_dereference *read_dereference(_mesa_glsl_parse_state *, 64 s_expression *); 65 66void 67_mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions, 68 const char *src, bool scan_for_protos) 69{ 70 s_expression *expr = s_expression::read_expression(state, src); 71 if (expr == NULL) { 72 ir_read_error(state, NULL, "couldn't parse S-Expression."); 73 return; 74 } 75 76 if (scan_for_protos) { 77 scan_for_prototypes(state, instructions, expr); 78 if (state->error) 79 return; 80 } 81 82 read_instructions(state, instructions, expr, NULL); 83 talloc_free(expr); 84 85 if (debug) 86 validate_ir_tree(instructions); 87} 88 89static void 90ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr, 91 const char *fmt, ...) 92{ 93 va_list ap; 94 95 state->error = true; 96 97 if (state->current_function != NULL) 98 state->info_log = talloc_asprintf_append(state->info_log, 99 "In function %s:\n", 100 state->current_function->function_name()); 101 state->info_log = talloc_strdup_append(state->info_log, "error: "); 102 103 va_start(ap, fmt); 104 state->info_log = talloc_vasprintf_append(state->info_log, fmt, ap); 105 va_end(ap); 106 state->info_log = talloc_strdup_append(state->info_log, "\n"); 107 108 if (expr != NULL) { 109 state->info_log = talloc_strdup_append(state->info_log, 110 "...in this context:\n "); 111 expr->print(); 112 state->info_log = talloc_strdup_append(state->info_log, "\n\n"); 113 } 114} 115 116static const glsl_type * 117read_type(_mesa_glsl_parse_state *st, s_expression *expr) 118{ 119 s_expression *s_base_type; 120 s_int *s_size; 121 122 s_pattern pat[] = { "array", s_base_type, s_size }; 123 if (MATCH(expr, pat)) { 124 const glsl_type *base_type = read_type(st, s_base_type); 125 if (base_type == NULL) { 126 ir_read_error(st, NULL, "when reading base type of array type"); 127 return NULL; 128 } 129 130 return glsl_type::get_array_instance(base_type, s_size->value()); 131 } 132 133 s_symbol *type_sym = SX_AS_SYMBOL(expr); 134 if (type_sym == NULL) { 135 ir_read_error(st, expr, "expected <type>"); 136 return NULL; 137 } 138 139 const glsl_type *type = st->symbols->get_type(type_sym->value()); 140 if (type == NULL) 141 ir_read_error(st, expr, "invalid type: %s", type_sym->value()); 142 143 return type; 144} 145 146 147static void 148scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions, 149 s_expression *expr) 150{ 151 s_list *list = SX_AS_LIST(expr); 152 if (list == NULL) { 153 ir_read_error(st, expr, "Expected (<instruction> ...); found an atom."); 154 return; 155 } 156 157 foreach_iter(exec_list_iterator, it, list->subexpressions) { 158 s_list *sub = SX_AS_LIST(it.get()); 159 if (sub == NULL) 160 continue; // not a (function ...); ignore it. 161 162 s_symbol *tag = SX_AS_SYMBOL(sub->subexpressions.get_head()); 163 if (tag == NULL || strcmp(tag->value(), "function") != 0) 164 continue; // not a (function ...); ignore it. 165 166 ir_function *f = read_function(st, sub, true); 167 if (f == NULL) 168 return; 169 instructions->push_tail(f); 170 } 171} 172 173static ir_function * 174read_function(_mesa_glsl_parse_state *st, s_expression *expr, bool skip_body) 175{ 176 void *ctx = st; 177 bool added = false; 178 s_symbol *name; 179 180 s_pattern pat[] = { "function", name }; 181 if (!PARTIAL_MATCH(expr, pat)) { 182 ir_read_error(st, expr, "Expected (function <name> (signature ...) ...)"); 183 return NULL; 184 } 185 186 ir_function *f = st->symbols->get_function(name->value()); 187 if (f == NULL) { 188 f = new(ctx) ir_function(name->value()); 189 added = st->symbols->add_function(f); 190 assert(added); 191 } 192 193 exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator(); 194 it.next(); // skip "function" tag 195 it.next(); // skip function name 196 for (/* nothing */; it.has_next(); it.next()) { 197 s_expression *s_sig = (s_expression *) it.get(); 198 read_function_sig(st, f, s_sig, skip_body); 199 } 200 return added ? f : NULL; 201} 202 203static void 204read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, 205 s_expression *expr, bool skip_body) 206{ 207 void *ctx = st; 208 s_expression *type_expr; 209 s_list *paramlist; 210 s_list *body_list; 211 212 s_pattern pat[] = { "signature", type_expr, paramlist, body_list }; 213 if (!MATCH(expr, pat)) { 214 ir_read_error(st, expr, "Expected (signature <type> (parameters ...) " 215 "(<instruction> ...))"); 216 return; 217 } 218 219 const glsl_type *return_type = read_type(st, type_expr); 220 if (return_type == NULL) 221 return; 222 223 s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head()); 224 if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) { 225 ir_read_error(st, paramlist, "Expected (parameters ...)"); 226 return; 227 } 228 229 // Read the parameters list into a temporary place. 230 exec_list hir_parameters; 231 st->symbols->push_scope(); 232 233 exec_list_iterator it = paramlist->subexpressions.iterator(); 234 for (it.next() /* skip "parameters" */; it.has_next(); it.next()) { 235 ir_variable *var = read_declaration(st, (s_expression *) it.get()); 236 if (var == NULL) 237 return; 238 239 hir_parameters.push_tail(var); 240 } 241 242 ir_function_signature *sig = f->exact_matching_signature(&hir_parameters); 243 if (sig == NULL && skip_body) { 244 /* If scanning for prototypes, generate a new signature. */ 245 sig = new(ctx) ir_function_signature(return_type); 246 sig->is_builtin = true; 247 f->add_signature(sig); 248 } else if (sig != NULL) { 249 const char *badvar = sig->qualifiers_match(&hir_parameters); 250 if (badvar != NULL) { 251 ir_read_error(st, expr, "function `%s' parameter `%s' qualifiers " 252 "don't match prototype", f->name, badvar); 253 return; 254 } 255 256 if (sig->return_type != return_type) { 257 ir_read_error(st, expr, "function `%s' return type doesn't " 258 "match prototype", f->name); 259 return; 260 } 261 } else { 262 /* No prototype for this body exists - skip it. */ 263 st->symbols->pop_scope(); 264 return; 265 } 266 assert(sig != NULL); 267 268 sig->replace_parameters(&hir_parameters); 269 270 if (!skip_body && !body_list->subexpressions.is_empty()) { 271 if (sig->is_defined) { 272 ir_read_error(st, expr, "function %s redefined", f->name); 273 return; 274 } 275 st->current_function = sig; 276 read_instructions(st, &sig->body, body_list, NULL); 277 st->current_function = NULL; 278 sig->is_defined = true; 279 } 280 281 st->symbols->pop_scope(); 282} 283 284static void 285read_instructions(_mesa_glsl_parse_state *st, exec_list *instructions, 286 s_expression *expr, ir_loop *loop_ctx) 287{ 288 // Read in a list of instructions 289 s_list *list = SX_AS_LIST(expr); 290 if (list == NULL) { 291 ir_read_error(st, expr, "Expected (<instruction> ...); found an atom."); 292 return; 293 } 294 295 foreach_iter(exec_list_iterator, it, list->subexpressions) { 296 s_expression *sub = (s_expression*) it.get(); 297 ir_instruction *ir = read_instruction(st, sub, loop_ctx); 298 if (ir != NULL) { 299 /* Global variable declarations should be moved to the top, before 300 * any functions that might use them. Functions are added to the 301 * instruction stream when scanning for prototypes, so without this 302 * hack, they always appear before variable declarations. 303 */ 304 if (st->current_function == NULL && ir->as_variable() != NULL) 305 instructions->push_head(ir); 306 else 307 instructions->push_tail(ir); 308 } 309 } 310} 311 312 313static ir_instruction * 314read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, 315 ir_loop *loop_ctx) 316{ 317 void *ctx = st; 318 s_symbol *symbol = SX_AS_SYMBOL(expr); 319 if (symbol != NULL) { 320 if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL) 321 return new(ctx) ir_loop_jump(ir_loop_jump::jump_break); 322 if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL) 323 return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue); 324 } 325 326 s_list *list = SX_AS_LIST(expr); 327 if (list == NULL || list->subexpressions.is_empty()) { 328 ir_read_error(st, expr, "Invalid instruction.\n"); 329 return NULL; 330 } 331 332 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head()); 333 if (tag == NULL) { 334 ir_read_error(st, expr, "expected instruction tag"); 335 return NULL; 336 } 337 338 ir_instruction *inst = NULL; 339 if (strcmp(tag->value(), "declare") == 0) { 340 inst = read_declaration(st, list); 341 } else if (strcmp(tag->value(), "assign") == 0) { 342 inst = read_assignment(st, list); 343 } else if (strcmp(tag->value(), "if") == 0) { 344 inst = read_if(st, list, loop_ctx); 345 } else if (strcmp(tag->value(), "loop") == 0) { 346 inst = read_loop(st, list); 347 } else if (strcmp(tag->value(), "return") == 0) { 348 inst = read_return(st, list); 349 } else if (strcmp(tag->value(), "function") == 0) { 350 inst = read_function(st, list, false); 351 } else { 352 inst = read_rvalue(st, list); 353 if (inst == NULL) 354 ir_read_error(st, NULL, "when reading instruction"); 355 } 356 return inst; 357} 358 359static ir_variable * 360read_declaration(_mesa_glsl_parse_state *st, s_expression *expr) 361{ 362 s_list *s_quals; 363 s_expression *s_type; 364 s_symbol *s_name; 365 366 s_pattern pat[] = { "declare", s_quals, s_type, s_name }; 367 if (!MATCH(expr, pat)) { 368 ir_read_error(st, expr, "expected (declare (<qualifiers>) <type> " 369 "<name>)"); 370 return NULL; 371 } 372 373 const glsl_type *type = read_type(st, s_type); 374 if (type == NULL) 375 return NULL; 376 377 ir_variable *var = new(st) ir_variable(type, s_name->value(), ir_var_auto); 378 379 foreach_iter(exec_list_iterator, it, s_quals->subexpressions) { 380 s_symbol *qualifier = SX_AS_SYMBOL(it.get()); 381 if (qualifier == NULL) { 382 ir_read_error(st, expr, "qualifier list must contain only symbols"); 383 return NULL; 384 } 385 386 // FINISHME: Check for duplicate/conflicting qualifiers. 387 if (strcmp(qualifier->value(), "centroid") == 0) { 388 var->centroid = 1; 389 } else if (strcmp(qualifier->value(), "invariant") == 0) { 390 var->invariant = 1; 391 } else if (strcmp(qualifier->value(), "uniform") == 0) { 392 var->mode = ir_var_uniform; 393 } else if (strcmp(qualifier->value(), "auto") == 0) { 394 var->mode = ir_var_auto; 395 } else if (strcmp(qualifier->value(), "in") == 0) { 396 var->mode = ir_var_in; 397 } else if (strcmp(qualifier->value(), "out") == 0) { 398 var->mode = ir_var_out; 399 } else if (strcmp(qualifier->value(), "inout") == 0) { 400 var->mode = ir_var_inout; 401 } else if (strcmp(qualifier->value(), "smooth") == 0) { 402 var->interpolation = ir_var_smooth; 403 } else if (strcmp(qualifier->value(), "flat") == 0) { 404 var->interpolation = ir_var_flat; 405 } else if (strcmp(qualifier->value(), "noperspective") == 0) { 406 var->interpolation = ir_var_noperspective; 407 } else { 408 ir_read_error(st, expr, "unknown qualifier: %s", qualifier->value()); 409 return NULL; 410 } 411 } 412 413 // Add the variable to the symbol table 414 st->symbols->add_variable(var); 415 416 return var; 417} 418 419 420static ir_if * 421read_if(_mesa_glsl_parse_state *st, s_expression *expr, ir_loop *loop_ctx) 422{ 423 s_expression *s_cond; 424 s_expression *s_then; 425 s_expression *s_else; 426 427 s_pattern pat[] = { "if", s_cond, s_then, s_else }; 428 if (!MATCH(expr, pat)) { 429 ir_read_error(st, expr, "expected (if <condition> (<then> ...) " 430 "(<else> ...))"); 431 return NULL; 432 } 433 434 ir_rvalue *condition = read_rvalue(st, s_cond); 435 if (condition == NULL) { 436 ir_read_error(st, NULL, "when reading condition of (if ...)"); 437 return NULL; 438 } 439 440 ir_if *iff = new(st) ir_if(condition); 441 442 read_instructions(st, &iff->then_instructions, s_then, loop_ctx); 443 read_instructions(st, &iff->else_instructions, s_else, loop_ctx); 444 if (st->error) { 445 delete iff; 446 iff = NULL; 447 } 448 return iff; 449} 450 451 452static ir_loop * 453read_loop(_mesa_glsl_parse_state *st, s_expression *expr) 454{ 455 s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body; 456 457 s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body }; 458 if (!MATCH(expr, pat)) { 459 ir_read_error(st, expr, "expected (loop <counter> <from> <to> " 460 "<increment> <body>)"); 461 return NULL; 462 } 463 464 // FINISHME: actually read the count/from/to fields. 465 466 ir_loop *loop = new(st) ir_loop; 467 read_instructions(st, &loop->body_instructions, s_body, loop); 468 if (st->error) { 469 delete loop; 470 loop = NULL; 471 } 472 return loop; 473} 474 475 476static ir_return * 477read_return(_mesa_glsl_parse_state *st, s_expression *expr) 478{ 479 s_expression *s_retval; 480 481 s_pattern pat[] = { "return", s_retval}; 482 if (!MATCH(expr, pat)) { 483 ir_read_error(st, expr, "expected (return <rvalue>)"); 484 return NULL; 485 } 486 487 ir_rvalue *retval = read_rvalue(st, s_retval); 488 if (retval == NULL) { 489 ir_read_error(st, NULL, "when reading return value"); 490 return NULL; 491 } 492 493 return new(st) ir_return(retval); 494} 495 496 497static ir_rvalue * 498read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr) 499{ 500 s_list *list = SX_AS_LIST(expr); 501 if (list == NULL || list->subexpressions.is_empty()) 502 return NULL; 503 504 s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.get_head()); 505 if (tag == NULL) { 506 ir_read_error(st, expr, "expected rvalue tag"); 507 return NULL; 508 } 509 510 ir_rvalue *rvalue = read_dereference(st, list); 511 if (rvalue != NULL || st->error) 512 return rvalue; 513 else if (strcmp(tag->value(), "swiz") == 0) { 514 rvalue = read_swizzle(st, list); 515 } else if (strcmp(tag->value(), "expression") == 0) { 516 rvalue = read_expression(st, list); 517 } else if (strcmp(tag->value(), "call") == 0) { 518 rvalue = read_call(st, list); 519 } else if (strcmp(tag->value(), "constant") == 0) { 520 rvalue = read_constant(st, list); 521 } else { 522 rvalue = read_texture(st, list); 523 if (rvalue == NULL && !st->error) 524 ir_read_error(st, expr, "unrecognized rvalue tag: %s", tag->value()); 525 } 526 527 return rvalue; 528} 529 530static ir_assignment * 531read_assignment(_mesa_glsl_parse_state *st, s_expression *expr) 532{ 533 s_expression *cond_expr, *lhs_expr, *rhs_expr; 534 s_list *mask_list; 535 536 s_pattern pat[] = { "assign", cond_expr, mask_list, lhs_expr, rhs_expr }; 537 if (!MATCH(expr, pat)) { 538 ir_read_error(st, expr, "expected (assign <condition> (<write mask>) " 539 "<lhs> <rhs>)"); 540 return NULL; 541 } 542 543 ir_rvalue *condition = read_rvalue(st, cond_expr); 544 if (condition == NULL) { 545 ir_read_error(st, NULL, "when reading condition of assignment"); 546 return NULL; 547 } 548 549 unsigned mask = 0; 550 551 s_symbol *mask_symbol; 552 s_pattern mask_pat[] = { mask_symbol }; 553 if (MATCH(mask_list, mask_pat)) { 554 const char *mask_str = mask_symbol->value(); 555 unsigned mask_length = strlen(mask_str); 556 if (mask_length > 4) { 557 ir_read_error(st, expr, "invalid write mask: %s", mask_str); 558 return NULL; 559 } 560 561 const unsigned idx_map[] = { 3, 0, 1, 2 }; /* w=bit 3, x=0, y=1, z=2 */ 562 563 for (unsigned i = 0; i < mask_length; i++) { 564 if (mask_str[i] < 'w' || mask_str[i] > 'z') { 565 ir_read_error(st, expr, "write mask contains invalid character: %c", 566 mask_str[i]); 567 return NULL; 568 } 569 mask |= 1 << idx_map[mask_str[i] - 'w']; 570 } 571 } else if (!mask_list->subexpressions.is_empty()) { 572 ir_read_error(st, mask_list, "expected () or (<write mask>)"); 573 return NULL; 574 } 575 576 ir_dereference *lhs = read_dereference(st, lhs_expr); 577 if (lhs == NULL) { 578 ir_read_error(st, NULL, "when reading left-hand side of assignment"); 579 return NULL; 580 } 581 582 ir_rvalue *rhs = read_rvalue(st, rhs_expr); 583 if (rhs == NULL) { 584 ir_read_error(st, NULL, "when reading right-hand side of assignment"); 585 return NULL; 586 } 587 588 if (mask == 0 && (lhs->type->is_vector() || lhs->type->is_scalar())) { 589 ir_read_error(st, expr, "non-zero write mask required."); 590 return NULL; 591 } 592 593 return new(st) ir_assignment(lhs, rhs, condition, mask); 594} 595 596static ir_call * 597read_call(_mesa_glsl_parse_state *st, s_expression *expr) 598{ 599 void *ctx = st; 600 s_symbol *name; 601 s_list *params; 602 603 s_pattern pat[] = { "call", name, params }; 604 if (!MATCH(expr, pat)) { 605 ir_read_error(st, expr, "expected (call <name> (<param> ...))"); 606 return NULL; 607 } 608 609 exec_list parameters; 610 611 foreach_iter(exec_list_iterator, it, params->subexpressions) { 612 s_expression *expr = (s_expression*) it.get(); 613 ir_rvalue *param = read_rvalue(st, expr); 614 if (param == NULL) { 615 ir_read_error(st, expr, "when reading parameter to function call"); 616 return NULL; 617 } 618 parameters.push_tail(param); 619 } 620 621 ir_function *f = st->symbols->get_function(name->value()); 622 if (f == NULL) { 623 ir_read_error(st, expr, "found call to undefined function %s", 624 name->value()); 625 return NULL; 626 } 627 628 ir_function_signature *callee = f->matching_signature(¶meters); 629 if (callee == NULL) { 630 ir_read_error(st, expr, "couldn't find matching signature for function " 631 "%s", name->value()); 632 return NULL; 633 } 634 635 return new(ctx) ir_call(callee, ¶meters); 636} 637 638static ir_expression * 639read_expression(_mesa_glsl_parse_state *st, s_expression *expr) 640{ 641 void *ctx = st; 642 s_expression *s_type; 643 s_symbol *s_op; 644 s_expression *s_arg1; 645 646 s_pattern pat[] = { "expression", s_type, s_op, s_arg1 }; 647 if (!PARTIAL_MATCH(expr, pat)) { 648 ir_read_error(st, expr, "expected (expression <type> <operator> " 649 "<operand> [<operand>])"); 650 return NULL; 651 } 652 s_expression *s_arg2 = (s_expression *) s_arg1->next; // may be tail sentinel 653 654 const glsl_type *type = read_type(st, s_type); 655 if (type == NULL) 656 return NULL; 657 658 /* Read the operator */ 659 ir_expression_operation op = ir_expression::get_operator(s_op->value()); 660 if (op == (ir_expression_operation) -1) { 661 ir_read_error(st, expr, "invalid operator: %s", s_op->value()); 662 return NULL; 663 } 664 665 unsigned num_operands = ir_expression::get_num_operands(op); 666 if (num_operands == 1 && !s_arg1->next->is_tail_sentinel()) { 667 ir_read_error(st, expr, "expected (expression <type> %s <operand>)", 668 s_op->value()); 669 return NULL; 670 } 671 672 ir_rvalue *arg1 = read_rvalue(st, s_arg1); 673 ir_rvalue *arg2 = NULL; 674 if (arg1 == NULL) { 675 ir_read_error(st, NULL, "when reading first operand of %s", 676 s_op->value()); 677 return NULL; 678 } 679 680 if (num_operands == 2) { 681 if (s_arg2->is_tail_sentinel() || !s_arg2->next->is_tail_sentinel()) { 682 ir_read_error(st, expr, "expected (expression <type> %s <operand> " 683 "<operand>)", s_op->value()); 684 return NULL; 685 } 686 arg2 = read_rvalue(st, s_arg2); 687 if (arg2 == NULL) { 688 ir_read_error(st, NULL, "when reading second operand of %s", 689 s_op->value()); 690 return NULL; 691 } 692 } 693 694 return new(ctx) ir_expression(op, type, arg1, arg2); 695} 696 697static ir_swizzle * 698read_swizzle(_mesa_glsl_parse_state *st, s_expression *expr) 699{ 700 s_symbol *swiz; 701 s_expression *sub; 702 703 s_pattern pat[] = { "swiz", swiz, sub }; 704 if (!MATCH(expr, pat)) { 705 ir_read_error(st, expr, "expected (swiz <swizzle> <rvalue>)"); 706 return NULL; 707 } 708 709 if (strlen(swiz->value()) > 4) { 710 ir_read_error(st, expr, "expected a valid swizzle; found %s", 711 swiz->value()); 712 return NULL; 713 } 714 715 ir_rvalue *rvalue = read_rvalue(st, sub); 716 if (rvalue == NULL) 717 return NULL; 718 719 ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(), 720 rvalue->type->vector_elements); 721 if (ir == NULL) 722 ir_read_error(st, expr, "invalid swizzle"); 723 724 return ir; 725} 726 727static ir_constant * 728read_constant(_mesa_glsl_parse_state *st, s_expression *expr) 729{ 730 void *ctx = st; 731 s_expression *type_expr; 732 s_list *values; 733 734 s_pattern pat[] = { "constant", type_expr, values }; 735 if (!MATCH(expr, pat)) { 736 ir_read_error(st, expr, "expected (constant <type> (...))"); 737 return NULL; 738 } 739 740 const glsl_type *type = read_type(st, type_expr); 741 if (type == NULL) 742 return NULL; 743 744 if (values == NULL) { 745 ir_read_error(st, expr, "expected (constant <type> (...))"); 746 return NULL; 747 } 748 749 if (type->is_array()) { 750 unsigned elements_supplied = 0; 751 exec_list elements; 752 foreach_iter(exec_list_iterator, it, values->subexpressions) { 753 s_expression *elt = (s_expression *) it.get(); 754 ir_constant *ir_elt = read_constant(st, elt); 755 if (ir_elt == NULL) 756 return NULL; 757 elements.push_tail(ir_elt); 758 elements_supplied++; 759 } 760 761 if (elements_supplied != type->length) { 762 ir_read_error(st, values, "expected exactly %u array elements, " 763 "given %u", type->length, elements_supplied); 764 return NULL; 765 } 766 return new(ctx) ir_constant(type, &elements); 767 } 768 769 const glsl_type *const base_type = type->get_base_type(); 770 771 ir_constant_data data = { { 0 } }; 772 773 // Read in list of values (at most 16). 774 int k = 0; 775 foreach_iter(exec_list_iterator, it, values->subexpressions) { 776 if (k >= 16) { 777 ir_read_error(st, values, "expected at most 16 numbers"); 778 return NULL; 779 } 780 781 s_expression *expr = (s_expression*) it.get(); 782 783 if (base_type->base_type == GLSL_TYPE_FLOAT) { 784 s_number *value = SX_AS_NUMBER(expr); 785 if (value == NULL) { 786 ir_read_error(st, values, "expected numbers"); 787 return NULL; 788 } 789 data.f[k] = value->fvalue(); 790 } else { 791 s_int *value = SX_AS_INT(expr); 792 if (value == NULL) { 793 ir_read_error(st, values, "expected integers"); 794 return NULL; 795 } 796 797 switch (base_type->base_type) { 798 case GLSL_TYPE_UINT: { 799 data.u[k] = value->value(); 800 break; 801 } 802 case GLSL_TYPE_INT: { 803 data.i[k] = value->value(); 804 break; 805 } 806 case GLSL_TYPE_BOOL: { 807 data.b[k] = value->value(); 808 break; 809 } 810 default: 811 ir_read_error(st, values, "unsupported constant type"); 812 return NULL; 813 } 814 } 815 ++k; 816 } 817 818 return new(ctx) ir_constant(type, &data); 819} 820 821static ir_dereference * 822read_dereference(_mesa_glsl_parse_state *st, s_expression *expr) 823{ 824 s_symbol *s_var; 825 s_expression *s_subject; 826 s_expression *s_index; 827 s_symbol *s_field; 828 829 s_pattern var_pat[] = { "var_ref", s_var }; 830 s_pattern array_pat[] = { "array_ref", s_subject, s_index }; 831 s_pattern record_pat[] = { "record_ref", s_subject, s_field }; 832 833 if (MATCH(expr, var_pat)) { 834 ir_variable *var = st->symbols->get_variable(s_var->value()); 835 if (var == NULL) { 836 ir_read_error(st, expr, "undeclared variable: %s", s_var->value()); 837 return NULL; 838 } 839 return new(st) ir_dereference_variable(var); 840 } else if (MATCH(expr, array_pat)) { 841 ir_rvalue *subject = read_rvalue(st, s_subject); 842 if (subject == NULL) { 843 ir_read_error(st, NULL, "when reading the subject of an array_ref"); 844 return NULL; 845 } 846 847 ir_rvalue *idx = read_rvalue(st, s_index); 848 if (subject == NULL) { 849 ir_read_error(st, NULL, "when reading the index of an array_ref"); 850 return NULL; 851 } 852 return new(st) ir_dereference_array(subject, idx); 853 } else if (MATCH(expr, record_pat)) { 854 ir_rvalue *subject = read_rvalue(st, s_subject); 855 if (subject == NULL) { 856 ir_read_error(st, NULL, "when reading the subject of a record_ref"); 857 return NULL; 858 } 859 return new(st) ir_dereference_record(subject, s_field->value()); 860 } 861 return NULL; 862} 863 864static ir_texture * 865read_texture(_mesa_glsl_parse_state *st, s_expression *expr) 866{ 867 s_symbol *tag = NULL; 868 s_expression *s_sampler = NULL; 869 s_expression *s_coord = NULL; 870 s_list *s_offset = NULL; 871 s_expression *s_proj = NULL; 872 s_list *s_shadow = NULL; 873 s_expression *s_lod = NULL; 874 875 ir_texture_opcode op; 876 877 s_pattern tex_pattern[] = 878 { "tex", s_sampler, s_coord, s_offset, s_proj, s_shadow }; 879 s_pattern txf_pattern[] = 880 { "txf", s_sampler, s_coord, s_offset, s_lod }; 881 s_pattern other_pattern[] = 882 { tag, s_sampler, s_coord, s_offset, s_proj, s_shadow, s_lod }; 883 884 if (MATCH(expr, tex_pattern)) { 885 op = ir_tex; 886 } else if (MATCH(expr, txf_pattern)) { 887 op = ir_txf; 888 } else if (MATCH(expr, other_pattern)) { 889 op = ir_texture::get_opcode(tag->value()); 890 if (op == -1) 891 return NULL; 892 } 893 894 ir_texture *tex = new(st) ir_texture(op); 895 896 // Read sampler (must be a deref) 897 ir_dereference *sampler = read_dereference(st, s_sampler); 898 if (sampler == NULL) { 899 ir_read_error(st, NULL, "when reading sampler in (%s ...)", 900 tex->opcode_string()); 901 return NULL; 902 } 903 tex->set_sampler(sampler); 904 905 // Read coordinate (any rvalue) 906 tex->coordinate = read_rvalue(st, s_coord); 907 if (tex->coordinate == NULL) { 908 ir_read_error(st, NULL, "when reading coordinate in (%s ...)", 909 tex->opcode_string()); 910 return NULL; 911 } 912 913 // Read texel offset, i.e. (0 0 0) 914 s_int *offset_x; 915 s_int *offset_y; 916 s_int *offset_z; 917 s_pattern offset_pat[] = { offset_x, offset_y, offset_z }; 918 if (!MATCH(s_offset, offset_pat)) { 919 ir_read_error(st, s_offset, "expected (<int> <int> <int>)"); 920 return NULL; 921 } 922 tex->offsets[0] = offset_x->value(); 923 tex->offsets[1] = offset_y->value(); 924 tex->offsets[2] = offset_z->value(); 925 926 if (op != ir_txf) { 927 s_int *proj_as_int = SX_AS_INT(s_proj); 928 if (proj_as_int && proj_as_int->value() == 1) { 929 tex->projector = NULL; 930 } else { 931 tex->projector = read_rvalue(st, s_proj); 932 if (tex->projector == NULL) { 933 ir_read_error(st, NULL, "when reading projective divide in (%s ..)", 934 tex->opcode_string()); 935 return NULL; 936 } 937 } 938 939 if (s_shadow->subexpressions.is_empty()) { 940 tex->shadow_comparitor = NULL; 941 } else { 942 tex->shadow_comparitor = read_rvalue(st, s_shadow); 943 if (tex->shadow_comparitor == NULL) { 944 ir_read_error(st, NULL, "when reading shadow comparitor in (%s ..)", 945 tex->opcode_string()); 946 return NULL; 947 } 948 } 949 } 950 951 switch (op) { 952 case ir_txb: 953 tex->lod_info.bias = read_rvalue(st, s_lod); 954 if (tex->lod_info.bias == NULL) { 955 ir_read_error(st, NULL, "when reading LOD bias in (txb ...)"); 956 return NULL; 957 } 958 break; 959 case ir_txl: 960 case ir_txf: 961 tex->lod_info.lod = read_rvalue(st, s_lod); 962 if (tex->lod_info.lod == NULL) { 963 ir_read_error(st, NULL, "when reading LOD in (%s ...)", 964 tex->opcode_string()); 965 return NULL; 966 } 967 break; 968 case ir_txd: { 969 s_expression *s_dx, *s_dy; 970 s_pattern dxdy_pat[] = { s_dx, s_dy }; 971 if (!MATCH(s_lod, dxdy_pat)) { 972 ir_read_error(st, s_lod, "expected (dPdx dPdy) in (txd ...)"); 973 return NULL; 974 } 975 tex->lod_info.grad.dPdx = read_rvalue(st, s_dx); 976 if (tex->lod_info.grad.dPdx == NULL) { 977 ir_read_error(st, NULL, "when reading dPdx in (txd ...)"); 978 return NULL; 979 } 980 tex->lod_info.grad.dPdy = read_rvalue(st, s_dy); 981 if (tex->lod_info.grad.dPdy == NULL) { 982 ir_read_error(st, NULL, "when reading dPdy in (txd ...)"); 983 return NULL; 984 } 985 break; 986 } 987 default: 988 // tex doesn't have any extra parameters. 989 break; 990 }; 991 return tex; 992} 993