ir.cpp revision 01e04c3f
101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2010 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg#include <string.h> 2401e04c3fSmrg#include "ir.h" 2501e04c3fSmrg#include "compiler/glsl_types.h" 2601e04c3fSmrg#include "glsl_parser_extras.h" 2701e04c3fSmrg 2801e04c3fSmrg 2901e04c3fSmrgir_rvalue::ir_rvalue(enum ir_node_type t) 3001e04c3fSmrg : ir_instruction(t) 3101e04c3fSmrg{ 3201e04c3fSmrg this->type = glsl_type::error_type; 3301e04c3fSmrg} 3401e04c3fSmrg 3501e04c3fSmrgbool ir_rvalue::is_zero() const 3601e04c3fSmrg{ 3701e04c3fSmrg return false; 3801e04c3fSmrg} 3901e04c3fSmrg 4001e04c3fSmrgbool ir_rvalue::is_one() const 4101e04c3fSmrg{ 4201e04c3fSmrg return false; 4301e04c3fSmrg} 4401e04c3fSmrg 4501e04c3fSmrgbool ir_rvalue::is_negative_one() const 4601e04c3fSmrg{ 4701e04c3fSmrg return false; 4801e04c3fSmrg} 4901e04c3fSmrg 5001e04c3fSmrg/** 5101e04c3fSmrg * Modify the swizzle make to move one component to another 5201e04c3fSmrg * 5301e04c3fSmrg * \param m IR swizzle to be modified 5401e04c3fSmrg * \param from Component in the RHS that is to be swizzled 5501e04c3fSmrg * \param to Desired swizzle location of \c from 5601e04c3fSmrg */ 5701e04c3fSmrgstatic void 5801e04c3fSmrgupdate_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to) 5901e04c3fSmrg{ 6001e04c3fSmrg switch (to) { 6101e04c3fSmrg case 0: m.x = from; break; 6201e04c3fSmrg case 1: m.y = from; break; 6301e04c3fSmrg case 2: m.z = from; break; 6401e04c3fSmrg case 3: m.w = from; break; 6501e04c3fSmrg default: assert(!"Should not get here."); 6601e04c3fSmrg } 6701e04c3fSmrg} 6801e04c3fSmrg 6901e04c3fSmrgvoid 7001e04c3fSmrgir_assignment::set_lhs(ir_rvalue *lhs) 7101e04c3fSmrg{ 7201e04c3fSmrg void *mem_ctx = this; 7301e04c3fSmrg bool swizzled = false; 7401e04c3fSmrg 7501e04c3fSmrg while (lhs != NULL) { 7601e04c3fSmrg ir_swizzle *swiz = lhs->as_swizzle(); 7701e04c3fSmrg 7801e04c3fSmrg if (swiz == NULL) 7901e04c3fSmrg break; 8001e04c3fSmrg 8101e04c3fSmrg unsigned write_mask = 0; 8201e04c3fSmrg ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 }; 8301e04c3fSmrg 8401e04c3fSmrg for (unsigned i = 0; i < swiz->mask.num_components; i++) { 8501e04c3fSmrg unsigned c = 0; 8601e04c3fSmrg 8701e04c3fSmrg switch (i) { 8801e04c3fSmrg case 0: c = swiz->mask.x; break; 8901e04c3fSmrg case 1: c = swiz->mask.y; break; 9001e04c3fSmrg case 2: c = swiz->mask.z; break; 9101e04c3fSmrg case 3: c = swiz->mask.w; break; 9201e04c3fSmrg default: assert(!"Should not get here."); 9301e04c3fSmrg } 9401e04c3fSmrg 9501e04c3fSmrg write_mask |= (((this->write_mask >> i) & 1) << c); 9601e04c3fSmrg update_rhs_swizzle(rhs_swiz, i, c); 9701e04c3fSmrg rhs_swiz.num_components = swiz->val->type->vector_elements; 9801e04c3fSmrg } 9901e04c3fSmrg 10001e04c3fSmrg this->write_mask = write_mask; 10101e04c3fSmrg lhs = swiz->val; 10201e04c3fSmrg 10301e04c3fSmrg this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz); 10401e04c3fSmrg swizzled = true; 10501e04c3fSmrg } 10601e04c3fSmrg 10701e04c3fSmrg if (swizzled) { 10801e04c3fSmrg /* Now, RHS channels line up with the LHS writemask. Collapse it 10901e04c3fSmrg * to just the channels that will be written. 11001e04c3fSmrg */ 11101e04c3fSmrg ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 }; 11201e04c3fSmrg int rhs_chan = 0; 11301e04c3fSmrg for (int i = 0; i < 4; i++) { 11401e04c3fSmrg if (write_mask & (1 << i)) 11501e04c3fSmrg update_rhs_swizzle(rhs_swiz, i, rhs_chan++); 11601e04c3fSmrg } 11701e04c3fSmrg rhs_swiz.num_components = rhs_chan; 11801e04c3fSmrg this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz); 11901e04c3fSmrg } 12001e04c3fSmrg 12101e04c3fSmrg assert((lhs == NULL) || lhs->as_dereference()); 12201e04c3fSmrg 12301e04c3fSmrg this->lhs = (ir_dereference *) lhs; 12401e04c3fSmrg} 12501e04c3fSmrg 12601e04c3fSmrgir_variable * 12701e04c3fSmrgir_assignment::whole_variable_written() 12801e04c3fSmrg{ 12901e04c3fSmrg ir_variable *v = this->lhs->whole_variable_referenced(); 13001e04c3fSmrg 13101e04c3fSmrg if (v == NULL) 13201e04c3fSmrg return NULL; 13301e04c3fSmrg 13401e04c3fSmrg if (v->type->is_scalar()) 13501e04c3fSmrg return v; 13601e04c3fSmrg 13701e04c3fSmrg if (v->type->is_vector()) { 13801e04c3fSmrg const unsigned mask = (1U << v->type->vector_elements) - 1; 13901e04c3fSmrg 14001e04c3fSmrg if (mask != this->write_mask) 14101e04c3fSmrg return NULL; 14201e04c3fSmrg } 14301e04c3fSmrg 14401e04c3fSmrg /* Either all the vector components are assigned or the variable is some 14501e04c3fSmrg * composite type (and the whole thing is assigned. 14601e04c3fSmrg */ 14701e04c3fSmrg return v; 14801e04c3fSmrg} 14901e04c3fSmrg 15001e04c3fSmrgir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, 15101e04c3fSmrg ir_rvalue *condition, unsigned write_mask) 15201e04c3fSmrg : ir_instruction(ir_type_assignment) 15301e04c3fSmrg{ 15401e04c3fSmrg this->condition = condition; 15501e04c3fSmrg this->rhs = rhs; 15601e04c3fSmrg this->lhs = lhs; 15701e04c3fSmrg this->write_mask = write_mask; 15801e04c3fSmrg 15901e04c3fSmrg if (lhs->type->is_scalar() || lhs->type->is_vector()) { 16001e04c3fSmrg int lhs_components = 0; 16101e04c3fSmrg for (int i = 0; i < 4; i++) { 16201e04c3fSmrg if (write_mask & (1 << i)) 16301e04c3fSmrg lhs_components++; 16401e04c3fSmrg } 16501e04c3fSmrg 16601e04c3fSmrg assert(lhs_components == this->rhs->type->vector_elements); 16701e04c3fSmrg } 16801e04c3fSmrg} 16901e04c3fSmrg 17001e04c3fSmrgir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, 17101e04c3fSmrg ir_rvalue *condition) 17201e04c3fSmrg : ir_instruction(ir_type_assignment) 17301e04c3fSmrg{ 17401e04c3fSmrg this->condition = condition; 17501e04c3fSmrg this->rhs = rhs; 17601e04c3fSmrg 17701e04c3fSmrg /* If the RHS is a vector type, assume that all components of the vector 17801e04c3fSmrg * type are being written to the LHS. The write mask comes from the RHS 17901e04c3fSmrg * because we can have a case where the LHS is a vec4 and the RHS is a 18001e04c3fSmrg * vec3. In that case, the assignment is: 18101e04c3fSmrg * 18201e04c3fSmrg * (assign (...) (xyz) (var_ref lhs) (var_ref rhs)) 18301e04c3fSmrg */ 18401e04c3fSmrg if (rhs->type->is_vector()) 18501e04c3fSmrg this->write_mask = (1U << rhs->type->vector_elements) - 1; 18601e04c3fSmrg else if (rhs->type->is_scalar()) 18701e04c3fSmrg this->write_mask = 1; 18801e04c3fSmrg else 18901e04c3fSmrg this->write_mask = 0; 19001e04c3fSmrg 19101e04c3fSmrg this->set_lhs(lhs); 19201e04c3fSmrg} 19301e04c3fSmrg 19401e04c3fSmrgir_expression::ir_expression(int op, const struct glsl_type *type, 19501e04c3fSmrg ir_rvalue *op0, ir_rvalue *op1, 19601e04c3fSmrg ir_rvalue *op2, ir_rvalue *op3) 19701e04c3fSmrg : ir_rvalue(ir_type_expression) 19801e04c3fSmrg{ 19901e04c3fSmrg this->type = type; 20001e04c3fSmrg this->operation = ir_expression_operation(op); 20101e04c3fSmrg this->operands[0] = op0; 20201e04c3fSmrg this->operands[1] = op1; 20301e04c3fSmrg this->operands[2] = op2; 20401e04c3fSmrg this->operands[3] = op3; 20501e04c3fSmrg init_num_operands(); 20601e04c3fSmrg 20701e04c3fSmrg#ifndef NDEBUG 20801e04c3fSmrg for (unsigned i = num_operands; i < 4; i++) { 20901e04c3fSmrg assert(this->operands[i] == NULL); 21001e04c3fSmrg } 21101e04c3fSmrg 21201e04c3fSmrg for (unsigned i = 0; i < num_operands; i++) { 21301e04c3fSmrg assert(this->operands[i] != NULL); 21401e04c3fSmrg } 21501e04c3fSmrg#endif 21601e04c3fSmrg} 21701e04c3fSmrg 21801e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0) 21901e04c3fSmrg : ir_rvalue(ir_type_expression) 22001e04c3fSmrg{ 22101e04c3fSmrg this->operation = ir_expression_operation(op); 22201e04c3fSmrg this->operands[0] = op0; 22301e04c3fSmrg this->operands[1] = NULL; 22401e04c3fSmrg this->operands[2] = NULL; 22501e04c3fSmrg this->operands[3] = NULL; 22601e04c3fSmrg 22701e04c3fSmrg assert(op <= ir_last_unop); 22801e04c3fSmrg init_num_operands(); 22901e04c3fSmrg assert(num_operands == 1); 23001e04c3fSmrg assert(this->operands[0]); 23101e04c3fSmrg 23201e04c3fSmrg switch (this->operation) { 23301e04c3fSmrg case ir_unop_bit_not: 23401e04c3fSmrg case ir_unop_logic_not: 23501e04c3fSmrg case ir_unop_neg: 23601e04c3fSmrg case ir_unop_abs: 23701e04c3fSmrg case ir_unop_sign: 23801e04c3fSmrg case ir_unop_rcp: 23901e04c3fSmrg case ir_unop_rsq: 24001e04c3fSmrg case ir_unop_sqrt: 24101e04c3fSmrg case ir_unop_exp: 24201e04c3fSmrg case ir_unop_log: 24301e04c3fSmrg case ir_unop_exp2: 24401e04c3fSmrg case ir_unop_log2: 24501e04c3fSmrg case ir_unop_trunc: 24601e04c3fSmrg case ir_unop_ceil: 24701e04c3fSmrg case ir_unop_floor: 24801e04c3fSmrg case ir_unop_fract: 24901e04c3fSmrg case ir_unop_round_even: 25001e04c3fSmrg case ir_unop_sin: 25101e04c3fSmrg case ir_unop_cos: 25201e04c3fSmrg case ir_unop_dFdx: 25301e04c3fSmrg case ir_unop_dFdx_coarse: 25401e04c3fSmrg case ir_unop_dFdx_fine: 25501e04c3fSmrg case ir_unop_dFdy: 25601e04c3fSmrg case ir_unop_dFdy_coarse: 25701e04c3fSmrg case ir_unop_dFdy_fine: 25801e04c3fSmrg case ir_unop_bitfield_reverse: 25901e04c3fSmrg case ir_unop_interpolate_at_centroid: 26001e04c3fSmrg case ir_unop_saturate: 26101e04c3fSmrg this->type = op0->type; 26201e04c3fSmrg break; 26301e04c3fSmrg 26401e04c3fSmrg case ir_unop_f2i: 26501e04c3fSmrg case ir_unop_b2i: 26601e04c3fSmrg case ir_unop_u2i: 26701e04c3fSmrg case ir_unop_d2i: 26801e04c3fSmrg case ir_unop_bitcast_f2i: 26901e04c3fSmrg case ir_unop_bit_count: 27001e04c3fSmrg case ir_unop_find_msb: 27101e04c3fSmrg case ir_unop_find_lsb: 27201e04c3fSmrg case ir_unop_subroutine_to_int: 27301e04c3fSmrg case ir_unop_i642i: 27401e04c3fSmrg case ir_unop_u642i: 27501e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_INT, 27601e04c3fSmrg op0->type->vector_elements, 1); 27701e04c3fSmrg break; 27801e04c3fSmrg 27901e04c3fSmrg case ir_unop_b2f: 28001e04c3fSmrg case ir_unop_i2f: 28101e04c3fSmrg case ir_unop_u2f: 28201e04c3fSmrg case ir_unop_d2f: 28301e04c3fSmrg case ir_unop_bitcast_i2f: 28401e04c3fSmrg case ir_unop_bitcast_u2f: 28501e04c3fSmrg case ir_unop_i642f: 28601e04c3fSmrg case ir_unop_u642f: 28701e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 28801e04c3fSmrg op0->type->vector_elements, 1); 28901e04c3fSmrg break; 29001e04c3fSmrg 29101e04c3fSmrg case ir_unop_f2b: 29201e04c3fSmrg case ir_unop_i2b: 29301e04c3fSmrg case ir_unop_d2b: 29401e04c3fSmrg case ir_unop_i642b: 29501e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, 29601e04c3fSmrg op0->type->vector_elements, 1); 29701e04c3fSmrg break; 29801e04c3fSmrg 29901e04c3fSmrg case ir_unop_f2d: 30001e04c3fSmrg case ir_unop_i2d: 30101e04c3fSmrg case ir_unop_u2d: 30201e04c3fSmrg case ir_unop_i642d: 30301e04c3fSmrg case ir_unop_u642d: 30401e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, 30501e04c3fSmrg op0->type->vector_elements, 1); 30601e04c3fSmrg break; 30701e04c3fSmrg 30801e04c3fSmrg case ir_unop_i2u: 30901e04c3fSmrg case ir_unop_f2u: 31001e04c3fSmrg case ir_unop_d2u: 31101e04c3fSmrg case ir_unop_bitcast_f2u: 31201e04c3fSmrg case ir_unop_i642u: 31301e04c3fSmrg case ir_unop_u642u: 31401e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT, 31501e04c3fSmrg op0->type->vector_elements, 1); 31601e04c3fSmrg break; 31701e04c3fSmrg 31801e04c3fSmrg case ir_unop_i2i64: 31901e04c3fSmrg case ir_unop_u2i64: 32001e04c3fSmrg case ir_unop_b2i64: 32101e04c3fSmrg case ir_unop_f2i64: 32201e04c3fSmrg case ir_unop_d2i64: 32301e04c3fSmrg case ir_unop_u642i64: 32401e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_INT64, 32501e04c3fSmrg op0->type->vector_elements, 1); 32601e04c3fSmrg break; 32701e04c3fSmrg 32801e04c3fSmrg case ir_unop_i2u64: 32901e04c3fSmrg case ir_unop_u2u64: 33001e04c3fSmrg case ir_unop_f2u64: 33101e04c3fSmrg case ir_unop_d2u64: 33201e04c3fSmrg case ir_unop_i642u64: 33301e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, 33401e04c3fSmrg op0->type->vector_elements, 1); 33501e04c3fSmrg break; 33601e04c3fSmrg case ir_unop_noise: 33701e04c3fSmrg this->type = glsl_type::float_type; 33801e04c3fSmrg break; 33901e04c3fSmrg 34001e04c3fSmrg case ir_unop_unpack_double_2x32: 34101e04c3fSmrg case ir_unop_unpack_uint_2x32: 34201e04c3fSmrg this->type = glsl_type::uvec2_type; 34301e04c3fSmrg break; 34401e04c3fSmrg 34501e04c3fSmrg case ir_unop_unpack_int_2x32: 34601e04c3fSmrg this->type = glsl_type::ivec2_type; 34701e04c3fSmrg break; 34801e04c3fSmrg 34901e04c3fSmrg case ir_unop_pack_snorm_2x16: 35001e04c3fSmrg case ir_unop_pack_snorm_4x8: 35101e04c3fSmrg case ir_unop_pack_unorm_2x16: 35201e04c3fSmrg case ir_unop_pack_unorm_4x8: 35301e04c3fSmrg case ir_unop_pack_half_2x16: 35401e04c3fSmrg this->type = glsl_type::uint_type; 35501e04c3fSmrg break; 35601e04c3fSmrg 35701e04c3fSmrg case ir_unop_pack_double_2x32: 35801e04c3fSmrg this->type = glsl_type::double_type; 35901e04c3fSmrg break; 36001e04c3fSmrg 36101e04c3fSmrg case ir_unop_pack_int_2x32: 36201e04c3fSmrg this->type = glsl_type::int64_t_type; 36301e04c3fSmrg break; 36401e04c3fSmrg 36501e04c3fSmrg case ir_unop_pack_uint_2x32: 36601e04c3fSmrg this->type = glsl_type::uint64_t_type; 36701e04c3fSmrg break; 36801e04c3fSmrg 36901e04c3fSmrg case ir_unop_unpack_snorm_2x16: 37001e04c3fSmrg case ir_unop_unpack_unorm_2x16: 37101e04c3fSmrg case ir_unop_unpack_half_2x16: 37201e04c3fSmrg this->type = glsl_type::vec2_type; 37301e04c3fSmrg break; 37401e04c3fSmrg 37501e04c3fSmrg case ir_unop_unpack_snorm_4x8: 37601e04c3fSmrg case ir_unop_unpack_unorm_4x8: 37701e04c3fSmrg this->type = glsl_type::vec4_type; 37801e04c3fSmrg break; 37901e04c3fSmrg 38001e04c3fSmrg case ir_unop_unpack_sampler_2x32: 38101e04c3fSmrg case ir_unop_unpack_image_2x32: 38201e04c3fSmrg this->type = glsl_type::uvec2_type; 38301e04c3fSmrg break; 38401e04c3fSmrg 38501e04c3fSmrg case ir_unop_pack_sampler_2x32: 38601e04c3fSmrg case ir_unop_pack_image_2x32: 38701e04c3fSmrg this->type = op0->type; 38801e04c3fSmrg break; 38901e04c3fSmrg 39001e04c3fSmrg case ir_unop_frexp_sig: 39101e04c3fSmrg this->type = op0->type; 39201e04c3fSmrg break; 39301e04c3fSmrg case ir_unop_frexp_exp: 39401e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_INT, 39501e04c3fSmrg op0->type->vector_elements, 1); 39601e04c3fSmrg break; 39701e04c3fSmrg 39801e04c3fSmrg case ir_unop_get_buffer_size: 39901e04c3fSmrg case ir_unop_ssbo_unsized_array_length: 40001e04c3fSmrg this->type = glsl_type::int_type; 40101e04c3fSmrg break; 40201e04c3fSmrg 40301e04c3fSmrg case ir_unop_bitcast_i642d: 40401e04c3fSmrg case ir_unop_bitcast_u642d: 40501e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, 40601e04c3fSmrg op0->type->vector_elements, 1); 40701e04c3fSmrg break; 40801e04c3fSmrg 40901e04c3fSmrg case ir_unop_bitcast_d2i64: 41001e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_INT64, 41101e04c3fSmrg op0->type->vector_elements, 1); 41201e04c3fSmrg break; 41301e04c3fSmrg case ir_unop_bitcast_d2u64: 41401e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, 41501e04c3fSmrg op0->type->vector_elements, 1); 41601e04c3fSmrg break; 41701e04c3fSmrg 41801e04c3fSmrg default: 41901e04c3fSmrg assert(!"not reached: missing automatic type setup for ir_expression"); 42001e04c3fSmrg this->type = op0->type; 42101e04c3fSmrg break; 42201e04c3fSmrg } 42301e04c3fSmrg} 42401e04c3fSmrg 42501e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) 42601e04c3fSmrg : ir_rvalue(ir_type_expression) 42701e04c3fSmrg{ 42801e04c3fSmrg this->operation = ir_expression_operation(op); 42901e04c3fSmrg this->operands[0] = op0; 43001e04c3fSmrg this->operands[1] = op1; 43101e04c3fSmrg this->operands[2] = NULL; 43201e04c3fSmrg this->operands[3] = NULL; 43301e04c3fSmrg 43401e04c3fSmrg assert(op > ir_last_unop); 43501e04c3fSmrg init_num_operands(); 43601e04c3fSmrg assert(num_operands == 2); 43701e04c3fSmrg for (unsigned i = 0; i < num_operands; i++) { 43801e04c3fSmrg assert(this->operands[i] != NULL); 43901e04c3fSmrg } 44001e04c3fSmrg 44101e04c3fSmrg switch (this->operation) { 44201e04c3fSmrg case ir_binop_all_equal: 44301e04c3fSmrg case ir_binop_any_nequal: 44401e04c3fSmrg this->type = glsl_type::bool_type; 44501e04c3fSmrg break; 44601e04c3fSmrg 44701e04c3fSmrg case ir_binop_add: 44801e04c3fSmrg case ir_binop_sub: 44901e04c3fSmrg case ir_binop_min: 45001e04c3fSmrg case ir_binop_max: 45101e04c3fSmrg case ir_binop_pow: 45201e04c3fSmrg case ir_binop_mul: 45301e04c3fSmrg case ir_binop_div: 45401e04c3fSmrg case ir_binop_mod: 45501e04c3fSmrg if (op0->type->is_scalar()) { 45601e04c3fSmrg this->type = op1->type; 45701e04c3fSmrg } else if (op1->type->is_scalar()) { 45801e04c3fSmrg this->type = op0->type; 45901e04c3fSmrg } else { 46001e04c3fSmrg if (this->operation == ir_binop_mul) { 46101e04c3fSmrg this->type = glsl_type::get_mul_type(op0->type, op1->type); 46201e04c3fSmrg } else { 46301e04c3fSmrg assert(op0->type == op1->type); 46401e04c3fSmrg this->type = op0->type; 46501e04c3fSmrg } 46601e04c3fSmrg } 46701e04c3fSmrg break; 46801e04c3fSmrg 46901e04c3fSmrg case ir_binop_logic_and: 47001e04c3fSmrg case ir_binop_logic_xor: 47101e04c3fSmrg case ir_binop_logic_or: 47201e04c3fSmrg case ir_binop_bit_and: 47301e04c3fSmrg case ir_binop_bit_xor: 47401e04c3fSmrg case ir_binop_bit_or: 47501e04c3fSmrg assert(!op0->type->is_matrix()); 47601e04c3fSmrg assert(!op1->type->is_matrix()); 47701e04c3fSmrg if (op0->type->is_scalar()) { 47801e04c3fSmrg this->type = op1->type; 47901e04c3fSmrg } else if (op1->type->is_scalar()) { 48001e04c3fSmrg this->type = op0->type; 48101e04c3fSmrg } else { 48201e04c3fSmrg assert(op0->type->vector_elements == op1->type->vector_elements); 48301e04c3fSmrg this->type = op0->type; 48401e04c3fSmrg } 48501e04c3fSmrg break; 48601e04c3fSmrg 48701e04c3fSmrg case ir_binop_equal: 48801e04c3fSmrg case ir_binop_nequal: 48901e04c3fSmrg case ir_binop_gequal: 49001e04c3fSmrg case ir_binop_less: 49101e04c3fSmrg assert(op0->type == op1->type); 49201e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, 49301e04c3fSmrg op0->type->vector_elements, 1); 49401e04c3fSmrg break; 49501e04c3fSmrg 49601e04c3fSmrg case ir_binop_dot: 49701e04c3fSmrg this->type = op0->type->get_base_type(); 49801e04c3fSmrg break; 49901e04c3fSmrg 50001e04c3fSmrg case ir_binop_imul_high: 50101e04c3fSmrg case ir_binop_carry: 50201e04c3fSmrg case ir_binop_borrow: 50301e04c3fSmrg case ir_binop_lshift: 50401e04c3fSmrg case ir_binop_rshift: 50501e04c3fSmrg case ir_binop_ldexp: 50601e04c3fSmrg case ir_binop_interpolate_at_offset: 50701e04c3fSmrg case ir_binop_interpolate_at_sample: 50801e04c3fSmrg this->type = op0->type; 50901e04c3fSmrg break; 51001e04c3fSmrg 51101e04c3fSmrg case ir_binop_vector_extract: 51201e04c3fSmrg this->type = op0->type->get_scalar_type(); 51301e04c3fSmrg break; 51401e04c3fSmrg 51501e04c3fSmrg default: 51601e04c3fSmrg assert(!"not reached: missing automatic type setup for ir_expression"); 51701e04c3fSmrg this->type = glsl_type::float_type; 51801e04c3fSmrg } 51901e04c3fSmrg} 52001e04c3fSmrg 52101e04c3fSmrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, 52201e04c3fSmrg ir_rvalue *op2) 52301e04c3fSmrg : ir_rvalue(ir_type_expression) 52401e04c3fSmrg{ 52501e04c3fSmrg this->operation = ir_expression_operation(op); 52601e04c3fSmrg this->operands[0] = op0; 52701e04c3fSmrg this->operands[1] = op1; 52801e04c3fSmrg this->operands[2] = op2; 52901e04c3fSmrg this->operands[3] = NULL; 53001e04c3fSmrg 53101e04c3fSmrg assert(op > ir_last_binop && op <= ir_last_triop); 53201e04c3fSmrg init_num_operands(); 53301e04c3fSmrg assert(num_operands == 3); 53401e04c3fSmrg for (unsigned i = 0; i < num_operands; i++) { 53501e04c3fSmrg assert(this->operands[i] != NULL); 53601e04c3fSmrg } 53701e04c3fSmrg 53801e04c3fSmrg switch (this->operation) { 53901e04c3fSmrg case ir_triop_fma: 54001e04c3fSmrg case ir_triop_lrp: 54101e04c3fSmrg case ir_triop_bitfield_extract: 54201e04c3fSmrg case ir_triop_vector_insert: 54301e04c3fSmrg this->type = op0->type; 54401e04c3fSmrg break; 54501e04c3fSmrg 54601e04c3fSmrg case ir_triop_csel: 54701e04c3fSmrg this->type = op1->type; 54801e04c3fSmrg break; 54901e04c3fSmrg 55001e04c3fSmrg default: 55101e04c3fSmrg assert(!"not reached: missing automatic type setup for ir_expression"); 55201e04c3fSmrg this->type = glsl_type::float_type; 55301e04c3fSmrg } 55401e04c3fSmrg} 55501e04c3fSmrg 55601e04c3fSmrg/** 55701e04c3fSmrg * This is only here for ir_reader to used for testing purposes. Please use 55801e04c3fSmrg * the precomputed num_operands field if you need the number of operands. 55901e04c3fSmrg */ 56001e04c3fSmrgunsigned 56101e04c3fSmrgir_expression::get_num_operands(ir_expression_operation op) 56201e04c3fSmrg{ 56301e04c3fSmrg assert(op <= ir_last_opcode); 56401e04c3fSmrg 56501e04c3fSmrg if (op <= ir_last_unop) 56601e04c3fSmrg return 1; 56701e04c3fSmrg 56801e04c3fSmrg if (op <= ir_last_binop) 56901e04c3fSmrg return 2; 57001e04c3fSmrg 57101e04c3fSmrg if (op <= ir_last_triop) 57201e04c3fSmrg return 3; 57301e04c3fSmrg 57401e04c3fSmrg if (op <= ir_last_quadop) 57501e04c3fSmrg return 4; 57601e04c3fSmrg 57701e04c3fSmrg unreachable("Could not calculate number of operands"); 57801e04c3fSmrg} 57901e04c3fSmrg 58001e04c3fSmrg#include "ir_expression_operation_strings.h" 58101e04c3fSmrg 58201e04c3fSmrgconst char* 58301e04c3fSmrgdepth_layout_string(ir_depth_layout layout) 58401e04c3fSmrg{ 58501e04c3fSmrg switch(layout) { 58601e04c3fSmrg case ir_depth_layout_none: return ""; 58701e04c3fSmrg case ir_depth_layout_any: return "depth_any"; 58801e04c3fSmrg case ir_depth_layout_greater: return "depth_greater"; 58901e04c3fSmrg case ir_depth_layout_less: return "depth_less"; 59001e04c3fSmrg case ir_depth_layout_unchanged: return "depth_unchanged"; 59101e04c3fSmrg 59201e04c3fSmrg default: 59301e04c3fSmrg assert(0); 59401e04c3fSmrg return ""; 59501e04c3fSmrg } 59601e04c3fSmrg} 59701e04c3fSmrg 59801e04c3fSmrgir_expression_operation 59901e04c3fSmrgir_expression::get_operator(const char *str) 60001e04c3fSmrg{ 60101e04c3fSmrg for (int op = 0; op <= int(ir_last_opcode); op++) { 60201e04c3fSmrg if (strcmp(str, ir_expression_operation_strings[op]) == 0) 60301e04c3fSmrg return (ir_expression_operation) op; 60401e04c3fSmrg } 60501e04c3fSmrg return (ir_expression_operation) -1; 60601e04c3fSmrg} 60701e04c3fSmrg 60801e04c3fSmrgir_variable * 60901e04c3fSmrgir_expression::variable_referenced() const 61001e04c3fSmrg{ 61101e04c3fSmrg switch (operation) { 61201e04c3fSmrg case ir_binop_vector_extract: 61301e04c3fSmrg case ir_triop_vector_insert: 61401e04c3fSmrg /* We get these for things like a[0] where a is a vector type. In these 61501e04c3fSmrg * cases we want variable_referenced() to return the actual vector 61601e04c3fSmrg * variable this is wrapping. 61701e04c3fSmrg */ 61801e04c3fSmrg return operands[0]->variable_referenced(); 61901e04c3fSmrg default: 62001e04c3fSmrg return ir_rvalue::variable_referenced(); 62101e04c3fSmrg } 62201e04c3fSmrg} 62301e04c3fSmrg 62401e04c3fSmrgir_constant::ir_constant() 62501e04c3fSmrg : ir_rvalue(ir_type_constant) 62601e04c3fSmrg{ 62701e04c3fSmrg this->const_elements = NULL; 62801e04c3fSmrg} 62901e04c3fSmrg 63001e04c3fSmrgir_constant::ir_constant(const struct glsl_type *type, 63101e04c3fSmrg const ir_constant_data *data) 63201e04c3fSmrg : ir_rvalue(ir_type_constant) 63301e04c3fSmrg{ 63401e04c3fSmrg this->const_elements = NULL; 63501e04c3fSmrg 63601e04c3fSmrg assert((type->base_type >= GLSL_TYPE_UINT) 63701e04c3fSmrg && (type->base_type <= GLSL_TYPE_IMAGE)); 63801e04c3fSmrg 63901e04c3fSmrg this->type = type; 64001e04c3fSmrg memcpy(& this->value, data, sizeof(this->value)); 64101e04c3fSmrg} 64201e04c3fSmrg 64301e04c3fSmrgir_constant::ir_constant(float f, unsigned vector_elements) 64401e04c3fSmrg : ir_rvalue(ir_type_constant) 64501e04c3fSmrg{ 64601e04c3fSmrg assert(vector_elements <= 4); 64701e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, vector_elements, 1); 64801e04c3fSmrg for (unsigned i = 0; i < vector_elements; i++) { 64901e04c3fSmrg this->value.f[i] = f; 65001e04c3fSmrg } 65101e04c3fSmrg for (unsigned i = vector_elements; i < 16; i++) { 65201e04c3fSmrg this->value.f[i] = 0; 65301e04c3fSmrg } 65401e04c3fSmrg} 65501e04c3fSmrg 65601e04c3fSmrgir_constant::ir_constant(double d, unsigned vector_elements) 65701e04c3fSmrg : ir_rvalue(ir_type_constant) 65801e04c3fSmrg{ 65901e04c3fSmrg assert(vector_elements <= 4); 66001e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, vector_elements, 1); 66101e04c3fSmrg for (unsigned i = 0; i < vector_elements; i++) { 66201e04c3fSmrg this->value.d[i] = d; 66301e04c3fSmrg } 66401e04c3fSmrg for (unsigned i = vector_elements; i < 16; i++) { 66501e04c3fSmrg this->value.d[i] = 0.0; 66601e04c3fSmrg } 66701e04c3fSmrg} 66801e04c3fSmrg 66901e04c3fSmrgir_constant::ir_constant(unsigned int u, unsigned vector_elements) 67001e04c3fSmrg : ir_rvalue(ir_type_constant) 67101e04c3fSmrg{ 67201e04c3fSmrg assert(vector_elements <= 4); 67301e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT, vector_elements, 1); 67401e04c3fSmrg for (unsigned i = 0; i < vector_elements; i++) { 67501e04c3fSmrg this->value.u[i] = u; 67601e04c3fSmrg } 67701e04c3fSmrg for (unsigned i = vector_elements; i < 16; i++) { 67801e04c3fSmrg this->value.u[i] = 0; 67901e04c3fSmrg } 68001e04c3fSmrg} 68101e04c3fSmrg 68201e04c3fSmrgir_constant::ir_constant(int integer, unsigned vector_elements) 68301e04c3fSmrg : ir_rvalue(ir_type_constant) 68401e04c3fSmrg{ 68501e04c3fSmrg assert(vector_elements <= 4); 68601e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_INT, vector_elements, 1); 68701e04c3fSmrg for (unsigned i = 0; i < vector_elements; i++) { 68801e04c3fSmrg this->value.i[i] = integer; 68901e04c3fSmrg } 69001e04c3fSmrg for (unsigned i = vector_elements; i < 16; i++) { 69101e04c3fSmrg this->value.i[i] = 0; 69201e04c3fSmrg } 69301e04c3fSmrg} 69401e04c3fSmrg 69501e04c3fSmrgir_constant::ir_constant(uint64_t u64, unsigned vector_elements) 69601e04c3fSmrg : ir_rvalue(ir_type_constant) 69701e04c3fSmrg{ 69801e04c3fSmrg assert(vector_elements <= 4); 69901e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1); 70001e04c3fSmrg for (unsigned i = 0; i < vector_elements; i++) { 70101e04c3fSmrg this->value.u64[i] = u64; 70201e04c3fSmrg } 70301e04c3fSmrg for (unsigned i = vector_elements; i < 16; i++) { 70401e04c3fSmrg this->value.u64[i] = 0; 70501e04c3fSmrg } 70601e04c3fSmrg} 70701e04c3fSmrg 70801e04c3fSmrgir_constant::ir_constant(int64_t int64, unsigned vector_elements) 70901e04c3fSmrg : ir_rvalue(ir_type_constant) 71001e04c3fSmrg{ 71101e04c3fSmrg assert(vector_elements <= 4); 71201e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1); 71301e04c3fSmrg for (unsigned i = 0; i < vector_elements; i++) { 71401e04c3fSmrg this->value.i64[i] = int64; 71501e04c3fSmrg } 71601e04c3fSmrg for (unsigned i = vector_elements; i < 16; i++) { 71701e04c3fSmrg this->value.i64[i] = 0; 71801e04c3fSmrg } 71901e04c3fSmrg} 72001e04c3fSmrg 72101e04c3fSmrgir_constant::ir_constant(bool b, unsigned vector_elements) 72201e04c3fSmrg : ir_rvalue(ir_type_constant) 72301e04c3fSmrg{ 72401e04c3fSmrg assert(vector_elements <= 4); 72501e04c3fSmrg this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, vector_elements, 1); 72601e04c3fSmrg for (unsigned i = 0; i < vector_elements; i++) { 72701e04c3fSmrg this->value.b[i] = b; 72801e04c3fSmrg } 72901e04c3fSmrg for (unsigned i = vector_elements; i < 16; i++) { 73001e04c3fSmrg this->value.b[i] = false; 73101e04c3fSmrg } 73201e04c3fSmrg} 73301e04c3fSmrg 73401e04c3fSmrgir_constant::ir_constant(const ir_constant *c, unsigned i) 73501e04c3fSmrg : ir_rvalue(ir_type_constant) 73601e04c3fSmrg{ 73701e04c3fSmrg this->const_elements = NULL; 73801e04c3fSmrg this->type = c->type->get_base_type(); 73901e04c3fSmrg 74001e04c3fSmrg switch (this->type->base_type) { 74101e04c3fSmrg case GLSL_TYPE_UINT: this->value.u[0] = c->value.u[i]; break; 74201e04c3fSmrg case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break; 74301e04c3fSmrg case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break; 74401e04c3fSmrg case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break; 74501e04c3fSmrg case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break; 74601e04c3fSmrg default: assert(!"Should not get here."); break; 74701e04c3fSmrg } 74801e04c3fSmrg} 74901e04c3fSmrg 75001e04c3fSmrgir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) 75101e04c3fSmrg : ir_rvalue(ir_type_constant) 75201e04c3fSmrg{ 75301e04c3fSmrg this->const_elements = NULL; 75401e04c3fSmrg this->type = type; 75501e04c3fSmrg 75601e04c3fSmrg assert(type->is_scalar() || type->is_vector() || type->is_matrix() 75701e04c3fSmrg || type->is_record() || type->is_array()); 75801e04c3fSmrg 75901e04c3fSmrg /* If the constant is a record, the types of each of the entries in 76001e04c3fSmrg * value_list must be a 1-for-1 match with the structure components. Each 76101e04c3fSmrg * entry must also be a constant. Just move the nodes from the value_list 76201e04c3fSmrg * to the list in the ir_constant. 76301e04c3fSmrg */ 76401e04c3fSmrg if (type->is_array() || type->is_record()) { 76501e04c3fSmrg this->const_elements = ralloc_array(this, ir_constant *, type->length); 76601e04c3fSmrg unsigned i = 0; 76701e04c3fSmrg foreach_in_list(ir_constant, value, value_list) { 76801e04c3fSmrg assert(value->as_constant() != NULL); 76901e04c3fSmrg 77001e04c3fSmrg this->const_elements[i++] = value; 77101e04c3fSmrg } 77201e04c3fSmrg return; 77301e04c3fSmrg } 77401e04c3fSmrg 77501e04c3fSmrg for (unsigned i = 0; i < 16; i++) { 77601e04c3fSmrg this->value.u[i] = 0; 77701e04c3fSmrg } 77801e04c3fSmrg 77901e04c3fSmrg ir_constant *value = (ir_constant *) (value_list->get_head_raw()); 78001e04c3fSmrg 78101e04c3fSmrg /* Constructors with exactly one scalar argument are special for vectors 78201e04c3fSmrg * and matrices. For vectors, the scalar value is replicated to fill all 78301e04c3fSmrg * the components. For matrices, the scalar fills the components of the 78401e04c3fSmrg * diagonal while the rest is filled with 0. 78501e04c3fSmrg */ 78601e04c3fSmrg if (value->type->is_scalar() && value->next->is_tail_sentinel()) { 78701e04c3fSmrg if (type->is_matrix()) { 78801e04c3fSmrg /* Matrix - fill diagonal (rest is already set to 0) */ 78901e04c3fSmrg assert(type->is_float() || type->is_double()); 79001e04c3fSmrg for (unsigned i = 0; i < type->matrix_columns; i++) { 79101e04c3fSmrg if (type->is_float()) 79201e04c3fSmrg this->value.f[i * type->vector_elements + i] = 79301e04c3fSmrg value->value.f[0]; 79401e04c3fSmrg else 79501e04c3fSmrg this->value.d[i * type->vector_elements + i] = 79601e04c3fSmrg value->value.d[0]; 79701e04c3fSmrg } 79801e04c3fSmrg } else { 79901e04c3fSmrg /* Vector or scalar - fill all components */ 80001e04c3fSmrg switch (type->base_type) { 80101e04c3fSmrg case GLSL_TYPE_UINT: 80201e04c3fSmrg case GLSL_TYPE_INT: 80301e04c3fSmrg for (unsigned i = 0; i < type->components(); i++) 80401e04c3fSmrg this->value.u[i] = value->value.u[0]; 80501e04c3fSmrg break; 80601e04c3fSmrg case GLSL_TYPE_FLOAT: 80701e04c3fSmrg for (unsigned i = 0; i < type->components(); i++) 80801e04c3fSmrg this->value.f[i] = value->value.f[0]; 80901e04c3fSmrg break; 81001e04c3fSmrg case GLSL_TYPE_DOUBLE: 81101e04c3fSmrg for (unsigned i = 0; i < type->components(); i++) 81201e04c3fSmrg this->value.d[i] = value->value.d[0]; 81301e04c3fSmrg break; 81401e04c3fSmrg case GLSL_TYPE_UINT64: 81501e04c3fSmrg case GLSL_TYPE_INT64: 81601e04c3fSmrg for (unsigned i = 0; i < type->components(); i++) 81701e04c3fSmrg this->value.u64[i] = value->value.u64[0]; 81801e04c3fSmrg break; 81901e04c3fSmrg case GLSL_TYPE_BOOL: 82001e04c3fSmrg for (unsigned i = 0; i < type->components(); i++) 82101e04c3fSmrg this->value.b[i] = value->value.b[0]; 82201e04c3fSmrg break; 82301e04c3fSmrg case GLSL_TYPE_SAMPLER: 82401e04c3fSmrg case GLSL_TYPE_IMAGE: 82501e04c3fSmrg this->value.u64[0] = value->value.u64[0]; 82601e04c3fSmrg break; 82701e04c3fSmrg default: 82801e04c3fSmrg assert(!"Should not get here."); 82901e04c3fSmrg break; 83001e04c3fSmrg } 83101e04c3fSmrg } 83201e04c3fSmrg return; 83301e04c3fSmrg } 83401e04c3fSmrg 83501e04c3fSmrg if (type->is_matrix() && value->type->is_matrix()) { 83601e04c3fSmrg assert(value->next->is_tail_sentinel()); 83701e04c3fSmrg 83801e04c3fSmrg /* From section 5.4.2 of the GLSL 1.20 spec: 83901e04c3fSmrg * "If a matrix is constructed from a matrix, then each component 84001e04c3fSmrg * (column i, row j) in the result that has a corresponding component 84101e04c3fSmrg * (column i, row j) in the argument will be initialized from there." 84201e04c3fSmrg */ 84301e04c3fSmrg unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns); 84401e04c3fSmrg unsigned rows = MIN2(type->vector_elements, value->type->vector_elements); 84501e04c3fSmrg for (unsigned i = 0; i < cols; i++) { 84601e04c3fSmrg for (unsigned j = 0; j < rows; j++) { 84701e04c3fSmrg const unsigned src = i * value->type->vector_elements + j; 84801e04c3fSmrg const unsigned dst = i * type->vector_elements + j; 84901e04c3fSmrg this->value.f[dst] = value->value.f[src]; 85001e04c3fSmrg } 85101e04c3fSmrg } 85201e04c3fSmrg 85301e04c3fSmrg /* "All other components will be initialized to the identity matrix." */ 85401e04c3fSmrg for (unsigned i = cols; i < type->matrix_columns; i++) 85501e04c3fSmrg this->value.f[i * type->vector_elements + i] = 1.0; 85601e04c3fSmrg 85701e04c3fSmrg return; 85801e04c3fSmrg } 85901e04c3fSmrg 86001e04c3fSmrg /* Use each component from each entry in the value_list to initialize one 86101e04c3fSmrg * component of the constant being constructed. 86201e04c3fSmrg */ 86301e04c3fSmrg unsigned i = 0; 86401e04c3fSmrg for (;;) { 86501e04c3fSmrg assert(value->as_constant() != NULL); 86601e04c3fSmrg assert(!value->is_tail_sentinel()); 86701e04c3fSmrg 86801e04c3fSmrg for (unsigned j = 0; j < value->type->components(); j++) { 86901e04c3fSmrg switch (type->base_type) { 87001e04c3fSmrg case GLSL_TYPE_UINT: 87101e04c3fSmrg this->value.u[i] = value->get_uint_component(j); 87201e04c3fSmrg break; 87301e04c3fSmrg case GLSL_TYPE_INT: 87401e04c3fSmrg this->value.i[i] = value->get_int_component(j); 87501e04c3fSmrg break; 87601e04c3fSmrg case GLSL_TYPE_FLOAT: 87701e04c3fSmrg this->value.f[i] = value->get_float_component(j); 87801e04c3fSmrg break; 87901e04c3fSmrg case GLSL_TYPE_BOOL: 88001e04c3fSmrg this->value.b[i] = value->get_bool_component(j); 88101e04c3fSmrg break; 88201e04c3fSmrg case GLSL_TYPE_DOUBLE: 88301e04c3fSmrg this->value.d[i] = value->get_double_component(j); 88401e04c3fSmrg break; 88501e04c3fSmrg case GLSL_TYPE_UINT64: 88601e04c3fSmrg this->value.u64[i] = value->get_uint64_component(j); 88701e04c3fSmrg break; 88801e04c3fSmrg case GLSL_TYPE_INT64: 88901e04c3fSmrg this->value.i64[i] = value->get_int64_component(j); 89001e04c3fSmrg break; 89101e04c3fSmrg default: 89201e04c3fSmrg /* FINISHME: What to do? Exceptions are not the answer. 89301e04c3fSmrg */ 89401e04c3fSmrg break; 89501e04c3fSmrg } 89601e04c3fSmrg 89701e04c3fSmrg i++; 89801e04c3fSmrg if (i >= type->components()) 89901e04c3fSmrg break; 90001e04c3fSmrg } 90101e04c3fSmrg 90201e04c3fSmrg if (i >= type->components()) 90301e04c3fSmrg break; /* avoid downcasting a list sentinel */ 90401e04c3fSmrg value = (ir_constant *) value->next; 90501e04c3fSmrg } 90601e04c3fSmrg} 90701e04c3fSmrg 90801e04c3fSmrgir_constant * 90901e04c3fSmrgir_constant::zero(void *mem_ctx, const glsl_type *type) 91001e04c3fSmrg{ 91101e04c3fSmrg assert(type->is_scalar() || type->is_vector() || type->is_matrix() 91201e04c3fSmrg || type->is_record() || type->is_array()); 91301e04c3fSmrg 91401e04c3fSmrg ir_constant *c = new(mem_ctx) ir_constant; 91501e04c3fSmrg c->type = type; 91601e04c3fSmrg memset(&c->value, 0, sizeof(c->value)); 91701e04c3fSmrg 91801e04c3fSmrg if (type->is_array()) { 91901e04c3fSmrg c->const_elements = ralloc_array(c, ir_constant *, type->length); 92001e04c3fSmrg 92101e04c3fSmrg for (unsigned i = 0; i < type->length; i++) 92201e04c3fSmrg c->const_elements[i] = ir_constant::zero(c, type->fields.array); 92301e04c3fSmrg } 92401e04c3fSmrg 92501e04c3fSmrg if (type->is_record()) { 92601e04c3fSmrg c->const_elements = ralloc_array(c, ir_constant *, type->length); 92701e04c3fSmrg 92801e04c3fSmrg for (unsigned i = 0; i < type->length; i++) { 92901e04c3fSmrg c->const_elements[i] = 93001e04c3fSmrg ir_constant::zero(mem_ctx, type->fields.structure[i].type); 93101e04c3fSmrg } 93201e04c3fSmrg } 93301e04c3fSmrg 93401e04c3fSmrg return c; 93501e04c3fSmrg} 93601e04c3fSmrg 93701e04c3fSmrgbool 93801e04c3fSmrgir_constant::get_bool_component(unsigned i) const 93901e04c3fSmrg{ 94001e04c3fSmrg switch (this->type->base_type) { 94101e04c3fSmrg case GLSL_TYPE_UINT: return this->value.u[i] != 0; 94201e04c3fSmrg case GLSL_TYPE_INT: return this->value.i[i] != 0; 94301e04c3fSmrg case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0; 94401e04c3fSmrg case GLSL_TYPE_BOOL: return this->value.b[i]; 94501e04c3fSmrg case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0; 94601e04c3fSmrg case GLSL_TYPE_SAMPLER: 94701e04c3fSmrg case GLSL_TYPE_IMAGE: 94801e04c3fSmrg case GLSL_TYPE_UINT64: return this->value.u64[i] != 0; 94901e04c3fSmrg case GLSL_TYPE_INT64: return this->value.i64[i] != 0; 95001e04c3fSmrg default: assert(!"Should not get here."); break; 95101e04c3fSmrg } 95201e04c3fSmrg 95301e04c3fSmrg /* Must return something to make the compiler happy. This is clearly an 95401e04c3fSmrg * error case. 95501e04c3fSmrg */ 95601e04c3fSmrg return false; 95701e04c3fSmrg} 95801e04c3fSmrg 95901e04c3fSmrgfloat 96001e04c3fSmrgir_constant::get_float_component(unsigned i) const 96101e04c3fSmrg{ 96201e04c3fSmrg switch (this->type->base_type) { 96301e04c3fSmrg case GLSL_TYPE_UINT: return (float) this->value.u[i]; 96401e04c3fSmrg case GLSL_TYPE_INT: return (float) this->value.i[i]; 96501e04c3fSmrg case GLSL_TYPE_FLOAT: return this->value.f[i]; 96601e04c3fSmrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0f : 0.0f; 96701e04c3fSmrg case GLSL_TYPE_DOUBLE: return (float) this->value.d[i]; 96801e04c3fSmrg case GLSL_TYPE_SAMPLER: 96901e04c3fSmrg case GLSL_TYPE_IMAGE: 97001e04c3fSmrg case GLSL_TYPE_UINT64: return (float) this->value.u64[i]; 97101e04c3fSmrg case GLSL_TYPE_INT64: return (float) this->value.i64[i]; 97201e04c3fSmrg default: assert(!"Should not get here."); break; 97301e04c3fSmrg } 97401e04c3fSmrg 97501e04c3fSmrg /* Must return something to make the compiler happy. This is clearly an 97601e04c3fSmrg * error case. 97701e04c3fSmrg */ 97801e04c3fSmrg return 0.0; 97901e04c3fSmrg} 98001e04c3fSmrg 98101e04c3fSmrgdouble 98201e04c3fSmrgir_constant::get_double_component(unsigned i) const 98301e04c3fSmrg{ 98401e04c3fSmrg switch (this->type->base_type) { 98501e04c3fSmrg case GLSL_TYPE_UINT: return (double) this->value.u[i]; 98601e04c3fSmrg case GLSL_TYPE_INT: return (double) this->value.i[i]; 98701e04c3fSmrg case GLSL_TYPE_FLOAT: return (double) this->value.f[i]; 98801e04c3fSmrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0; 98901e04c3fSmrg case GLSL_TYPE_DOUBLE: return this->value.d[i]; 99001e04c3fSmrg case GLSL_TYPE_SAMPLER: 99101e04c3fSmrg case GLSL_TYPE_IMAGE: 99201e04c3fSmrg case GLSL_TYPE_UINT64: return (double) this->value.u64[i]; 99301e04c3fSmrg case GLSL_TYPE_INT64: return (double) this->value.i64[i]; 99401e04c3fSmrg default: assert(!"Should not get here."); break; 99501e04c3fSmrg } 99601e04c3fSmrg 99701e04c3fSmrg /* Must return something to make the compiler happy. This is clearly an 99801e04c3fSmrg * error case. 99901e04c3fSmrg */ 100001e04c3fSmrg return 0.0; 100101e04c3fSmrg} 100201e04c3fSmrg 100301e04c3fSmrgint 100401e04c3fSmrgir_constant::get_int_component(unsigned i) const 100501e04c3fSmrg{ 100601e04c3fSmrg switch (this->type->base_type) { 100701e04c3fSmrg case GLSL_TYPE_UINT: return this->value.u[i]; 100801e04c3fSmrg case GLSL_TYPE_INT: return this->value.i[i]; 100901e04c3fSmrg case GLSL_TYPE_FLOAT: return (int) this->value.f[i]; 101001e04c3fSmrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 101101e04c3fSmrg case GLSL_TYPE_DOUBLE: return (int) this->value.d[i]; 101201e04c3fSmrg case GLSL_TYPE_SAMPLER: 101301e04c3fSmrg case GLSL_TYPE_IMAGE: 101401e04c3fSmrg case GLSL_TYPE_UINT64: return (int) this->value.u64[i]; 101501e04c3fSmrg case GLSL_TYPE_INT64: return (int) this->value.i64[i]; 101601e04c3fSmrg default: assert(!"Should not get here."); break; 101701e04c3fSmrg } 101801e04c3fSmrg 101901e04c3fSmrg /* Must return something to make the compiler happy. This is clearly an 102001e04c3fSmrg * error case. 102101e04c3fSmrg */ 102201e04c3fSmrg return 0; 102301e04c3fSmrg} 102401e04c3fSmrg 102501e04c3fSmrgunsigned 102601e04c3fSmrgir_constant::get_uint_component(unsigned i) const 102701e04c3fSmrg{ 102801e04c3fSmrg switch (this->type->base_type) { 102901e04c3fSmrg case GLSL_TYPE_UINT: return this->value.u[i]; 103001e04c3fSmrg case GLSL_TYPE_INT: return this->value.i[i]; 103101e04c3fSmrg case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i]; 103201e04c3fSmrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 103301e04c3fSmrg case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i]; 103401e04c3fSmrg case GLSL_TYPE_SAMPLER: 103501e04c3fSmrg case GLSL_TYPE_IMAGE: 103601e04c3fSmrg case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i]; 103701e04c3fSmrg case GLSL_TYPE_INT64: return (unsigned) this->value.i64[i]; 103801e04c3fSmrg default: assert(!"Should not get here."); break; 103901e04c3fSmrg } 104001e04c3fSmrg 104101e04c3fSmrg /* Must return something to make the compiler happy. This is clearly an 104201e04c3fSmrg * error case. 104301e04c3fSmrg */ 104401e04c3fSmrg return 0; 104501e04c3fSmrg} 104601e04c3fSmrg 104701e04c3fSmrgint64_t 104801e04c3fSmrgir_constant::get_int64_component(unsigned i) const 104901e04c3fSmrg{ 105001e04c3fSmrg switch (this->type->base_type) { 105101e04c3fSmrg case GLSL_TYPE_UINT: return this->value.u[i]; 105201e04c3fSmrg case GLSL_TYPE_INT: return this->value.i[i]; 105301e04c3fSmrg case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i]; 105401e04c3fSmrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 105501e04c3fSmrg case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i]; 105601e04c3fSmrg case GLSL_TYPE_SAMPLER: 105701e04c3fSmrg case GLSL_TYPE_IMAGE: 105801e04c3fSmrg case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i]; 105901e04c3fSmrg case GLSL_TYPE_INT64: return this->value.i64[i]; 106001e04c3fSmrg default: assert(!"Should not get here."); break; 106101e04c3fSmrg } 106201e04c3fSmrg 106301e04c3fSmrg /* Must return something to make the compiler happy. This is clearly an 106401e04c3fSmrg * error case. 106501e04c3fSmrg */ 106601e04c3fSmrg return 0; 106701e04c3fSmrg} 106801e04c3fSmrg 106901e04c3fSmrguint64_t 107001e04c3fSmrgir_constant::get_uint64_component(unsigned i) const 107101e04c3fSmrg{ 107201e04c3fSmrg switch (this->type->base_type) { 107301e04c3fSmrg case GLSL_TYPE_UINT: return this->value.u[i]; 107401e04c3fSmrg case GLSL_TYPE_INT: return this->value.i[i]; 107501e04c3fSmrg case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i]; 107601e04c3fSmrg case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; 107701e04c3fSmrg case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i]; 107801e04c3fSmrg case GLSL_TYPE_SAMPLER: 107901e04c3fSmrg case GLSL_TYPE_IMAGE: 108001e04c3fSmrg case GLSL_TYPE_UINT64: return this->value.u64[i]; 108101e04c3fSmrg case GLSL_TYPE_INT64: return (uint64_t) this->value.i64[i]; 108201e04c3fSmrg default: assert(!"Should not get here."); break; 108301e04c3fSmrg } 108401e04c3fSmrg 108501e04c3fSmrg /* Must return something to make the compiler happy. This is clearly an 108601e04c3fSmrg * error case. 108701e04c3fSmrg */ 108801e04c3fSmrg return 0; 108901e04c3fSmrg} 109001e04c3fSmrg 109101e04c3fSmrgir_constant * 109201e04c3fSmrgir_constant::get_array_element(unsigned i) const 109301e04c3fSmrg{ 109401e04c3fSmrg assert(this->type->is_array()); 109501e04c3fSmrg 109601e04c3fSmrg /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec: 109701e04c3fSmrg * 109801e04c3fSmrg * "Behavior is undefined if a shader subscripts an array with an index 109901e04c3fSmrg * less than 0 or greater than or equal to the size the array was 110001e04c3fSmrg * declared with." 110101e04c3fSmrg * 110201e04c3fSmrg * Most out-of-bounds accesses are removed before things could get this far. 110301e04c3fSmrg * There are cases where non-constant array index values can get constant 110401e04c3fSmrg * folded. 110501e04c3fSmrg */ 110601e04c3fSmrg if (int(i) < 0) 110701e04c3fSmrg i = 0; 110801e04c3fSmrg else if (i >= this->type->length) 110901e04c3fSmrg i = this->type->length - 1; 111001e04c3fSmrg 111101e04c3fSmrg return const_elements[i]; 111201e04c3fSmrg} 111301e04c3fSmrg 111401e04c3fSmrgir_constant * 111501e04c3fSmrgir_constant::get_record_field(int idx) 111601e04c3fSmrg{ 111701e04c3fSmrg assert(this->type->is_record()); 111801e04c3fSmrg assert(idx >= 0 && (unsigned) idx < this->type->length); 111901e04c3fSmrg 112001e04c3fSmrg return const_elements[idx]; 112101e04c3fSmrg} 112201e04c3fSmrg 112301e04c3fSmrgvoid 112401e04c3fSmrgir_constant::copy_offset(ir_constant *src, int offset) 112501e04c3fSmrg{ 112601e04c3fSmrg switch (this->type->base_type) { 112701e04c3fSmrg case GLSL_TYPE_UINT: 112801e04c3fSmrg case GLSL_TYPE_INT: 112901e04c3fSmrg case GLSL_TYPE_FLOAT: 113001e04c3fSmrg case GLSL_TYPE_DOUBLE: 113101e04c3fSmrg case GLSL_TYPE_SAMPLER: 113201e04c3fSmrg case GLSL_TYPE_IMAGE: 113301e04c3fSmrg case GLSL_TYPE_UINT64: 113401e04c3fSmrg case GLSL_TYPE_INT64: 113501e04c3fSmrg case GLSL_TYPE_BOOL: { 113601e04c3fSmrg unsigned int size = src->type->components(); 113701e04c3fSmrg assert (size <= this->type->components() - offset); 113801e04c3fSmrg for (unsigned int i=0; i<size; i++) { 113901e04c3fSmrg switch (this->type->base_type) { 114001e04c3fSmrg case GLSL_TYPE_UINT: 114101e04c3fSmrg value.u[i+offset] = src->get_uint_component(i); 114201e04c3fSmrg break; 114301e04c3fSmrg case GLSL_TYPE_INT: 114401e04c3fSmrg value.i[i+offset] = src->get_int_component(i); 114501e04c3fSmrg break; 114601e04c3fSmrg case GLSL_TYPE_FLOAT: 114701e04c3fSmrg value.f[i+offset] = src->get_float_component(i); 114801e04c3fSmrg break; 114901e04c3fSmrg case GLSL_TYPE_BOOL: 115001e04c3fSmrg value.b[i+offset] = src->get_bool_component(i); 115101e04c3fSmrg break; 115201e04c3fSmrg case GLSL_TYPE_DOUBLE: 115301e04c3fSmrg value.d[i+offset] = src->get_double_component(i); 115401e04c3fSmrg break; 115501e04c3fSmrg case GLSL_TYPE_SAMPLER: 115601e04c3fSmrg case GLSL_TYPE_IMAGE: 115701e04c3fSmrg case GLSL_TYPE_UINT64: 115801e04c3fSmrg value.u64[i+offset] = src->get_uint64_component(i); 115901e04c3fSmrg break; 116001e04c3fSmrg case GLSL_TYPE_INT64: 116101e04c3fSmrg value.i64[i+offset] = src->get_int64_component(i); 116201e04c3fSmrg break; 116301e04c3fSmrg default: // Shut up the compiler 116401e04c3fSmrg break; 116501e04c3fSmrg } 116601e04c3fSmrg } 116701e04c3fSmrg break; 116801e04c3fSmrg } 116901e04c3fSmrg 117001e04c3fSmrg case GLSL_TYPE_STRUCT: 117101e04c3fSmrg case GLSL_TYPE_ARRAY: { 117201e04c3fSmrg assert (src->type == this->type); 117301e04c3fSmrg for (unsigned i = 0; i < this->type->length; i++) { 117401e04c3fSmrg this->const_elements[i] = src->const_elements[i]->clone(this, NULL); 117501e04c3fSmrg } 117601e04c3fSmrg break; 117701e04c3fSmrg } 117801e04c3fSmrg 117901e04c3fSmrg default: 118001e04c3fSmrg assert(!"Should not get here."); 118101e04c3fSmrg break; 118201e04c3fSmrg } 118301e04c3fSmrg} 118401e04c3fSmrg 118501e04c3fSmrgvoid 118601e04c3fSmrgir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask) 118701e04c3fSmrg{ 118801e04c3fSmrg assert (!type->is_array() && !type->is_record()); 118901e04c3fSmrg 119001e04c3fSmrg if (!type->is_vector() && !type->is_matrix()) { 119101e04c3fSmrg offset = 0; 119201e04c3fSmrg mask = 1; 119301e04c3fSmrg } 119401e04c3fSmrg 119501e04c3fSmrg int id = 0; 119601e04c3fSmrg for (int i=0; i<4; i++) { 119701e04c3fSmrg if (mask & (1 << i)) { 119801e04c3fSmrg switch (this->type->base_type) { 119901e04c3fSmrg case GLSL_TYPE_UINT: 120001e04c3fSmrg value.u[i+offset] = src->get_uint_component(id++); 120101e04c3fSmrg break; 120201e04c3fSmrg case GLSL_TYPE_INT: 120301e04c3fSmrg value.i[i+offset] = src->get_int_component(id++); 120401e04c3fSmrg break; 120501e04c3fSmrg case GLSL_TYPE_FLOAT: 120601e04c3fSmrg value.f[i+offset] = src->get_float_component(id++); 120701e04c3fSmrg break; 120801e04c3fSmrg case GLSL_TYPE_BOOL: 120901e04c3fSmrg value.b[i+offset] = src->get_bool_component(id++); 121001e04c3fSmrg break; 121101e04c3fSmrg case GLSL_TYPE_DOUBLE: 121201e04c3fSmrg value.d[i+offset] = src->get_double_component(id++); 121301e04c3fSmrg break; 121401e04c3fSmrg case GLSL_TYPE_SAMPLER: 121501e04c3fSmrg case GLSL_TYPE_IMAGE: 121601e04c3fSmrg case GLSL_TYPE_UINT64: 121701e04c3fSmrg value.u64[i+offset] = src->get_uint64_component(id++); 121801e04c3fSmrg break; 121901e04c3fSmrg case GLSL_TYPE_INT64: 122001e04c3fSmrg value.i64[i+offset] = src->get_int64_component(id++); 122101e04c3fSmrg break; 122201e04c3fSmrg default: 122301e04c3fSmrg assert(!"Should not get here."); 122401e04c3fSmrg return; 122501e04c3fSmrg } 122601e04c3fSmrg } 122701e04c3fSmrg } 122801e04c3fSmrg} 122901e04c3fSmrg 123001e04c3fSmrgbool 123101e04c3fSmrgir_constant::has_value(const ir_constant *c) const 123201e04c3fSmrg{ 123301e04c3fSmrg if (this->type != c->type) 123401e04c3fSmrg return false; 123501e04c3fSmrg 123601e04c3fSmrg if (this->type->is_array() || this->type->is_record()) { 123701e04c3fSmrg for (unsigned i = 0; i < this->type->length; i++) { 123801e04c3fSmrg if (!this->const_elements[i]->has_value(c->const_elements[i])) 123901e04c3fSmrg return false; 124001e04c3fSmrg } 124101e04c3fSmrg return true; 124201e04c3fSmrg } 124301e04c3fSmrg 124401e04c3fSmrg for (unsigned i = 0; i < this->type->components(); i++) { 124501e04c3fSmrg switch (this->type->base_type) { 124601e04c3fSmrg case GLSL_TYPE_UINT: 124701e04c3fSmrg if (this->value.u[i] != c->value.u[i]) 124801e04c3fSmrg return false; 124901e04c3fSmrg break; 125001e04c3fSmrg case GLSL_TYPE_INT: 125101e04c3fSmrg if (this->value.i[i] != c->value.i[i]) 125201e04c3fSmrg return false; 125301e04c3fSmrg break; 125401e04c3fSmrg case GLSL_TYPE_FLOAT: 125501e04c3fSmrg if (this->value.f[i] != c->value.f[i]) 125601e04c3fSmrg return false; 125701e04c3fSmrg break; 125801e04c3fSmrg case GLSL_TYPE_BOOL: 125901e04c3fSmrg if (this->value.b[i] != c->value.b[i]) 126001e04c3fSmrg return false; 126101e04c3fSmrg break; 126201e04c3fSmrg case GLSL_TYPE_DOUBLE: 126301e04c3fSmrg if (this->value.d[i] != c->value.d[i]) 126401e04c3fSmrg return false; 126501e04c3fSmrg break; 126601e04c3fSmrg case GLSL_TYPE_SAMPLER: 126701e04c3fSmrg case GLSL_TYPE_IMAGE: 126801e04c3fSmrg case GLSL_TYPE_UINT64: 126901e04c3fSmrg if (this->value.u64[i] != c->value.u64[i]) 127001e04c3fSmrg return false; 127101e04c3fSmrg break; 127201e04c3fSmrg case GLSL_TYPE_INT64: 127301e04c3fSmrg if (this->value.i64[i] != c->value.i64[i]) 127401e04c3fSmrg return false; 127501e04c3fSmrg break; 127601e04c3fSmrg default: 127701e04c3fSmrg assert(!"Should not get here."); 127801e04c3fSmrg return false; 127901e04c3fSmrg } 128001e04c3fSmrg } 128101e04c3fSmrg 128201e04c3fSmrg return true; 128301e04c3fSmrg} 128401e04c3fSmrg 128501e04c3fSmrgbool 128601e04c3fSmrgir_constant::is_value(float f, int i) const 128701e04c3fSmrg{ 128801e04c3fSmrg if (!this->type->is_scalar() && !this->type->is_vector()) 128901e04c3fSmrg return false; 129001e04c3fSmrg 129101e04c3fSmrg /* Only accept boolean values for 0/1. */ 129201e04c3fSmrg if (int(bool(i)) != i && this->type->is_boolean()) 129301e04c3fSmrg return false; 129401e04c3fSmrg 129501e04c3fSmrg for (unsigned c = 0; c < this->type->vector_elements; c++) { 129601e04c3fSmrg switch (this->type->base_type) { 129701e04c3fSmrg case GLSL_TYPE_FLOAT: 129801e04c3fSmrg if (this->value.f[c] != f) 129901e04c3fSmrg return false; 130001e04c3fSmrg break; 130101e04c3fSmrg case GLSL_TYPE_INT: 130201e04c3fSmrg if (this->value.i[c] != i) 130301e04c3fSmrg return false; 130401e04c3fSmrg break; 130501e04c3fSmrg case GLSL_TYPE_UINT: 130601e04c3fSmrg if (this->value.u[c] != unsigned(i)) 130701e04c3fSmrg return false; 130801e04c3fSmrg break; 130901e04c3fSmrg case GLSL_TYPE_BOOL: 131001e04c3fSmrg if (this->value.b[c] != bool(i)) 131101e04c3fSmrg return false; 131201e04c3fSmrg break; 131301e04c3fSmrg case GLSL_TYPE_DOUBLE: 131401e04c3fSmrg if (this->value.d[c] != double(f)) 131501e04c3fSmrg return false; 131601e04c3fSmrg break; 131701e04c3fSmrg case GLSL_TYPE_SAMPLER: 131801e04c3fSmrg case GLSL_TYPE_IMAGE: 131901e04c3fSmrg case GLSL_TYPE_UINT64: 132001e04c3fSmrg if (this->value.u64[c] != uint64_t(i)) 132101e04c3fSmrg return false; 132201e04c3fSmrg break; 132301e04c3fSmrg case GLSL_TYPE_INT64: 132401e04c3fSmrg if (this->value.i64[c] != i) 132501e04c3fSmrg return false; 132601e04c3fSmrg break; 132701e04c3fSmrg default: 132801e04c3fSmrg /* The only other base types are structures, arrays, and samplers. 132901e04c3fSmrg * Samplers cannot be constants, and the others should have been 133001e04c3fSmrg * filtered out above. 133101e04c3fSmrg */ 133201e04c3fSmrg assert(!"Should not get here."); 133301e04c3fSmrg return false; 133401e04c3fSmrg } 133501e04c3fSmrg } 133601e04c3fSmrg 133701e04c3fSmrg return true; 133801e04c3fSmrg} 133901e04c3fSmrg 134001e04c3fSmrgbool 134101e04c3fSmrgir_constant::is_zero() const 134201e04c3fSmrg{ 134301e04c3fSmrg return is_value(0.0, 0); 134401e04c3fSmrg} 134501e04c3fSmrg 134601e04c3fSmrgbool 134701e04c3fSmrgir_constant::is_one() const 134801e04c3fSmrg{ 134901e04c3fSmrg return is_value(1.0, 1); 135001e04c3fSmrg} 135101e04c3fSmrg 135201e04c3fSmrgbool 135301e04c3fSmrgir_constant::is_negative_one() const 135401e04c3fSmrg{ 135501e04c3fSmrg return is_value(-1.0, -1); 135601e04c3fSmrg} 135701e04c3fSmrg 135801e04c3fSmrgbool 135901e04c3fSmrgir_constant::is_uint16_constant() const 136001e04c3fSmrg{ 136101e04c3fSmrg if (!type->is_integer()) 136201e04c3fSmrg return false; 136301e04c3fSmrg 136401e04c3fSmrg return value.u[0] < (1 << 16); 136501e04c3fSmrg} 136601e04c3fSmrg 136701e04c3fSmrgir_loop::ir_loop() 136801e04c3fSmrg : ir_instruction(ir_type_loop) 136901e04c3fSmrg{ 137001e04c3fSmrg} 137101e04c3fSmrg 137201e04c3fSmrg 137301e04c3fSmrgir_dereference_variable::ir_dereference_variable(ir_variable *var) 137401e04c3fSmrg : ir_dereference(ir_type_dereference_variable) 137501e04c3fSmrg{ 137601e04c3fSmrg assert(var != NULL); 137701e04c3fSmrg 137801e04c3fSmrg this->var = var; 137901e04c3fSmrg this->type = var->type; 138001e04c3fSmrg} 138101e04c3fSmrg 138201e04c3fSmrg 138301e04c3fSmrgir_dereference_array::ir_dereference_array(ir_rvalue *value, 138401e04c3fSmrg ir_rvalue *array_index) 138501e04c3fSmrg : ir_dereference(ir_type_dereference_array) 138601e04c3fSmrg{ 138701e04c3fSmrg this->array_index = array_index; 138801e04c3fSmrg this->set_array(value); 138901e04c3fSmrg} 139001e04c3fSmrg 139101e04c3fSmrg 139201e04c3fSmrgir_dereference_array::ir_dereference_array(ir_variable *var, 139301e04c3fSmrg ir_rvalue *array_index) 139401e04c3fSmrg : ir_dereference(ir_type_dereference_array) 139501e04c3fSmrg{ 139601e04c3fSmrg void *ctx = ralloc_parent(var); 139701e04c3fSmrg 139801e04c3fSmrg this->array_index = array_index; 139901e04c3fSmrg this->set_array(new(ctx) ir_dereference_variable(var)); 140001e04c3fSmrg} 140101e04c3fSmrg 140201e04c3fSmrg 140301e04c3fSmrgvoid 140401e04c3fSmrgir_dereference_array::set_array(ir_rvalue *value) 140501e04c3fSmrg{ 140601e04c3fSmrg assert(value != NULL); 140701e04c3fSmrg 140801e04c3fSmrg this->array = value; 140901e04c3fSmrg 141001e04c3fSmrg const glsl_type *const vt = this->array->type; 141101e04c3fSmrg 141201e04c3fSmrg if (vt->is_array()) { 141301e04c3fSmrg type = vt->fields.array; 141401e04c3fSmrg } else if (vt->is_matrix()) { 141501e04c3fSmrg type = vt->column_type(); 141601e04c3fSmrg } else if (vt->is_vector()) { 141701e04c3fSmrg type = vt->get_base_type(); 141801e04c3fSmrg } 141901e04c3fSmrg} 142001e04c3fSmrg 142101e04c3fSmrg 142201e04c3fSmrgir_dereference_record::ir_dereference_record(ir_rvalue *value, 142301e04c3fSmrg const char *field) 142401e04c3fSmrg : ir_dereference(ir_type_dereference_record) 142501e04c3fSmrg{ 142601e04c3fSmrg assert(value != NULL); 142701e04c3fSmrg 142801e04c3fSmrg this->record = value; 142901e04c3fSmrg this->type = this->record->type->field_type(field); 143001e04c3fSmrg this->field_idx = this->record->type->field_index(field); 143101e04c3fSmrg} 143201e04c3fSmrg 143301e04c3fSmrg 143401e04c3fSmrgir_dereference_record::ir_dereference_record(ir_variable *var, 143501e04c3fSmrg const char *field) 143601e04c3fSmrg : ir_dereference(ir_type_dereference_record) 143701e04c3fSmrg{ 143801e04c3fSmrg void *ctx = ralloc_parent(var); 143901e04c3fSmrg 144001e04c3fSmrg this->record = new(ctx) ir_dereference_variable(var); 144101e04c3fSmrg this->type = this->record->type->field_type(field); 144201e04c3fSmrg this->field_idx = this->record->type->field_index(field); 144301e04c3fSmrg} 144401e04c3fSmrg 144501e04c3fSmrgbool 144601e04c3fSmrgir_dereference::is_lvalue(const struct _mesa_glsl_parse_state *state) const 144701e04c3fSmrg{ 144801e04c3fSmrg ir_variable *var = this->variable_referenced(); 144901e04c3fSmrg 145001e04c3fSmrg /* Every l-value derference chain eventually ends in a variable. 145101e04c3fSmrg */ 145201e04c3fSmrg if ((var == NULL) || var->data.read_only) 145301e04c3fSmrg return false; 145401e04c3fSmrg 145501e04c3fSmrg /* From section 4.1.7 of the ARB_bindless_texture spec: 145601e04c3fSmrg * 145701e04c3fSmrg * "Samplers can be used as l-values, so can be assigned into and used as 145801e04c3fSmrg * "out" and "inout" function parameters." 145901e04c3fSmrg * 146001e04c3fSmrg * From section 4.1.X of the ARB_bindless_texture spec: 146101e04c3fSmrg * 146201e04c3fSmrg * "Images can be used as l-values, so can be assigned into and used as 146301e04c3fSmrg * "out" and "inout" function parameters." 146401e04c3fSmrg */ 146501e04c3fSmrg if ((!state || state->has_bindless()) && 146601e04c3fSmrg (this->type->contains_sampler() || this->type->contains_image())) 146701e04c3fSmrg return true; 146801e04c3fSmrg 146901e04c3fSmrg /* From section 4.1.7 of the GLSL 4.40 spec: 147001e04c3fSmrg * 147101e04c3fSmrg * "Opaque variables cannot be treated as l-values; hence cannot 147201e04c3fSmrg * be used as out or inout function parameters, nor can they be 147301e04c3fSmrg * assigned into." 147401e04c3fSmrg */ 147501e04c3fSmrg if (this->type->contains_opaque()) 147601e04c3fSmrg return false; 147701e04c3fSmrg 147801e04c3fSmrg return true; 147901e04c3fSmrg} 148001e04c3fSmrg 148101e04c3fSmrg 148201e04c3fSmrgstatic const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels", "texture_samples", "samples_identical" }; 148301e04c3fSmrg 148401e04c3fSmrgconst char *ir_texture::opcode_string() 148501e04c3fSmrg{ 148601e04c3fSmrg assert((unsigned int) op < ARRAY_SIZE(tex_opcode_strs)); 148701e04c3fSmrg return tex_opcode_strs[op]; 148801e04c3fSmrg} 148901e04c3fSmrg 149001e04c3fSmrgir_texture_opcode 149101e04c3fSmrgir_texture::get_opcode(const char *str) 149201e04c3fSmrg{ 149301e04c3fSmrg const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]); 149401e04c3fSmrg for (int op = 0; op < count; op++) { 149501e04c3fSmrg if (strcmp(str, tex_opcode_strs[op]) == 0) 149601e04c3fSmrg return (ir_texture_opcode) op; 149701e04c3fSmrg } 149801e04c3fSmrg return (ir_texture_opcode) -1; 149901e04c3fSmrg} 150001e04c3fSmrg 150101e04c3fSmrg 150201e04c3fSmrgvoid 150301e04c3fSmrgir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type) 150401e04c3fSmrg{ 150501e04c3fSmrg assert(sampler != NULL); 150601e04c3fSmrg assert(type != NULL); 150701e04c3fSmrg this->sampler = sampler; 150801e04c3fSmrg this->type = type; 150901e04c3fSmrg 151001e04c3fSmrg if (this->op == ir_txs || this->op == ir_query_levels || 151101e04c3fSmrg this->op == ir_texture_samples) { 151201e04c3fSmrg assert(type->base_type == GLSL_TYPE_INT); 151301e04c3fSmrg } else if (this->op == ir_lod) { 151401e04c3fSmrg assert(type->vector_elements == 2); 151501e04c3fSmrg assert(type->is_float()); 151601e04c3fSmrg } else if (this->op == ir_samples_identical) { 151701e04c3fSmrg assert(type == glsl_type::bool_type); 151801e04c3fSmrg assert(sampler->type->is_sampler()); 151901e04c3fSmrg assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS); 152001e04c3fSmrg } else { 152101e04c3fSmrg assert(sampler->type->sampled_type == (int) type->base_type); 152201e04c3fSmrg if (sampler->type->sampler_shadow) 152301e04c3fSmrg assert(type->vector_elements == 4 || type->vector_elements == 1); 152401e04c3fSmrg else 152501e04c3fSmrg assert(type->vector_elements == 4); 152601e04c3fSmrg } 152701e04c3fSmrg} 152801e04c3fSmrg 152901e04c3fSmrg 153001e04c3fSmrgvoid 153101e04c3fSmrgir_swizzle::init_mask(const unsigned *comp, unsigned count) 153201e04c3fSmrg{ 153301e04c3fSmrg assert((count >= 1) && (count <= 4)); 153401e04c3fSmrg 153501e04c3fSmrg memset(&this->mask, 0, sizeof(this->mask)); 153601e04c3fSmrg this->mask.num_components = count; 153701e04c3fSmrg 153801e04c3fSmrg unsigned dup_mask = 0; 153901e04c3fSmrg switch (count) { 154001e04c3fSmrg case 4: 154101e04c3fSmrg assert(comp[3] <= 3); 154201e04c3fSmrg dup_mask |= (1U << comp[3]) 154301e04c3fSmrg & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2])); 154401e04c3fSmrg this->mask.w = comp[3]; 154501e04c3fSmrg 154601e04c3fSmrg case 3: 154701e04c3fSmrg assert(comp[2] <= 3); 154801e04c3fSmrg dup_mask |= (1U << comp[2]) 154901e04c3fSmrg & ((1U << comp[0]) | (1U << comp[1])); 155001e04c3fSmrg this->mask.z = comp[2]; 155101e04c3fSmrg 155201e04c3fSmrg case 2: 155301e04c3fSmrg assert(comp[1] <= 3); 155401e04c3fSmrg dup_mask |= (1U << comp[1]) 155501e04c3fSmrg & ((1U << comp[0])); 155601e04c3fSmrg this->mask.y = comp[1]; 155701e04c3fSmrg 155801e04c3fSmrg case 1: 155901e04c3fSmrg assert(comp[0] <= 3); 156001e04c3fSmrg this->mask.x = comp[0]; 156101e04c3fSmrg } 156201e04c3fSmrg 156301e04c3fSmrg this->mask.has_duplicates = dup_mask != 0; 156401e04c3fSmrg 156501e04c3fSmrg /* Based on the number of elements in the swizzle and the base type 156601e04c3fSmrg * (i.e., float, int, unsigned, or bool) of the vector being swizzled, 156701e04c3fSmrg * generate the type of the resulting value. 156801e04c3fSmrg */ 156901e04c3fSmrg type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1); 157001e04c3fSmrg} 157101e04c3fSmrg 157201e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z, 157301e04c3fSmrg unsigned w, unsigned count) 157401e04c3fSmrg : ir_rvalue(ir_type_swizzle), val(val) 157501e04c3fSmrg{ 157601e04c3fSmrg const unsigned components[4] = { x, y, z, w }; 157701e04c3fSmrg this->init_mask(components, count); 157801e04c3fSmrg} 157901e04c3fSmrg 158001e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp, 158101e04c3fSmrg unsigned count) 158201e04c3fSmrg : ir_rvalue(ir_type_swizzle), val(val) 158301e04c3fSmrg{ 158401e04c3fSmrg this->init_mask(comp, count); 158501e04c3fSmrg} 158601e04c3fSmrg 158701e04c3fSmrgir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) 158801e04c3fSmrg : ir_rvalue(ir_type_swizzle), val(val), mask(mask) 158901e04c3fSmrg{ 159001e04c3fSmrg this->type = glsl_type::get_instance(val->type->base_type, 159101e04c3fSmrg mask.num_components, 1); 159201e04c3fSmrg} 159301e04c3fSmrg 159401e04c3fSmrg#define X 1 159501e04c3fSmrg#define R 5 159601e04c3fSmrg#define S 9 159701e04c3fSmrg#define I 13 159801e04c3fSmrg 159901e04c3fSmrgir_swizzle * 160001e04c3fSmrgir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length) 160101e04c3fSmrg{ 160201e04c3fSmrg void *ctx = ralloc_parent(val); 160301e04c3fSmrg 160401e04c3fSmrg /* For each possible swizzle character, this table encodes the value in 160501e04c3fSmrg * \c idx_map that represents the 0th element of the vector. For invalid 160601e04c3fSmrg * swizzle characters (e.g., 'k'), a special value is used that will allow 160701e04c3fSmrg * detection of errors. 160801e04c3fSmrg */ 160901e04c3fSmrg static const unsigned char base_idx[26] = { 161001e04c3fSmrg /* a b c d e f g h i j k l m */ 161101e04c3fSmrg R, R, I, I, I, I, R, I, I, I, I, I, I, 161201e04c3fSmrg /* n o p q r s t u v w x y z */ 161301e04c3fSmrg I, I, S, S, R, S, S, I, I, X, X, X, X 161401e04c3fSmrg }; 161501e04c3fSmrg 161601e04c3fSmrg /* Each valid swizzle character has an entry in the previous table. This 161701e04c3fSmrg * table encodes the base index encoded in the previous table plus the actual 161801e04c3fSmrg * index of the swizzle character. When processing swizzles, the first 161901e04c3fSmrg * character in the string is indexed in the previous table. Each character 162001e04c3fSmrg * in the string is indexed in this table, and the value found there has the 162101e04c3fSmrg * value form the first table subtracted. The result must be on the range 162201e04c3fSmrg * [0,3]. 162301e04c3fSmrg * 162401e04c3fSmrg * For example, the string "wzyx" will get X from the first table. Each of 162501e04c3fSmrg * the charcaters will get X+3, X+2, X+1, and X+0 from this table. After 162601e04c3fSmrg * subtraction, the swizzle values are { 3, 2, 1, 0 }. 162701e04c3fSmrg * 162801e04c3fSmrg * The string "wzrg" will get X from the first table. Each of the characters 162901e04c3fSmrg * will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the 163001e04c3fSmrg * swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range 163101e04c3fSmrg * [0,3], the error is detected. 163201e04c3fSmrg */ 163301e04c3fSmrg static const unsigned char idx_map[26] = { 163401e04c3fSmrg /* a b c d e f g h i j k l m */ 163501e04c3fSmrg R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0, 163601e04c3fSmrg /* n o p q r s t u v w x y z */ 163701e04c3fSmrg 0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2 163801e04c3fSmrg }; 163901e04c3fSmrg 164001e04c3fSmrg int swiz_idx[4] = { 0, 0, 0, 0 }; 164101e04c3fSmrg unsigned i; 164201e04c3fSmrg 164301e04c3fSmrg 164401e04c3fSmrg /* Validate the first character in the swizzle string and look up the base 164501e04c3fSmrg * index value as described above. 164601e04c3fSmrg */ 164701e04c3fSmrg if ((str[0] < 'a') || (str[0] > 'z')) 164801e04c3fSmrg return NULL; 164901e04c3fSmrg 165001e04c3fSmrg const unsigned base = base_idx[str[0] - 'a']; 165101e04c3fSmrg 165201e04c3fSmrg 165301e04c3fSmrg for (i = 0; (i < 4) && (str[i] != '\0'); i++) { 165401e04c3fSmrg /* Validate the next character, and, as described above, convert it to a 165501e04c3fSmrg * swizzle index. 165601e04c3fSmrg */ 165701e04c3fSmrg if ((str[i] < 'a') || (str[i] > 'z')) 165801e04c3fSmrg return NULL; 165901e04c3fSmrg 166001e04c3fSmrg swiz_idx[i] = idx_map[str[i] - 'a'] - base; 166101e04c3fSmrg if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length)) 166201e04c3fSmrg return NULL; 166301e04c3fSmrg } 166401e04c3fSmrg 166501e04c3fSmrg if (str[i] != '\0') 166601e04c3fSmrg return NULL; 166701e04c3fSmrg 166801e04c3fSmrg return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2], 166901e04c3fSmrg swiz_idx[3], i); 167001e04c3fSmrg} 167101e04c3fSmrg 167201e04c3fSmrg#undef X 167301e04c3fSmrg#undef R 167401e04c3fSmrg#undef S 167501e04c3fSmrg#undef I 167601e04c3fSmrg 167701e04c3fSmrgir_variable * 167801e04c3fSmrgir_swizzle::variable_referenced() const 167901e04c3fSmrg{ 168001e04c3fSmrg return this->val->variable_referenced(); 168101e04c3fSmrg} 168201e04c3fSmrg 168301e04c3fSmrg 168401e04c3fSmrgbool ir_variable::temporaries_allocate_names = false; 168501e04c3fSmrg 168601e04c3fSmrgconst char ir_variable::tmp_name[] = "compiler_temp"; 168701e04c3fSmrg 168801e04c3fSmrgir_variable::ir_variable(const struct glsl_type *type, const char *name, 168901e04c3fSmrg ir_variable_mode mode) 169001e04c3fSmrg : ir_instruction(ir_type_variable) 169101e04c3fSmrg{ 169201e04c3fSmrg this->type = type; 169301e04c3fSmrg 169401e04c3fSmrg if (mode == ir_var_temporary && !ir_variable::temporaries_allocate_names) 169501e04c3fSmrg name = NULL; 169601e04c3fSmrg 169701e04c3fSmrg /* The ir_variable clone method may call this constructor with name set to 169801e04c3fSmrg * tmp_name. 169901e04c3fSmrg */ 170001e04c3fSmrg assert(name != NULL 170101e04c3fSmrg || mode == ir_var_temporary 170201e04c3fSmrg || mode == ir_var_function_in 170301e04c3fSmrg || mode == ir_var_function_out 170401e04c3fSmrg || mode == ir_var_function_inout); 170501e04c3fSmrg assert(name != ir_variable::tmp_name 170601e04c3fSmrg || mode == ir_var_temporary); 170701e04c3fSmrg if (mode == ir_var_temporary 170801e04c3fSmrg && (name == NULL || name == ir_variable::tmp_name)) { 170901e04c3fSmrg this->name = ir_variable::tmp_name; 171001e04c3fSmrg } else if (name == NULL || 171101e04c3fSmrg strlen(name) < ARRAY_SIZE(this->name_storage)) { 171201e04c3fSmrg strcpy(this->name_storage, name ? name : ""); 171301e04c3fSmrg this->name = this->name_storage; 171401e04c3fSmrg } else { 171501e04c3fSmrg this->name = ralloc_strdup(this, name); 171601e04c3fSmrg } 171701e04c3fSmrg 171801e04c3fSmrg this->u.max_ifc_array_access = NULL; 171901e04c3fSmrg 172001e04c3fSmrg this->data.explicit_location = false; 172101e04c3fSmrg this->data.has_initializer = false; 172201e04c3fSmrg this->data.location = -1; 172301e04c3fSmrg this->data.location_frac = 0; 172401e04c3fSmrg this->data.binding = 0; 172501e04c3fSmrg this->data.warn_extension_index = 0; 172601e04c3fSmrg this->constant_value = NULL; 172701e04c3fSmrg this->constant_initializer = NULL; 172801e04c3fSmrg this->data.origin_upper_left = false; 172901e04c3fSmrg this->data.pixel_center_integer = false; 173001e04c3fSmrg this->data.depth_layout = ir_depth_layout_none; 173101e04c3fSmrg this->data.used = false; 173201e04c3fSmrg this->data.always_active_io = false; 173301e04c3fSmrg this->data.read_only = false; 173401e04c3fSmrg this->data.centroid = false; 173501e04c3fSmrg this->data.sample = false; 173601e04c3fSmrg this->data.patch = false; 173701e04c3fSmrg this->data.invariant = false; 173801e04c3fSmrg this->data.how_declared = ir_var_declared_normally; 173901e04c3fSmrg this->data.mode = mode; 174001e04c3fSmrg this->data.interpolation = INTERP_MODE_NONE; 174101e04c3fSmrg this->data.max_array_access = -1; 174201e04c3fSmrg this->data.offset = 0; 174301e04c3fSmrg this->data.precision = GLSL_PRECISION_NONE; 174401e04c3fSmrg this->data.memory_read_only = false; 174501e04c3fSmrg this->data.memory_write_only = false; 174601e04c3fSmrg this->data.memory_coherent = false; 174701e04c3fSmrg this->data.memory_volatile = false; 174801e04c3fSmrg this->data.memory_restrict = false; 174901e04c3fSmrg this->data.from_ssbo_unsized_array = false; 175001e04c3fSmrg this->data.fb_fetch_output = false; 175101e04c3fSmrg this->data.bindless = false; 175201e04c3fSmrg this->data.bound = false; 175301e04c3fSmrg 175401e04c3fSmrg if (type != NULL) { 175501e04c3fSmrg if (type->is_interface()) 175601e04c3fSmrg this->init_interface_type(type); 175701e04c3fSmrg else if (type->without_array()->is_interface()) 175801e04c3fSmrg this->init_interface_type(type->without_array()); 175901e04c3fSmrg } 176001e04c3fSmrg} 176101e04c3fSmrg 176201e04c3fSmrg 176301e04c3fSmrgconst char * 176401e04c3fSmrginterpolation_string(unsigned interpolation) 176501e04c3fSmrg{ 176601e04c3fSmrg switch (interpolation) { 176701e04c3fSmrg case INTERP_MODE_NONE: return "no"; 176801e04c3fSmrg case INTERP_MODE_SMOOTH: return "smooth"; 176901e04c3fSmrg case INTERP_MODE_FLAT: return "flat"; 177001e04c3fSmrg case INTERP_MODE_NOPERSPECTIVE: return "noperspective"; 177101e04c3fSmrg } 177201e04c3fSmrg 177301e04c3fSmrg assert(!"Should not get here."); 177401e04c3fSmrg return ""; 177501e04c3fSmrg} 177601e04c3fSmrg 177701e04c3fSmrgconst char *const ir_variable::warn_extension_table[] = { 177801e04c3fSmrg "", 177901e04c3fSmrg "GL_ARB_shader_stencil_export", 178001e04c3fSmrg "GL_AMD_shader_stencil_export", 178101e04c3fSmrg}; 178201e04c3fSmrg 178301e04c3fSmrgvoid 178401e04c3fSmrgir_variable::enable_extension_warning(const char *extension) 178501e04c3fSmrg{ 178601e04c3fSmrg for (unsigned i = 0; i < ARRAY_SIZE(warn_extension_table); i++) { 178701e04c3fSmrg if (strcmp(warn_extension_table[i], extension) == 0) { 178801e04c3fSmrg this->data.warn_extension_index = i; 178901e04c3fSmrg return; 179001e04c3fSmrg } 179101e04c3fSmrg } 179201e04c3fSmrg 179301e04c3fSmrg assert(!"Should not get here."); 179401e04c3fSmrg this->data.warn_extension_index = 0; 179501e04c3fSmrg} 179601e04c3fSmrg 179701e04c3fSmrgconst char * 179801e04c3fSmrgir_variable::get_extension_warning() const 179901e04c3fSmrg{ 180001e04c3fSmrg return this->data.warn_extension_index == 0 180101e04c3fSmrg ? NULL : warn_extension_table[this->data.warn_extension_index]; 180201e04c3fSmrg} 180301e04c3fSmrg 180401e04c3fSmrgir_function_signature::ir_function_signature(const glsl_type *return_type, 180501e04c3fSmrg builtin_available_predicate b) 180601e04c3fSmrg : ir_instruction(ir_type_function_signature), 180701e04c3fSmrg return_type(return_type), is_defined(false), 180801e04c3fSmrg intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL) 180901e04c3fSmrg{ 181001e04c3fSmrg this->origin = NULL; 181101e04c3fSmrg} 181201e04c3fSmrg 181301e04c3fSmrg 181401e04c3fSmrgbool 181501e04c3fSmrgir_function_signature::is_builtin() const 181601e04c3fSmrg{ 181701e04c3fSmrg return builtin_avail != NULL; 181801e04c3fSmrg} 181901e04c3fSmrg 182001e04c3fSmrg 182101e04c3fSmrgbool 182201e04c3fSmrgir_function_signature::is_builtin_available(const _mesa_glsl_parse_state *state) const 182301e04c3fSmrg{ 182401e04c3fSmrg /* We can't call the predicate without a state pointer, so just say that 182501e04c3fSmrg * the signature is available. At compile time, we need the filtering, 182601e04c3fSmrg * but also receive a valid state pointer. At link time, we're resolving 182701e04c3fSmrg * imported built-in prototypes to their definitions, which will always 182801e04c3fSmrg * be an exact match. So we can skip the filtering. 182901e04c3fSmrg */ 183001e04c3fSmrg if (state == NULL) 183101e04c3fSmrg return true; 183201e04c3fSmrg 183301e04c3fSmrg assert(builtin_avail != NULL); 183401e04c3fSmrg return builtin_avail(state); 183501e04c3fSmrg} 183601e04c3fSmrg 183701e04c3fSmrg 183801e04c3fSmrgstatic bool 183901e04c3fSmrgmodes_match(unsigned a, unsigned b) 184001e04c3fSmrg{ 184101e04c3fSmrg if (a == b) 184201e04c3fSmrg return true; 184301e04c3fSmrg 184401e04c3fSmrg /* Accept "in" vs. "const in" */ 184501e04c3fSmrg if ((a == ir_var_const_in && b == ir_var_function_in) || 184601e04c3fSmrg (b == ir_var_const_in && a == ir_var_function_in)) 184701e04c3fSmrg return true; 184801e04c3fSmrg 184901e04c3fSmrg return false; 185001e04c3fSmrg} 185101e04c3fSmrg 185201e04c3fSmrg 185301e04c3fSmrgconst char * 185401e04c3fSmrgir_function_signature::qualifiers_match(exec_list *params) 185501e04c3fSmrg{ 185601e04c3fSmrg /* check that the qualifiers match. */ 185701e04c3fSmrg foreach_two_lists(a_node, &this->parameters, b_node, params) { 185801e04c3fSmrg ir_variable *a = (ir_variable *) a_node; 185901e04c3fSmrg ir_variable *b = (ir_variable *) b_node; 186001e04c3fSmrg 186101e04c3fSmrg if (a->data.read_only != b->data.read_only || 186201e04c3fSmrg !modes_match(a->data.mode, b->data.mode) || 186301e04c3fSmrg a->data.interpolation != b->data.interpolation || 186401e04c3fSmrg a->data.centroid != b->data.centroid || 186501e04c3fSmrg a->data.sample != b->data.sample || 186601e04c3fSmrg a->data.patch != b->data.patch || 186701e04c3fSmrg a->data.memory_read_only != b->data.memory_read_only || 186801e04c3fSmrg a->data.memory_write_only != b->data.memory_write_only || 186901e04c3fSmrg a->data.memory_coherent != b->data.memory_coherent || 187001e04c3fSmrg a->data.memory_volatile != b->data.memory_volatile || 187101e04c3fSmrg a->data.memory_restrict != b->data.memory_restrict) { 187201e04c3fSmrg 187301e04c3fSmrg /* parameter a's qualifiers don't match */ 187401e04c3fSmrg return a->name; 187501e04c3fSmrg } 187601e04c3fSmrg } 187701e04c3fSmrg return NULL; 187801e04c3fSmrg} 187901e04c3fSmrg 188001e04c3fSmrg 188101e04c3fSmrgvoid 188201e04c3fSmrgir_function_signature::replace_parameters(exec_list *new_params) 188301e04c3fSmrg{ 188401e04c3fSmrg /* Destroy all of the previous parameter information. If the previous 188501e04c3fSmrg * parameter information comes from the function prototype, it may either 188601e04c3fSmrg * specify incorrect parameter names or not have names at all. 188701e04c3fSmrg */ 188801e04c3fSmrg new_params->move_nodes_to(¶meters); 188901e04c3fSmrg} 189001e04c3fSmrg 189101e04c3fSmrg 189201e04c3fSmrgir_function::ir_function(const char *name) 189301e04c3fSmrg : ir_instruction(ir_type_function) 189401e04c3fSmrg{ 189501e04c3fSmrg this->subroutine_index = -1; 189601e04c3fSmrg this->name = ralloc_strdup(this, name); 189701e04c3fSmrg} 189801e04c3fSmrg 189901e04c3fSmrg 190001e04c3fSmrgbool 190101e04c3fSmrgir_function::has_user_signature() 190201e04c3fSmrg{ 190301e04c3fSmrg foreach_in_list(ir_function_signature, sig, &this->signatures) { 190401e04c3fSmrg if (!sig->is_builtin()) 190501e04c3fSmrg return true; 190601e04c3fSmrg } 190701e04c3fSmrg return false; 190801e04c3fSmrg} 190901e04c3fSmrg 191001e04c3fSmrg 191101e04c3fSmrgir_rvalue * 191201e04c3fSmrgir_rvalue::error_value(void *mem_ctx) 191301e04c3fSmrg{ 191401e04c3fSmrg ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_unset); 191501e04c3fSmrg 191601e04c3fSmrg v->type = glsl_type::error_type; 191701e04c3fSmrg return v; 191801e04c3fSmrg} 191901e04c3fSmrg 192001e04c3fSmrg 192101e04c3fSmrgvoid 192201e04c3fSmrgvisit_exec_list(exec_list *list, ir_visitor *visitor) 192301e04c3fSmrg{ 192401e04c3fSmrg foreach_in_list_safe(ir_instruction, node, list) { 192501e04c3fSmrg node->accept(visitor); 192601e04c3fSmrg } 192701e04c3fSmrg} 192801e04c3fSmrg 192901e04c3fSmrg 193001e04c3fSmrgstatic void 193101e04c3fSmrgsteal_memory(ir_instruction *ir, void *new_ctx) 193201e04c3fSmrg{ 193301e04c3fSmrg ir_variable *var = ir->as_variable(); 193401e04c3fSmrg ir_function *fn = ir->as_function(); 193501e04c3fSmrg ir_constant *constant = ir->as_constant(); 193601e04c3fSmrg if (var != NULL && var->constant_value != NULL) 193701e04c3fSmrg steal_memory(var->constant_value, ir); 193801e04c3fSmrg 193901e04c3fSmrg if (var != NULL && var->constant_initializer != NULL) 194001e04c3fSmrg steal_memory(var->constant_initializer, ir); 194101e04c3fSmrg 194201e04c3fSmrg if (fn != NULL && fn->subroutine_types) 194301e04c3fSmrg ralloc_steal(new_ctx, fn->subroutine_types); 194401e04c3fSmrg 194501e04c3fSmrg /* The components of aggregate constants are not visited by the normal 194601e04c3fSmrg * visitor, so steal their values by hand. 194701e04c3fSmrg */ 194801e04c3fSmrg if (constant != NULL && 194901e04c3fSmrg (constant->type->is_array() || constant->type->is_record())) { 195001e04c3fSmrg for (unsigned int i = 0; i < constant->type->length; i++) { 195101e04c3fSmrg steal_memory(constant->const_elements[i], ir); 195201e04c3fSmrg } 195301e04c3fSmrg } 195401e04c3fSmrg 195501e04c3fSmrg ralloc_steal(new_ctx, ir); 195601e04c3fSmrg} 195701e04c3fSmrg 195801e04c3fSmrg 195901e04c3fSmrgvoid 196001e04c3fSmrgreparent_ir(exec_list *list, void *mem_ctx) 196101e04c3fSmrg{ 196201e04c3fSmrg foreach_in_list(ir_instruction, node, list) { 196301e04c3fSmrg visit_tree(node, steal_memory, mem_ctx); 196401e04c3fSmrg } 196501e04c3fSmrg} 196601e04c3fSmrg 196701e04c3fSmrg 196801e04c3fSmrgstatic ir_rvalue * 196901e04c3fSmrgtry_min_one(ir_rvalue *ir) 197001e04c3fSmrg{ 197101e04c3fSmrg ir_expression *expr = ir->as_expression(); 197201e04c3fSmrg 197301e04c3fSmrg if (!expr || expr->operation != ir_binop_min) 197401e04c3fSmrg return NULL; 197501e04c3fSmrg 197601e04c3fSmrg if (expr->operands[0]->is_one()) 197701e04c3fSmrg return expr->operands[1]; 197801e04c3fSmrg 197901e04c3fSmrg if (expr->operands[1]->is_one()) 198001e04c3fSmrg return expr->operands[0]; 198101e04c3fSmrg 198201e04c3fSmrg return NULL; 198301e04c3fSmrg} 198401e04c3fSmrg 198501e04c3fSmrgstatic ir_rvalue * 198601e04c3fSmrgtry_max_zero(ir_rvalue *ir) 198701e04c3fSmrg{ 198801e04c3fSmrg ir_expression *expr = ir->as_expression(); 198901e04c3fSmrg 199001e04c3fSmrg if (!expr || expr->operation != ir_binop_max) 199101e04c3fSmrg return NULL; 199201e04c3fSmrg 199301e04c3fSmrg if (expr->operands[0]->is_zero()) 199401e04c3fSmrg return expr->operands[1]; 199501e04c3fSmrg 199601e04c3fSmrg if (expr->operands[1]->is_zero()) 199701e04c3fSmrg return expr->operands[0]; 199801e04c3fSmrg 199901e04c3fSmrg return NULL; 200001e04c3fSmrg} 200101e04c3fSmrg 200201e04c3fSmrgir_rvalue * 200301e04c3fSmrgir_rvalue::as_rvalue_to_saturate() 200401e04c3fSmrg{ 200501e04c3fSmrg ir_expression *expr = this->as_expression(); 200601e04c3fSmrg 200701e04c3fSmrg if (!expr) 200801e04c3fSmrg return NULL; 200901e04c3fSmrg 201001e04c3fSmrg ir_rvalue *max_zero = try_max_zero(expr); 201101e04c3fSmrg if (max_zero) { 201201e04c3fSmrg return try_min_one(max_zero); 201301e04c3fSmrg } else { 201401e04c3fSmrg ir_rvalue *min_one = try_min_one(expr); 201501e04c3fSmrg if (min_one) { 201601e04c3fSmrg return try_max_zero(min_one); 201701e04c3fSmrg } 201801e04c3fSmrg } 201901e04c3fSmrg 202001e04c3fSmrg return NULL; 202101e04c3fSmrg} 202201e04c3fSmrg 202301e04c3fSmrg 202401e04c3fSmrgunsigned 202501e04c3fSmrgvertices_per_prim(GLenum prim) 202601e04c3fSmrg{ 202701e04c3fSmrg switch (prim) { 202801e04c3fSmrg case GL_POINTS: 202901e04c3fSmrg return 1; 203001e04c3fSmrg case GL_LINES: 203101e04c3fSmrg return 2; 203201e04c3fSmrg case GL_TRIANGLES: 203301e04c3fSmrg return 3; 203401e04c3fSmrg case GL_LINES_ADJACENCY: 203501e04c3fSmrg return 4; 203601e04c3fSmrg case GL_TRIANGLES_ADJACENCY: 203701e04c3fSmrg return 6; 203801e04c3fSmrg default: 203901e04c3fSmrg assert(!"Bad primitive"); 204001e04c3fSmrg return 3; 204101e04c3fSmrg } 204201e04c3fSmrg} 204301e04c3fSmrg 204401e04c3fSmrg/** 204501e04c3fSmrg * Generate a string describing the mode of a variable 204601e04c3fSmrg */ 204701e04c3fSmrgconst char * 204801e04c3fSmrgmode_string(const ir_variable *var) 204901e04c3fSmrg{ 205001e04c3fSmrg switch (var->data.mode) { 205101e04c3fSmrg case ir_var_auto: 205201e04c3fSmrg return (var->data.read_only) ? "global constant" : "global variable"; 205301e04c3fSmrg 205401e04c3fSmrg case ir_var_uniform: 205501e04c3fSmrg return "uniform"; 205601e04c3fSmrg 205701e04c3fSmrg case ir_var_shader_storage: 205801e04c3fSmrg return "buffer"; 205901e04c3fSmrg 206001e04c3fSmrg case ir_var_shader_in: 206101e04c3fSmrg return "shader input"; 206201e04c3fSmrg 206301e04c3fSmrg case ir_var_shader_out: 206401e04c3fSmrg return "shader output"; 206501e04c3fSmrg 206601e04c3fSmrg case ir_var_function_in: 206701e04c3fSmrg case ir_var_const_in: 206801e04c3fSmrg return "function input"; 206901e04c3fSmrg 207001e04c3fSmrg case ir_var_function_out: 207101e04c3fSmrg return "function output"; 207201e04c3fSmrg 207301e04c3fSmrg case ir_var_function_inout: 207401e04c3fSmrg return "function inout"; 207501e04c3fSmrg 207601e04c3fSmrg case ir_var_system_value: 207701e04c3fSmrg return "shader input"; 207801e04c3fSmrg 207901e04c3fSmrg case ir_var_temporary: 208001e04c3fSmrg return "compiler temporary"; 208101e04c3fSmrg 208201e04c3fSmrg case ir_var_mode_count: 208301e04c3fSmrg break; 208401e04c3fSmrg } 208501e04c3fSmrg 208601e04c3fSmrg assert(!"Should not get here."); 208701e04c3fSmrg return "invalid variable"; 208801e04c3fSmrg} 2089