Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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