ir_constant_expression.cpp revision c1ee30a14590d73217f7dbd35e6a1839435cc5b4
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/** 25 * \file ir_constant_expression.cpp 26 * Evaluate and process constant valued expressions 27 * 28 * In GLSL, constant valued expressions are used in several places. These 29 * must be processed and evaluated very early in the compilation process. 30 * 31 * * Sizes of arrays 32 * * Initializers for uniforms 33 * * Initializers for \c const variables 34 */ 35 36#include <math.h> 37#include "ir.h" 38#include "ir_visitor.h" 39#include "glsl_types.h" 40 41/** 42 * Visitor class for evaluating constant expressions 43 */ 44class ir_constant_visitor : public ir_visitor { 45public: 46 ir_constant_visitor() 47 : value(NULL) 48 { 49 /* empty */ 50 } 51 52 virtual ~ir_constant_visitor() 53 { 54 /* empty */ 55 } 56 57 /** 58 * \name Visit methods 59 * 60 * As typical for the visitor pattern, there must be one \c visit method for 61 * each concrete subclass of \c ir_instruction. Virtual base classes within 62 * the hierarchy should not have \c visit methods. 63 */ 64 /*@{*/ 65 virtual void visit(ir_variable *); 66 virtual void visit(ir_function_signature *); 67 virtual void visit(ir_function *); 68 virtual void visit(ir_expression *); 69 virtual void visit(ir_texture *); 70 virtual void visit(ir_swizzle *); 71 virtual void visit(ir_dereference_variable *); 72 virtual void visit(ir_dereference_array *); 73 virtual void visit(ir_dereference_record *); 74 virtual void visit(ir_assignment *); 75 virtual void visit(ir_constant *); 76 virtual void visit(ir_call *); 77 virtual void visit(ir_return *); 78 virtual void visit(ir_discard *); 79 virtual void visit(ir_if *); 80 virtual void visit(ir_loop *); 81 virtual void visit(ir_loop_jump *); 82 /*@}*/ 83 84 /** 85 * Value of the constant expression. 86 * 87 * \note 88 * This field will be \c NULL if the expression is not constant valued. 89 */ 90 /* FINIHSME: This cannot hold values for constant arrays or structures. */ 91 ir_constant *value; 92}; 93 94 95ir_constant * 96ir_instruction::constant_expression_value() 97{ 98 ir_constant_visitor visitor; 99 100 this->accept(& visitor); 101 return visitor.value; 102} 103 104 105void 106ir_constant_visitor::visit(ir_variable *ir) 107{ 108 (void) ir; 109 value = NULL; 110} 111 112 113void 114ir_constant_visitor::visit(ir_function_signature *ir) 115{ 116 (void) ir; 117 value = NULL; 118} 119 120 121void 122ir_constant_visitor::visit(ir_function *ir) 123{ 124 (void) ir; 125 value = NULL; 126} 127 128void 129ir_constant_visitor::visit(ir_expression *ir) 130{ 131 value = NULL; 132 ir_constant *op[2] = { NULL, NULL }; 133 ir_constant_data data; 134 135 memset(&data, 0, sizeof(data)); 136 137 for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) { 138 op[operand] = ir->operands[operand]->constant_expression_value(); 139 if (!op[operand]) 140 return; 141 } 142 143 if (op[1] != NULL) 144 assert(op[0]->type->base_type == op[1]->type->base_type); 145 146 bool op0_scalar = op[0]->type->is_scalar(); 147 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar(); 148 149 /* When iterating over a vector or matrix's components, we want to increase 150 * the loop counter. However, for scalars, we want to stay at 0. 151 */ 152 unsigned c0_inc = op0_scalar ? 0 : 1; 153 unsigned c1_inc = op1_scalar ? 0 : 1; 154 unsigned components; 155 if (op1_scalar || !op[1]) { 156 components = op[0]->type->components(); 157 } else { 158 components = op[1]->type->components(); 159 } 160 161 switch (ir->operation) { 162 case ir_unop_logic_not: 163 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 164 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) 165 data.b[c] = !op[0]->value.b[c]; 166 break; 167 168 case ir_unop_f2i: 169 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 170 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 171 data.i[c] = op[0]->value.f[c]; 172 } 173 break; 174 case ir_unop_i2f: 175 assert(op[0]->type->base_type == GLSL_TYPE_UINT || 176 op[0]->type->base_type == GLSL_TYPE_INT); 177 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 178 if (op[0]->type->base_type == GLSL_TYPE_INT) 179 data.f[c] = op[0]->value.i[c]; 180 else 181 data.f[c] = op[0]->value.u[c]; 182 } 183 break; 184 case ir_unop_b2f: 185 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 186 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 187 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0; 188 } 189 break; 190 case ir_unop_f2b: 191 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 192 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 193 data.b[c] = bool(op[0]->value.f[c]); 194 } 195 break; 196 case ir_unop_b2i: 197 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 198 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 199 data.u[c] = op[0]->value.b[c] ? 1 : 0; 200 } 201 break; 202 case ir_unop_i2b: 203 assert(op[0]->type->is_integer()); 204 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 205 data.b[c] = bool(op[0]->value.u[c]); 206 } 207 break; 208 209 case ir_unop_trunc: 210 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 211 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 212 data.f[c] = truncf(op[0]->value.f[c]); 213 } 214 break; 215 216 case ir_unop_ceil: 217 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 218 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 219 data.f[c] = ceilf(op[0]->value.f[c]); 220 } 221 break; 222 223 case ir_unop_fract: 224 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 225 switch (ir->type->base_type) { 226 case GLSL_TYPE_UINT: 227 data.u[c] = 0; 228 break; 229 case GLSL_TYPE_INT: 230 data.i[c] = 0; 231 break; 232 case GLSL_TYPE_FLOAT: 233 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]); 234 break; 235 default: 236 assert(0); 237 } 238 } 239 break; 240 241 case ir_unop_neg: 242 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 243 switch (ir->type->base_type) { 244 case GLSL_TYPE_UINT: 245 data.u[c] = -op[0]->value.u[c]; 246 break; 247 case GLSL_TYPE_INT: 248 data.i[c] = -op[0]->value.i[c]; 249 break; 250 case GLSL_TYPE_FLOAT: 251 data.f[c] = -op[0]->value.f[c]; 252 break; 253 default: 254 assert(0); 255 } 256 } 257 break; 258 259 case ir_unop_abs: 260 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 261 switch (ir->type->base_type) { 262 case GLSL_TYPE_UINT: 263 data.u[c] = op[0]->value.u[c]; 264 break; 265 case GLSL_TYPE_INT: 266 data.i[c] = op[0]->value.i[c]; 267 if (data.i[c] < 0) 268 data.i[c] = -data.i[c]; 269 break; 270 case GLSL_TYPE_FLOAT: 271 data.f[c] = fabs(op[0]->value.f[c]); 272 break; 273 default: 274 assert(0); 275 } 276 } 277 break; 278 279 case ir_unop_sign: 280 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 281 switch (ir->type->base_type) { 282 case GLSL_TYPE_UINT: 283 data.u[c] = op[0]->value.i[c] > 0; 284 break; 285 case GLSL_TYPE_INT: 286 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0); 287 break; 288 case GLSL_TYPE_FLOAT: 289 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0)); 290 break; 291 default: 292 assert(0); 293 } 294 } 295 break; 296 297 case ir_unop_rcp: 298 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 299 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 300 switch (ir->type->base_type) { 301 case GLSL_TYPE_UINT: 302 if (op[0]->value.u[c] != 0.0) 303 data.u[c] = 1 / op[0]->value.u[c]; 304 break; 305 case GLSL_TYPE_INT: 306 if (op[0]->value.i[c] != 0.0) 307 data.i[c] = 1 / op[0]->value.i[c]; 308 break; 309 case GLSL_TYPE_FLOAT: 310 if (op[0]->value.f[c] != 0.0) 311 data.f[c] = 1.0 / op[0]->value.f[c]; 312 break; 313 default: 314 assert(0); 315 } 316 } 317 break; 318 319 case ir_unop_rsq: 320 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 321 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 322 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]); 323 } 324 break; 325 326 case ir_unop_sqrt: 327 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 328 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 329 data.f[c] = sqrtf(op[0]->value.f[c]); 330 } 331 break; 332 333 case ir_unop_exp: 334 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 335 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 336 data.f[c] = expf(op[0]->value.f[c]); 337 } 338 break; 339 340 case ir_unop_exp2: 341 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 342 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 343 data.f[c] = exp2f(op[0]->value.f[c]); 344 } 345 break; 346 347 case ir_unop_log: 348 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 349 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 350 data.f[c] = logf(op[0]->value.f[c]); 351 } 352 break; 353 354 case ir_unop_log2: 355 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 356 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 357 data.f[c] = log2f(op[0]->value.f[c]); 358 } 359 break; 360 361 case ir_unop_dFdx: 362 case ir_unop_dFdy: 363 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 364 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 365 data.f[c] = 0.0; 366 } 367 break; 368 369 case ir_binop_dot: 370 assert(op[0]->type->is_vector() && op[1]->type->is_vector()); 371 data.f[0] = 0; 372 for (unsigned c = 0; c < op[0]->type->components(); c++) { 373 switch (ir->operands[0]->type->base_type) { 374 case GLSL_TYPE_UINT: 375 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c]; 376 break; 377 case GLSL_TYPE_INT: 378 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c]; 379 break; 380 case GLSL_TYPE_FLOAT: 381 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c]; 382 break; 383 default: 384 assert(0); 385 } 386 } 387 388 break; 389 case ir_binop_add: 390 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 391 for (unsigned c = 0, c0 = 0, c1 = 0; 392 c < components; 393 c0 += c0_inc, c1 += c1_inc, c++) { 394 395 switch (ir->operands[0]->type->base_type) { 396 case GLSL_TYPE_UINT: 397 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1]; 398 break; 399 case GLSL_TYPE_INT: 400 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1]; 401 break; 402 case GLSL_TYPE_FLOAT: 403 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1]; 404 break; 405 default: 406 assert(0); 407 } 408 } 409 410 break; 411 case ir_binop_sub: 412 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 413 for (unsigned c = 0, c0 = 0, c1 = 0; 414 c < components; 415 c0 += c0_inc, c1 += c1_inc, c++) { 416 417 switch (ir->operands[0]->type->base_type) { 418 case GLSL_TYPE_UINT: 419 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1]; 420 break; 421 case GLSL_TYPE_INT: 422 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1]; 423 break; 424 case GLSL_TYPE_FLOAT: 425 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]; 426 break; 427 default: 428 assert(0); 429 } 430 } 431 432 break; 433 case ir_binop_mul: 434 /* Check for equal types, or unequal types involving scalars */ 435 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix()) 436 || op0_scalar || op1_scalar) { 437 for (unsigned c = 0, c0 = 0, c1 = 0; 438 c < components; 439 c0 += c0_inc, c1 += c1_inc, c++) { 440 441 switch (ir->operands[0]->type->base_type) { 442 case GLSL_TYPE_UINT: 443 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1]; 444 break; 445 case GLSL_TYPE_INT: 446 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1]; 447 break; 448 case GLSL_TYPE_FLOAT: 449 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1]; 450 break; 451 default: 452 assert(0); 453 } 454 } 455 } else { 456 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix()); 457 458 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either 459 * matrix can be a GLSL vector, either N or P can be 1. 460 * 461 * For vec*mat, the vector is treated as a row vector. This 462 * means the vector is a 1-row x M-column matrix. 463 * 464 * For mat*vec, the vector is treated as a column vector. Since 465 * matrix_columns is 1 for vectors, this just works. 466 */ 467 const unsigned n = op[0]->type->is_vector() 468 ? 1 : op[0]->type->vector_elements; 469 const unsigned m = op[1]->type->vector_elements; 470 const unsigned p = op[1]->type->matrix_columns; 471 for (unsigned j = 0; j < p; j++) { 472 for (unsigned i = 0; i < n; i++) { 473 for (unsigned k = 0; k < m; k++) { 474 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j]; 475 } 476 } 477 } 478 } 479 480 break; 481 case ir_binop_div: 482 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 483 for (unsigned c = 0, c0 = 0, c1 = 0; 484 c < components; 485 c0 += c0_inc, c1 += c1_inc, c++) { 486 487 switch (ir->operands[0]->type->base_type) { 488 case GLSL_TYPE_UINT: 489 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1]; 490 break; 491 case GLSL_TYPE_INT: 492 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1]; 493 break; 494 case GLSL_TYPE_FLOAT: 495 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1]; 496 break; 497 default: 498 assert(0); 499 } 500 } 501 502 break; 503 case ir_binop_logic_and: 504 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 505 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) 506 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c]; 507 break; 508 case ir_binop_logic_xor: 509 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 510 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) 511 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c]; 512 break; 513 case ir_binop_logic_or: 514 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 515 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) 516 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c]; 517 break; 518 519 case ir_binop_less: 520 switch (ir->operands[0]->type->base_type) { 521 case GLSL_TYPE_UINT: 522 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0]; 523 break; 524 case GLSL_TYPE_INT: 525 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0]; 526 break; 527 case GLSL_TYPE_FLOAT: 528 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0]; 529 break; 530 default: 531 assert(0); 532 } 533 break; 534 case ir_binop_greater: 535 switch (ir->operands[0]->type->base_type) { 536 case GLSL_TYPE_UINT: 537 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0]; 538 break; 539 case GLSL_TYPE_INT: 540 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0]; 541 break; 542 case GLSL_TYPE_FLOAT: 543 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0]; 544 break; 545 default: 546 assert(0); 547 } 548 break; 549 case ir_binop_lequal: 550 switch (ir->operands[0]->type->base_type) { 551 case GLSL_TYPE_UINT: 552 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0]; 553 break; 554 case GLSL_TYPE_INT: 555 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0]; 556 break; 557 case GLSL_TYPE_FLOAT: 558 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0]; 559 break; 560 default: 561 assert(0); 562 } 563 break; 564 case ir_binop_gequal: 565 switch (ir->operands[0]->type->base_type) { 566 case GLSL_TYPE_UINT: 567 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0]; 568 break; 569 case GLSL_TYPE_INT: 570 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0]; 571 break; 572 case GLSL_TYPE_FLOAT: 573 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0]; 574 break; 575 default: 576 assert(0); 577 } 578 break; 579 580 case ir_binop_equal: 581 data.b[0] = true; 582 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 583 switch (ir->operands[0]->type->base_type) { 584 case GLSL_TYPE_UINT: 585 data.b[0] = data.b[0] && op[0]->value.u[c] == op[1]->value.u[c]; 586 break; 587 case GLSL_TYPE_INT: 588 data.b[0] = data.b[0] && op[0]->value.i[c] == op[1]->value.i[c]; 589 break; 590 case GLSL_TYPE_FLOAT: 591 data.b[0] = data.b[0] && op[0]->value.f[c] == op[1]->value.f[c]; 592 break; 593 case GLSL_TYPE_BOOL: 594 data.b[0] = data.b[0] && op[0]->value.b[c] == op[1]->value.b[c]; 595 break; 596 default: 597 assert(0); 598 } 599 } 600 break; 601 case ir_binop_nequal: 602 data.b[0] = false; 603 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 604 switch (ir->operands[0]->type->base_type) { 605 case GLSL_TYPE_UINT: 606 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c]; 607 break; 608 case GLSL_TYPE_INT: 609 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c]; 610 break; 611 case GLSL_TYPE_FLOAT: 612 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c]; 613 break; 614 case GLSL_TYPE_BOOL: 615 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c]; 616 break; 617 default: 618 assert(0); 619 } 620 } 621 break; 622 623 default: 624 /* FINISHME: Should handle all expression types. */ 625 return; 626 } 627 628 void *ctx = talloc_parent(ir); 629 this->value = new(ctx) ir_constant(ir->type, &data); 630} 631 632 633void 634ir_constant_visitor::visit(ir_texture *ir) 635{ 636 // FINISHME: Do stuff with texture lookups 637 (void) ir; 638 value = NULL; 639} 640 641 642void 643ir_constant_visitor::visit(ir_swizzle *ir) 644{ 645 ir_constant *v = ir->val->constant_expression_value(); 646 647 this->value = NULL; 648 649 if (v != NULL) { 650 ir_constant_data data; 651 652 const unsigned swiz_idx[4] = { 653 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w 654 }; 655 656 for (unsigned i = 0; i < ir->mask.num_components; i++) { 657 switch (v->type->base_type) { 658 case GLSL_TYPE_UINT: 659 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; 660 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; 661 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; 662 default: assert(!"Should not get here."); break; 663 } 664 } 665 666 void *ctx = talloc_parent(ir); 667 this->value = new(ctx) ir_constant(ir->type, &data); 668 } 669} 670 671 672void 673ir_constant_visitor::visit(ir_dereference_variable *ir) 674{ 675 value = NULL; 676 677 ir_variable *var = ir->variable_referenced(); 678 if (var && var->constant_value) 679 value = var->constant_value->clone(NULL); 680} 681 682 683void 684ir_constant_visitor::visit(ir_dereference_array *ir) 685{ 686 void *ctx = talloc_parent(ir); 687 ir_constant *array = ir->array->constant_expression_value(); 688 ir_constant *idx = ir->array_index->constant_expression_value(); 689 690 this->value = NULL; 691 692 if ((array != NULL) && (idx != NULL)) { 693 if (array->type->is_matrix()) { 694 /* Array access of a matrix results in a vector. 695 */ 696 const unsigned column = idx->value.u[0]; 697 698 const glsl_type *const column_type = array->type->column_type(); 699 700 /* Offset in the constant matrix to the first element of the column 701 * to be extracted. 702 */ 703 const unsigned mat_idx = column * column_type->vector_elements; 704 705 ir_constant_data data; 706 707 switch (column_type->base_type) { 708 case GLSL_TYPE_UINT: 709 case GLSL_TYPE_INT: 710 for (unsigned i = 0; i < column_type->vector_elements; i++) 711 data.u[i] = array->value.u[mat_idx + i]; 712 713 break; 714 715 case GLSL_TYPE_FLOAT: 716 for (unsigned i = 0; i < column_type->vector_elements; i++) 717 data.f[i] = array->value.f[mat_idx + i]; 718 719 break; 720 721 default: 722 assert(!"Should not get here."); 723 break; 724 } 725 726 this->value = new(ctx) ir_constant(column_type, &data); 727 } else if (array->type->is_vector()) { 728 const unsigned component = idx->value.u[0]; 729 730 this->value = new(ctx) ir_constant(array, component); 731 } else { 732 /* FINISHME: Handle access of constant arrays. */ 733 } 734 } 735} 736 737 738void 739ir_constant_visitor::visit(ir_dereference_record *ir) 740{ 741 ir_constant *v = ir->record->constant_expression_value(); 742 743 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL; 744} 745 746 747void 748ir_constant_visitor::visit(ir_assignment *ir) 749{ 750 (void) ir; 751 value = NULL; 752} 753 754 755void 756ir_constant_visitor::visit(ir_constant *ir) 757{ 758 value = ir; 759} 760 761 762void 763ir_constant_visitor::visit(ir_call *ir) 764{ 765 (void) ir; 766 value = NULL; 767} 768 769 770void 771ir_constant_visitor::visit(ir_return *ir) 772{ 773 (void) ir; 774 value = NULL; 775} 776 777 778void 779ir_constant_visitor::visit(ir_discard *ir) 780{ 781 (void) ir; 782 value = NULL; 783} 784 785 786void 787ir_constant_visitor::visit(ir_if *ir) 788{ 789 (void) ir; 790 value = NULL; 791} 792 793 794void 795ir_constant_visitor::visit(ir_loop *ir) 796{ 797 (void) ir; 798 value = NULL; 799} 800 801 802void 803ir_constant_visitor::visit(ir_loop_jump *ir) 804{ 805 (void) ir; 806 value = NULL; 807} 808