ir_to_mesa.cpp revision 455290e4281bf53ce2fe248a2adf5163563c44c8
184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/* 2bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. 3bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Copyright © 2010 Intel Corporation 584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * copy of this software and associated documentation files (the "Software"), 884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to deal in the Software without restriction, including without limitation 984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 1184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software is furnished to do so, subject to the following conditions: 1284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 1384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * The above copyright notice and this permission notice (including the next 1484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * paragraph) shall be included in all copies or substantial portions of the 1584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software. 1684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 1784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * DEALINGS IN THE SOFTWARE. 2484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 2584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/** 2784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * \file ir_to_mesa.cpp 2884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 2984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Translates the IR to ARB_fragment_program text if possible, 3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * printing the result 3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 3284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 330161515c395c44233529c8d51f823b60050bc7baEric Anholt#include <stdio.h> 3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h" 3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h" 3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h" 3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h" 3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h" 39364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h" 40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h" 41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h" 42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h" 4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 44aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" { 450a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h" 46afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h" 47afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/uniforms.h" 48fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h" 49afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h" 50afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h" 51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h" 52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h" 53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h" 54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h" 55aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt} 5684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 579c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtstatic int swizzle_for_size(int size); 589c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/** 60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with 61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields. 62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg { 649c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg(int file, int index, const glsl_type *type) 659c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 669c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->file = file; 679c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->index = index; 689c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) 699c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = swizzle_for_size(type->vector_elements); 709c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt else 719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = SWIZZLE_XYZW; 729c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->negate = 0; 739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->reladdr = NULL; 749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 759c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg() 779c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 789c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->file = PROGRAM_UNDEFINED; 799c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 809c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 82554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 83582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 84554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int negate; /**< NEGATE_XYZW mask from mesa */ 85f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 86f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 87554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg; 88554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 89554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg { 90554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 91554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 92554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 93854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLuint cond_mask:4; 94f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 95f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg; 97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef; 99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node { 101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op; 103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst_reg; 104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src_reg[3]; 105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** Pointer to the ir source this tree came from for debugging */ 106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_instruction *ir; 107854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLboolean cond_update; 108d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler; /**< sampler index */ 109d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int tex_target; /**< One of TEXTURE_*_INDEX */ 110b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt GLboolean tex_shadow; 1117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ 113554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 114554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 115b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node { 116554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 117b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage(ir_variable *var, int file, int index) 118554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt : file(file), index(index), var(var) 119554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt { 120554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /* empty */ 121554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt } 122554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 123554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; 124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; 125554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_variable *var; /* variable that maps to this, if any */ 126554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 127554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node { 1297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic: 1307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig; 1317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * identifier of this function signature used by the program. 1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * At the point that Mesa instructions for function calls are 1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * generated, we don't know the address of the first instruction of 1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * the function body. So we make the BranchTarget that is called a 1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * small integer and rewrite them during set_branchtargets(). 1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int sig_id; 1417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Pointer to first instruction of the function body. 1447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set during function body emits after main() is processed. 1467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *bgn_inst; 1487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Index of the first instruction of the function body in actual 1517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Mesa IR. 1527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set after convertion from ir_to_mesa_instruction to prog_instruction. 1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int inst; 1567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** Storage for the return value. */ 1587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg return_reg; 1597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}; 1607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 161554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor { 162554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_visitor(); 164fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt ~ir_to_mesa_visitor(); 165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *current_function; 1677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 168364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLcontext *ctx; 169364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 170364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int next_temp; 172a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 173b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *find_variable_storage(ir_variable *var); 174554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *get_function_signature(ir_function_signature *sig); 1767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1778364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt ir_to_mesa_src_reg get_temp(const glsl_type *type); 178f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt void reladdr_to_temp(ir_instruction *ir, 179f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr); 180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg src_reg_for_float(float val); 182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 183554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 184554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 185554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 190554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 191554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 192554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 193554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 194554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 195554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 196554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 197554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 200554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 201554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 202554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 203554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 20516efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg result; 211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 212b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 213b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 2167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 2177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 2187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 219554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 220554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 222021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir, 223021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op); 224021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 225554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir, 226554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 227554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 228554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 229554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 230554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir, 231554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 232554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 233554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 234554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1); 235554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 236554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir, 237554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 238554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 239554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 240554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1, 241554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src2); 242554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt void ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 244554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 245554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 246554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 2470ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt 248904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt void ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 249904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 250904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 251904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0, 252904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1); 253904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 2543f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt GLboolean try_emit_mad(ir_expression *ir, 2553f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 2563f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 25747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt int add_uniform(const char *name, 25847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt const glsl_type *type, 25947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir_constant *constant); 26026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt void add_aggregate_uniform(ir_instruction *ir, 26126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt const char *name, 26226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt const struct glsl_type *type, 26347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir_constant *constant, 26426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt struct ir_to_mesa_dst_reg temp); 26526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 266fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt struct hash_table *sampler_map; 267d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 268fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt void set_sampler_location(ir_variable *sampler, int location); 269fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt int get_sampler_location(ir_variable *sampler); 270d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 271364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 272554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 273554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL); 27584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 276c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = { 277f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL, 278c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}; 279c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2800161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = { 281f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL 2820161515c395c44233529c8d51f823b60050bc7baEric Anholt}; 2830161515c395c44233529c8d51f823b60050bc7baEric Anholt 2840161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size) 2850161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 2860161515c395c44233529c8d51f823b60050bc7baEric Anholt int size_swizzles[4] = { 2870161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 2880161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 2890161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 2900161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 2910161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 2920161515c395c44233529c8d51f823b60050bc7baEric Anholt 2930161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 2940161515c395c44233529c8d51f823b60050bc7baEric Anholt} 2950161515c395c44233529c8d51f823b60050bc7baEric Anholt 29684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 2970161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir, 2980161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 2990161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3000161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 3010161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1, 3020161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src2) 30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 304364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 305f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 306f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 307f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 308f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 309f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 310f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 311f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 312f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 313f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 314f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 315f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 316f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 317f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 318f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 319f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 320f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 321f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, 322f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *dst.reladdr); 323f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 324f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 325f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 326f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 32784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 32884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 32984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->dst_reg = dst; 33084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[0] = src0; 33184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[1] = src1; 33284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[2] = src2; 333c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 33484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function = NULL; 3367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3370161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 33884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 33984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 34084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 34184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 34284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 34384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3440161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir, 3450161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3460161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3470161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 3480161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1) 34984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3500161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef); 35184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 35284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 35384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3540161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir, 3550161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3560161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3570161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0) 358bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 3595a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(dst.writemask != 0); 3600161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, 3610161515c395c44233529c8d51f823b60050bc7baEric Anholt src0, ir_to_mesa_undef, ir_to_mesa_undef); 362bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 363bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 364021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 365021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir, 366021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op) 367021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 368021222c6a872ca2eef770ebadb8754f659775204Eric Anholt return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst, 369021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 370021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 371021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef); 372021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 373021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 374d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtvoid 375fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::set_sampler_location(ir_variable *sampler, int location) 376d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{ 377fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt if (this->sampler_map == NULL) { 378fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt this->sampler_map = hash_table_ctor(0, hash_table_pointer_hash, 379fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt hash_table_pointer_compare); 380d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 381d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 382fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt hash_table_insert(this->sampler_map, (void *)(uintptr_t)location, sampler); 383d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt} 384d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 385d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtint 386fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::get_sampler_location(ir_variable *sampler) 387d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{ 388fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt void *result = hash_table_find(this->sampler_map, sampler); 389fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt 390fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt return (int)(uintptr_t)result; 391d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt} 392d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 3930161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg 3940161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg) 39584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3960161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst_reg; 39784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3980161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.file = reg.file; 3990161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.index = reg.index; 4000161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.writemask = WRITEMASK_XYZW; 401854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt dst_reg.cond_mask = COND_TR; 402f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt dst_reg.reladdr = reg.reladdr; 4030161515c395c44233529c8d51f823b60050bc7baEric Anholt 4040161515c395c44233529c8d51f823b60050bc7baEric Anholt return dst_reg; 405bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 406bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 4072d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg 4082d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg) 4092d1789e667c4180777829f96856daf91326721b9Eric Anholt{ 4109c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt return ir_to_mesa_src_reg(reg.file, reg.index, NULL); 4112d1789e667c4180777829f96856daf91326721b9Eric Anholt} 4122d1789e667c4180777829f96856daf91326721b9Eric Anholt 41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 41412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 41512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 41612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 41712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 41812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 41912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 42012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 42112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 422904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 4230161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 4240161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 425904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src0, 426904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src1) 42712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 42812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 429315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 43212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 43312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 43412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 43512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 436582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 43712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 438904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0 = orig_src0; 439904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1 = orig_src1; 44012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 444904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 445904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 44612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 449904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 45012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 45112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 45212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 453904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 456904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 45712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 458904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt inst = ir_to_mesa_emit_op2(ir, op, 4590161515c395c44233529c8d51f823b60050bc7baEric Anholt dst, 460904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0, 461904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1); 46212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt inst->dst_reg.writemask = this_mask; 46312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 46412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 46512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 46612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 467904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 468904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 469904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 470904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 471904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0) 472904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 47359a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt ir_to_mesa_src_reg undef = ir_to_mesa_undef; 474904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 475904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 476904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 477904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef); 478904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 479904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 4800161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg 4810161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 482b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 4839c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL); 4841d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 485582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 486582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt &val, 1, &src_reg.swizzle); 4871d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4880161515c395c44233529c8d51f823b60050bc7baEric Anholt return src_reg; 4891d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 4901d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 4922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 4932c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 4942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 4962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 4972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 4982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 4992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 5002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 502a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 5039968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 504a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 505a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 506a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 507a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 508a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 509a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 510a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 511a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 5122c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 5132c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 5142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 5152c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 5162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 5172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 5182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 5192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 5202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 5212c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 5222c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 5232c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 5242c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 525d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 526d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 527d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 528d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 529d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 530d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 531d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg 532d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 533d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 534d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt ir_to_mesa_src_reg src_reg; 535d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int swizzle[4]; 536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int i; 537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 538d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.file = PROGRAM_TEMPORARY; 539d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.index = next_temp; 540f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 541d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 542d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 54320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (type->is_array() || type->is_record()) { 54420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.swizzle = SWIZZLE_NOOP; 54520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } else { 54620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < type->vector_elements; i++) 54720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[i] = i; 54820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (; i < 4; i++) 54920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[i] = type->vector_elements - 1; 55020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], 55120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[2], swizzle[3]); 55220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 553ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt src_reg.negate = 0; 554d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 555d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt return src_reg; 556d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 557d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 558b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 559a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 561a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 562b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 56384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 564b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 565b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 56684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 5670161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 568a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 56984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 57084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 571a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 572a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 57684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 5774a962170d7cf4243d6ae156fca20a6167388925dEric Anholt if (strcmp(ir->name, "gl_FragCoord") == 0) { 5784a962170d7cf4243d6ae156fca20a6167388925dEric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 5794a962170d7cf4243d6ae156fca20a6167388925dEric Anholt 5804a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->OriginUpperLeft = ir->origin_upper_left; 5814a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->PixelCenterInteger = ir->pixel_center_integer; 5824a962170d7cf4243d6ae156fca20a6167388925dEric Anholt } 58384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 58484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 58864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->from); 58964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->to); 59064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->increment); 59164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->counter); 59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 593021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); 59464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 595021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); 59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 60164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 60264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 603021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BRK); 60464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 60564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 606021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_CONT); 60764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 60864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 61684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 61784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 61884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 62084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 62184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 62284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 62384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 62484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 62584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 62684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 62784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 62884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 62984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 63084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 63184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 63284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 63384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 63484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 63584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 63684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 63784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 63884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 63984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 64084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6413f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean 6423f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 6433f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 6443f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 6453f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_src_reg a, b, c; 6463f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6473f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 6483f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 6493f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 6503f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6513f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 6523f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 6533f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 6543f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 6553f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 6563f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 6573f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6583f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 6593f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_emit_op3(ir, OPCODE_MAD, 6603f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_dst_reg_from_src(this->result), a, b, c); 6613f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6623f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 6633f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 6643f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 66584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 666f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 667f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr) 668f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 669f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 670f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 671f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 672f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr); 673f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 674f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 675f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 676f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 677f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, 678f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_dst_reg_from_src(temp), *reg); 679f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 680f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 681f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 682f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 683f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 684f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 685f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 689f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt struct ir_to_mesa_src_reg op[2]; 6900161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg result_src; 6910161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg result_dst; 69284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1); 69384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1); 69484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1); 69584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6963f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 6973f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 6983f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 6993f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 7003f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 7013f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 7023f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 7033f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 7043f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 70584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 7060161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 70784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 7080161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 70984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 71084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 71284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 71384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 71484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 7158364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 7164ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 7174ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 7184ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 7194ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 72084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 72184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 7220161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 7230161515c395c44233529c8d51f823b60050bc7baEric Anholt 7240161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 7250161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 7260161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 7278364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 7280161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 7290161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 7309cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 7319cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 7329cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 7339cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 7349cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 73584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 73684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 7371d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 738f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, 739f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt op[0], src_reg_for_float(0.0)); 7401d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 741c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 7420161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 7430161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 744c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 745524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 746524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]); 747524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 7483acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 7493acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]); 7503acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 7518761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 7528761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]); 7538761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 754524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 7558c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp: 756b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, 757b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt src_reg_for_float(M_E), op[0]); 7588c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7598c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 7600161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]); 7618c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7628c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 7630161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]); 7648c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7658c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 7660161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]); 7678c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7683c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 7690161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]); 7703c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 7713c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 7720161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]); 7733c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 774ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 775ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 776ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]); 777ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 778ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 779ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]); 780ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 781ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 78284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 7837b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]); 78484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 78584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 7867b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]); 78784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 7889b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 78984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 7904ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]); 79184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 79284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 7939a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 794411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 795411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 796411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 79738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 79838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 799f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]); 80038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 80138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 802f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]); 80338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 80438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 805f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]); 80638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 80738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 808f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); 80938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 81038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 811f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 81238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 813763cd75863ed9a16912e585887580c44d1e8109fEric Anholt case ir_binop_logic_xor: 81438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_nequal: 815f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 81638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 81738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 8184380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_or: 8190161515c395c44233529c8d51f823b60050bc7baEric Anholt /* This could be a saturated add and skip the SNE. */ 8200161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, 8210161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8220161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 8230161515c395c44233529c8d51f823b60050bc7baEric Anholt 8240161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 8250161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8260161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 8274380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8284380099c98119611ceee684669d00be26195c7d7Eric Anholt 8294380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 8304380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 8310161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 8320161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8330161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 8344380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8354380099c98119611ceee684669d00be26195c7d7Eric Anholt 83684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 83784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (ir->operands[0]->type == vec4_type) { 83884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec4_type); 8390161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP4, 8400161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8410161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 84284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec3_type) { 84384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec3_type); 8440161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP3, 8450161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8460161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 84784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec2_type) { 84884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec2_type); 8490161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP2, 8500161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8510161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 85284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 85384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 8549be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 8559be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt case ir_binop_cross: 8569be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]); 8579be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt break; 8589be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 8600161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 8618f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src); 8628f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt /* For incoming channels < 0, set the result to 0. */ 8638f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst, 8648f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt op[0], src_reg_for_float(0.0), result_src); 86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 866878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 8670161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 868878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 86950ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 870d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 871d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 872423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 8730161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 87450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 875423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 8760161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 877423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 8781d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 879411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 8800161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, 8810161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 8821d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 883c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 8840161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 885c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 886c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 8870161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 8880161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 8890161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 890c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 891c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 8920161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 893c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 894d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 895d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]); 896d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 897d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 898c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 8990161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]); 900c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 901c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 9020161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]); 903c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 904904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 905904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]); 906904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 907e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 908e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_bit_not: 909e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_u2f: 910e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 911e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 912e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 913e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 914e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 915e64a4aaacbc682f24180dff3627b84861844476dEric Anholt assert(!"GLSL 1.30 features unsupported"); 916e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 91784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 918b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 9190161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 92184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 92284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 92384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 92484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 92584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 9260161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 92784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 930b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 931b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 932b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 933b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 93484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 9364006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt src_reg = this->result; 9374006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt assert(src_reg.file != PROGRAM_UNDEFINED); 93884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 93984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 94184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 94284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 943698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x); 94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 946698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y); 94784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 94884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 949698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z); 95084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 95184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 952698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w); 95384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 95484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 95584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 95684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 95784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 95884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 959698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 96084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 96184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 96284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9630161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], 9640161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[1], 9650161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[2], 9660161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[3]); 96784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9680161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 96984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 97084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 971dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic const struct { 972dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt const char *name; 973dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt const char *field; 974dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt int tokens[STATE_LENGTH]; 975dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt int swizzle; 976dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt bool array_indexed; 977dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt} statevars[] = { 978dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_DepthRange", "near", 979dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX}, 980dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_DepthRange", "far", 981dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY}, 982dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_DepthRange", "diff", 983dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ}, 984dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 985dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ClipPlane", NULL, 986dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW, true} 987dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt, 988dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "size", 989dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_POINT_SIZE}, SWIZZLE_XXXX}, 990dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "sizeMin", 991dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_POINT_SIZE}, SWIZZLE_YYYY}, 992dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "sizeMax", 993dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_POINT_SIZE}, SWIZZLE_ZZZZ}, 994dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "fadeThresholdSize", 995dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_POINT_SIZE}, SWIZZLE_WWWW}, 996dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "distanceConstantAttenuation", 997dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX}, 998dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "distanceLinearAttenuation", 999dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY}, 1000dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "distanceQuadraticAttenuation", 1001dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ}, 1002dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1003dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "emission", 1004dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW}, 1005dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "ambient", 1006dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW}, 1007dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "diffuse", 1008dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW}, 1009dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "specular", 1010dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW}, 1011dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "shininess", 1012dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX}, 1013dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1014dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "emission", 1015dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW}, 1016dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "ambient", 1017dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW}, 1018dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "diffuse", 1019dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW}, 1020dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "specular", 1021dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW}, 1022dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "shininess", 1023dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX}, 1024dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1025dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "ambient", 1026dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true}, 1027dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "diffuse", 1028dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true}, 1029dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "specular", 1030dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true}, 1031dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "position", 1032dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW, true}, 1033dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "halfVector", 1034dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW, true}, 1035dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotDirection", 1036dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW, true}, 1037dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotCosCutoff", 1038dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW, true}, 1039dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotCutoff", 1040dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX, true}, 1041dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotExponent", 1042dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW, true}, 1043dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "constantAttenuation", 1044dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX, true}, 1045dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "linearAttenuation", 1046dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY, true}, 1047dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "quadraticAttenuation", 1048dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ, true}, 1049dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1050dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightModel", NULL, 1051dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW}, 1052dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1053dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontLightModelProduct", NULL, 1054dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW}, 1055dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackLightModelProduct", NULL, 1056dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW}, 1057dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1058dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontLightProduct", "ambient", 1059dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true}, 1060dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontLightProduct", "diffuse", 1061dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true}, 1062dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontLightProduct", "specular", 1063dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true}, 1064dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1065dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackLightProduct", "ambient", 1066dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW, true}, 1067dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackLightProduct", "diffuse", 1068dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, true}, 1069dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackLightProduct", "specular", 1070dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW, true}, 1071dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1072dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_TextureEnvColor", "ambient", 1073dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW, true}, 1074dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1075dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneS", NULL, 1076dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW, true}, 1077dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneT", NULL, 1078dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW, true}, 1079dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneR", NULL, 1080dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW, true}, 1081dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneQ", NULL, 1082dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW, true}, 1083dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1084dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneS", NULL, 1085dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW, true}, 1086dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneT", NULL, 1087dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW, true}, 1088dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneR", NULL, 1089dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW, true}, 1090dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneQ", NULL, 1091dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW, true}, 1092dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1093dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "color", 1094dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_FOG_COLOR}, SWIZZLE_XYZW}, 1095dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "density", 1096dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_FOG_PARAMS}, SWIZZLE_XXXX}, 1097dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "start", 1098dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_FOG_PARAMS}, SWIZZLE_YYYY}, 1099dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "end", 1100dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ}, 1101dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "scale", 1102dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_FOG_PARAMS}, SWIZZLE_WWWW}, 1103dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt}; 1104dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1105dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic ir_to_mesa_src_reg 1106dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtget_builtin_uniform_reg(struct gl_program *prog, 1107dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt const char *name, int array_index, const char *field) 1108dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt{ 1109dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt unsigned int i; 1110dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_to_mesa_src_reg src_reg; 1111dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt int tokens[STATE_LENGTH]; 1112dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1113dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt for (i = 0; i < Elements(statevars); i++) { 1114dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (strcmp(statevars[i].name, name) != 0) 1115dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt continue; 1116dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (!field && statevars[i].field) { 1117dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt assert(!"FINISHME: whole-structure state var dereference"); 1118dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1119dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (field && strcmp(statevars[i].field, field) != 0) 1120dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt continue; 1121dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt break; 1122dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1123dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1124dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (i == Elements(statevars)) { 1125dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt printf("builtin uniform %s%s%s not found\n", 1126dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt name, 1127dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt field ? "." : "", 1128dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt field ? field : ""); 1129dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt abort(); 1130dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1131dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1132dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt memcpy(&tokens, statevars[i].tokens, sizeof(tokens)); 1133dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (statevars[i].array_indexed) 1134dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt tokens[1] = array_index; 1135dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1136dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.file = PROGRAM_STATE_VAR; 1137dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.index = _mesa_add_state_reference(prog->Parameters, 1138dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt (gl_state_index *)tokens); 1139dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.swizzle = statevars[i].swizzle; 1140dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.negate = 0; 1141dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.reladdr = false; 1142dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1143dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt return src_reg; 1144dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt} 1145dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 114676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int 114776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens) 114876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{ 114976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 115076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int i; 115176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 115276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt /* Add a ref for each column. It looks like the reason we do 115376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * it this way is that _mesa_add_state_reference doesn't work 115476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * for things that aren't vec4s, so the tokens[2]/tokens[3] 115576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * range has to be equal. 115676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt */ 115776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < 4; i++) { 115876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[2] = i; 115976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[3] = i; 116076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = _mesa_add_state_reference(prog->Parameters, 116176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt (gl_state_index *)tokens); 116276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 116376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 116476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 116576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + i == pos); 116676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 116776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 116876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return base_pos; 116976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt} 117076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1171b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage * 117276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var, 117376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_rvalue *array_index) 1174bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{ 1175bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* 1176bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * NOTE: The ARB_vertex_program extension specified that matrices get 1177bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * loaded in registers in row-major order. With GLSL, we want column- 1178bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * major order. So, we need to transpose all matrices here... 1179bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 1180bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt static const struct { 1181bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt const char *name; 1182bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int matrix; 1183bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int modifier; 1184bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } matrices[] = { 1185bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, 1186bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS }, 1187bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, 1188bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 1189bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1190bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE }, 1191bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS }, 1192bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 }, 1193bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE }, 1194bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1195bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE }, 1196bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS }, 1197bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 }, 1198bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE }, 1199bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1200bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE }, 1201bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS }, 1202bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 }, 1203bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, 1204bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1205bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 1206bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1207bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt }; 1208bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt unsigned int i; 1209b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 1210bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1211bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* C++ gets angry when we try to use an int as a gl_state_index, so we use 1212bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * ints for gl_state_index. Make sure they're compatible. 1213bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 1214bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt assert(sizeof(gl_state_index) == sizeof(int)); 1215bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1216bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt for (i = 0; i < Elements(matrices); i++) { 1217bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (strcmp(var->name, matrices[i].name) == 0) { 1218bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int tokens[STATE_LENGTH]; 121976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 1220bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1221bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[0] = matrices[i].matrix; 1222bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[4] = matrices[i].modifier; 122376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (matrices[i].matrix == STATE_TEXTURE_MATRIX) { 122476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_constant *index = array_index->constant_expression_value(); 122576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 122676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = index->value.i[0]; 122776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 122876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 122976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < var->type->length; i++) { 123076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = i; 123176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = add_matrix_ref(prog, tokens); 123276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 123376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 123476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 123576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + (int)i * 4 == pos); 123676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 123776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 123876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 123976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = 0; /* unused array index */ 124076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 1241bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 124276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[4] = matrices[i].modifier; 1243bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1244b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(var, 1245b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_STATE_VAR, 1246b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt base_pos); 1247bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1248bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return entry; 1249bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1250bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1251bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1252bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return NULL; 1253bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt} 1254bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 125547f305a4fcd23f859d097c6cc25a739547462939Eric Anholtint 125647f305a4fcd23f859d097c6cc25a739547462939Eric Anholtir_to_mesa_visitor::add_uniform(const char *name, 125747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt const glsl_type *type, 125847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir_constant *constant) 125947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt{ 126047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt int len; 126147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 126247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt if (type->is_vector() || 126347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt type->is_scalar()) { 126447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt len = type->vector_elements; 126547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } else { 126647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt len = type_size(type) * 4; 126747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } 126847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 126947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt float *values = NULL; 127047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt if (constant && type->is_array()) { 127147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values = (float *)malloc(type->length * 4 * sizeof(float)); 127247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 127347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt assert(type->fields.array->is_scalar() || 127447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt type->fields.array->is_vector() || 127547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt !"FINISHME: uniform array initializers for non-vector"); 127647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 127747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt for (unsigned int i = 0; i < type->length; i++) { 127847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir_constant *element = constant->array_elements[i]; 127947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt unsigned int c; 128047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 128147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt for (c = 0; c < type->fields.array->vector_elements; c++) { 128247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt switch (type->fields.array->base_type) { 128347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_FLOAT: 128447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[4 * i + c] = element->value.f[c]; 128547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 128647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_INT: 128747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[4 * i + c] = element->value.i[c]; 128847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 128947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_UINT: 129047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[4 * i + c] = element->value.u[c]; 129147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 129247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_BOOL: 129347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[4 * i + c] = element->value.b[c]; 129447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 129547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt default: 129647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt assert(!"not reached"); 129747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } 129847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } 129947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } 130047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } else if (constant) { 130147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values = (float *)malloc(16 * sizeof(float)); 130247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt for (unsigned int i = 0; i < type->components(); i++) { 130347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt switch (type->base_type) { 130447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_FLOAT: 130547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[i] = constant->value.f[i]; 130647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 130747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_INT: 130847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[i] = constant->value.i[i]; 130947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 131047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_UINT: 131147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[i] = constant->value.u[i]; 131247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 131347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt case GLSL_TYPE_BOOL: 131447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values[i] = constant->value.b[i]; 131547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt break; 131647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt default: 131747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt assert(!"not reached"); 131847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } 131947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } 132047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt } 132147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 132247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt int loc = _mesa_add_uniform(this->prog->Parameters, 132347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt name, 132447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt len, 132547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt type->gl_type, 132647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt values); 132747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt free(values); 132847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 132947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt return loc; 133047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt} 133147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 133226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt/* Recursively add all the members of the aggregate uniform as uniform names 133326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt * to Mesa, moving those uniforms to our structured temporary. 133426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt */ 133526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholtvoid 133626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholtir_to_mesa_visitor::add_aggregate_uniform(ir_instruction *ir, 133726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt const char *name, 133826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt const struct glsl_type *type, 133947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir_constant *constant, 134026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt struct ir_to_mesa_dst_reg temp) 134126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt{ 134226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt int loc; 134326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 134426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt if (type->is_record()) { 134526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt void *mem_ctx = talloc_new(NULL); 134647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir_constant *field_constant = NULL; 134747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 134847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt if (constant) 134947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt field_constant = (ir_constant *)constant->components.get_head(); 135026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 135126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt for (unsigned int i = 0; i < type->length; i++) { 135226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt const glsl_type *field_type = type->fields.structure[i].type; 135347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 135426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt add_aggregate_uniform(ir, 135526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt talloc_asprintf(mem_ctx, "%s.%s", name, 135626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt type->fields.structure[i].name), 135747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt field_type, field_constant, temp); 135826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt temp.index += type_size(field_type); 135947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt 136047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt if (constant) 136147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt field_constant = (ir_constant *)field_constant->next; 136226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt } 136326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 136426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt talloc_free(mem_ctx); 136526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 136626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt return; 136726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt } 136826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 136926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt assert(type->is_vector() || type->is_scalar() || !"FINISHME: other types"); 137026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 137147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt loc = add_uniform(name, type, constant); 137226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 137326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt ir_to_mesa_src_reg uniform(PROGRAM_UNIFORM, loc, type); 137426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 137526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt for (int i = 0; i < type_size(type); i++) { 137626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, uniform); 137726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt temp.index++; 137826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt uniform.index++; 137926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt } 138026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt} 138126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 138226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 138384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 138484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 138584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1386b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 1387a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt unsigned int loc; 138884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 13898364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 13908364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt switch (ir->var->mode) { 13918364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 139276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var, 139376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt NULL); 1394bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (entry) 1395bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt break; 1396bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 139785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt /* FINISHME: Fix up uniform name for arrays and things */ 1398d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) { 1399d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler = _mesa_add_sampler(this->prog->Parameters, 1400d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->var->name, 1401d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->var->type->gl_type); 1402fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt set_sampler_location(ir->var, sampler); 1403d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1404b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER, 1405b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt sampler); 1406b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1407d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1408d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1409d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 141085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt assert(ir->var->type->gl_type != 0 && 141185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt ir->var->type->gl_type != GL_INVALID_ENUM); 14129a670c2e9b7e07ba43d175f3bfb23951296794c4Eric Anholt 141326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt /* Oh, the joy of aggregate types in Mesa. Like constants, 141426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt * we can only really do vec4s. So, make a temp, chop the 141526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt * aggregate up into vec4s, and move those vec4s to the temp. 141626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt */ 141726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt if (ir->var->type->is_record()) { 141826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt ir_to_mesa_src_reg temp = get_temp(ir->var->type); 141926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 142026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt entry = new(mem_ctx) variable_storage(ir->var, 142126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt temp.file, 142226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt temp.index); 142326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt this->variables.push_tail(entry); 142426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 142526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt add_aggregate_uniform(ir->var, ir->var->name, ir->var->type, 142647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir->var->constant_value, 142747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir_to_mesa_dst_reg_from_src(temp)); 142826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt break; 142926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt } 143026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt 143147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt loc = add_uniform(ir->var->name, 143247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir->var->type, 143347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt ir->var->constant_value); 1434d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 143585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt /* Always mark the uniform used at this point. If it isn't 143685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * used, dead code elimination should have nuked the decl already. 143785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 143885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt this->prog->Parameters->Parameters[loc].Used = GL_TRUE; 1439224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 1440b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc); 1441b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 14428364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 14438364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 14448364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_out: 14458364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1446a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1447a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * including deprecated builtins (like gl_Color), user-assign 1448a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * generic attributes (glBindVertexLocation), and 1449a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * user-defined varyings. 1450a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1451a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1452f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1453f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt assert(ir->var->location != -1); 1454a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt if (ir->var->mode == ir_var_in || 1455a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt ir->var->mode == ir_var_inout) { 1456b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1457b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_INPUT, 1458b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1459edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt 1460edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && 1461edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->location >= VERT_ATTRIB_GENERIC0) { 1462edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt _mesa_add_attribute(prog->Attributes, 1463edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->name, 1464edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt type_size(ir->var->type) * 4, 1465edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->type->gl_type, 1466c64da87611823b4b53e93188f861f748a69936a3Eric Anholt ir->var->location - VERT_ATTRIB_GENERIC0); 1467edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt } 1468f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } else { 1469b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1470b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_OUTPUT, 1471b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1472f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } 1473f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt 14748364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 14758364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 14767e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1477b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY, 1478b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1479b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1480224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 14818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt next_temp += type_size(ir->var->type); 14828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 148384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 14848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 14858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 14868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt printf("Failed to make storage for %s\n", ir->var->name); 14878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1488224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 148984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 149084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14919c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result = ir_to_mesa_src_reg(entry->file, entry->index, ir->var->type); 149284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 149384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 149484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 149584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 149684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1497dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_variable *var = ir->variable_referenced(); 1498ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 14990161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 150076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_dereference_variable *deref_var = ir->array->as_dereference_variable(); 15018258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1502ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1503ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 15044e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 150576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (deref_var && strncmp(deref_var->var->name, 150676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt "gl_TextureMatrix", 150776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt strlen("gl_TextureMatrix")) == 0) { 1508b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt struct variable_storage *entry; 150976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 151076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var, 151176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index); 151276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(entry); 151376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 15149c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg src_reg(entry->file, entry->index, ir->type); 151576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 151676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 1517f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 151876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 151976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type); 152076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 152176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index->accept(this); 152276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 152376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 15248258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt this->result, src_reg_for_float(element_size)); 152576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1526f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 1527f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 152876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 152976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 153076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt this->result = src_reg; 153176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return; 153276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 153376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1534dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform && 1535dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt !var->type->is_matrix()) { 1536dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_dereference_record *record = NULL; 1537dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (ir->array->ir_type == ir_type_dereference_record) 1538dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt record = (ir_dereference_record *)ir->array; 1539dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1540dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt assert(index || !"FINISHME: variable-indexed builtin uniform access"); 1541dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1542dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt this->result = get_builtin_uniform_reg(prog, 1543dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt var->name, 1544dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt index->value.i[0], 1545dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt record ? record->field : NULL); 1546dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1547dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1548ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 15490161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg = this->result; 15504e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 15514d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 15524d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.index += index->value.i[0] * element_size; 15534e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 15544d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg array_base = this->result; 15554d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 15564d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 15574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 15584d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 15594d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 15608258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 15614d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg index_reg; 15628258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 15634d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 15644d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 15654d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 15664d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1567f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 15684d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 15694d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 15704d5da50b94115d055ba8d0ff8717054582665384Eric Anholt this->result, src_reg_for_float(element_size)); 1571bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 15724d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 15734d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 15744d5da50b94115d055ba8d0ff8717054582665384Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 15754e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 157684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 157784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 157885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 157985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); 158085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 158185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = SWIZZLE_NOOP; 158284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15830161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 158484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 158584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15862c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 15872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 15882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 15892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 15900161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 15912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 1592dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_variable *var = ir->record->variable_referenced(); 1593dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1594dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform) { 1595dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt assert(var); 1596dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1597dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt this->result = get_builtin_uniform_reg(prog, 1598dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt var->name, 1599dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 0, 1600dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir->field); 1601dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt return; 1602dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 16032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16040161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 16052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 16070161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 16082c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 16092c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 16102c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 161185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 16120161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 16132c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 16142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 16152c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 16162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 16172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 16182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 16192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 16200161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg 16215a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v, 162218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt ir_to_mesa_src_reg *r) 1623b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 16245a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* The LHS must be a dereference. If the LHS is a variable indexed array 16255a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * access of a vector, it must be separated into a series conditional moves 16265a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * before reaching this point (see ir_vec_index_to_cond_assign). 16275a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 16285a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->as_dereference()); 1629ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1630ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1631ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1632ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1633ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 16340161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 16350161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 16360161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 16372c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 16385a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick return ir_to_mesa_dst_reg_from_src(v->result); 1639cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1640cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 164184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 164284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 164384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 16440161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg l; 16450161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg r; 16467d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 164784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 164884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 164984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1650cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 165118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt l = get_assignment_lhs(ir->lhs, this, &r); 1652cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 16535a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This should really set to the correct maximal writemask for each 16545a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: component written (in the loops below). This case can only 16555a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: occur for matrices, arrays, and structures. 16565a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 16575a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick if (ir->write_mask == 0) { 16585a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 16595a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 16605a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else if (ir->lhs->type->is_scalar()) { 16615a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This hack makes writing to gl_FragData, which lives in the 16625a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: W component of fragment shader output zero, work correctly. 16635a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 16645a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 16655a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else { 16665a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->lhs->type->is_vector()); 16675a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = ir->write_mask; 16685a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } 16695a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick 16700161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 16710161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 167284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1673346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 16742d1789e667c4180777829f96856daf91326721b9Eric Anholt ir_to_mesa_src_reg condition; 16752d1789e667c4180777829f96856daf91326721b9Eric Anholt 16762d1789e667c4180777829f96856daf91326721b9Eric Anholt ir->condition->accept(this); 16772d1789e667c4180777829f96856daf91326721b9Eric Anholt condition = this->result; 16782d1789e667c4180777829f96856daf91326721b9Eric Anholt 16792d1789e667c4180777829f96856daf91326721b9Eric Anholt /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, 16802d1789e667c4180777829f96856daf91326721b9Eric Anholt * and the condition we produced is 0.0 or 1.0. By flipping the 16812d1789e667c4180777829f96856daf91326721b9Eric Anholt * sign, we can choose which value OPCODE_CMP produces without 16822d1789e667c4180777829f96856daf91326721b9Eric Anholt * an extra computing the condition. 16832d1789e667c4180777829f96856daf91326721b9Eric Anholt */ 16842d1789e667c4180777829f96856daf91326721b9Eric Anholt condition.negate = ~condition.negate; 16857d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 16867d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, 16877d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt condition, r, ir_to_mesa_src_reg_from_dst(l)); 16887d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 16897d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 16907d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 16912d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 16927d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 16937d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 16947d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 16957d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 16967d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1697346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 169884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 169984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 170084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 170184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 170284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 170384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 17040161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 17050bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat stack_vals[4]; 17060bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 17070bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 170884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 17095b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt /* Unfortunately, 4 floats is all we can get into 17105b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store an 17115b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * aggregate constant and move each constant value into it. If we 17125b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * get lucky, copy propagation will eliminate the extra moves. 17135b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt */ 17145b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 17155b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt if (ir->type->base_type == GLSL_TYPE_STRUCT) { 17165b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_src_reg temp_base = get_temp(ir->type); 17175b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); 17185b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 17195b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt foreach_iter(exec_list_iterator, iter, ir->components) { 17205b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_constant *field_value = (ir_constant *)iter.get(); 17215b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt int size = type_size(field_value->type); 17225b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 17235b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt assert(size > 0); 17245b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 17255b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt field_value->accept(this); 17265b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg = this->result; 17275b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 17285b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt for (i = 0; i < (unsigned int)size; i++) { 17295b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); 17305b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 17315b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg.index++; 17325b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt temp.index++; 17335b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 17345b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 17355b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt this->result = temp_base; 17365b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt return; 17375b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 17385b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 173920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (ir->type->is_array()) { 174020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_src_reg temp_base = get_temp(ir->type); 174120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); 174220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt int size = type_size(ir->type->fields.array); 174320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 174420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt assert(size > 0); 174520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 174620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < ir->type->length; i++) { 174720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir->array_elements[i]->accept(this); 174820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg = this->result; 174920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (int j = 0; j < size; j++) { 175020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); 175120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 175220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.index++; 175320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt temp.index++; 175420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 175520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 175620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt this->result = temp_base; 175720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt return; 175820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 175920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1760ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1761c91809e1e4a4fa8884e6588159368ea32431ee0eEric Anholt ir_to_mesa_src_reg mat = get_temp(ir->type); 1762ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat); 1763ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1764ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1765ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1766ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1767ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 17689c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL); 1769ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 17709c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt values, 17719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 17729c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &src_reg.swizzle); 1773ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg); 1774ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1775ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1776ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1777ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1778ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1779582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 17800bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 17810bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt src_reg.file = PROGRAM_CONSTANT; 17820bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 17830bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 17840bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 17850bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 17860bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 17870bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 17880bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 17890bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 17900bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 17910bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 17920bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 17930bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 17940bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 17950bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 17960bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 17970bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 17980bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 17990bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 18000bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 18010bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 18020bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 18030bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 18040bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 18059c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type); 18069c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, 18079c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt values, 18089c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 18099c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &this->result.swizzle); 181084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 181184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 18127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry * 18137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) 18147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{ 18157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry; 18167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, this->function_signatures) { 18187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = (function_entry *)iter.get(); 18197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig == sig) 18217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 18227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = talloc(mem_ctx, function_entry); 18257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig = sig; 18267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig_id = this->next_signature_id++; 18277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = NULL; 18287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Allocate storage for all the parameters. */ 18307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, sig->parameters) { 18317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)iter.get(); 1832b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage; 18337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt storage = find_variable_storage(param); 18357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!storage); 18367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1837b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 1838b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1839b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(storage); 18407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->next_temp += type_size(param->type); 18427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1844576d01ad8c8b8aa57b4711c98d8e004d4f20fc0bEric Anholt if (!sig->return_type->is_void()) { 18457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = get_temp(sig->return_type); 18467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } else { 18477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = ir_to_mesa_undef; 18487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->function_signatures.push_tail(entry); 18517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 18527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt} 185384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 185484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 185584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 185684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 18577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *call_inst; 18587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig = ir->get_callee(); 18597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = get_function_signature(sig); 18607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 18617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process in parameters. */ 18637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list_iterator sig_iter = sig->parameters.iterator(); 18647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 18657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 18667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 18677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_in || 18697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1870b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 18717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 18727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 18747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 18757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 18777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.file = storage->file; 18787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index = storage->index; 18797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.reladdr = NULL; 18807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.writemask = WRITEMASK_XYZW; 18817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.cond_mask = COND_TR; 18827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 18847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 18857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 18867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 18877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 18917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 18937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit call instruction */ 18957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL, 18967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 18977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst->function = entry; 18987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process out parameters. */ 19007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter = sig->parameters.iterator(); 19017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 19027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 19037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 19047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_out || 19067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1907b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 19087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 19097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r; 19117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.file = storage->file; 19127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index = storage->index; 19137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.reladdr = NULL; 19147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.swizzle = SWIZZLE_NOOP; 19157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.negate = 0; 19167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 19187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result); 19197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 19217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 19227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 19237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 19247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 19287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 19307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 19317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process return value. */ 19327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->result = entry->return_reg; 193384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 193484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 193584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 193684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 193784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 193884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 19399c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg result_src, coord, lod_info, projector; 1940d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_dst_reg result_dst, coord_dst; 1941d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 1942d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 194384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 194484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->coordinate->accept(this); 1945d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1946d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 1947d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 1948d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 1949d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 1950d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1951d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 1952d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst = ir_to_mesa_dst_reg_from_src(coord); 1953d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, 1954d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt this->result); 1955d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1956de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 1957de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 1958de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 1959de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 1960de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 1961d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 1962d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 1963d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1964d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 1965d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 1966d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1967d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 1968d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 1969d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 1970d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1971d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 1972d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 1973d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 1974d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1975d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1976d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 1977d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 1978d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 1979d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1980d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1981d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 1982d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txf: 1983d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"GLSL 1.30 features unsupported"); 1984d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1985d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1986d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1987d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 1988d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 1989d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 1990d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1991d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector); 1992d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1993d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 1994d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 1995d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_src_reg coord_w = coord; 1996d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 1997d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1998d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 1999d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 2000d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 2001d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 2002d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 2003d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector); 2004d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2005d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 2006d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w); 2007d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2008d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2009d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 2010d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2011d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2012d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2013b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) { 2014b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 2015b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 2016b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 2017b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 2018b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_Z; 2019b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result); 2020b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2021b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 2022b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2023d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 2024d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 2025d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 2026d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info); 2027d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 2028d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 2029d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2030d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord); 2031d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 2032b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 2033b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 2034b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 2035d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_dereference_variable *sampler = ir->sampler->as_dereference_variable(); 2036d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(sampler); /* FINISHME: sampler arrays */ 2037d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* generate the mapping, remove when we generate storage at 2038d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * declaration time 2039d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 2040d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler->accept(this); 2041d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2042fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt inst->sampler = get_sampler_location(sampler->var); 2043d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2044d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (sampler->type->sampler_dimensionality) { 2045d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 2046d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_1D_INDEX; 2047d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2048d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 2049d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_2D_INDEX; 2050d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2051d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 2052d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 2053d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2054d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 2055d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 2056d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 2057d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 2058d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"FINISHME: other texture targets"); 2059d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2060d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2061d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 206284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 206384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 206484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 206584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 206684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 20677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(current_function); 20687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (ir->get_value()) { 20707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 20717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 20727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir->get_value()->accept(this); 20747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 207584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 20767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l = ir_to_mesa_dst_reg_from_src(current_function->return_reg); 20777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(current_function->sig->return_type); i++) { 20797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 20807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 20817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 20827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op0(ir, OPCODE_RET); 208684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 208784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 208816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 208916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 209016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 20915e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt assert(ir->condition == NULL); /* FINISHME */ 209216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 2093021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV); 209416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 209584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 209684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 209784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 209884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 2099854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL; 2100cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 2101cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2102cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2103c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2104c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 21050161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 2106c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2107854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if (ctx->Shader.EmitCondCodes) { 2108854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2109cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2110cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 2111cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 2112cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 2113cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 2114cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 2115cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type); 2116cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV, 2117cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_dst_reg_from_src(temp), 2118cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt result); 2119cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 2120854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 2121854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 2122021222c6a872ca2eef770ebadb8754f659775204Eric Anholt if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF); 2123854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst->dst_reg.cond_mask = COND_NE; 2124854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 2125854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, 2126854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt OPCODE_IF, ir_to_mesa_undef_dst, 2127854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt this->result); 2128854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 2129c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2130c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 2131c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2132c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 2133c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2134c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 2135021222c6a872ca2eef770ebadb8754f659775204Eric Anholt else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE); 21360a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 2137c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2138c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 21390161515c395c44233529c8d51f823b60050bc7baEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF, 21400161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 214184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 214284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2143ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 2144ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 21450161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 2146ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 21477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 2148d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler_map = NULL; 21497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 2150ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 2151ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 2152fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor() 2153fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{ 2154fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt if (this->sampler_map) 2155fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt hash_table_dtor(this->sampler_map); 2156fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt} 2157fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt 215884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 215984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) 216084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 216184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 216284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 216384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 2164aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt assert(reg.index < (1 << INST_INDEX_BITS) - 1); 216584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 216634195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 2167f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 2168ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 2169285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 2170b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt mesa_reg.HasIndex2 = GL_FALSE; 217184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 217284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 217384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 217484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2175c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 21767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 21777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 2178c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2179c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2180e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 218164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 218264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 218364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 2184c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2185c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 218664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 218764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 2188c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 218964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 219064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 219164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 219264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 219364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 219464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 219564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 219664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 219764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 219864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 219964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 2200c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2201c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 220264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack = (int *)calloc(if_count, sizeof(*if_stack)); 220364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack)); 2204c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2205c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2206c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 2207c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 220864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 2209c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 2210c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2211c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 221264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 221364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 2214c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2215c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 221664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 2217c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 2218c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 221964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 222064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 222164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 222264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 222364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 222464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 222564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 222664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 222764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 222864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 222964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 223064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 223164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 223264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 223364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 223464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 223564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 223664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 223764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 223864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 223964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 22407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 22417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 22427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 22437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 22447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 22457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 22467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 22477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 22487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 22497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 22507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 2251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 2252c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2253c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2254c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2255c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2256c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt free(if_stack); 2257c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2258c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2259c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 2260c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 2261c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 2262c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2263c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2264c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 2265c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2266748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 2267c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2268c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2269c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 2270c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 2271c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2272748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 2273748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 227464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 2275748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 2276748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2277748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 2278748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 2279748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 2280748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 2281c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 2282c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 2283748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2284748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 2285c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2286c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2287748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 2288748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 2289c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2290c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2291c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2292ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void 22934d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_input(struct gl_program *prog, 22944d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int index, 22954d5da50b94115d055ba8d0ff8717054582665384Eric Anholt GLboolean reladdr) 22964d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{ 22974d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->InputsRead |= BITFIELD64_BIT(index); 22984d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int i; 22994d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 23004d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (reladdr) { 23014d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) { 23024d5da50b94115d055ba8d0ff8717054582665384Eric Anholt for (i = 0; i < 8; i++) { 23034d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i); 23044d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 23054d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 23064d5da50b94115d055ba8d0ff8717054582665384Eric Anholt assert(!"FINISHME: Mark InputsRead for varying arrays"); 23074d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 23084d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 23094d5da50b94115d055ba8d0ff8717054582665384Eric Anholt} 23104d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 23114d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void 23124d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_output(struct gl_program *prog, 23134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int index, 23144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt GLboolean reladdr) 23154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{ 23164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->OutputsWritten |= BITFIELD64_BIT(index); 23174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int i; 23184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 23194d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (reladdr) { 23204d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) { 23214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt for (i = 0; i < 8; i++) { 23224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i); 23234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 23244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 23254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt assert(!"FINISHME: Mark OutputsWritten for varying arrays"); 23264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 23274d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 23284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt} 23294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 23304d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void 2331ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog) 2332ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{ 2333d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt unsigned int i; 2334d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2335ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt prog->InputsRead = 0; 2336ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt prog->OutputsWritten = 0; 2337d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed = 0; 2338ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2339ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (i = 0; i < prog->NumInstructions; i++) { 2340ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt struct prog_instruction *inst = &prog->Instructions[i]; 2341ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt unsigned int reg; 2342ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2343ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt switch (inst->DstReg.File) { 2344ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_OUTPUT: 23454d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr); 2346ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2347ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_INPUT: 23484d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr); 2349ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2350ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt default: 2351ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2352ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2353ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2354ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) { 2355ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt switch (inst->SrcReg[reg].File) { 2356ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_OUTPUT: 23574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_output(prog, inst->SrcReg[reg].Index, 23584d5da50b94115d055ba8d0ff8717054582665384Eric Anholt inst->SrcReg[reg].RelAddr); 2359ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2360ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_INPUT: 23614d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr); 2362ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2363ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt default: 2364ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2365ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2366ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2367d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2368d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Instead of just using the uniform's value to map to a 2369d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * sampler, Mesa first allocates a separate number for the 2370d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * sampler (_mesa_add_sampler), then we reindex it down to a 2371d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * small integer (sampler_map[], SamplersUsed), then that gets 2372d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * mapped to the uniform's value, and we get an actual sampler. 2373d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 2374d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (_mesa_is_tex_instruction(inst->Opcode)) { 2375d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplerTargets[inst->TexSrcUnit] = 2376d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt (gl_texture_index)inst->TexSrcTarget; 2377d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed |= 1 << inst->TexSrcUnit; 2378d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (inst->TexShadow) { 2379d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->ShadowSamplers |= 1 << inst->TexSrcUnit; 2380d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2381d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2382ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2383d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2384d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt _mesa_update_shader_textures_used(prog); 2385ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt} 2386ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 238785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt/* Each stage has some uniforms in its Parameters list. The Uniforms 238885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * list for the linked shader program has a pointer to these uniforms 238985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * in each of the stage's Parameters list, so that their values can be 239085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * updated when a uniform is set. 239185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 239285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void 239385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtlink_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms, 239485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt struct gl_program *prog) 239585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 239685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt unsigned int i; 239785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 239885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt for (i = 0; i < prog->Parameters->NumParameters; i++) { 239985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt const struct gl_program_parameter *p = prog->Parameters->Parameters + i; 240085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 240185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) { 240285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt struct gl_uniform *uniform = 240385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt _mesa_append_uniform(uniforms, p->Name, prog->Target, i); 240485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt if (uniform) 240585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt uniform->Initialized = p->Initialized; 240685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 240785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 240885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 240985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2410364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program * 241195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, 241295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 241384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 241495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt void *mem_ctx = shader_program; 241584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 241684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2417c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 2418c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2419364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 2420364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 2421c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 24227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt GLboolean progress; 2423364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2424364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 2425c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 2426c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 2427c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 2428c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2429c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 2430c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 2431c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 2432c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2433c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 2434c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 2435c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2436364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 243784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 24381124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 24391124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 2440859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 2441364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 2442364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 2443364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 2444364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2445364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Attributes = _mesa_new_parameter_list(); 2446364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 2447364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 2448364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2449364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.mem_ctx = talloc_new(NULL); 24507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 245216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 2453021222c6a872ca2eef770ebadb8754f659775204Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_END); 245484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 24557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Now emit bodies for any functions that were used. */ 24567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt do { 24577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_FALSE; 24587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v.function_signatures) { 24607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 24617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (!entry->bgn_inst) { 24637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt v.current_function = entry; 24647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB); 24667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst->function = entry; 24677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt visit_exec_list(&entry->sig->body, &v); 24697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2470806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt ir_to_mesa_instruction *last; 2471806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt last = (ir_to_mesa_instruction *)v.instructions.get_tail(); 2472806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt if (last->op != OPCODE_RET) 2473806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_RET); 2474806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt 247540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt ir_to_mesa_instruction *end; 247640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB); 247740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end->function = entry; 247840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt 24797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_TRUE; 24807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 24817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 24827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } while (progress); 24837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2484364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 2485364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 248684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 248784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 248884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 248984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 249084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 249184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 249284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 249384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 2494364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *, 2495364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 249684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 249784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 2498c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 249984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 250084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 2501b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 250284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 2503854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 250484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.File = inst->dst_reg.file; 250584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.Index = inst->dst_reg.index; 2506854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask; 250712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; 2508f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL; 250984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); 251084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); 251184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); 2512d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 2513d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 2514b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 2515c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 2516aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 251795c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { 251895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->InfoLog = 251995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt talloc_asprintf_append(shader_program->InfoLog, 252095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt "Couldn't flatten if statement\n"); 252195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->LinkStatus = false; 252295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt } 252395c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt 252440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt switch (mesa_inst->Opcode) { 252540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_BGNSUB: 25267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function->inst = i; 252740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 252840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 252940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ENDSUB: 253040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 253140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 253240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_CAL: 25337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ 253440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 253540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ARL: 2536d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 253740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 253840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt default: 253940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 254040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt } 25417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 254284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 2543c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 254484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 2545c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 25467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 2547c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2548455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2549455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL IR for linked %s program %d:\n", target_string, 2550455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2551455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt _mesa_print_ir(shader->ir, NULL); 2552455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2553455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2554455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("Mesa IR for linked %s program %d:\n", target_string, 2555455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2556364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 2557364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 2558364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2559364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2560364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 2561364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 2562364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 256316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 2564364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 256528faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 256628faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 256728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 256828faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 2569364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 2570364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2571364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 257216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 257316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 257416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 257516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) 2576364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 25772462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 25782462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 25795e18b051c039564d1998818d08caf1bff3983630Ian Romanick 2580153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 258106143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick state->error = preprocess(state, &source, &state->info_log, 258206143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick &ctx->Extensions); 2583153eca98064252be4daad9cc27746f37c245b627Ian Romanick 2584153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 2585153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 2586153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 2587153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 2588153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 2589364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 259016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 2591364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 259216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 2593364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 259416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 2595ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2596ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 25974802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt /* Lowering */ 25984802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_mat_op_to_vec(shader->ir); 25994802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_mod_to_fract(shader->ir); 26004802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_div_to_mul_rcp(shader->ir); 26014802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt 26024802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt /* Optimization passes */ 2603364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt bool progress; 2604364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt do { 2605364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt progress = false; 2606364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 260716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_function_inlining(shader->ir) || progress; 260816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_if_simplification(shader->ir) || progress; 260916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_copy_propagation(shader->ir) || progress; 261016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_dead_code_local(shader->ir) || progress; 261166d4c65ee2c311ea0c71c39a28456d0c11798d6bEric Anholt progress = do_dead_code_unlinked(shader->ir) || progress; 2612784695442c415cf0be882434a25671ecfb635d34Eric Anholt progress = do_tree_grafting(shader->ir) || progress; 261316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_constant_variable_unlinked(shader->ir) || progress; 261416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_constant_folding(shader->ir) || progress; 2615832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt progress = do_algebraic(shader->ir) || progress; 2616d674ebcee0d2731e50d6530502cefcebc39dcdb6Eric Anholt progress = do_if_return(shader->ir) || progress; 2617952d0f88e1741d51b641be75f7c5a6565e245a69Eric Anholt if (1 || ctx->Shader.EmitNoIfs) 261895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt progress = do_if_to_cond_assign(shader->ir) || progress; 2619a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 262016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_vec_index_to_swizzle(shader->ir) || progress; 2621a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Do this one after the previous to let the easier pass handle 2622a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * constant vector indexing. 2623a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 2624a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt progress = do_vec_index_to_cond_assign(shader->ir) || progress; 2625a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 262616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_swizzle_swizzle(shader->ir) || progress; 2627364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } while (progress); 2628ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 2629ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2630364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2631364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2632364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 2633364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2634364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 2635364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 263625f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 2637d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 2638d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 2639d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 2640c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2641b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt if (ctx->Shader.Flags & GLSL_LOG) { 2642b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt _mesa_write_shader_to_file(shader); 2643b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt } 2644b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt 2645455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2646455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL source for shader %d:\n", shader->Name); 2647455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("%s\n", shader->Source); 2648455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt 2649455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL IR for shader %d:\n", shader->Name); 2650455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt _mesa_print_ir(shader->ir, NULL); 2651455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n\n"); 2652455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt } 2653455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt 2654116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 265560e2d06d1ccc66ad00cd7ab81c418853f21be291Ian Romanick reparent_ir(shader->ir, shader); 2656116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 2657364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt talloc_free(state); 2658364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2659364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2660364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 2661364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog) 2662364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 2663364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 2664849e18153cd91d812f694b806a84008498860bc3Eric Anholt 2665364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 2666364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2667849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 2668364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2669364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 2670849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 2671849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->InfoLog = 2672849e18153cd91d812f694b806a84008498860bc3Eric Anholt talloc_asprintf_append(prog->InfoLog, 2673364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt "linking with uncompiled shader"); 2674849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 2675364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2676364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2677364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2678364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2679364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); 2680364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); 2681364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2682849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 2683849e18153cd91d812f694b806a84008498860bc3Eric Anholt link_shaders(prog); 2684849e18153cd91d812f694b806a84008498860bc3Eric Anholt 2685849e18153cd91d812f694b806a84008498860bc3Eric Anholt /* We don't use the linker's uniforms list, and cook up our own at 2686849e18153cd91d812f694b806a84008498860bc3Eric Anholt * generate time. 2687849e18153cd91d812f694b806a84008498860bc3Eric Anholt */ 2688849e18153cd91d812f694b806a84008498860bc3Eric Anholt free(prog->Uniforms); 2689849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->Uniforms = _mesa_new_uniform_list(); 2690849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 2691364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2692364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 26933fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick for (i = 0; i < prog->_NumLinkedShaders; i++) { 2694364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *linked_prog; 2695859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt bool ok = true; 2696364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2697849e18153cd91d812f694b806a84008498860bc3Eric Anholt linked_prog = get_mesa_program(ctx, prog, 26983fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick prog->_LinkedShaders[i]); 2699ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt count_resources(linked_prog); 2700364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 270185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog); 270285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 27033fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick switch (prog->_LinkedShaders[i]->Type) { 2704364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt case GL_VERTEX_SHADER: 2705364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, 2706364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt (struct gl_vertex_program *)linked_prog); 2707859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 2708859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt linked_prog); 2709364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt break; 2710364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt case GL_FRAGMENT_SHADER: 2711364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, 2712364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt (struct gl_fragment_program *)linked_prog); 2713859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 2714859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt linked_prog); 2715364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt break; 2716364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2717859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt if (!ok) { 2718859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt prog->LinkStatus = GL_FALSE; 2719859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt } 2720364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2721364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2722364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2723364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2724364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 2725