ir_constant_expression.cpp revision 2d0ef6bfee64b6889cbfb69762f167a6dfc20131
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 "main/core.h" /* for MAX2, MIN2, CLAMP */ 38#include "ir.h" 39#include "ir_visitor.h" 40#include "glsl_types.h" 41 42static float 43dot(ir_constant *op0, ir_constant *op1) 44{ 45 assert(op0->type->is_float() && op1->type->is_float()); 46 47 float result = 0; 48 for (unsigned c = 0; c < op0->type->components(); c++) 49 result += op0->value.f[c] * op1->value.f[c]; 50 51 return result; 52} 53 54ir_constant * 55ir_expression::constant_expression_value() 56{ 57 ir_constant *op[2] = { NULL, NULL }; 58 ir_constant_data data; 59 60 memset(&data, 0, sizeof(data)); 61 62 for (unsigned operand = 0; operand < this->get_num_operands(); operand++) { 63 op[operand] = this->operands[operand]->constant_expression_value(); 64 if (!op[operand]) 65 return NULL; 66 } 67 68 if (op[1] != NULL) 69 assert(op[0]->type->base_type == op[1]->type->base_type); 70 71 bool op0_scalar = op[0]->type->is_scalar(); 72 bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar(); 73 74 /* When iterating over a vector or matrix's components, we want to increase 75 * the loop counter. However, for scalars, we want to stay at 0. 76 */ 77 unsigned c0_inc = op0_scalar ? 0 : 1; 78 unsigned c1_inc = op1_scalar ? 0 : 1; 79 unsigned components; 80 if (op1_scalar || !op[1]) { 81 components = op[0]->type->components(); 82 } else { 83 components = op[1]->type->components(); 84 } 85 86 void *ctx = talloc_parent(this); 87 88 /* Handle array operations here, rather than below. */ 89 if (op[0]->type->is_array()) { 90 assert(op[1] != NULL && op[1]->type->is_array()); 91 switch (this->operation) { 92 case ir_binop_equal: 93 return new(ctx) ir_constant(op[0]->has_value(op[1])); 94 case ir_binop_nequal: 95 return new(ctx) ir_constant(!op[0]->has_value(op[1])); 96 default: 97 break; 98 } 99 return NULL; 100 } 101 102 switch (this->operation) { 103 case ir_unop_logic_not: 104 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 105 for (unsigned c = 0; c < op[0]->type->components(); c++) 106 data.b[c] = !op[0]->value.b[c]; 107 break; 108 109 case ir_unop_f2i: 110 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 111 for (unsigned c = 0; c < op[0]->type->components(); c++) { 112 data.i[c] = op[0]->value.f[c]; 113 } 114 break; 115 case ir_unop_i2f: 116 assert(op[0]->type->base_type == GLSL_TYPE_INT); 117 for (unsigned c = 0; c < op[0]->type->components(); c++) { 118 data.f[c] = op[0]->value.i[c]; 119 } 120 break; 121 case ir_unop_u2f: 122 assert(op[0]->type->base_type == GLSL_TYPE_UINT); 123 for (unsigned c = 0; c < op[0]->type->components(); c++) { 124 data.f[c] = op[0]->value.u[c]; 125 } 126 break; 127 case ir_unop_b2f: 128 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 129 for (unsigned c = 0; c < op[0]->type->components(); c++) { 130 data.f[c] = op[0]->value.b[c] ? 1.0 : 0.0; 131 } 132 break; 133 case ir_unop_f2b: 134 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 135 for (unsigned c = 0; c < op[0]->type->components(); c++) { 136 data.b[c] = bool(op[0]->value.f[c]); 137 } 138 break; 139 case ir_unop_b2i: 140 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 141 for (unsigned c = 0; c < op[0]->type->components(); c++) { 142 data.u[c] = op[0]->value.b[c] ? 1 : 0; 143 } 144 break; 145 case ir_unop_i2b: 146 assert(op[0]->type->is_integer()); 147 for (unsigned c = 0; c < op[0]->type->components(); c++) { 148 data.b[c] = bool(op[0]->value.u[c]); 149 } 150 break; 151 152 case ir_unop_any: 153 assert(op[0]->type->is_boolean()); 154 data.b[0] = false; 155 for (unsigned c = 0; c < op[0]->type->components(); c++) { 156 if (op[0]->value.b[c]) 157 data.b[0] = true; 158 } 159 break; 160 161 case ir_unop_trunc: 162 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 163 for (unsigned c = 0; c < op[0]->type->components(); c++) { 164 data.f[c] = truncf(op[0]->value.f[c]); 165 } 166 break; 167 168 case ir_unop_ceil: 169 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 170 for (unsigned c = 0; c < op[0]->type->components(); c++) { 171 data.f[c] = ceilf(op[0]->value.f[c]); 172 } 173 break; 174 175 case ir_unop_floor: 176 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 177 for (unsigned c = 0; c < op[0]->type->components(); c++) { 178 data.f[c] = floorf(op[0]->value.f[c]); 179 } 180 break; 181 182 case ir_unop_fract: 183 for (unsigned c = 0; c < op[0]->type->components(); c++) { 184 switch (this->type->base_type) { 185 case GLSL_TYPE_UINT: 186 data.u[c] = 0; 187 break; 188 case GLSL_TYPE_INT: 189 data.i[c] = 0; 190 break; 191 case GLSL_TYPE_FLOAT: 192 data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]); 193 break; 194 default: 195 assert(0); 196 } 197 } 198 break; 199 200 case ir_unop_sin: 201 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 202 for (unsigned c = 0; c < op[0]->type->components(); c++) { 203 data.f[c] = sinf(op[0]->value.f[c]); 204 } 205 break; 206 207 case ir_unop_cos: 208 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 209 for (unsigned c = 0; c < op[0]->type->components(); c++) { 210 data.f[c] = cosf(op[0]->value.f[c]); 211 } 212 break; 213 214 case ir_unop_neg: 215 for (unsigned c = 0; c < op[0]->type->components(); c++) { 216 switch (this->type->base_type) { 217 case GLSL_TYPE_UINT: 218 data.u[c] = -op[0]->value.u[c]; 219 break; 220 case GLSL_TYPE_INT: 221 data.i[c] = -op[0]->value.i[c]; 222 break; 223 case GLSL_TYPE_FLOAT: 224 data.f[c] = -op[0]->value.f[c]; 225 break; 226 default: 227 assert(0); 228 } 229 } 230 break; 231 232 case ir_unop_abs: 233 for (unsigned c = 0; c < op[0]->type->components(); c++) { 234 switch (this->type->base_type) { 235 case GLSL_TYPE_UINT: 236 data.u[c] = op[0]->value.u[c]; 237 break; 238 case GLSL_TYPE_INT: 239 data.i[c] = op[0]->value.i[c]; 240 if (data.i[c] < 0) 241 data.i[c] = -data.i[c]; 242 break; 243 case GLSL_TYPE_FLOAT: 244 data.f[c] = fabs(op[0]->value.f[c]); 245 break; 246 default: 247 assert(0); 248 } 249 } 250 break; 251 252 case ir_unop_sign: 253 for (unsigned c = 0; c < op[0]->type->components(); c++) { 254 switch (this->type->base_type) { 255 case GLSL_TYPE_UINT: 256 data.u[c] = op[0]->value.i[c] > 0; 257 break; 258 case GLSL_TYPE_INT: 259 data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0); 260 break; 261 case GLSL_TYPE_FLOAT: 262 data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0)); 263 break; 264 default: 265 assert(0); 266 } 267 } 268 break; 269 270 case ir_unop_rcp: 271 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 272 for (unsigned c = 0; c < op[0]->type->components(); c++) { 273 switch (this->type->base_type) { 274 case GLSL_TYPE_UINT: 275 if (op[0]->value.u[c] != 0.0) 276 data.u[c] = 1 / op[0]->value.u[c]; 277 break; 278 case GLSL_TYPE_INT: 279 if (op[0]->value.i[c] != 0.0) 280 data.i[c] = 1 / op[0]->value.i[c]; 281 break; 282 case GLSL_TYPE_FLOAT: 283 if (op[0]->value.f[c] != 0.0) 284 data.f[c] = 1.0 / op[0]->value.f[c]; 285 break; 286 default: 287 assert(0); 288 } 289 } 290 break; 291 292 case ir_unop_rsq: 293 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 294 for (unsigned c = 0; c < op[0]->type->components(); c++) { 295 data.f[c] = 1.0 / sqrtf(op[0]->value.f[c]); 296 } 297 break; 298 299 case ir_unop_sqrt: 300 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 301 for (unsigned c = 0; c < op[0]->type->components(); c++) { 302 data.f[c] = sqrtf(op[0]->value.f[c]); 303 } 304 break; 305 306 case ir_unop_exp: 307 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 308 for (unsigned c = 0; c < op[0]->type->components(); c++) { 309 data.f[c] = expf(op[0]->value.f[c]); 310 } 311 break; 312 313 case ir_unop_exp2: 314 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 315 for (unsigned c = 0; c < op[0]->type->components(); c++) { 316 data.f[c] = exp2f(op[0]->value.f[c]); 317 } 318 break; 319 320 case ir_unop_log: 321 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 322 for (unsigned c = 0; c < op[0]->type->components(); c++) { 323 data.f[c] = logf(op[0]->value.f[c]); 324 } 325 break; 326 327 case ir_unop_log2: 328 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 329 for (unsigned c = 0; c < op[0]->type->components(); c++) { 330 data.f[c] = log2f(op[0]->value.f[c]); 331 } 332 break; 333 334 case ir_unop_dFdx: 335 case ir_unop_dFdy: 336 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 337 for (unsigned c = 0; c < op[0]->type->components(); c++) { 338 data.f[c] = 0.0; 339 } 340 break; 341 342 case ir_binop_pow: 343 assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); 344 for (unsigned c = 0; c < op[0]->type->components(); c++) { 345 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]); 346 } 347 break; 348 349 case ir_binop_dot: 350 data.f[0] = dot(op[0], op[1]); 351 break; 352 353 case ir_binop_min: 354 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 355 for (unsigned c = 0, c0 = 0, c1 = 0; 356 c < components; 357 c0 += c0_inc, c1 += c1_inc, c++) { 358 359 switch (op[0]->type->base_type) { 360 case GLSL_TYPE_UINT: 361 data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]); 362 break; 363 case GLSL_TYPE_INT: 364 data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]); 365 break; 366 case GLSL_TYPE_FLOAT: 367 data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]); 368 break; 369 default: 370 assert(0); 371 } 372 } 373 374 break; 375 case ir_binop_max: 376 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 377 for (unsigned c = 0, c0 = 0, c1 = 0; 378 c < components; 379 c0 += c0_inc, c1 += c1_inc, c++) { 380 381 switch (op[0]->type->base_type) { 382 case GLSL_TYPE_UINT: 383 data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]); 384 break; 385 case GLSL_TYPE_INT: 386 data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]); 387 break; 388 case GLSL_TYPE_FLOAT: 389 data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]); 390 break; 391 default: 392 assert(0); 393 } 394 } 395 break; 396 397 case ir_binop_cross: 398 assert(op[0]->type == glsl_type::vec3_type); 399 assert(op[1]->type == glsl_type::vec3_type); 400 data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] - 401 op[1]->value.f[1] * op[0]->value.f[2]); 402 data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] - 403 op[1]->value.f[2] * op[0]->value.f[0]); 404 data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] - 405 op[1]->value.f[0] * op[0]->value.f[1]); 406 break; 407 408 case ir_binop_add: 409 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 410 for (unsigned c = 0, c0 = 0, c1 = 0; 411 c < components; 412 c0 += c0_inc, c1 += c1_inc, c++) { 413 414 switch (op[0]->type->base_type) { 415 case GLSL_TYPE_UINT: 416 data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1]; 417 break; 418 case GLSL_TYPE_INT: 419 data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1]; 420 break; 421 case GLSL_TYPE_FLOAT: 422 data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1]; 423 break; 424 default: 425 assert(0); 426 } 427 } 428 429 break; 430 case ir_binop_sub: 431 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 432 for (unsigned c = 0, c0 = 0, c1 = 0; 433 c < components; 434 c0 += c0_inc, c1 += c1_inc, c++) { 435 436 switch (op[0]->type->base_type) { 437 case GLSL_TYPE_UINT: 438 data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1]; 439 break; 440 case GLSL_TYPE_INT: 441 data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1]; 442 break; 443 case GLSL_TYPE_FLOAT: 444 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]; 445 break; 446 default: 447 assert(0); 448 } 449 } 450 451 break; 452 case ir_binop_mul: 453 /* Check for equal types, or unequal types involving scalars */ 454 if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix()) 455 || op0_scalar || op1_scalar) { 456 for (unsigned c = 0, c0 = 0, c1 = 0; 457 c < components; 458 c0 += c0_inc, c1 += c1_inc, c++) { 459 460 switch (op[0]->type->base_type) { 461 case GLSL_TYPE_UINT: 462 data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1]; 463 break; 464 case GLSL_TYPE_INT: 465 data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1]; 466 break; 467 case GLSL_TYPE_FLOAT: 468 data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1]; 469 break; 470 default: 471 assert(0); 472 } 473 } 474 } else { 475 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix()); 476 477 /* Multiply an N-by-M matrix with an M-by-P matrix. Since either 478 * matrix can be a GLSL vector, either N or P can be 1. 479 * 480 * For vec*mat, the vector is treated as a row vector. This 481 * means the vector is a 1-row x M-column matrix. 482 * 483 * For mat*vec, the vector is treated as a column vector. Since 484 * matrix_columns is 1 for vectors, this just works. 485 */ 486 const unsigned n = op[0]->type->is_vector() 487 ? 1 : op[0]->type->vector_elements; 488 const unsigned m = op[1]->type->vector_elements; 489 const unsigned p = op[1]->type->matrix_columns; 490 for (unsigned j = 0; j < p; j++) { 491 for (unsigned i = 0; i < n; i++) { 492 for (unsigned k = 0; k < m; k++) { 493 data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j]; 494 } 495 } 496 } 497 } 498 499 break; 500 case ir_binop_div: 501 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 502 for (unsigned c = 0, c0 = 0, c1 = 0; 503 c < components; 504 c0 += c0_inc, c1 += c1_inc, c++) { 505 506 switch (op[0]->type->base_type) { 507 case GLSL_TYPE_UINT: 508 data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1]; 509 break; 510 case GLSL_TYPE_INT: 511 data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1]; 512 break; 513 case GLSL_TYPE_FLOAT: 514 data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1]; 515 break; 516 default: 517 assert(0); 518 } 519 } 520 521 break; 522 case ir_binop_mod: 523 assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar); 524 for (unsigned c = 0, c0 = 0, c1 = 0; 525 c < components; 526 c0 += c0_inc, c1 += c1_inc, c++) { 527 528 switch (op[0]->type->base_type) { 529 case GLSL_TYPE_UINT: 530 data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1]; 531 break; 532 case GLSL_TYPE_INT: 533 data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1]; 534 break; 535 case GLSL_TYPE_FLOAT: 536 /* We don't use fmod because it rounds toward zero; GLSL specifies 537 * the use of floor. 538 */ 539 data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1] 540 * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]); 541 break; 542 default: 543 assert(0); 544 } 545 } 546 547 break; 548 549 case ir_binop_logic_and: 550 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 551 for (unsigned c = 0; c < op[0]->type->components(); c++) 552 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c]; 553 break; 554 case ir_binop_logic_xor: 555 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 556 for (unsigned c = 0; c < op[0]->type->components(); c++) 557 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c]; 558 break; 559 case ir_binop_logic_or: 560 assert(op[0]->type->base_type == GLSL_TYPE_BOOL); 561 for (unsigned c = 0; c < op[0]->type->components(); c++) 562 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c]; 563 break; 564 565 case ir_binop_less: 566 switch (op[0]->type->base_type) { 567 case GLSL_TYPE_UINT: 568 data.b[0] = op[0]->value.u[0] < op[1]->value.u[0]; 569 break; 570 case GLSL_TYPE_INT: 571 data.b[0] = op[0]->value.i[0] < op[1]->value.i[0]; 572 break; 573 case GLSL_TYPE_FLOAT: 574 data.b[0] = op[0]->value.f[0] < op[1]->value.f[0]; 575 break; 576 default: 577 assert(0); 578 } 579 break; 580 case ir_binop_greater: 581 switch (op[0]->type->base_type) { 582 case GLSL_TYPE_UINT: 583 data.b[0] = op[0]->value.u[0] > op[1]->value.u[0]; 584 break; 585 case GLSL_TYPE_INT: 586 data.b[0] = op[0]->value.i[0] > op[1]->value.i[0]; 587 break; 588 case GLSL_TYPE_FLOAT: 589 data.b[0] = op[0]->value.f[0] > op[1]->value.f[0]; 590 break; 591 default: 592 assert(0); 593 } 594 break; 595 case ir_binop_lequal: 596 switch (op[0]->type->base_type) { 597 case GLSL_TYPE_UINT: 598 data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0]; 599 break; 600 case GLSL_TYPE_INT: 601 data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0]; 602 break; 603 case GLSL_TYPE_FLOAT: 604 data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0]; 605 break; 606 default: 607 assert(0); 608 } 609 break; 610 case ir_binop_gequal: 611 switch (op[0]->type->base_type) { 612 case GLSL_TYPE_UINT: 613 data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0]; 614 break; 615 case GLSL_TYPE_INT: 616 data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0]; 617 break; 618 case GLSL_TYPE_FLOAT: 619 data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0]; 620 break; 621 default: 622 assert(0); 623 } 624 break; 625 626 case ir_binop_equal: 627 data.b[0] = op[0]->has_value(op[1]); 628 break; 629 case ir_binop_nequal: 630 data.b[0] = !op[0]->has_value(op[1]); 631 break; 632 633 default: 634 /* FINISHME: Should handle all expression types. */ 635 return NULL; 636 } 637 638 return new(ctx) ir_constant(this->type, &data); 639} 640 641 642ir_constant * 643ir_texture::constant_expression_value() 644{ 645 /* texture lookups aren't constant expressions */ 646 return NULL; 647} 648 649 650ir_constant * 651ir_swizzle::constant_expression_value() 652{ 653 ir_constant *v = this->val->constant_expression_value(); 654 655 if (v != NULL) { 656 ir_constant_data data = { { 0 } }; 657 658 const unsigned swiz_idx[4] = { 659 this->mask.x, this->mask.y, this->mask.z, this->mask.w 660 }; 661 662 for (unsigned i = 0; i < this->mask.num_components; i++) { 663 switch (v->type->base_type) { 664 case GLSL_TYPE_UINT: 665 case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; 666 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; 667 case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; 668 default: assert(!"Should not get here."); break; 669 } 670 } 671 672 void *ctx = talloc_parent(this); 673 return new(ctx) ir_constant(this->type, &data); 674 } 675 return NULL; 676} 677 678 679ir_constant * 680ir_dereference_variable::constant_expression_value() 681{ 682 /* This may occur during compile and var->type is glsl_type::error_type */ 683 if (!var) 684 return NULL; 685 686 /* The constant_value of a uniform variable is its initializer, 687 * not the lifetime constant value of the uniform. 688 */ 689 if (var->mode == ir_var_uniform) 690 return NULL; 691 692 if (!var->constant_value) 693 return NULL; 694 695 return var->constant_value->clone(talloc_parent(var), NULL); 696} 697 698 699ir_constant * 700ir_dereference_array::constant_expression_value() 701{ 702 ir_constant *array = this->array->constant_expression_value(); 703 ir_constant *idx = this->array_index->constant_expression_value(); 704 705 if ((array != NULL) && (idx != NULL)) { 706 void *ctx = talloc_parent(this); 707 if (array->type->is_matrix()) { 708 /* Array access of a matrix results in a vector. 709 */ 710 const unsigned column = idx->value.u[0]; 711 712 const glsl_type *const column_type = array->type->column_type(); 713 714 /* Offset in the constant matrix to the first element of the column 715 * to be extracted. 716 */ 717 const unsigned mat_idx = column * column_type->vector_elements; 718 719 ir_constant_data data; 720 721 switch (column_type->base_type) { 722 case GLSL_TYPE_UINT: 723 case GLSL_TYPE_INT: 724 for (unsigned i = 0; i < column_type->vector_elements; i++) 725 data.u[i] = array->value.u[mat_idx + i]; 726 727 break; 728 729 case GLSL_TYPE_FLOAT: 730 for (unsigned i = 0; i < column_type->vector_elements; i++) 731 data.f[i] = array->value.f[mat_idx + i]; 732 733 break; 734 735 default: 736 assert(!"Should not get here."); 737 break; 738 } 739 740 return new(ctx) ir_constant(column_type, &data); 741 } else if (array->type->is_vector()) { 742 const unsigned component = idx->value.u[0]; 743 744 return new(ctx) ir_constant(array, component); 745 } else { 746 const unsigned index = idx->value.u[0]; 747 return array->get_array_element(index)->clone(ctx, NULL); 748 } 749 } 750 return NULL; 751} 752 753 754ir_constant * 755ir_dereference_record::constant_expression_value() 756{ 757 ir_constant *v = this->record->constant_expression_value(); 758 759 return (v != NULL) ? v->get_record_field(this->field) : NULL; 760} 761 762 763ir_constant * 764ir_assignment::constant_expression_value() 765{ 766 /* FINISHME: Handle CEs involving assignment (return RHS) */ 767 return NULL; 768} 769 770 771ir_constant * 772ir_constant::constant_expression_value() 773{ 774 return this; 775} 776 777 778ir_constant * 779ir_call::constant_expression_value() 780{ 781 if (this->type == glsl_type::error_type) 782 return NULL; 783 784 /* From the GLSL 1.20 spec, page 23: 785 * "Function calls to user-defined functions (non-built-in functions) 786 * cannot be used to form constant expressions." 787 */ 788 if (!this->callee->function()->is_builtin) 789 return NULL; 790 791 unsigned num_parameters = 0; 792 793 /* Check if all parameters are constant */ 794 ir_constant *op[3]; 795 foreach_list(n, &this->actual_parameters) { 796 ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(); 797 if (constant == NULL) 798 return NULL; 799 800 op[num_parameters] = constant; 801 802 assert(num_parameters < 3); 803 num_parameters++; 804 } 805 806 /* Individual cases below can either: 807 * - Assign "expr" a new ir_expression to evaluate (for basic opcodes) 808 * - Fill "data" with appopriate constant data 809 * - Return an ir_constant directly. 810 */ 811 void *mem_ctx = talloc_parent(this); 812 ir_expression *expr = NULL; 813 814 ir_constant_data data; 815 memset(&data, 0, sizeof(data)); 816 817 const char *callee = this->callee_name(); 818 if (strcmp(callee, "abs") == 0) { 819 expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL); 820 } else if (strcmp(callee, "all") == 0) { 821 assert(op[0]->type->is_boolean()); 822 for (unsigned c = 0; c < op[0]->type->components(); c++) { 823 if (!op[0]->value.b[c]) 824 return new(mem_ctx) ir_constant(false); 825 } 826 return new(mem_ctx) ir_constant(true); 827 } else if (strcmp(callee, "any") == 0) { 828 assert(op[0]->type->is_boolean()); 829 for (unsigned c = 0; c < op[0]->type->components(); c++) { 830 if (op[0]->value.b[c]) 831 return new(mem_ctx) ir_constant(true); 832 } 833 return new(mem_ctx) ir_constant(false); 834 } else if (strcmp(callee, "acos") == 0) { 835 assert(op[0]->type->is_float()); 836 for (unsigned c = 0; c < op[0]->type->components(); c++) 837 data.f[c] = acosf(op[0]->value.f[c]); 838 } else if (strcmp(callee, "asin") == 0) { 839 assert(op[0]->type->is_float()); 840 for (unsigned c = 0; c < op[0]->type->components(); c++) 841 data.f[c] = asinf(op[0]->value.f[c]); 842 } else if (strcmp(callee, "atan") == 0) { 843 assert(op[0]->type->is_float()); 844 if (num_parameters == 2) { 845 assert(op[1]->type->is_float()); 846 for (unsigned c = 0; c < op[0]->type->components(); c++) 847 data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]); 848 } else { 849 for (unsigned c = 0; c < op[0]->type->components(); c++) 850 data.f[c] = atanf(op[0]->value.f[c]); 851 } 852 } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) { 853 return ir_constant::zero(mem_ctx, this->type); 854 } else if (strcmp(callee, "ceil") == 0) { 855 expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL); 856 } else if (strcmp(callee, "clamp") == 0) { 857 assert(num_parameters == 3); 858 unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1; 859 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; 860 for (unsigned c = 0, c1 = 0, c2 = 0; 861 c < op[0]->type->components(); 862 c1 += c1_inc, c2 += c2_inc, c++) { 863 864 switch (op[0]->type->base_type) { 865 case GLSL_TYPE_UINT: 866 data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1], 867 op[2]->value.u[c2]); 868 break; 869 case GLSL_TYPE_INT: 870 data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1], 871 op[2]->value.i[c2]); 872 break; 873 case GLSL_TYPE_FLOAT: 874 data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1], 875 op[2]->value.f[c2]); 876 break; 877 default: 878 assert(!"Should not get here."); 879 } 880 } 881 } else if (strcmp(callee, "cos") == 0) { 882 expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL); 883 } else if (strcmp(callee, "cosh") == 0) { 884 assert(op[0]->type->is_float()); 885 for (unsigned c = 0; c < op[0]->type->components(); c++) 886 data.f[c] = coshf(op[0]->value.f[c]); 887 } else if (strcmp(callee, "cross") == 0) { 888 expr = new(mem_ctx) ir_expression(ir_binop_cross, type, op[0], op[1]); 889 } else if (strcmp(callee, "degrees") == 0) { 890 assert(op[0]->type->is_float()); 891 for (unsigned c = 0; c < op[0]->type->components(); c++) 892 data.f[c] = 180.0/M_PI * op[0]->value.f[c]; 893 } else if (strcmp(callee, "distance") == 0) { 894 assert(op[0]->type->is_float() && op[1]->type->is_float()); 895 float length_squared = 0.0; 896 for (unsigned c = 0; c < op[0]->type->components(); c++) { 897 float t = op[0]->value.f[c] - op[1]->value.f[c]; 898 length_squared += t * t; 899 } 900 return new(mem_ctx) ir_constant(sqrtf(length_squared)); 901 } else if (strcmp(callee, "dot") == 0) { 902 return new(mem_ctx) ir_constant(dot(op[0], op[1])); 903 } else if (strcmp(callee, "equal") == 0) { 904 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 905 for (unsigned c = 0; c < op[0]->type->components(); c++) { 906 switch (op[0]->type->base_type) { 907 case GLSL_TYPE_UINT: 908 data.b[c] = op[0]->value.u[c] == op[1]->value.u[c]; 909 break; 910 case GLSL_TYPE_INT: 911 data.b[c] = op[0]->value.i[c] == op[1]->value.i[c]; 912 break; 913 case GLSL_TYPE_FLOAT: 914 data.b[c] = op[0]->value.f[c] == op[1]->value.f[c]; 915 break; 916 case GLSL_TYPE_BOOL: 917 data.b[c] = op[0]->value.b[c] == op[1]->value.b[c]; 918 break; 919 default: 920 assert(!"Should not get here."); 921 } 922 } 923 } else if (strcmp(callee, "exp") == 0) { 924 expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL); 925 } else if (strcmp(callee, "exp2") == 0) { 926 expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL); 927 } else if (strcmp(callee, "faceforward") == 0) { 928 if (dot(op[2], op[1]) < 0) 929 return op[0]; 930 for (unsigned c = 0; c < op[0]->type->components(); c++) 931 data.f[c] = -op[0]->value.f[c]; 932 } else if (strcmp(callee, "floor") == 0) { 933 expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL); 934 } else if (strcmp(callee, "fract") == 0) { 935 expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL); 936 } else if (strcmp(callee, "fwidth") == 0) { 937 return ir_constant::zero(mem_ctx, this->type); 938 } else if (strcmp(callee, "greaterThan") == 0) { 939 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 940 for (unsigned c = 0; c < op[0]->type->components(); c++) { 941 switch (op[0]->type->base_type) { 942 case GLSL_TYPE_UINT: 943 data.b[c] = op[0]->value.u[c] > op[1]->value.u[c]; 944 break; 945 case GLSL_TYPE_INT: 946 data.b[c] = op[0]->value.i[c] > op[1]->value.i[c]; 947 break; 948 case GLSL_TYPE_FLOAT: 949 data.b[c] = op[0]->value.f[c] > op[1]->value.f[c]; 950 break; 951 default: 952 assert(!"Should not get here."); 953 } 954 } 955 } else if (strcmp(callee, "greaterThanEqual") == 0) { 956 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 957 for (unsigned c = 0; c < op[0]->type->components(); c++) { 958 switch (op[0]->type->base_type) { 959 case GLSL_TYPE_UINT: 960 data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c]; 961 break; 962 case GLSL_TYPE_INT: 963 data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c]; 964 break; 965 case GLSL_TYPE_FLOAT: 966 data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c]; 967 break; 968 default: 969 assert(!"Should not get here."); 970 } 971 } 972 } else if (strcmp(callee, "inversesqrt") == 0) { 973 expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL); 974 } else if (strcmp(callee, "length") == 0) { 975 return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0]))); 976 } else if (strcmp(callee, "lessThan") == 0) { 977 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 978 for (unsigned c = 0; c < op[0]->type->components(); c++) { 979 switch (op[0]->type->base_type) { 980 case GLSL_TYPE_UINT: 981 data.b[c] = op[0]->value.u[c] < op[1]->value.u[c]; 982 break; 983 case GLSL_TYPE_INT: 984 data.b[c] = op[0]->value.i[c] < op[1]->value.i[c]; 985 break; 986 case GLSL_TYPE_FLOAT: 987 data.b[c] = op[0]->value.f[c] < op[1]->value.f[c]; 988 break; 989 default: 990 assert(!"Should not get here."); 991 } 992 } 993 } else if (strcmp(callee, "lessThanEqual") == 0) { 994 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 995 for (unsigned c = 0; c < op[0]->type->components(); c++) { 996 switch (op[0]->type->base_type) { 997 case GLSL_TYPE_UINT: 998 data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c]; 999 break; 1000 case GLSL_TYPE_INT: 1001 data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c]; 1002 break; 1003 case GLSL_TYPE_FLOAT: 1004 data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c]; 1005 break; 1006 default: 1007 assert(!"Should not get here."); 1008 } 1009 } 1010 } else if (strcmp(callee, "log") == 0) { 1011 expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL); 1012 } else if (strcmp(callee, "log2") == 0) { 1013 expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL); 1014 } else if (strcmp(callee, "matrixCompMult") == 0) { 1015 assert(op[0]->type->is_float() && op[1]->type->is_float()); 1016 for (unsigned c = 0; c < op[0]->type->components(); c++) 1017 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c]; 1018 } else if (strcmp(callee, "max") == 0) { 1019 expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]); 1020 } else if (strcmp(callee, "min") == 0) { 1021 expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]); 1022 } else if (strcmp(callee, "mix") == 0) { 1023 assert(op[0]->type->is_float() && op[1]->type->is_float()); 1024 if (op[2]->type->is_float()) { 1025 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1; 1026 unsigned components = op[0]->type->components(); 1027 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) { 1028 data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) + 1029 op[1]->value.f[c] * op[2]->value.f[c2]; 1030 } 1031 } else { 1032 assert(op[2]->type->is_boolean()); 1033 for (unsigned c = 0; c < op[0]->type->components(); c++) 1034 data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c]; 1035 } 1036 } else if (strcmp(callee, "mod") == 0) { 1037 expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]); 1038 } else if (strcmp(callee, "normalize") == 0) { 1039 assert(op[0]->type->is_float()); 1040 float length = sqrtf(dot(op[0], op[0])); 1041 1042 if (length == 0) 1043 return ir_constant::zero(mem_ctx, this->type); 1044 1045 for (unsigned c = 0; c < op[0]->type->components(); c++) 1046 data.f[c] = op[0]->value.f[c] / length; 1047 } else if (strcmp(callee, "not") == 0) { 1048 expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL); 1049 } else if (strcmp(callee, "notEqual") == 0) { 1050 assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector()); 1051 for (unsigned c = 0; c < op[0]->type->components(); c++) { 1052 switch (op[0]->type->base_type) { 1053 case GLSL_TYPE_UINT: 1054 data.b[c] = op[0]->value.u[c] != op[1]->value.u[c]; 1055 break; 1056 case GLSL_TYPE_INT: 1057 data.b[c] = op[0]->value.i[c] != op[1]->value.i[c]; 1058 break; 1059 case GLSL_TYPE_FLOAT: 1060 data.b[c] = op[0]->value.f[c] != op[1]->value.f[c]; 1061 break; 1062 case GLSL_TYPE_BOOL: 1063 data.b[c] = op[0]->value.b[c] != op[1]->value.b[c]; 1064 break; 1065 default: 1066 assert(!"Should not get here."); 1067 } 1068 } 1069 } else if (strcmp(callee, "outerProduct") == 0) { 1070 assert(op[0]->type->is_vector() && op[1]->type->is_vector()); 1071 const unsigned m = op[0]->type->vector_elements; 1072 const unsigned n = op[1]->type->vector_elements; 1073 for (unsigned j = 0; j < n; j++) { 1074 for (unsigned i = 0; i < m; i++) { 1075 data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j]; 1076 } 1077 } 1078 } else if (strcmp(callee, "pow") == 0) { 1079 expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]); 1080 } else if (strcmp(callee, "radians") == 0) { 1081 assert(op[0]->type->is_float()); 1082 for (unsigned c = 0; c < op[0]->type->components(); c++) 1083 data.f[c] = M_PI/180.0 * op[0]->value.f[c]; 1084 } else if (strcmp(callee, "reflect") == 0) { 1085 assert(op[0]->type->is_float()); 1086 float dot_NI = dot(op[1], op[0]); 1087 for (unsigned c = 0; c < op[0]->type->components(); c++) 1088 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c]; 1089 } else if (strcmp(callee, "refract") == 0) { 1090 const float eta = op[2]->value.f[0]; 1091 const float dot_NI = dot(op[1], op[0]); 1092 const float k = 1.0 - eta * eta * (1.0 - dot_NI * dot_NI); 1093 if (k < 0.0) { 1094 return ir_constant::zero(mem_ctx, this->type); 1095 } else { 1096 for (unsigned c = 0; c < type->components(); c++) { 1097 data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k)) 1098 * op[1]->value.f[c]; 1099 } 1100 } 1101 } else if (strcmp(callee, "sign") == 0) { 1102 expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL); 1103 } else if (strcmp(callee, "sin") == 0) { 1104 expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL); 1105 } else if (strcmp(callee, "sinh") == 0) { 1106 assert(op[0]->type->is_float()); 1107 for (unsigned c = 0; c < op[0]->type->components(); c++) 1108 data.f[c] = sinhf(op[0]->value.f[c]); 1109 } else if (strcmp(callee, "smoothstep") == 0) { 1110 assert(num_parameters == 3); 1111 assert(op[1]->type == op[0]->type); 1112 unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1; 1113 for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) { 1114 const float edge0 = op[0]->value.f[e]; 1115 const float edge1 = op[1]->value.f[e]; 1116 if (edge0 == edge1) { 1117 data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */ 1118 } else { 1119 const float numerator = op[2]->value.f[c] - edge0; 1120 const float denominator = edge1 - edge0; 1121 const float t = CLAMP(numerator/denominator, 0, 1); 1122 data.f[c] = t * t * (3 - 2 * t); 1123 } 1124 } 1125 } else if (strcmp(callee, "sqrt") == 0) { 1126 expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL); 1127 } else if (strcmp(callee, "step") == 0) { 1128 assert(op[0]->type->is_float() && op[1]->type->is_float()); 1129 /* op[0] (edge) may be either a scalar or a vector */ 1130 const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1; 1131 for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++) 1132 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0 : 1.0; 1133 } else if (strcmp(callee, "tan") == 0) { 1134 assert(op[0]->type->is_float()); 1135 for (unsigned c = 0; c < op[0]->type->components(); c++) 1136 data.f[c] = tanf(op[0]->value.f[c]); 1137 } else if (strcmp(callee, "tanh") == 0) { 1138 assert(op[0]->type->is_float()); 1139 for (unsigned c = 0; c < op[0]->type->components(); c++) 1140 data.f[c] = tanhf(op[0]->value.f[c]); 1141 } else if (strcmp(callee, "transpose") == 0) { 1142 assert(op[0]->type->is_matrix()); 1143 const unsigned n = op[0]->type->vector_elements; 1144 const unsigned m = op[0]->type->matrix_columns; 1145 for (unsigned j = 0; j < m; j++) { 1146 for (unsigned i = 0; i < n; i++) { 1147 data.f[m*i+j] += op[0]->value.f[i+n*j]; 1148 } 1149 } 1150 } else { 1151 /* Unsupported builtin - some are not allowed in constant expressions. */ 1152 return NULL; 1153 } 1154 1155 if (expr != NULL) 1156 return expr->constant_expression_value(); 1157 1158 return new(mem_ctx) ir_constant(this->type, &data); 1159} 1160