Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4358 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_print_visitor.h"
25
#include "glsl_types.h"
26
#include "glsl_parser_extras.h"
27
#include "main/macros.h"
28
#include "program/hash_table.h"
29
 
30
static void print_type(const glsl_type *t);
31
 
32
void
33
ir_instruction::print(void) const
34
{
35
   ir_instruction *deconsted = const_cast(this);
36
 
37
   ir_print_visitor v;
38
   deconsted->accept(&v);
39
}
40
 
41
extern "C" {
42
void
43
_mesa_print_ir(exec_list *instructions,
44
	       struct _mesa_glsl_parse_state *state)
45
{
46
   if (state) {
47
      for (unsigned i = 0; i < state->num_user_structures; i++) {
48
	 const glsl_type *const s = state->user_structures[i];
49
 
50
	 printf("(structure (%s) (%s@%p) (%u) (\n",
51
		s->name, s->name, (void *) s, s->length);
52
 
53
	 for (unsigned j = 0; j < s->length; j++) {
54
	    printf("\t((");
55
	    print_type(s->fields.structure[j].type);
56
	    printf(")(%s))\n", s->fields.structure[j].name);
57
	 }
58
 
59
	 printf(")\n");
60
      }
61
   }
62
 
63
   printf("(\n");
64
   foreach_iter(exec_list_iterator, iter, *instructions) {
65
      ir_instruction *ir = (ir_instruction *)iter.get();
66
      ir->print();
67
      if (ir->ir_type != ir_type_function)
68
	 printf("\n");
69
   }
70
   printf("\n)");
71
}
72
 
73
} /* extern "C" */
74
 
75
ir_print_visitor::ir_print_visitor()
76
{
77
   indentation = 0;
78
   printable_names =
79
      hash_table_ctor(32, hash_table_pointer_hash, hash_table_pointer_compare);
80
   symbols = _mesa_symbol_table_ctor();
81
   mem_ctx = ralloc_context(NULL);
82
}
83
 
84
ir_print_visitor::~ir_print_visitor()
85
{
86
   hash_table_dtor(printable_names);
87
   _mesa_symbol_table_dtor(symbols);
88
   ralloc_free(mem_ctx);
89
}
90
 
91
void ir_print_visitor::indent(void)
92
{
93
   for (int i = 0; i < indentation; i++)
94
      printf("  ");
95
}
96
 
97
const char *
98
ir_print_visitor::unique_name(ir_variable *var)
99
{
100
   /* var->name can be NULL in function prototypes when a type is given for a
101
    * parameter but no name is given.  In that case, just return an empty
102
    * string.  Don't worry about tracking the generated name in the printable
103
    * names hash because this is the only scope where it can ever appear.
104
    */
105
   if (var->name == NULL) {
106
      static unsigned arg = 1;
107
      return ralloc_asprintf(this->mem_ctx, "parameter@%u", arg++);
108
   }
109
 
110
   /* Do we already have a name for this variable? */
111
   const char *name = (const char *) hash_table_find(this->printable_names, var);
112
   if (name != NULL)
113
      return name;
114
 
115
   /* If there's no conflict, just use the original name */
116
   if (_mesa_symbol_table_find_symbol(this->symbols, -1, var->name) == NULL) {
117
      name = var->name;
118
   } else {
119
      static unsigned i = 1;
120
      name = ralloc_asprintf(this->mem_ctx, "%s@%u", var->name, ++i);
121
   }
122
   hash_table_insert(this->printable_names, (void *) name, var);
123
   _mesa_symbol_table_add_symbol(this->symbols, -1, name, var);
124
   return name;
125
}
126
 
127
static void
128
print_type(const glsl_type *t)
129
{
130
   if (t->base_type == GLSL_TYPE_ARRAY) {
131
      printf("(array ");
132
      print_type(t->fields.array);
133
      printf(" %u)", t->length);
134
   } else if ((t->base_type == GLSL_TYPE_STRUCT)
135
	      && (strncmp("gl_", t->name, 3) != 0)) {
136
      printf("%s@%p", t->name, (void *) t);
137
   } else {
138
      printf("%s", t->name);
139
   }
140
}
141
 
142
void ir_print_visitor::visit(ir_rvalue *ir)
143
{
144
   printf("error");
145
}
146
 
147
void ir_print_visitor::visit(ir_variable *ir)
148
{
149
   printf("(declare ");
150
 
151
   const char *const cent = (ir->centroid) ? "centroid " : "";
152
   const char *const inv = (ir->invariant) ? "invariant " : "";
153
   const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
154
                                "in ", "out ", "inout ",
155
			        "const_in ", "sys ", "temporary " };
156
   STATIC_ASSERT(ARRAY_SIZE(mode) == ir_var_mode_count);
157
   const char *const interp[] = { "", "smooth", "flat", "noperspective" };
158
   STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
159
 
160
   printf("(%s%s%s%s) ",
161
	  cent, inv, mode[ir->mode], interp[ir->interpolation]);
162
 
163
   print_type(ir->type);
164
   printf(" %s)", unique_name(ir));
165
}
166
 
167
 
