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 28 static void print_type(const glsl_type *t); 29 30 void 31 ir_instruction::print(void) const 32 { 33 ir_instruction *deconsted = const_cast<ir_instruction *>(this); 34 35 ir_print_visitor v; 36 deconsted->accept(&v); 37 } 38 39 void 40 _mesa_print_ir(exec_list *instructions, 41 struct _mesa_glsl_parse_state *state) 42 { 43 if (state) { 44 for (unsigned i = 0; i < state->num_user_structures; i++) { 45 const glsl_type *const s = state->user_structures[i]; 46 47 printf("(structure (%s) (%s@%p) (%u) (\n", 48 s->name, s->name, (void *) s, s->length); 49 50 for (unsigned j = 0; j < s->length; j++) { 51 printf("\t(("); 52 print_type(s->fields.structure[j].type); 53 printf(")(%s))\n", s->fields.structure[j].name); 54 } 55 56 printf(")\n"); 57 } 58 } 59 60 printf("(\n"); 61 foreach_iter(exec_list_iterator, iter, *instructions) { 62 ir_instruction *ir = (ir_instruction *)iter.get(); 63 ir->print(); 64 if (ir->ir_type != ir_type_function) 65 printf("\n"); 66 } 67 printf("\n)"); 68 } 69 70 71 void ir_print_visitor::indent(void) 72 { 73 for (int i = 0; i < indentation; i++) 74 printf(" "); 75 } 76 77 static void 78 print_type(const glsl_type *t) 79 { 80 if (t->base_type == GLSL_TYPE_ARRAY) { 81 printf("(array "); 82 print_type(t->fields.array); 83 printf(" %u)", t->length); 84 } else if ((t->base_type == GLSL_TYPE_STRUCT) 85 && (strncmp("gl_", t->name, 3) != 0)) { 86 printf("%s@%p", t->name, (void *) t); 87 } else { 88 printf("%s", t->name); 89 } 90 } 91 92 93 void ir_print_visitor::visit(ir_variable *ir) 94 { 95 printf("(declare "); 96 97 const char *const cent = (ir->centroid) ? "centroid " : ""; 98 const char *const inv = (ir->invariant) ? "invariant " : ""; 99 const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ", 100 "temporary " }; 101 const char *const interp[] = { "", "flat", "noperspective" }; 102 103 printf("(%s%s%s%s) ", 104 cent, inv, mode[ir->mode], interp[ir->interpolation]); 105 106 print_type(ir->type); 107 printf(" %s@%p)", ir->name, (void *) ir); 108 } 109 110 111 void ir_print_visitor::visit(ir_function_signature *ir) 112 { 113 printf("(signature "); 114 indentation++; 115 116 print_type(ir->return_type); 117 printf("\n"); 118 indent(); 119 120 printf("(parameters\n"); 121 indentation++; 122 123 foreach_iter(exec_list_iterator, iter, ir->parameters) { 124 ir_variable *const inst = (ir_variable *) iter.get(); 125 126 indent(); 127 inst->accept(this); 128 printf("\n"); 129 } 130 indentation--; 131 132 indent(); 133 printf(")\n"); 134 135 indent(); 136 137 printf("(\n"); 138 indentation++; 139 140 foreach_iter(exec_list_iterator, iter, ir->body) { 141 ir_instruction *const inst = (ir_instruction *) iter.get(); 142 143 indent(); 144 inst->accept(this); 145 printf("\n"); 146 } 147 indentation--; 148 indent(); 149 printf("))\n"); 150 indentation--; 151 } 152 153 154 void ir_print_visitor::visit(ir_function *ir) 155 { 156 printf("(function %s\n", ir->name); 157 indentation++; 158 foreach_iter(exec_list_iterator, iter, *ir) { 159 ir_function_signature *const sig = (ir_function_signature *) iter.get(); 160 indent(); 161 sig->accept(this); 162 printf("\n"); 163 } 164 indentation--; 165 indent(); 166 printf(")\n\n"); 167 } 168 169 170 void ir_print_visitor::visit(ir_expression *ir) 171 { 172 printf("(expression "); 173 174 print_type(ir->type); 175 176 printf(" %s ", ir->operator_string()); 177 178 for (unsigned i = 0; i < ir->get_num_operands(); i++) { 179 ir->operands[i]->accept(this); 180 } 181 182 printf(") "); 183 } 184 185 186 void ir_print_visitor::visit(ir_texture *ir) 187 { 188 printf("(%s ", ir->opcode_string()); 189 190 ir->sampler->accept(this); 191 printf(" "); 192 193 ir->coordinate->accept(this); 194 195 printf(" (%d %d %d) ", ir->offsets[0], ir->offsets[1], ir->offsets[2]); 196 197 if (ir->op != ir_txf) { 198 if (ir->projector) 199 ir->projector->accept(this); 200 else 201 printf("1"); 202 203 if (ir->shadow_comparitor) { 204 printf(" "); 205 ir->shadow_comparitor->accept(this); 206 } else { 207 printf(" ()"); 208 } 209 } 210 211 printf(" "); 212 switch (ir->op) 213 { 214 case ir_tex: 215 break; 216 case ir_txb: 217 ir->lod_info.bias->accept(this); 218 break; 219 case ir_txl: 220 case ir_txf: 221 ir->lod_info.lod->accept(this); 222 break; 223 case ir_txd: 224 printf("("); 225 ir->lod_info.grad.dPdx->accept(this); 226 printf(" "); 227 ir->lod_info.grad.dPdy->accept(this); 228 printf(")"); 229 break; 230 }; 231 printf(")"); 232 } 233 234 235 void ir_print_visitor::visit(ir_swizzle *ir) 236 { 237 const unsigned swiz[4] = { 238 ir->mask.x, 239 ir->mask.y, 240 ir->mask.z, 241 ir->mask.w, 242 }; 243 244 printf("(swiz "); 245 for (unsigned i = 0; i < ir->mask.num_components; i++) { 246 printf("%c", "xyzw"[swiz[i]]); 247 } 248 printf(" "); 249 ir->val->accept(this); 250 printf(")"); 251 } 252 253 254 void ir_print_visitor::visit(ir_dereference_variable *ir) 255 { 256 ir_variable *var = ir->variable_referenced(); 257 printf("(var_ref %s@%p) ", var->name, (void *) var); 258 } 259 260 261 void ir_print_visitor::visit(ir_dereference_array *ir) 262 { 263 printf("(array_ref "); 264 ir->array->accept(this); 265 ir->array_index->accept(this); 266 printf(") "); 267 } 268 269 270 void ir_print_visitor::visit(ir_dereference_record *ir) 271 { 272 printf("(record_ref "); 273 ir->record->accept(this); 274 printf(" %s) ", ir->field); 275 } 276 277 278 void ir_print_visitor::visit(ir_assignment *ir) 279 { 280 printf("(assign "); 281 282 if (ir->condition) 283 ir->condition->accept(this); 284 else 285 printf("(constant bool (1))"); 286 287 288 char mask[5]; 289 unsigned j = 0; 290 291 for (unsigned i = 0; i < 4; i++) { 292 if ((ir->write_mask & (1 << i)) != 0) { 293 mask[j] = "xyzw"[i]; 294 j++; 295 } 296 } 297 mask[j] = '\0'; 298 299 printf(" (%s) ", mask); 300 301 ir->lhs->accept(this); 302 303 printf(" "); 304 305 ir->rhs->accept(this); 306 printf(") "); 307 } 308 309 310 void ir_print_visitor::visit(ir_constant *ir) 311 { 312 const glsl_type *const base_type = ir->type->get_base_type(); 313 314 printf("(constant "); 315 print_type(ir->type); 316 printf(" ("); 317 318 if (ir->type->is_array()) { 319 for (unsigned i = 0; i < ir->type->length; i++) 320 ir->get_array_element(i)->accept(this); 321 } else if (ir->type->is_record()) { 322 ir_constant *value = (ir_constant *) ir->components.get_head(); 323 for (unsigned i = 0; i < ir->type->length; i++) { 324 printf("(%s ", ir->type->fields.structure->name); 325 value->accept(this); 326 printf(")"); 327 328 value = (ir_constant *) value->next; 329 } 330 } else { 331 for (unsigned i = 0; i < ir->type->components(); i++) { 332 if (i != 0) 333 printf(" "); 334 switch (base_type->base_type) { 335 case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break; 336 case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break; 337 case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break; 338 case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break; 339 default: assert(0); 340 } 341 } 342 } 343 printf(")) "); 344 } 345 346 347 void 348 ir_print_visitor::visit(ir_call *ir) 349 { 350 printf("(call %s (", ir->callee_name()); 351 foreach_iter(exec_list_iterator, iter, *ir) { 352 ir_instruction *const inst = (ir_instruction *) iter.get(); 353 354 inst->accept(this); 355 } 356 printf("))\n"); 357 } 358 359 360 void 361 ir_print_visitor::visit(ir_return *ir) 362 { 363 printf("(return"); 364 365 ir_rvalue *const value = ir->get_value(); 366 if (value) { 367 printf(" "); 368 value->accept(this); 369 } 370 371 printf(")"); 372 } 373 374 375 void 376 ir_print_visitor::visit(ir_discard *ir) 377 { 378 printf("(discard "); 379 380 if (ir->condition != NULL) { 381 printf(" "); 382 ir->condition->accept(this); 383 } 384 385 printf(")"); 386 } 387 388 389 void 390 ir_print_visitor::visit(ir_if *ir) 391 { 392 printf("(if "); 393 ir->condition->accept(this); 394 395 printf("(\n"); 396 indentation++; 397 398 foreach_iter(exec_list_iterator, iter, ir->then_instructions) { 399 ir_instruction *const inst = (ir_instruction *) iter.get(); 400 401 indent(); 402 inst->accept(this); 403 printf("\n"); 404 } 405 406 indentation--; 407 indent(); 408 printf(")\n"); 409 410 indent(); 411 if (!ir->else_instructions.is_empty()) { 412 printf("(\n"); 413 indentation++; 414 415 foreach_iter(exec_list_iterator, iter, ir->else_instructions) { 416 ir_instruction *const inst = (ir_instruction *) iter.get(); 417 418 indent(); 419 inst->accept(this); 420 printf("\n"); 421 } 422 indentation--; 423 indent(); 424 printf("))\n"); 425 } else { 426 printf("())\n"); 427 } 428 } 429 430 431 void 432 ir_print_visitor::visit(ir_loop *ir) 433 { 434 printf("(loop ("); 435 if (ir->counter != NULL) 436 ir->counter->accept(this); 437 printf(") ("); 438 if (ir->from != NULL) 439 ir->from->accept(this); 440 printf(") ("); 441 if (ir->to != NULL) 442 ir->to->accept(this); 443 printf(") ("); 444 if (ir->increment != NULL) 445 ir->increment->accept(this); 446 printf(") (\n"); 447 indentation++; 448 449 foreach_iter(exec_list_iterator, iter, ir->body_instructions) { 450 ir_instruction *const inst = (ir_instruction *) iter.get(); 451 452 indent(); 453 inst->accept(this); 454 printf("\n"); 455 } 456 indentation--; 457 indent(); 458 printf("))\n"); 459 } 460 461 462 void 463 ir_print_visitor::visit(ir_loop_jump *ir) 464 { 465 printf("%s", ir->is_break() ? "break" : "continue"); 466 } 467