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