168
void ir_print_visitor::visit(ir_function_signature *ir)
169
{
170
   _mesa_symbol_table_push_scope(symbols);
171
   printf("(signature ");
172
   indentation++;
173
 
174
   print_type(ir->return_type);
175
   printf("\n");
176
   indent();
177
 
178
   printf("(parameters\n");
179
   indentation++;
180
 
181
   foreach_iter(exec_list_iterator, iter, ir->parameters) {
182
      ir_variable *const inst = (ir_variable *) iter.get();
183
 
184
      indent();
185
      inst->accept(this);
186
      printf("\n");
187
   }
188
   indentation--;
189
 
190
   indent();
191
   printf(")\n");
192
 
193
   indent();
194
 
195
   printf("(\n");
196
   indentation++;
197
 
198
   foreach_iter(exec_list_iterator, iter, ir->body) {
199
      ir_instruction *const inst = (ir_instruction *) iter.get();
200
 
201
      indent();
202
      inst->accept(this);
203
      printf("\n");
204
   }
205
   indentation--;
206
   indent();
207
   printf("))\n");
208
   indentation--;
209
   _mesa_symbol_table_pop_scope(symbols);
210
}
211
 
212
 
213
void ir_print_visitor::visit(ir_function *ir)
214
{
215
   printf("(function %s\n", ir->name);
216
   indentation++;
217
   foreach_iter(exec_list_iterator, iter, *ir) {
218
      ir_function_signature *const sig = (ir_function_signature *) iter.get();
219
      indent();
220
      sig->accept(this);
221
      printf("\n");
222
   }
223
   indentation--;
224
   indent();
225
   printf(")\n\n");
226
}
227
 
228
 
229
void ir_print_visitor::visit(ir_expression *ir)
230
{
231
   printf("(expression ");
232
 
233
   print_type(ir->type);
234
 
235
   printf(" %s ", ir->operator_string());
236
 
237
   for (unsigned i = 0; i < ir->get_num_operands(); i++) {
238
      ir->operands[i]->accept(this);
239
   }
240
 
241
   printf(") ");
242
}
243
 
244
 
245
void ir_print_visitor::visit(ir_texture *ir)
246
{
247
   printf("(%s ", ir->opcode_string());
248
 
249
   print_type(ir->type);
250
   printf(" ");
251
 
252
   ir->sampler->accept(this);
253
   printf(" ");
254
 
255
   if (ir->op != ir_txs) {
256
      ir->coordinate->accept(this);
257
 
258
      printf(" ");
259
 
260
      if (ir->offset != NULL) {
261
	 ir->offset->accept(this);
262
      } else {
263
	 printf("0");
264
      }
265
 
266
      printf(" ");
267
   }
268
 
269
   if (ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_txs) {
270
      if (ir->projector)
271
	 ir->projector->accept(this);
272
      else
273
	 printf("1");
274
 
275
      if (ir->shadow_comparitor) {
276
	 printf(" ");
277
	 ir->shadow_comparitor->accept(this);
278
      } else {
279
	 printf(" ()");
280
      }
281
   }
282
 
283
   printf(" ");
284
   switch (ir->op)
285
   {
286
   case ir_tex:
287
   case ir_lod:
288
      break;
289
   case ir_txb:
290
      ir->lod_info.bias->accept(this);
291
      break;
292
   case ir_txl:
293
   case ir_txf:
294
   case ir_txs:
295
      ir->lod_info.lod->accept(this);
296
      break;
297
   case ir_txf_ms:
298
      ir->lod_info.sample_index->accept(this);
299
      break;
300
   case ir_txd:
301
      printf("(");
302
      ir->lod_info.grad.dPdx->accept(this);
303
      printf(" ");
304
      ir->lod_info.grad.dPdy->accept(this);
305
      printf(")");
306
      break;
307
   };
308
   printf(")");
309
}
310
 
311
 
312
void ir_print_visitor::visit(ir_swizzle *ir)
313
{
314
   const unsigned swiz[4] = {
315
      ir->mask.x,
316
      ir->mask.y,
317
      ir->mask.z,
318
      ir->mask.w,
319
   };
320
 
321
   printf("(swiz ");
322
   for (unsigned i = 0; i < ir->mask.num_components; i++) {
323
      printf("%c", "xyzw"[swiz[i]]);
324
   }
325
   printf(" ");
326
   ir->val->accept(this);
327
   printf(")");
328
}
329
 
330
 
331
void ir_print_visitor::visit(ir_dereference_variable *ir)
332
{
333
   ir_variable *var = ir->variable_referenced();
334
   printf("(var_ref %s) ", unique_name(var));
335
}
336
 
337
 
338
void ir_print_visitor::visit(ir_dereference_array *ir)
339
{
340
   printf("(array_ref ");
341
   ir->array->accept(this);
342
   ir->array_index->accept(this);
343
   printf(") ");
344
}
345
 
346
 
347
void ir_print_visitor::visit(ir_dereference_record *ir)
348
{
349
   printf("(record_ref ");
350
   ir->record->accept(this);
351
   printf(" %s) ", ir->field);
352
}
353
 
354
 
