1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2010 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21b8e80941Smrg * DEALINGS IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg/** 25b8e80941Smrg * \file ir_constant_expression.cpp 26b8e80941Smrg * Evaluate and process constant valued expressions 27b8e80941Smrg * 28b8e80941Smrg * In GLSL, constant valued expressions are used in several places. These 29b8e80941Smrg * must be processed and evaluated very early in the compilation process. 30b8e80941Smrg * 31b8e80941Smrg * * Sizes of arrays 32b8e80941Smrg * * Initializers for uniforms 33b8e80941Smrg * * Initializers for \c const variables 34b8e80941Smrg */ 35b8e80941Smrg 36b8e80941Smrg#include <math.h> 37b8e80941Smrg#include "util/rounding.h" /* for _mesa_roundeven */ 38b8e80941Smrg#include "util/half_float.h" 39b8e80941Smrg#include "ir.h" 40b8e80941Smrg#include "compiler/glsl_types.h" 41b8e80941Smrg#include "util/hash_table.h" 42b8e80941Smrg#include "util/u_math.h" 43b8e80941Smrg 44b8e80941Smrgstatic float 45b8e80941Smrgdot_f(ir_constant *op0, ir_constant *op1) 46b8e80941Smrg{ 47b8e80941Smrg assert(op0->type->is_float() && op1->type->is_float()); 48b8e80941Smrg 49b8e80941Smrg float result = 0; 50b8e80941Smrg for (unsigned c = 0; c < op0->type->components(); c++) 51b8e80941Smrg result += op0->value.f[c] * op1->value.f[c]; 52b8e80941Smrg 53b8e80941Smrg return result; 54b8e80941Smrg} 55b8e80941Smrg 56b8e80941Smrgstatic double 57b8e80941Smrgdot_d(ir_constant *op0, ir_constant *op1) 58b8e80941Smrg{ 59b8e80941Smrg assert(op0->type->is_double() && op1->type->is_double()); 60b8e80941Smrg 61b8e80941Smrg double result = 0; 62b8e80941Smrg for (unsigned c = 0; c < op0->type->components(); c++) 63b8e80941Smrg result += op0->value.d[c] * op1->value.d[c]; 64b8e80941Smrg 65b8e80941Smrg return result; 66b8e80941Smrg} 67b8e80941Smrg 68b8e80941Smrg/* This method is the only one supported by gcc. Unions in particular 69b8e80941Smrg * are iffy, and read-through-converted-pointer is killed by strict 70b8e80941Smrg * aliasing. OTOH, the compiler sees through the memcpy, so the 71b8e80941Smrg * resulting asm is reasonable. 72b8e80941Smrg */ 73b8e80941Smrgstatic float 74b8e80941Smrgbitcast_u2f(unsigned int u) 75b8e80941Smrg{ 76b8e80941Smrg assert(sizeof(float) == sizeof(unsigned int)); 77b8e80941Smrg float f; 78b8e80941Smrg memcpy(&f, &u, sizeof(f)); 79b8e80941Smrg return f; 80b8e80941Smrg} 81b8e80941Smrg 82b8e80941Smrgstatic unsigned int 83b8e80941Smrgbitcast_f2u(float f) 84b8e80941Smrg{ 85b8e80941Smrg assert(sizeof(float) == sizeof(unsigned int)); 86b8e80941Smrg unsigned int u; 87b8e80941Smrg memcpy(&u, &f, sizeof(f)); 88b8e80941Smrg return u; 89b8e80941Smrg} 90b8e80941Smrg 91b8e80941Smrgstatic double 92b8e80941Smrgbitcast_u642d(uint64_t u) 93b8e80941Smrg{ 94b8e80941Smrg assert(sizeof(double) == sizeof(uint64_t)); 95b8e80941Smrg double d; 96b8e80941Smrg memcpy(&d, &u, sizeof(d)); 97b8e80941Smrg return d; 98b8e80941Smrg} 99b8e80941Smrg 100b8e80941Smrgstatic double 101b8e80941Smrgbitcast_i642d(int64_t i) 102b8e80941Smrg{ 103b8e80941Smrg assert(sizeof(double) == sizeof(int64_t)); 104b8e80941Smrg double d; 105b8e80941Smrg memcpy(&d, &i, sizeof(d)); 106b8e80941Smrg return d; 107b8e80941Smrg} 108b8e80941Smrg 109b8e80941Smrgstatic double 110b8e80941Smrgbitcast_d2u64(double d) 111b8e80941Smrg{ 112b8e80941Smrg assert(sizeof(double) == sizeof(uint64_t)); 113b8e80941Smrg uint64_t u; 114b8e80941Smrg memcpy(&u, &d, sizeof(d)); 115b8e80941Smrg return u; 116b8e80941Smrg} 117b8e80941Smrg 118b8e80941Smrgstatic double 119b8e80941Smrgbitcast_d2i64(double d) 120b8e80941Smrg{ 121b8e80941Smrg assert(sizeof(double) == sizeof(int64_t)); 122b8e80941Smrg int64_t i; 123b8e80941Smrg memcpy(&i, &d, sizeof(d)); 124b8e80941Smrg return i; 125b8e80941Smrg} 126b8e80941Smrg 127b8e80941Smrg/** 128b8e80941Smrg * Evaluate one component of a floating-point 4x8 unpacking function. 129b8e80941Smrg */ 130b8e80941Smrgtypedef uint8_t 131b8e80941Smrg(*pack_1x8_func_t)(float); 132b8e80941Smrg 133b8e80941Smrg/** 134b8e80941Smrg * Evaluate one component of a floating-point 2x16 unpacking function. 135b8e80941Smrg */ 136b8e80941Smrgtypedef uint16_t 137b8e80941Smrg(*pack_1x16_func_t)(float); 138b8e80941Smrg 139b8e80941Smrg/** 140b8e80941Smrg * Evaluate one component of a floating-point 4x8 unpacking function. 141b8e80941Smrg */ 142b8e80941Smrgtypedef float 143b8e80941Smrg(*unpack_1x8_func_t)(uint8_t); 144b8e80941Smrg 145b8e80941Smrg/** 146b8e80941Smrg * Evaluate one component of a floating-point 2x16 unpacking function. 147b8e80941Smrg */ 148b8e80941Smrgtypedef float 149b8e80941Smrg(*unpack_1x16_func_t)(uint16_t); 150b8e80941Smrg 151b8e80941Smrg/** 152b8e80941Smrg * Evaluate a 2x16 floating-point packing function. 153b8e80941Smrg */ 154b8e80941Smrgstatic uint32_t 155b8e80941Smrgpack_2x16(pack_1x16_func_t pack_1x16, 156b8e80941Smrg float x, float y) 157b8e80941Smrg{ 158b8e80941Smrg /* From section 8.4 of the GLSL ES 3.00 spec: 159b8e80941Smrg * 160b8e80941Smrg * packSnorm2x16 161b8e80941Smrg * ------------- 162b8e80941Smrg * The first component of the vector will be written to the least 163b8e80941Smrg * significant bits of the output; the last component will be written to 164b8e80941Smrg * the most significant bits. 165b8e80941Smrg * 166b8e80941Smrg * The specifications for the other packing functions contain similar 167b8e80941Smrg * language. 168b8e80941Smrg */ 169b8e80941Smrg uint32_t u = 0; 170b8e80941Smrg u |= ((uint32_t) pack_1x16(x) << 0); 171b8e80941Smrg u |= ((uint32_t) pack_1x16(y) << 16); 172b8e80941Smrg return u; 173b8e80941Smrg} 174b8e80941Smrg 175b8e80941Smrg/** 176b8e80941Smrg * Evaluate a 4x8 floating-point packing function. 177b8e80941Smrg */ 178b8e80941Smrgstatic uint32_t 179b8e80941Smrgpack_4x8(pack_1x8_func_t pack_1x8, 180b8e80941Smrg float x, float y, float z, float w) 181b8e80941Smrg{ 182b8e80941Smrg /* From section 8.4 of the GLSL 4.30 spec: 183b8e80941Smrg * 184b8e80941Smrg * packSnorm4x8 185b8e80941Smrg * ------------ 186b8e80941Smrg * The first component of the vector will be written to the least 187b8e80941Smrg * significant bits of the output; the last component will be written to 188b8e80941Smrg * the most significant bits. 189b8e80941Smrg * 190b8e80941Smrg * The specifications for the other packing functions contain similar 191b8e80941Smrg * language. 192b8e80941Smrg */ 193b8e80941Smrg uint32_t u = 0; 194b8e80941Smrg u |= ((uint32_t) pack_1x8(x) << 0); 195b8e80941Smrg u |= ((uint32_t) pack_1x8(y) << 8); 196b8e80941Smrg u |= ((uint32_t) pack_1x8(z) << 16); 197b8e80941Smrg u |= ((uint32_t) pack_1x8(w) << 24); 198b8e80941Smrg return u; 199b8e80941Smrg} 200b8e80941Smrg 201b8e80941Smrg/** 202b8e80941Smrg * Evaluate a 2x16 floating-point unpacking function. 203b8e80941Smrg */ 204b8e80941Smrgstatic void 205b8e80941Smrgunpack_2x16(unpack_1x16_func_t unpack_1x16, 206b8e80941Smrg uint32_t u, 207b8e80941Smrg float *x, float *y) 208b8e80941Smrg{ 209b8e80941Smrg /* From section 8.4 of the GLSL ES 3.00 spec: 210b8e80941Smrg * 211b8e80941Smrg * unpackSnorm2x16 212b8e80941Smrg * --------------- 213b8e80941Smrg * The first component of the returned vector will be extracted from 214b8e80941Smrg * the least significant bits of the input; the last component will be 215b8e80941Smrg * extracted from the most significant bits. 216b8e80941Smrg * 217b8e80941Smrg * The specifications for the other unpacking functions contain similar 218b8e80941Smrg * language. 219b8e80941Smrg */ 220b8e80941Smrg *x = unpack_1x16((uint16_t) (u & 0xffff)); 221b8e80941Smrg *y = unpack_1x16((uint16_t) (u >> 16)); 222b8e80941Smrg} 223b8e80941Smrg 224b8e80941Smrg/** 225b8e80941Smrg * Evaluate a 4x8 floating-point unpacking function. 226b8e80941Smrg */ 227b8e80941Smrgstatic void 228b8e80941Smrgunpack_4x8(unpack_1x8_func_t unpack_1x8, uint32_t u, 229b8e80941Smrg float *x, float *y, float *z, float *w) 230b8e80941Smrg{ 231b8e80941Smrg /* From section 8.4 of the GLSL 4.30 spec: 232b8e80941Smrg * 233b8e80941Smrg * unpackSnorm4x8 234b8e80941Smrg * -------------- 235b8e80941Smrg * The first component of the returned vector will be extracted from 236b8e80941Smrg * the least significant bits of the input; the last component will be 237b8e80941Smrg * extracted from the most significant bits. 238b8e80941Smrg * 239b8e80941Smrg * The specifications for the other unpacking functions contain similar 240b8e80941Smrg * language. 241b8e80941Smrg */ 242b8e80941Smrg *x = unpack_1x8((uint8_t) (u & 0xff)); 243b8e80941Smrg *y = unpack_1x8((uint8_t) (u >> 8)); 244b8e80941Smrg *z = unpack_1x8((uint8_t) (u >> 16)); 245b8e80941Smrg *w = unpack_1x8((uint8_t) (u >> 24)); 246b8e80941Smrg} 247b8e80941Smrg 248b8e80941Smrg/** 249b8e80941Smrg * Evaluate one component of packSnorm4x8. 250b8e80941Smrg */ 251b8e80941Smrgstatic uint8_t 252b8e80941Smrgpack_snorm_1x8(float x) 253b8e80941Smrg{ 254b8e80941Smrg /* From section 8.4 of the GLSL 4.30 spec: 255b8e80941Smrg * 256b8e80941Smrg * packSnorm4x8 257b8e80941Smrg * ------------ 258b8e80941Smrg * The conversion for component c of v to fixed point is done as 259b8e80941Smrg * follows: 260b8e80941Smrg * 261b8e80941Smrg * packSnorm4x8: round(clamp(c, -1, +1) * 127.0) 262b8e80941Smrg */ 263b8e80941Smrg return (uint8_t) 264b8e80941Smrg _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 127.0f); 265b8e80941Smrg} 266b8e80941Smrg 267b8e80941Smrg/** 268b8e80941Smrg * Evaluate one component of packSnorm2x16. 269b8e80941Smrg */ 270b8e80941Smrgstatic uint16_t 271b8e80941Smrgpack_snorm_1x16(float x) 272b8e80941Smrg{ 273b8e80941Smrg /* From section 8.4 of the GLSL ES 3.00 spec: 274b8e80941Smrg * 275b8e80941Smrg * packSnorm2x16 276b8e80941Smrg * ------------- 277b8e80941Smrg * The conversion for component c of v to fixed point is done as 278b8e80941Smrg * follows: 279b8e80941Smrg * 280b8e80941Smrg * packSnorm2x16: round(clamp(c, -1, +1) * 32767.0) 281b8e80941Smrg */ 282b8e80941Smrg return (uint16_t) 283b8e80941Smrg _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 32767.0f); 284b8e80941Smrg} 285b8e80941Smrg 286b8e80941Smrg/** 287b8e80941Smrg * Evaluate one component of unpackSnorm4x8. 288b8e80941Smrg */ 289b8e80941Smrgstatic float 290b8e80941Smrgunpack_snorm_1x8(uint8_t u) 291b8e80941Smrg{ 292b8e80941Smrg /* From section 8.4 of the GLSL 4.30 spec: 293b8e80941Smrg * 294b8e80941Smrg * unpackSnorm4x8 295b8e80941Smrg * -------------- 296b8e80941Smrg * The conversion for unpacked fixed-point value f to floating point is 297b8e80941Smrg * done as follows: 298b8e80941Smrg * 299b8e80941Smrg * unpackSnorm4x8: clamp(f / 127.0, -1, +1) 300b8e80941Smrg */ 301b8e80941Smrg return CLAMP((int8_t) u / 127.0f, -1.0f, +1.0f); 302b8e80941Smrg} 303b8e80941Smrg 304b8e80941Smrg/** 305b8e80941Smrg * Evaluate one component of unpackSnorm2x16. 306b8e80941Smrg */ 307b8e80941Smrgstatic float 308b8e80941Smrgunpack_snorm_1x16(uint16_t u) 309b8e80941Smrg{ 310b8e80941Smrg /* From section 8.4 of the GLSL ES 3.00 spec: 311b8e80941Smrg * 312b8e80941Smrg * unpackSnorm2x16 313b8e80941Smrg * --------------- 314b8e80941Smrg * The conversion for unpacked fixed-point value f to floating point is 315b8e80941Smrg * done as follows: 316b8e80941Smrg * 317b8e80941Smrg * unpackSnorm2x16: clamp(f / 32767.0, -1, +1) 318b8e80941Smrg */ 319b8e80941Smrg return CLAMP((int16_t) u / 32767.0f, -1.0f, +1.0f); 320b8e80941Smrg} 321b8e80941Smrg 322b8e80941Smrg/** 323b8e80941Smrg * Evaluate one component packUnorm4x8. 324b8e80941Smrg */ 325b8e80941Smrgstatic uint8_t 326b8e80941Smrgpack_unorm_1x8(float x) 327b8e80941Smrg{ 328b8e80941Smrg /* From section 8.4 of the GLSL 4.30 spec: 329b8e80941Smrg * 330b8e80941Smrg * packUnorm4x8 331b8e80941Smrg * ------------ 332b8e80941Smrg * The conversion for component c of v to fixed point is done as 333b8e80941Smrg * follows: 334b8e80941Smrg * 335b8e80941Smrg * packUnorm4x8: round(clamp(c, 0, +1) * 255.0) 336b8e80941Smrg */ 337b8e80941Smrg return (uint8_t) (int) _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 255.0f); 338b8e80941Smrg} 339b8e80941Smrg 340b8e80941Smrg/** 341b8e80941Smrg * Evaluate one component packUnorm2x16. 342b8e80941Smrg */ 343b8e80941Smrgstatic uint16_t 344b8e80941Smrgpack_unorm_1x16(float x) 345b8e80941Smrg{ 346b8e80941Smrg /* From section 8.4 of the GLSL ES 3.00 spec: 347b8e80941Smrg * 348b8e80941Smrg * packUnorm2x16 349b8e80941Smrg * ------------- 350b8e80941Smrg * The conversion for component c of v to fixed point is done as 351b8e80941Smrg * follows: 352b8e80941Smrg * 353b8e80941Smrg * packUnorm2x16: round(clamp(c, 0, +1) * 65535.0) 354b8e80941Smrg */ 355b8e80941Smrg return (uint16_t) (int) 356b8e80941Smrg _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 65535.0f); 357b8e80941Smrg} 358b8e80941Smrg 359b8e80941Smrg/** 360b8e80941Smrg * Evaluate one component of unpackUnorm4x8. 361b8e80941Smrg */ 362b8e80941Smrgstatic float 363b8e80941Smrgunpack_unorm_1x8(uint8_t u) 364b8e80941Smrg{ 365b8e80941Smrg /* From section 8.4 of the GLSL 4.30 spec: 366b8e80941Smrg * 367b8e80941Smrg * unpackUnorm4x8 368b8e80941Smrg * -------------- 369b8e80941Smrg * The conversion for unpacked fixed-point value f to floating point is 370b8e80941Smrg * done as follows: 371b8e80941Smrg * 372b8e80941Smrg * unpackUnorm4x8: f / 255.0 373b8e80941Smrg */ 374b8e80941Smrg return (float) u / 255.0f; 375b8e80941Smrg} 376b8e80941Smrg 377b8e80941Smrg/** 378b8e80941Smrg * Evaluate one component of unpackUnorm2x16. 379b8e80941Smrg */ 380b8e80941Smrgstatic float 381b8e80941Smrgunpack_unorm_1x16(uint16_t u) 382b8e80941Smrg{ 383b8e80941Smrg /* From section 8.4 of the GLSL ES 3.00 spec: 384b8e80941Smrg * 385b8e80941Smrg * unpackUnorm2x16 386b8e80941Smrg * --------------- 387b8e80941Smrg * The conversion for unpacked fixed-point value f to floating point is 388b8e80941Smrg * done as follows: 389b8e80941Smrg * 390b8e80941Smrg * unpackUnorm2x16: f / 65535.0 391b8e80941Smrg */ 392b8e80941Smrg return (float) u / 65535.0f; 393b8e80941Smrg} 394b8e80941Smrg 395b8e80941Smrg/** 396b8e80941Smrg * Evaluate one component of packHalf2x16. 397b8e80941Smrg */ 398b8e80941Smrgstatic uint16_t 399b8e80941Smrgpack_half_1x16(float x) 400b8e80941Smrg{ 401b8e80941Smrg return _mesa_float_to_half(x); 402b8e80941Smrg} 403b8e80941Smrg 404b8e80941Smrg/** 405b8e80941Smrg * Evaluate one component of unpackHalf2x16. 406b8e80941Smrg */ 407b8e80941Smrgstatic float 408b8e80941Smrgunpack_half_1x16(uint16_t u) 409b8e80941Smrg{ 410b8e80941Smrg return _mesa_half_to_float(u); 411b8e80941Smrg} 412b8e80941Smrg 413b8e80941Smrg/** 414b8e80941Smrg * Get the constant that is ultimately referenced by an r-value, in a constant 415b8e80941Smrg * expression evaluation context. 416b8e80941Smrg * 417b8e80941Smrg * The offset is used when the reference is to a specific column of a matrix. 418b8e80941Smrg */ 419b8e80941Smrgstatic bool 420b8e80941Smrgconstant_referenced(const ir_dereference *deref, 421b8e80941Smrg struct hash_table *variable_context, 422b8e80941Smrg ir_constant *&store, int &offset) 423b8e80941Smrg{ 424b8e80941Smrg store = NULL; 425b8e80941Smrg offset = 0; 426b8e80941Smrg 427b8e80941Smrg if (variable_context == NULL) 428b8e80941Smrg return false; 429b8e80941Smrg 430b8e80941Smrg switch (deref->ir_type) { 431b8e80941Smrg case ir_type_dereference_array: { 432b8e80941Smrg const ir_dereference_array *const da = 433b8e80941Smrg (const ir_dereference_array *) deref; 434b8e80941Smrg 435b8e80941Smrg ir_constant *const index_c = 436b8e80941Smrg da->array_index->constant_expression_value(variable_context); 437b8e80941Smrg 438b8e80941Smrg if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer()) 439b8e80941Smrg break; 440b8e80941Smrg 441b8e80941Smrg const int index = index_c->type->base_type == GLSL_TYPE_INT ? 442b8e80941Smrg index_c->get_int_component(0) : 443b8e80941Smrg index_c->get_uint_component(0); 444b8e80941Smrg 445b8e80941Smrg ir_constant *substore; 446b8e80941Smrg int suboffset; 447b8e80941Smrg 448b8e80941Smrg const ir_dereference *const deref = da->array->as_dereference(); 449b8e80941Smrg if (!deref) 450b8e80941Smrg break; 451b8e80941Smrg 452b8e80941Smrg if (!constant_referenced(deref, variable_context, substore, suboffset)) 453b8e80941Smrg break; 454b8e80941Smrg 455b8e80941Smrg const glsl_type *const vt = da->array->type; 456b8e80941Smrg if (vt->is_array()) { 457b8e80941Smrg store = substore->get_array_element(index); 458b8e80941Smrg offset = 0; 459b8e80941Smrg } else if (vt->is_matrix()) { 460b8e80941Smrg store = substore; 461b8e80941Smrg offset = index * vt->vector_elements; 462b8e80941Smrg } else if (vt->is_vector()) { 463b8e80941Smrg store = substore; 464b8e80941Smrg offset = suboffset + index; 465b8e80941Smrg } 466b8e80941Smrg 467b8e80941Smrg break; 468b8e80941Smrg } 469b8e80941Smrg 470b8e80941Smrg case ir_type_dereference_record: { 471b8e80941Smrg const ir_dereference_record *const dr = 472b8e80941Smrg (const ir_dereference_record *) deref; 473b8e80941Smrg 474b8e80941Smrg const ir_dereference *const deref = dr->record->as_dereference(); 475b8e80941Smrg if (!deref) 476b8e80941Smrg break; 477b8e80941Smrg 478b8e80941Smrg ir_constant *substore; 479b8e80941Smrg int suboffset; 480b8e80941Smrg 481b8e80941Smrg if (!constant_referenced(deref, variable_context, substore, suboffset)) 482b8e80941Smrg break; 483b8e80941Smrg 484b8e80941Smrg /* Since we're dropping it on the floor... 485b8e80941Smrg */ 486b8e80941Smrg assert(suboffset == 0); 487b8e80941Smrg 488b8e80941Smrg store = substore->get_record_field(dr->field_idx); 489b8e80941Smrg break; 490b8e80941Smrg } 491b8e80941Smrg 492b8e80941Smrg case ir_type_dereference_variable: { 493b8e80941Smrg const ir_dereference_variable *const dv = 494b8e80941Smrg (const ir_dereference_variable *) deref; 495b8e80941Smrg 496b8e80941Smrg hash_entry *entry = _mesa_hash_table_search(variable_context, dv->var); 497b8e80941Smrg if (entry) 498b8e80941Smrg store = (ir_constant *) entry->data; 499b8e80941Smrg break; 500b8e80941Smrg } 501b8e80941Smrg 502b8e80941Smrg default: 503b8e80941Smrg assert(!"Should not get here."); 504b8e80941Smrg break; 505b8e80941Smrg } 506b8e80941Smrg 507b8e80941Smrg return store != NULL; 508b8e80941Smrg} 509b8e80941Smrg 510b8e80941Smrg 511b8e80941Smrgir_constant * 512b8e80941Smrgir_rvalue::constant_expression_value(void *, struct hash_table *) 513b8e80941Smrg{ 514b8e80941Smrg assert(this->type->is_error()); 515b8e80941Smrg return NULL; 516b8e80941Smrg} 517b8e80941Smrg 518b8e80941Smrgstatic uint32_t 519b8e80941Smrgbitfield_reverse(uint32_t v) 520b8e80941Smrg{ 521b8e80941Smrg /* http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */ 522b8e80941Smrg uint32_t r = v; // r will be reversed bits of v; first get LSB of v 523b8e80941Smrg int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end 524b8e80941Smrg 525b8e80941Smrg for (v >>= 1; v; v >>= 1) { 526b8e80941Smrg r <<= 1; 527b8e80941Smrg r |= v & 1; 528b8e80941Smrg s--; 529b8e80941Smrg } 530b8e80941Smrg r <<= s; // shift when v's highest bits are zero 531b8e80941Smrg 532b8e80941Smrg return r; 533b8e80941Smrg} 534b8e80941Smrg 535b8e80941Smrgstatic int 536b8e80941Smrgfind_msb_uint(uint32_t v) 537b8e80941Smrg{ 538b8e80941Smrg int count = 0; 539b8e80941Smrg 540b8e80941Smrg /* If v == 0, then the loop will terminate when count == 32. In that case 541b8e80941Smrg * 31-count will produce the -1 result required by GLSL findMSB(). 542b8e80941Smrg */ 543b8e80941Smrg while (((v & (1u << 31)) == 0) && count != 32) { 544b8e80941Smrg count++; 545b8e80941Smrg v <<= 1; 546b8e80941Smrg } 547b8e80941Smrg 548b8e80941Smrg return 31 - count; 549b8e80941Smrg} 550b8e80941Smrg 551b8e80941Smrgstatic int 552b8e80941Smrgfind_msb_int(int32_t v) 553b8e80941Smrg{ 554b8e80941Smrg /* If v is signed, findMSB() returns the position of the most significant 555b8e80941Smrg * zero bit. 556b8e80941Smrg */ 557b8e80941Smrg return find_msb_uint(v < 0 ? ~v : v); 558b8e80941Smrg} 559b8e80941Smrg 560b8e80941Smrgstatic float 561b8e80941Smrgldexpf_flush_subnormal(float x, int exp) 562b8e80941Smrg{ 563b8e80941Smrg const float result = ldexpf(x, exp); 564b8e80941Smrg 565b8e80941Smrg /* Flush subnormal values to zero. */ 566b8e80941Smrg return !isnormal(result) ? copysignf(0.0f, x) : result; 567b8e80941Smrg} 568b8e80941Smrg 569b8e80941Smrgstatic double 570b8e80941Smrgldexp_flush_subnormal(double x, int exp) 571b8e80941Smrg{ 572b8e80941Smrg const double result = ldexp(x, exp); 573b8e80941Smrg 574b8e80941Smrg /* Flush subnormal values to zero. */ 575b8e80941Smrg return !isnormal(result) ? copysign(0.0, x) : result; 576b8e80941Smrg} 577b8e80941Smrg 578b8e80941Smrgstatic uint32_t 579b8e80941Smrgbitfield_extract_uint(uint32_t value, int offset, int bits) 580b8e80941Smrg{ 581b8e80941Smrg if (bits == 0) 582b8e80941Smrg return 0; 583b8e80941Smrg else if (offset < 0 || bits < 0) 584b8e80941Smrg return 0; /* Undefined, per spec. */ 585b8e80941Smrg else if (offset + bits > 32) 586b8e80941Smrg return 0; /* Undefined, per spec. */ 587b8e80941Smrg else { 588b8e80941Smrg value <<= 32 - bits - offset; 589b8e80941Smrg value >>= 32 - bits; 590b8e80941Smrg return value; 591b8e80941Smrg } 592b8e80941Smrg} 593b8e80941Smrg 594b8e80941Smrgstatic int32_t 595b8e80941Smrgbitfield_extract_int(int32_t value, int offset, int bits) 596b8e80941Smrg{ 597b8e80941Smrg if (bits == 0) 598b8e80941Smrg return 0; 599b8e80941Smrg else if (offset < 0 || bits < 0) 600b8e80941Smrg return 0; /* Undefined, per spec. */ 601b8e80941Smrg else if (offset + bits > 32) 602b8e80941Smrg return 0; /* Undefined, per spec. */ 603b8e80941Smrg else { 604b8e80941Smrg value <<= 32 - bits - offset; 605b8e80941Smrg value >>= 32 - bits; 606b8e80941Smrg return value; 607b8e80941Smrg } 608b8e80941Smrg} 609b8e80941Smrg 610b8e80941Smrgstatic uint32_t 611b8e80941Smrgbitfield_insert(uint32_t base, uint32_t insert, int offset, int bits) 612b8e80941Smrg{ 613b8e80941Smrg if (bits == 0) 614b8e80941Smrg return base; 615b8e80941Smrg else if (offset < 0 || bits < 0) 616b8e80941Smrg return 0; /* Undefined, per spec. */ 617b8e80941Smrg else if (offset + bits > 32) 618b8e80941Smrg return 0; /* Undefined, per spec. */ 619b8e80941Smrg else { 620b8e80941Smrg unsigned insert_mask = ((1ull << bits) - 1) << offset; 621b8e80941Smrg 622b8e80941Smrg insert <<= offset; 623b8e80941Smrg insert &= insert_mask; 624b8e80941Smrg base &= ~insert_mask; 625b8e80941Smrg 626b8e80941Smrg return base | insert; 627b8e80941Smrg } 628b8e80941Smrg} 629b8e80941Smrg 630b8e80941Smrgir_constant * 631b8e80941Smrgir_expression::constant_expression_value(void *mem_ctx, 632b8e80941Smrg struct hash_table *variable_context) 633b8e80941Smrg{ 634b8e80941Smrg assert(mem_ctx); 635b8e80941Smrg 636b8e80941Smrg if (this->type->is_error()) 637b8e80941Smrg return NULL; 638b8e80941Smrg 639b8e80941Smrg ir_constant *op[ARRAY_SIZE(this->operands)] = { NULL, }; 640b8e80941Smrg ir_constant_data data; 641b8e80941Smrg 642b8e80941Smrg memset(&data, 0, sizeof(data)); 643b8e80941Smrg 644b8e80941Smrg for (unsigned operand = 0; operand < this->num_operands; operand++) { 645b8e80941Smrg op[operand] = 646b8e80941Smrg this->operands[operand]->constant_expression_value(mem_ctx, 647b8e80941Smrg variable_context); 648b8e80941Smrg if (!op[operand]) 649b8e80941Smrg return NULL; 650b8e80941Smrg } 651b8e80941Smrg 652b8e80941Smrg if (op[1] != NULL) 653b8e80941Smrg switch (this->operation) { 654b8e80941Smrg case ir_binop_lshift: 655b8e80941Smrg case ir_binop_rshift: 656b8e80941Smrg case ir_binop_ldexp: 657b8e80941Smrg case ir_binop_interpolate_at_offset: 658b8e80941Smrg case ir_binop_interpolate_at_sample: 659b8e80941Smrg case ir_binop_vector_extract: 660b8e80941Smrg case ir_triop_csel: 661b8e80941Smrg case ir_triop_bitfield_extract: 662b8e80941Smrg break; 663b8e80941Smrg 664b8e80941Smrg default: 665b8e80941Smrg assert(op[0]->type->base_type == op[1]->type->base_type); 666b8e80941Smrg break; 667b8e80941Smrg } 668b8e80941Smrg 669b8e80941Smrg bool op0_scalar = op[0]->type->is_scalar(); 670b8e80941Smrg bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar(); 671b8e80941Smrg 672b8e80941Smrg /* When iterating over a vector or matrix's components, we want to increase 673b8e80941Smrg * the loop counter. However, for scalars, we want to stay at 0. 674b8e80941Smrg */ 675b8e80941Smrg unsigned c0_inc = op0_scalar ? 0 : 1; 676b8e80941Smrg unsigned c1_inc = op1_scalar ? 0 : 1; 677b8e80941Smrg unsigned components; 678b8e80941Smrg if (op1_scalar || !op[1]) { 679b8e80941Smrg components = op[0]->type->components(); 680b8e80941Smrg } else { 681b8e80941Smrg components = op[1]->type->components(); 682b8e80941Smrg } 683b8e80941Smrg 684b8e80941Smrg /* Handle array operations here, rather than below. */ 685b8e80941Smrg if (op[0]->type->is_array()) { 686b8e80941Smrg assert(op[1] != NULL && op[1]->type->is_array()); 687b8e80941Smrg switch (this->operation) { 688b8e80941Smrg case ir_binop_all_equal: 689b8e80941Smrg return new(mem_ctx) ir_constant(op[0]->has_value(op[1])); 690b8e80941Smrg case ir_binop_any_nequal: 691b8e80941Smrg return new(mem_ctx) ir_constant(!op[0]->has_value(op[1])); 692b8e80941Smrg default: 693b8e80941Smrg break; 694b8e80941Smrg } 695b8e80941Smrg return NULL; 696b8e80941Smrg } 697b8e80941Smrg 698b8e80941Smrg#include "ir_expression_operation_constant.h" 699b8e80941Smrg 700b8e80941Smrg return new(mem_ctx) ir_constant(this->type, &data); 701b8e80941Smrg} 702b8e80941Smrg 703b8e80941Smrg 704b8e80941Smrgir_constant * 705b8e80941Smrgir_texture::constant_expression_value(void *, struct hash_table *) 706b8e80941Smrg{ 707b8e80941Smrg /* texture lookups aren't constant expressions */ 708b8e80941Smrg return NULL; 709b8e80941Smrg} 710b8e80941Smrg 711b8e80941Smrg 712b8e80941Smrgir_constant * 713b8e80941Smrgir_swizzle::constant_expression_value(void *mem_ctx, 714b8e80941Smrg struct hash_table *variable_context) 715b8e80941Smrg{ 716b8e80941Smrg assert(mem_ctx); 717b8e80941Smrg 718b8e80941Smrg ir_constant *v = this->val->constant_expression_value(mem_ctx, 719b8e80941Smrg variable_context); 720b8e80941Smrg 721b8e80941Smrg if (v != NULL) { 722b8e80941Smrg ir_constant_data data = { { 0 } }; 723b8e80941Smrg 724b8e80941Smrg const unsigned swiz_idx[4] = { 725b8e80941Smrg this->mask.x, this->mask.y, this->mask.z, this->mask.w 726b8e80941Smrg }; 727b8e80941Smrg 728b8e80941Smrg for (unsigned i = 0; i < this->mask.num_components; i++) { 729b8e80941Smrg switch (v->type->base_type) { 730b8e80941Smrg case GLSL_TYPE_UINT: 731b8e80941Smrg case GLSL_TYPE_INT: data.u[i] = v->value.u[swiz_idx[i]]; break; 732b8e80941Smrg case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break; 733b8e80941Smrg case GLSL_TYPE_BOOL: data.b[i] = v->value.b[swiz_idx[i]]; break; 734b8e80941Smrg case GLSL_TYPE_DOUBLE:data.d[i] = v->value.d[swiz_idx[i]]; break; 735b8e80941Smrg case GLSL_TYPE_UINT64:data.u64[i] = v->value.u64[swiz_idx[i]]; break; 736b8e80941Smrg case GLSL_TYPE_INT64: data.i64[i] = v->value.i64[swiz_idx[i]]; break; 737b8e80941Smrg default: assert(!"Should not get here."); break; 738b8e80941Smrg } 739b8e80941Smrg } 740b8e80941Smrg 741b8e80941Smrg return new(mem_ctx) ir_constant(this->type, &data); 742b8e80941Smrg } 743b8e80941Smrg return NULL; 744b8e80941Smrg} 745b8e80941Smrg 746b8e80941Smrg 747b8e80941Smrgir_constant * 748b8e80941Smrgir_dereference_variable::constant_expression_value(void *mem_ctx, 749b8e80941Smrg struct hash_table *variable_context) 750b8e80941Smrg{ 751b8e80941Smrg assert(var); 752b8e80941Smrg assert(mem_ctx); 753b8e80941Smrg 754b8e80941Smrg /* Give priority to the context hashtable, if it exists */ 755b8e80941Smrg if (variable_context) { 756b8e80941Smrg hash_entry *entry = _mesa_hash_table_search(variable_context, var); 757b8e80941Smrg 758b8e80941Smrg if(entry) 759b8e80941Smrg return (ir_constant *) entry->data; 760b8e80941Smrg } 761b8e80941Smrg 762b8e80941Smrg /* The constant_value of a uniform variable is its initializer, 763b8e80941Smrg * not the lifetime constant value of the uniform. 764b8e80941Smrg */ 765b8e80941Smrg if (var->data.mode == ir_var_uniform) 766b8e80941Smrg return NULL; 767b8e80941Smrg 768b8e80941Smrg if (!var->constant_value) 769b8e80941Smrg return NULL; 770b8e80941Smrg 771b8e80941Smrg return var->constant_value->clone(mem_ctx, NULL); 772b8e80941Smrg} 773b8e80941Smrg 774b8e80941Smrg 775b8e80941Smrgir_constant * 776b8e80941Smrgir_dereference_array::constant_expression_value(void *mem_ctx, 777b8e80941Smrg struct hash_table *variable_context) 778b8e80941Smrg{ 779b8e80941Smrg assert(mem_ctx); 780b8e80941Smrg 781b8e80941Smrg ir_constant *array = this->array->constant_expression_value(mem_ctx, variable_context); 782b8e80941Smrg ir_constant *idx = this->array_index->constant_expression_value(mem_ctx, variable_context); 783b8e80941Smrg 784b8e80941Smrg if ((array != NULL) && (idx != NULL)) { 785b8e80941Smrg if (array->type->is_matrix()) { 786b8e80941Smrg /* Array access of a matrix results in a vector. 787b8e80941Smrg */ 788b8e80941Smrg const unsigned column = idx->value.u[0]; 789b8e80941Smrg 790b8e80941Smrg const glsl_type *const column_type = array->type->column_type(); 791b8e80941Smrg 792b8e80941Smrg /* Offset in the constant matrix to the first element of the column 793b8e80941Smrg * to be extracted. 794b8e80941Smrg */ 795b8e80941Smrg const unsigned mat_idx = column * column_type->vector_elements; 796b8e80941Smrg 797b8e80941Smrg ir_constant_data data = { { 0 } }; 798b8e80941Smrg 799b8e80941Smrg switch (column_type->base_type) { 800b8e80941Smrg case GLSL_TYPE_UINT: 801b8e80941Smrg case GLSL_TYPE_INT: 802b8e80941Smrg for (unsigned i = 0; i < column_type->vector_elements; i++) 803b8e80941Smrg data.u[i] = array->value.u[mat_idx + i]; 804b8e80941Smrg 805b8e80941Smrg break; 806b8e80941Smrg 807b8e80941Smrg case GLSL_TYPE_FLOAT: 808b8e80941Smrg for (unsigned i = 0; i < column_type->vector_elements; i++) 809b8e80941Smrg data.f[i] = array->value.f[mat_idx + i]; 810b8e80941Smrg 811b8e80941Smrg break; 812b8e80941Smrg 813b8e80941Smrg case GLSL_TYPE_DOUBLE: 814b8e80941Smrg for (unsigned i = 0; i < column_type->vector_elements; i++) 815b8e80941Smrg data.d[i] = array->value.d[mat_idx + i]; 816b8e80941Smrg 817b8e80941Smrg break; 818b8e80941Smrg 819b8e80941Smrg default: 820b8e80941Smrg assert(!"Should not get here."); 821b8e80941Smrg break; 822b8e80941Smrg } 823b8e80941Smrg 824b8e80941Smrg return new(mem_ctx) ir_constant(column_type, &data); 825b8e80941Smrg } else if (array->type->is_vector()) { 826b8e80941Smrg const unsigned component = idx->value.u[0]; 827b8e80941Smrg 828b8e80941Smrg return new(mem_ctx) ir_constant(array, component); 829b8e80941Smrg } else if (array->type->is_array()) { 830b8e80941Smrg const unsigned index = idx->value.u[0]; 831b8e80941Smrg return array->get_array_element(index)->clone(mem_ctx, NULL); 832b8e80941Smrg } 833b8e80941Smrg } 834b8e80941Smrg return NULL; 835b8e80941Smrg} 836b8e80941Smrg 837b8e80941Smrg 838b8e80941Smrgir_constant * 839b8e80941Smrgir_dereference_record::constant_expression_value(void *mem_ctx, 840b8e80941Smrg struct hash_table *) 841b8e80941Smrg{ 842b8e80941Smrg assert(mem_ctx); 843b8e80941Smrg 844b8e80941Smrg ir_constant *v = this->record->constant_expression_value(mem_ctx); 845b8e80941Smrg 846b8e80941Smrg return (v != NULL) ? v->get_record_field(this->field_idx) : NULL; 847b8e80941Smrg} 848b8e80941Smrg 849b8e80941Smrg 850b8e80941Smrgir_constant * 851b8e80941Smrgir_assignment::constant_expression_value(void *, struct hash_table *) 852b8e80941Smrg{ 853b8e80941Smrg /* FINISHME: Handle CEs involving assignment (return RHS) */ 854b8e80941Smrg return NULL; 855b8e80941Smrg} 856b8e80941Smrg 857b8e80941Smrg 858b8e80941Smrgir_constant * 859b8e80941Smrgir_constant::constant_expression_value(void *, struct hash_table *) 860b8e80941Smrg{ 861b8e80941Smrg return this; 862b8e80941Smrg} 863b8e80941Smrg 864b8e80941Smrg 865b8e80941Smrgir_constant * 866b8e80941Smrgir_call::constant_expression_value(void *mem_ctx, struct hash_table *variable_context) 867b8e80941Smrg{ 868b8e80941Smrg assert(mem_ctx); 869b8e80941Smrg 870b8e80941Smrg return this->callee->constant_expression_value(mem_ctx, 871b8e80941Smrg &this->actual_parameters, 872b8e80941Smrg variable_context); 873b8e80941Smrg} 874b8e80941Smrg 875b8e80941Smrg 876b8e80941Smrgbool ir_function_signature::constant_expression_evaluate_expression_list(void *mem_ctx, 877b8e80941Smrg const struct exec_list &body, 878b8e80941Smrg struct hash_table *variable_context, 879b8e80941Smrg ir_constant **result) 880b8e80941Smrg{ 881b8e80941Smrg assert(mem_ctx); 882b8e80941Smrg 883b8e80941Smrg foreach_in_list(ir_instruction, inst, &body) { 884b8e80941Smrg switch(inst->ir_type) { 885b8e80941Smrg 886b8e80941Smrg /* (declare () type symbol) */ 887b8e80941Smrg case ir_type_variable: { 888b8e80941Smrg ir_variable *var = inst->as_variable(); 889b8e80941Smrg _mesa_hash_table_insert(variable_context, var, ir_constant::zero(this, var->type)); 890b8e80941Smrg break; 891b8e80941Smrg } 892b8e80941Smrg 893b8e80941Smrg /* (assign [condition] (write-mask) (ref) (value)) */ 894b8e80941Smrg case ir_type_assignment: { 895b8e80941Smrg ir_assignment *asg = inst->as_assignment(); 896b8e80941Smrg if (asg->condition) { 897b8e80941Smrg ir_constant *cond = 898b8e80941Smrg asg->condition->constant_expression_value(mem_ctx, 899b8e80941Smrg variable_context); 900b8e80941Smrg if (!cond) 901b8e80941Smrg return false; 902b8e80941Smrg if (!cond->get_bool_component(0)) 903b8e80941Smrg break; 904b8e80941Smrg } 905b8e80941Smrg 906b8e80941Smrg ir_constant *store = NULL; 907b8e80941Smrg int offset = 0; 908b8e80941Smrg 909b8e80941Smrg if (!constant_referenced(asg->lhs, variable_context, store, offset)) 910b8e80941Smrg return false; 911b8e80941Smrg 912b8e80941Smrg ir_constant *value = 913b8e80941Smrg asg->rhs->constant_expression_value(mem_ctx, variable_context); 914b8e80941Smrg 915b8e80941Smrg if (!value) 916b8e80941Smrg return false; 917b8e80941Smrg 918b8e80941Smrg store->copy_masked_offset(value, offset, asg->write_mask); 919b8e80941Smrg break; 920b8e80941Smrg } 921b8e80941Smrg 922b8e80941Smrg /* (return (expression)) */ 923b8e80941Smrg case ir_type_return: 924b8e80941Smrg assert (result); 925b8e80941Smrg *result = 926b8e80941Smrg inst->as_return()->value->constant_expression_value(mem_ctx, 927b8e80941Smrg variable_context); 928b8e80941Smrg return *result != NULL; 929b8e80941Smrg 930b8e80941Smrg /* (call name (ref) (params))*/ 931b8e80941Smrg case ir_type_call: { 932b8e80941Smrg ir_call *call = inst->as_call(); 933b8e80941Smrg 934b8e80941Smrg /* Just say no to void functions in constant expressions. We 935b8e80941Smrg * don't need them at that point. 936b8e80941Smrg */ 937b8e80941Smrg 938b8e80941Smrg if (!call->return_deref) 939b8e80941Smrg return false; 940b8e80941Smrg 941b8e80941Smrg ir_constant *store = NULL; 942b8e80941Smrg int offset = 0; 943b8e80941Smrg 944b8e80941Smrg if (!constant_referenced(call->return_deref, variable_context, 945b8e80941Smrg store, offset)) 946b8e80941Smrg return false; 947b8e80941Smrg 948b8e80941Smrg ir_constant *value = 949b8e80941Smrg call->constant_expression_value(mem_ctx, variable_context); 950b8e80941Smrg 951b8e80941Smrg if(!value) 952b8e80941Smrg return false; 953b8e80941Smrg 954b8e80941Smrg store->copy_offset(value, offset); 955b8e80941Smrg break; 956b8e80941Smrg } 957b8e80941Smrg 958b8e80941Smrg /* (if condition (then-instructions) (else-instructions)) */ 959b8e80941Smrg case ir_type_if: { 960b8e80941Smrg ir_if *iif = inst->as_if(); 961b8e80941Smrg 962b8e80941Smrg ir_constant *cond = 963b8e80941Smrg iif->condition->constant_expression_value(mem_ctx, 964b8e80941Smrg variable_context); 965b8e80941Smrg if (!cond || !cond->type->is_boolean()) 966b8e80941Smrg return false; 967b8e80941Smrg 968b8e80941Smrg exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions; 969b8e80941Smrg 970b8e80941Smrg *result = NULL; 971b8e80941Smrg if (!constant_expression_evaluate_expression_list(mem_ctx, branch, 972b8e80941Smrg variable_context, 973b8e80941Smrg result)) 974b8e80941Smrg return false; 975b8e80941Smrg 976b8e80941Smrg /* If there was a return in the branch chosen, drop out now. */ 977b8e80941Smrg if (*result) 978b8e80941Smrg return true; 979b8e80941Smrg 980b8e80941Smrg break; 981b8e80941Smrg } 982b8e80941Smrg 983b8e80941Smrg /* Every other expression type, we drop out. */ 984b8e80941Smrg default: 985b8e80941Smrg return false; 986b8e80941Smrg } 987b8e80941Smrg } 988b8e80941Smrg 989b8e80941Smrg /* Reaching the end of the block is not an error condition */ 990b8e80941Smrg if (result) 991b8e80941Smrg *result = NULL; 992b8e80941Smrg 993b8e80941Smrg return true; 994b8e80941Smrg} 995b8e80941Smrg 996b8e80941Smrgir_constant * 997b8e80941Smrgir_function_signature::constant_expression_value(void *mem_ctx, 998b8e80941Smrg exec_list *actual_parameters, 999b8e80941Smrg struct hash_table *variable_context) 1000b8e80941Smrg{ 1001b8e80941Smrg assert(mem_ctx); 1002b8e80941Smrg 1003b8e80941Smrg const glsl_type *type = this->return_type; 1004b8e80941Smrg if (type == glsl_type::void_type) 1005b8e80941Smrg return NULL; 1006b8e80941Smrg 1007b8e80941Smrg /* From the GLSL 1.20 spec, page 23: 1008b8e80941Smrg * "Function calls to user-defined functions (non-built-in functions) 1009b8e80941Smrg * cannot be used to form constant expressions." 1010b8e80941Smrg */ 1011b8e80941Smrg if (!this->is_builtin()) 1012b8e80941Smrg return NULL; 1013b8e80941Smrg 1014b8e80941Smrg /* 1015b8e80941Smrg * Of the builtin functions, only the texture lookups and the noise 1016b8e80941Smrg * ones must not be used in constant expressions. They all include 1017b8e80941Smrg * specific opcodes so they don't need to be special-cased at this 1018b8e80941Smrg * point. 1019b8e80941Smrg */ 1020b8e80941Smrg 1021b8e80941Smrg /* Initialize the table of dereferencable names with the function 1022b8e80941Smrg * parameters. Verify their const-ness on the way. 1023b8e80941Smrg * 1024b8e80941Smrg * We expect the correctness of the number of parameters to have 1025b8e80941Smrg * been checked earlier. 1026b8e80941Smrg */ 1027b8e80941Smrg hash_table *deref_hash = _mesa_pointer_hash_table_create(NULL); 1028b8e80941Smrg 1029b8e80941Smrg /* If "origin" is non-NULL, then the function body is there. So we 1030b8e80941Smrg * have to use the variable objects from the object with the body, 1031b8e80941Smrg * but the parameter instanciation on the current object. 1032b8e80941Smrg */ 1033b8e80941Smrg const exec_node *parameter_info = origin ? origin->parameters.get_head_raw() : parameters.get_head_raw(); 1034b8e80941Smrg 1035b8e80941Smrg foreach_in_list(ir_rvalue, n, actual_parameters) { 1036b8e80941Smrg ir_constant *constant = 1037b8e80941Smrg n->constant_expression_value(mem_ctx, variable_context); 1038b8e80941Smrg if (constant == NULL) { 1039b8e80941Smrg _mesa_hash_table_destroy(deref_hash, NULL); 1040b8e80941Smrg return NULL; 1041b8e80941Smrg } 1042b8e80941Smrg 1043b8e80941Smrg 1044b8e80941Smrg ir_variable *var = (ir_variable *)parameter_info; 1045b8e80941Smrg _mesa_hash_table_insert(deref_hash, var, constant); 1046b8e80941Smrg 1047b8e80941Smrg parameter_info = parameter_info->next; 1048b8e80941Smrg } 1049b8e80941Smrg 1050b8e80941Smrg ir_constant *result = NULL; 1051b8e80941Smrg 1052b8e80941Smrg /* Now run the builtin function until something non-constant 1053b8e80941Smrg * happens or we get the result. 1054b8e80941Smrg */ 1055b8e80941Smrg if (constant_expression_evaluate_expression_list(mem_ctx, origin ? origin->body : body, deref_hash, &result) && 1056b8e80941Smrg result) 1057b8e80941Smrg result = result->clone(mem_ctx, NULL); 1058b8e80941Smrg 1059b8e80941Smrg _mesa_hash_table_destroy(deref_hash, NULL); 1060b8e80941Smrg 1061b8e80941Smrg return result; 1062b8e80941Smrg} 1063