ir_constant_expression.cpp revision 3fab376bef8c5f407d4011b89a17ea4fd414f213
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_floor: 224 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 225 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 226 data.f[c] = floorf(op[0]->value.f[c]); 227 } 228 break; 229 230 case ir_unop_fract: 231 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 232 switch (ir->type->base_type) { 233 case GLSL_TYPE_UINT: 234 data.u[c] = 0; 235 break; 236 case GLSL_TYPE_INT: 237 data.i[c] = 0; 238 break; 239 case GLSL_TYPE_FLOAT: 240 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]); 241 break; 242 default: 243 assert(0); 244 } 245 } 246 break; 247 248 case ir_unop_sin: 249 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 250 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 251 data.f[c] = sinf(op[0]->value.f[c]); 252 } 253 break; 254 255 case ir_unop_cos: 256 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 257 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 258 data.f[c] = cosf(op[0]->value.f[c]); 259 } 260 break; 261 262 case ir_unop_neg: 263 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 264 switch (ir->type->base_type) { 265 case GLSL_TYPE_UINT: 266 data.u[c] = -op[0]->value.u[c]; 267 break; 268 case GLSL_TYPE_INT: 269 data.i[c] = -op[0]->value.i[c]; 270 break; 271 case GLSL_TYPE_FLOAT: 272 data.f[c] = -op[0]->value.f[c]; 273 break; 274 default: 275 assert(0); 276 } 277 } 278 break; 279 280 case ir_unop_abs: 281 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 282 switch (ir->type->base_type) { 283 case GLSL_TYPE_UINT: 284 data.u[c] = op[0]->value.u[c]; 285 break; 286 case GLSL_TYPE_INT: 287 data.i[c] = op[0]->value.i[c]; 288 if (data.i[c] < 0) 289 data.i[c] = -data.i[c]; 290 break; 291 case GLSL_TYPE_FLOAT: 292 data.f[c] = fabs(op[0]->value.f[c]); 293 break; 294 default: 295 assert(0); 296 } 297 } 298 break; 299 300 case ir_unop_sign: 301 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 302 switch (ir->type->base_type) { 303 case GLSL_TYPE_UINT: 304 data.u[c] = op[0]->value.i[c] > 0; 305 break; 306 case GLSL_TYPE_INT: 307 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0); 308 break; 309 case GLSL_TYPE_FLOAT: 310 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0)); 311 break; 312 default: 313 assert(0); 314 } 315 } 316 break; 317 318 case ir_unop_rcp: 319 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 320 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 321 switch (ir->type->base_type) { 322 case GLSL_TYPE_UINT: 323 if (op[0]->value.u[c] != 0.0) 324 data.u[c] = 1 / op[0]->value.u[c]; 325 break; 326 case GLSL_TYPE_INT: 327 if (op[0]->value.i[c] != 0.0) 328 data.i[c] = 1 / op[0]->value.i[c]; 329 break; 330 case GLSL_TYPE_FLOAT: 331 if (op[0]->value.f[c] != 0.0) 332 data.f[c] = 1.0 / op[0]->value.f[c]; 333 break; 334 default: 335 assert(0); 336 } 337 } 338 break; 339 340 case ir_unop_rsq: 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] = 1.0 / sqrtf(op[0]->value.f[c]); 344 } 345 break; 346 347 case ir_unop_sqrt: 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] = sqrtf(op[0]->value.f[c]); 351 } 352 break; 353 354 case ir_unop_exp: 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] = expf(op[0]->value.f[c]); 358 } 359 break; 360 361 case ir_unop_exp2: 362 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 363 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 364 data.f[c] = exp2f(op[0]->value.f[c]); 365 } 366 break; 367 368 case ir_unop_log: 369 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 370 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 371 data.f[c] = logf(op[0]->value.f[c]); 372 } 373 break; 374 375 case ir_unop_log2: 376 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 377 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 378 data.f[c] = log2f(op[0]->value.f[c]); 379 } 380 break; 381 382 case ir_unop_dFdx: 383 case ir_unop_dFdy: 384 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 385 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 386 data.f[c] = 0.0; 387 } 388 break; 389 390 case ir_binop_dot: 391 assert(op[0]->type->is_vector() && op[1]->type->is_vector()); 392 data.f[0] = 0; 393 for (unsigned c = 0; c < op[0]->type->components(); c++) { 394 switch (ir->operands[0]->type->base_type) { 395 case GLSL_TYPE_UINT: 396 data.u[0] += op[0]->value.u[c] * op[1]->value.u[c]; 397 break; 398 case GLSL_TYPE_INT: 399 data.i[0] += op[0]->value.i[c] * op[1]->value.i[c]; 400 break; 401 case GLSL_TYPE_FLOAT: 402 data.f[0] += op[0]->value.f[c] * op[1]->value.f[c]; 403 break; 404 default: 405 assert(0); 406 } 407 } 408 409 break; 410 case ir_binop_add: 411 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 412 for (unsigned c = 0, c0 = 0, c1 = 0; 413 c < components; 414 c0 += c0_inc, c1 += c1_inc, c++) { 415 416 switch (ir->operands[0]->type->base_type) { 417 case GLSL_TYPE_UINT: 418 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1]; 419 break; 420 case GLSL_TYPE_INT: 421 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1]; 422 break; 423 case GLSL_TYPE_FLOAT: 424 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1]; 425 break; 426 default: 427 assert(0); 428 } 429 } 430 431 break; 432 case ir_binop_sub: 433 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 434 for (unsigned c = 0, c0 = 0, c1 = 0; 435 c < components; 436 c0 += c0_inc, c1 += c1_inc, c++) { 437 438 switch (ir->operands[0]->type->base_type) { 439 case GLSL_TYPE_UINT: 440 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1]; 441 break; 442 case GLSL_TYPE_INT: 443 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1]; 444 break; 445 case GLSL_TYPE_FLOAT: 446 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]; 447 break; 448 default: 449 assert(0); 450 } 451 } 452 453 break; 454 case ir_binop_mul: 455 /* Check for equal types, or unequal types involving scalars */ 456 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix()) 457 || op0_scalar || op1_scalar) { 458 for (unsigned c = 0, c0 = 0, c1 = 0; 459 c < components; 460 c0 += c0_inc, c1 += c1_inc, c++) { 461 462 switch (ir->operands[0]->type->base_type) { 463 case GLSL_TYPE_UINT: 464 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1]; 465 break; 466 case GLSL_TYPE_INT: 467 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1]; 468 break; 469 case GLSL_TYPE_FLOAT: 470 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1]; 471 break; 472 default: 473 assert(0); 474 } 475 } 476 } else { 477 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix()); 478 479 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either 480 * matrix can be a GLSL vector, either N or P can be 1. 481 * 482 * For vec*mat, the vector is treated as a row vector. This 483 * means the vector is a 1-row x M-column matrix. 484 * 485 * For mat*vec, the vector is treated as a column vector. Since 486 * matrix_columns is 1 for vectors, this just works. 487 */ 488 const unsigned n = op[0]->type->is_vector() 489 ? 1 : op[0]->type->vector_elements; 490 const unsigned m = op[1]->type->vector_elements; 491 const unsigned p = op[1]->type->matrix_columns; 492 for (unsigned j = 0; j < p; j++) { 493 for (unsigned i = 0; i < n; i++) { 494 for (unsigned k = 0; k < m; k++) { 495 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j]; 496 } 497 } 498 } 499 } 500 501 break; 502 case ir_binop_div: 503 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 504 for (unsigned c = 0, c0 = 0, c1 = 0; 505 c < components; 506 c0 += c0_inc, c1 += c1_inc, c++) { 507 508 switch (ir->operands[0]->type->base_type) { 509 case GLSL_TYPE_UINT: 510 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1]; 511 break; 512 case GLSL_TYPE_INT: 513 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1]; 514 break; 515 case GLSL_TYPE_FLOAT: 516 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1]; 517 break; 518 default: 519 assert(0); 520 } 521 } 522 523 break; 524 case ir_binop_logic_and: 525 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 526 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) 527 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c]; 528 break; 529 case ir_binop_logic_xor: 530 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 531 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) 532 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c]; 533 break; 534 case ir_binop_logic_or: 535 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 536 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) 537 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c]; 538 break; 539 540 case ir_binop_less: 541 switch (ir->operands[0]->type->base_type) { 542 case GLSL_TYPE_UINT: 543 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0]; 544 break; 545 case GLSL_TYPE_INT: 546 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0]; 547 break; 548 case GLSL_TYPE_FLOAT: 549 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0]; 550 break; 551 default: 552 assert(0); 553 } 554 break; 555 case ir_binop_greater: 556 switch (ir->operands[0]->type->base_type) { 557 case GLSL_TYPE_UINT: 558 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0]; 559 break; 560 case GLSL_TYPE_INT: 561 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0]; 562 break; 563 case GLSL_TYPE_FLOAT: 564 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0]; 565 break; 566 default: 567 assert(0); 568 } 569 break; 570 case ir_binop_lequal: 571 switch (ir->operands[0]->type->base_type) { 572 case GLSL_TYPE_UINT: 573 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0]; 574 break; 575 case GLSL_TYPE_INT: 576 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0]; 577 break; 578 case GLSL_TYPE_FLOAT: 579 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0]; 580 break; 581 default: 582 assert(0); 583 } 584 break; 585 case ir_binop_gequal: 586 switch (ir->operands[0]->type->base_type) { 587 case GLSL_TYPE_UINT: 588 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0]; 589 break; 590 case GLSL_TYPE_INT: 591 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0]; 592 break; 593 case GLSL_TYPE_FLOAT: 594 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0]; 595 break; 596 default: 597 assert(0); 598 } 599 break; 600 601 case ir_binop_equal: 602 data.b[0] = true; 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 case ir_binop_nequal: 623 data.b[0] = false; 624 for (unsigned c = 0; c < ir->operands[0]->type->components(); c++) { 625 switch (ir->operands[0]->type->base_type) { 626 case GLSL_TYPE_UINT: 627 data.b[0] = data.b[0] || op[0]->value.u[c] != op[1]->value.u[c]; 628 break; 629 case GLSL_TYPE_INT: 630 data.b[0] = data.b[0] || op[0]->value.i[c] != op[1]->value.i[c]; 631 break; 632 case GLSL_TYPE_FLOAT: 633 data.b[0] = data.b[0] || op[0]->value.f[c] != op[1]->value.f[c]; 634 break; 635 case GLSL_TYPE_BOOL: 636 data.b[0] = data.b[0] || op[0]->value.b[c] != op[1]->value.b[c]; 637 break; 638 default: 639 assert(0); 640 } 641 } 642 break; 643 644 default: 645 /* FINISHME: Should handle all expression types. */ 646 return; 647 } 648 649 void *ctx = talloc_parent(ir); 650 this->value = new(ctx) ir_constant(ir->type, &data); 651} 652 653 654void 655ir_constant_visitor::visit(ir_texture *ir) 656{ 657 // FINISHME: Do stuff with texture lookups 658 (void) ir; 659 value = NULL; 660} 661 662 663void 664ir_constant_visitor::visit(ir_swizzle *ir) 665{ 666 ir_constant *v = ir->val->constant_expression_value(); 667 668 this->value = NULL; 669 670 if (v != NULL) { 671 ir_constant_data data; 672 673 const unsigned swiz_idx[4] = { 674 ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w 675 }; 676 677 for (unsigned i = 0; i < ir->mask.num_components; i++) { 678 switch (v->type->base_type) { 679 case GLSL_TYPE_UINT: 680 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; 681 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; 682 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; 683 default: assert(!"Should not get here."); break; 684 } 685 } 686 687 void *ctx = talloc_parent(ir); 688 this->value = new(ctx) ir_constant(ir->type, &data); 689 } 690} 691 692 693void 694ir_constant_visitor::visit(ir_dereference_variable *ir) 695{ 696 value = NULL; 697 698 ir_variable *var = ir->variable_referenced(); 699 if (var && var->constant_value) 700 value = var->constant_value->clone(NULL); 701} 702 703 704void 705ir_constant_visitor::visit(ir_dereference_array *ir) 706{ 707 void *ctx = talloc_parent(ir); 708 ir_constant *array = ir->array->constant_expression_value(); 709 ir_constant *idx = ir->array_index->constant_expression_value(); 710 711 this->value = NULL; 712 713 if ((array != NULL) && (idx != NULL)) { 714 if (array->type->is_matrix()) { 715 /* Array access of a matrix results in a vector. 716 */ 717 const unsigned column = idx->value.u[0]; 718 719 const glsl_type *const column_type = array->type->column_type(); 720 721 /* Offset in the constant matrix to the first element of the column 722 * to be extracted. 723 */ 724 const unsigned mat_idx = column * column_type->vector_elements; 725 726 ir_constant_data data; 727 728 switch (column_type->base_type) { 729 case GLSL_TYPE_UINT: 730 case GLSL_TYPE_INT: 731 for (unsigned i = 0; i < column_type->vector_elements; i++) 732 data.u[i] = array->value.u[mat_idx + i]; 733 734 break; 735 736 case GLSL_TYPE_FLOAT: 737 for (unsigned i = 0; i < column_type->vector_elements; i++) 738 data.f[i] = array->value.f[mat_idx + i]; 739 740 break; 741 742 default: 743 assert(!"Should not get here."); 744 break; 745 } 746 747 this->value = new(ctx) ir_constant(column_type, &data); 748 } else if (array->type->is_vector()) { 749 const unsigned component = idx->value.u[0]; 750 751 this->value = new(ctx) ir_constant(array, component); 752 } else { 753 /* FINISHME: Handle access of constant arrays. */ 754 } 755 } 756} 757 758 759void 760ir_constant_visitor::visit(ir_dereference_record *ir) 761{ 762 ir_constant *v = ir->record->constant_expression_value(); 763 764 this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL; 765} 766 767 768void 769ir_constant_visitor::visit(ir_assignment *ir) 770{ 771 (void) ir; 772 value = NULL; 773} 774 775 776void 777ir_constant_visitor::visit(ir_constant *ir) 778{ 779 value = ir; 780} 781 782 783void 784ir_constant_visitor::visit(ir_call *ir) 785{ 786 (void) ir; 787 value = NULL; 788} 789 790 791void 792ir_constant_visitor::visit(ir_return *ir) 793{ 794 (void) ir; 795 value = NULL; 796} 797 798 799void 800ir_constant_visitor::visit(ir_discard *ir) 801{ 802 (void) ir; 803 value = NULL; 804} 805 806 807void 808ir_constant_visitor::visit(ir_if *ir) 809{ 810 (void) ir; 811 value = NULL; 812} 813 814 815void 816ir_constant_visitor::visit(ir_loop *ir) 817{ 818 (void) ir; 819 value = NULL; 820} 821 822 823void 824ir_constant_visitor::visit(ir_loop_jump *ir) 825{ 826 (void) ir; 827 value = NULL; 828} 829