355
void ir_print_visitor::visit(ir_assignment *ir)
356
{
357
   printf("(assign ");
358
 
359
   if (ir->condition)
360
      ir->condition->accept(this);
361
 
362
   char mask[5];
363
   unsigned j = 0;
364
 
365
   for (unsigned i = 0; i < 4; i++) {
366
      if ((ir->write_mask & (1 << i)) != 0) {
367
	 mask[j] = "xyzw"[i];
368
	 j++;
369
      }
370
   }
371
   mask[j] = '\0';
372
 
373
   printf(" (%s) ", mask);
374
 
375
   ir->lhs->accept(this);
376
 
377
   printf(" ");
378
 
379
   ir->rhs->accept(this);
380
   printf(") ");
381
}
382
 
383
 
384
void ir_print_visitor::visit(ir_constant *ir)
385
{
386
   printf("(constant ");
387
   print_type(ir->type);
388
   printf(" (");
389
 
390
   if (ir->type->is_array()) {
391
      for (unsigned i = 0; i < ir->type->length; i++)
392
	 ir->get_array_element(i)->accept(this);
393
   } else if (ir->type->is_record()) {
394
      ir_constant *value = (ir_constant *) ir->components.get_head();
395
      for (unsigned i = 0; i < ir->type->length; i++) {
396
	 printf("(%s ", ir->type->fields.structure[i].name);
397
	 value->accept(this);
398
	 printf(")");
399
 
400
	 value = (ir_constant *) value->next;
401
      }
402
   } else {
403
      for (unsigned i = 0; i < ir->type->components(); i++) {
404
	 if (i != 0)
405
	    printf(" ");
406
	 switch (ir->type->base_type) {
407
	 case GLSL_TYPE_UINT:  printf("%u", ir->value.u[i]); break;
408
	 case GLSL_TYPE_INT:   printf("%d", ir->value.i[i]); break;
409
	 case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
410
	 case GLSL_TYPE_BOOL:  printf("%d", ir->value.b[i]); break;
411
	 default: assert(0);
412
	 }
413
      }
414
   }
415
   printf(")) ");
416
}
417
 
418
 
419
void
420
ir_print_visitor::visit(ir_call *ir)
421
{
422
   printf("(call %s ", ir->callee_name());
423
   if (ir->return_deref)
424
      ir->return_deref->accept(this);
425
   printf(" (");
426
   foreach_iter(exec_list_iterator, iter, *ir) {
427
      ir_instruction *const inst = (ir_instruction *) iter.get();
428
 
429
      inst->accept(this);
430
   }
431
   printf("))\n");
432
}
433
 
434
 
435
void
436
ir_print_visitor::visit(ir_return *ir)
437
{
438
   printf("(return");
439
 
440
   ir_rvalue *const value = ir->get_value();
441
   if (value) {
442
      printf(" ");
443
      value->accept(this);
444
   }
445
 
446
   printf(")");
447
}
448
 
449
 
450
void
451
ir_print_visitor::visit(ir_discard *ir)
452
{
453
   printf("(discard ");
454
 
455
   if (ir->condition != NULL) {
456
      printf(" ");
457
      ir->condition->accept(this);
458
   }
459
 
460
   printf(")");
461
}
462
 
463
 
464
void
465
ir_print_visitor::visit(ir_if *ir)
466
{
467
   printf("(if ");
468
   ir->condition->accept(this);
469
 
470
   printf("(\n");
471
   indentation++;
472
 
473
   foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
474
      ir_instruction *const inst = (ir_instruction *) iter.get();
475
 
476
      indent();
477
      inst->accept(this);
478
      printf("\n");
479
   }
480
 
481
   indentation--;
482
   indent();
483
   printf(")\n");
484
 
485
   indent();
486
   if (!ir->else_instructions.is_empty()) {
487
      printf("(\n");
488
      indentation++;
489
 
490
      foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
491
	 ir_instruction *const inst = (ir_instruction *) iter.get();
492
 
493
	 indent();
494
	 inst->accept(this);
495
	 printf("\n");
496
      }
497
      indentation--;
498
      indent();
499
      printf("))\n");
500
   } else {
501
      printf("())\n");
502
   }
503
}
504
 
505
 
506
void
507
ir_print_visitor::visit(ir_loop *ir)
508
{
509
   printf("(loop (");
510
   if (ir->counter != NULL)
511
      ir->counter->accept(this);
512
   printf(") (");
513
   if (ir->from != NULL)
514
      ir->from->accept(this);
515
   printf(") (");
516
   if (ir->to != NULL)
517
      ir->to->accept(this);
518
   printf(") (");
519
   if (ir->increment != NULL)
520
      ir->increment->accept(this);
521
   printf(") (\n");
522
   indentation++;
523
 
524
   foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
525
      ir_instruction *const inst = (ir_instruction *) iter.get();
526
 
527
      indent();
528
      inst->accept(this);
529
      printf("\n");
530
   }
531
   indentation--;
532
   indent();
533
   printf("))\n");
534
}
535
 
536
 
537
void
538
ir_print_visitor::visit(ir_loop_jump *ir)
539
{
540
   printf("%s", ir->is_break() ? "break" : "continue");
541
}