ir_to_mesa.cpp revision 5b6890a388d554f06880e88d61c73dcd62c5f141
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" 48afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h" 49afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h" 50afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h" 51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h" 52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h" 53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h" 54aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt} 5584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 56554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/** 57554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with 58554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields. 59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg { 61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 63582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 64554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int negate; /**< NEGATE_XYZW mask from mesa */ 65f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 66f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg; 68554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 69554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg { 70554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 71554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 72554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 73854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLuint cond_mask:4; 74f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 75f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 76554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg; 77554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 78554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef; 79554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 80554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node { 81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 82554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op; 83554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst_reg; 84554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src_reg[3]; 85554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** Pointer to the ir source this tree came from for debugging */ 86554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_instruction *ir; 87854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLboolean cond_update; 88d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler; /**< sampler index */ 89d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int tex_target; /**< One of TEXTURE_*_INDEX */ 90b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt GLboolean tex_shadow; 917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ 93554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 94554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 95b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node { 96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 97b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage(ir_variable *var, int file, int index) 98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt : file(file), index(index), var(var) 99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt { 100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /* empty */ 101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt } 102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; 104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; 105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_variable *var; /* variable that maps to this, if any */ 106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 107554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node { 1097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic: 1107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig; 1117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * identifier of this function signature used by the program. 1147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * At the point that Mesa instructions for function calls are 1167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * generated, we don't know the address of the first instruction of 1177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * the function body. So we make the BranchTarget that is called a 1187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * small integer and rewrite them during set_branchtargets(). 1197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int sig_id; 1217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Pointer to first instruction of the function body. 1247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set during function body emits after main() is processed. 1267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *bgn_inst; 1287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Index of the first instruction of the function body in actual 1317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Mesa IR. 1327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set after convertion from ir_to_mesa_instruction to prog_instruction. 1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int inst; 1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** Storage for the return value. */ 1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg return_reg; 1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}; 1407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 141554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor { 142554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 143554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_visitor(); 144554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *current_function; 1467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 147364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLcontext *ctx; 148364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 149364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 150554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int next_temp; 151a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 152b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *find_variable_storage(ir_variable *var); 153554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *get_function_signature(ir_function_signature *sig); 1557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1568364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt ir_to_mesa_src_reg get_temp(const glsl_type *type); 157f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt void reladdr_to_temp(ir_instruction *ir, 158f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr); 159554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 160554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg src_reg_for_float(float val); 161554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 162554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 164554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 166554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 170554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 172554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 173554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 174554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 175554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 176554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 177554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 179554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 183554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 18416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 185554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg result; 190554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 191b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 192b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 193554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 1957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 1967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 1977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 200554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 201021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir, 202021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op); 203021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir, 205554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir, 210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 212554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 213554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1); 214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 215554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir, 216554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 217554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 218554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 219554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1, 220554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src2); 221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 222554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt void ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 223554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 224554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 225554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 2260ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt 227904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt void ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 228904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 229904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 230904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0, 231904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1); 232904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 2333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt GLboolean try_emit_mad(ir_expression *ir, 2343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 2353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 236d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int *sampler_map; 237d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler_map_size; 238d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 239d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt void map_sampler(int location, int sampler); 240d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int get_sampler_number(int location); 241d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 242364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 244554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 24584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = { 246f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, NULL, 24784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}; 24884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 249c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = { 250f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL, 251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}; 252c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2530161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = { 254f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL 2550161515c395c44233529c8d51f823b60050bc7baEric Anholt}; 2560161515c395c44233529c8d51f823b60050bc7baEric Anholt 2570161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size) 2580161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 2590161515c395c44233529c8d51f823b60050bc7baEric Anholt int size_swizzles[4] = { 2600161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 2610161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 2620161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 2630161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 2640161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 2650161515c395c44233529c8d51f823b60050bc7baEric Anholt 2660161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 2670161515c395c44233529c8d51f823b60050bc7baEric Anholt} 2680161515c395c44233529c8d51f823b60050bc7baEric Anholt 26984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 2700161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir, 2710161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 2720161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 2730161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 2740161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1, 2750161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src2) 27684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 277364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 278f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 279f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 280f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 281f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 282f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 283f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 284f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 285f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 286f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 287f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 288f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 289f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 290f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 291f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 292f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 293f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 294f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, 295f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *dst.reladdr); 296f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 297f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 298f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 299f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 30084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 30284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->dst_reg = dst; 30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[0] = src0; 30484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[1] = src1; 30584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[2] = src2; 306c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 30784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function = NULL; 3097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3100161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 31184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 31284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 31384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 31484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 31584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 31684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3170161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir, 3180161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3190161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3200161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 3210161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1) 32284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3230161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef); 32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 32684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3270161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir, 3280161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3290161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3300161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0) 331bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 3320161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, 3330161515c395c44233529c8d51f823b60050bc7baEric Anholt src0, ir_to_mesa_undef, ir_to_mesa_undef); 334bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 335bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 336021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 337021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir, 338021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op) 339021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 340021222c6a872ca2eef770ebadb8754f659775204Eric Anholt return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst, 341021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 342021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 343021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef); 344021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 345021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 346d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtvoid 347d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::map_sampler(int location, int sampler) 348d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{ 349d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (this->sampler_map_size <= location) { 350d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map, 351d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int, location + 1); 352d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->sampler_map_size = location + 1; 353d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 354d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 355d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->sampler_map[location] = sampler; 356d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt} 357d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 358d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtint 359d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::get_sampler_number(int location) 360d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{ 361d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(location < this->sampler_map_size); 362d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt return this->sampler_map[location]; 363d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt} 364d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 3650161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg 3660161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg) 36784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3680161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst_reg; 36984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3700161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.file = reg.file; 3710161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.index = reg.index; 3720161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.writemask = WRITEMASK_XYZW; 373854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt dst_reg.cond_mask = COND_TR; 374f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt dst_reg.reladdr = reg.reladdr; 3750161515c395c44233529c8d51f823b60050bc7baEric Anholt 3760161515c395c44233529c8d51f823b60050bc7baEric Anholt return dst_reg; 377bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 378bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 3792d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg 3802d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg) 3812d1789e667c4180777829f96856daf91326721b9Eric Anholt{ 3822d1789e667c4180777829f96856daf91326721b9Eric Anholt ir_to_mesa_src_reg src_reg; 3832d1789e667c4180777829f96856daf91326721b9Eric Anholt 3842d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.file = reg.file; 3852d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.index = reg.index; 3862d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.swizzle = SWIZZLE_XYZW; 3872d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.negate = 0; 388f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = reg.reladdr; 3892d1789e667c4180777829f96856daf91326721b9Eric Anholt 3902d1789e667c4180777829f96856daf91326721b9Eric Anholt return src_reg; 3912d1789e667c4180777829f96856daf91326721b9Eric Anholt} 3922d1789e667c4180777829f96856daf91326721b9Eric Anholt 39312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 39412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 39512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 39612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 39712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 39812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 39912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 40012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 40112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 402904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 4030161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 4040161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 405904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src0, 406904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src1) 40712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 40812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 409315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 41012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 41112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 41212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 41412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 41512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 416582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 41712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 418904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0 = orig_src0; 419904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1 = orig_src1; 42012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 42112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 42212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 42312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 424904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 425904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 42612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 427904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 428904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 429904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 43212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 433904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 434904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 435904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 436904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 43712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 438904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt inst = ir_to_mesa_emit_op2(ir, op, 4390161515c395c44233529c8d51f823b60050bc7baEric Anholt dst, 440904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0, 441904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1); 44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt inst->dst_reg.writemask = this_mask; 44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 44412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 44512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 44612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 449904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 450904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 451904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0) 452904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 45359a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt ir_to_mesa_src_reg undef = ir_to_mesa_undef; 454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 456904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 457904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef); 458904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 459904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 4600161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg 4610161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 462b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 4630161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 4641d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4650161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.file = PROGRAM_CONSTANT; 466582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 467582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt &val, 1, &src_reg.swizzle); 468f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 4698bb15c1ed55eb71533d2af94a6afbf01e3d23610Eric Anholt src_reg.negate = 0; 4701d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4710161515c395c44233529c8d51f823b60050bc7baEric Anholt return src_reg; 4721d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 4731d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 4752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 4762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 4772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 4782c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 4792c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 4802c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 4812c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 4822c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 4832c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 4842c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 485a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 4869968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 487a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 488a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 489a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 490a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 491a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 492a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 493a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 494a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 4962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 4972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 4982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 4992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 5002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 5022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 5032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 5042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 5052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 5062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 5072c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 508d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 509d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 510d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 511d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 512d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 513d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 514d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg 515d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 516d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 517d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt ir_to_mesa_src_reg src_reg; 518d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int swizzle[4]; 519d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int i; 520d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 521d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt assert(!type->is_array()); 522d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 523d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.file = PROGRAM_TEMPORARY; 524d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.index = next_temp; 525f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 526d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 527d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 528d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt for (i = 0; i < type->vector_elements; i++) 529d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt swizzle[i] = i; 530d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt for (; i < 4; i++) 531d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt swizzle[i] = type->vector_elements - 1; 532d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], 533d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt swizzle[2], swizzle[3]); 534ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt src_reg.negate = 0; 535d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt return src_reg; 537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 538d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 539b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 540a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 54184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 542a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 543b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 54484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 545b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 546b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 54784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 5480161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 549a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 55084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 55184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 552a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 553a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 55484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 55584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 55684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 55784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 5588364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt (void)ir; 55984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 56184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 56284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 56384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 56464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->from); 56564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->to); 56664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->increment); 56764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->counter); 56884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 569021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); 57064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 571021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); 57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 57684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 57764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 57864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 579021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BRK); 58064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 58164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 582021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_CONT); 58364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 58464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 58884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 58984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 59084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 60184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 60284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 60384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 60484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 60684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 60784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 60884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 61684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6173f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean 6183f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 6193f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 6203f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 6213f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_src_reg a, b, c; 6223f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6233f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 6243f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 6253f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 6263f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 6283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 6293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 6303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 6313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 6323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 6333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 6353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_emit_op3(ir, OPCODE_MAD, 6363f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_dst_reg_from_src(this->result), a, b, c); 6373f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6383f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 6393f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 6403f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 64184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 642f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 643f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr) 644f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 645f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 646f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 647f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 648f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr); 649f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 650f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 651f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 652f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 653f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, 654f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_dst_reg_from_src(temp), *reg); 655f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 656f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 657f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 658f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 659f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 660f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 661f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 66284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 66384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 66484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 665f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt struct ir_to_mesa_src_reg op[2]; 6660161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg result_src; 6670161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg result_dst; 66884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1); 66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1); 67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1); 67184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6723f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 6733f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 6743f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 6753f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 6763f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 6773f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 6783f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 6793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 6803f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 68184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 6820161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 68384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 6840161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 68584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 69084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 6918364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 6924ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 6934ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 6944ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 6954ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 69684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 69784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6980161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 6990161515c395c44233529c8d51f823b60050bc7baEric Anholt 7000161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 7010161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 7020161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 7038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 7040161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 7050161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 7069cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 7079cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 7089cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 7099cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 7109cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 71284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 7131d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 714f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, 715f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt op[0], src_reg_for_float(0.0)); 7161d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 717c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 7180161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 7190161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 720c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 721524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 722524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]); 723524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 7243acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 7253acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]); 7263acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 7278761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 7288761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]); 7298761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 730524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 7318c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp: 732b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, 733b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt src_reg_for_float(M_E), op[0]); 7348c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7358c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 7360161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]); 7378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7388c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 7390161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]); 7408c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7418c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 7420161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]); 7438c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7443c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 7450161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]); 7463c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 7473c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 7480161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]); 7493c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 750ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 751ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 752ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]); 753ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 754ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 755ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]); 756ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 757ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 75884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 7597b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]); 76084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 76184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 7627b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]); 76384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 7649b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 76584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 7664ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]); 76784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 76884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 7699a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 770411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 771411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 772411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 77338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 77438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 775f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]); 77638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 77738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 778f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]); 77938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 781f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]); 78238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 784f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); 78538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 787f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 78838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 789763cd75863ed9a16912e585887580c44d1e8109fEric Anholt case ir_binop_logic_xor: 79038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_nequal: 791f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 79238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 79338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 7944380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_or: 7950161515c395c44233529c8d51f823b60050bc7baEric Anholt /* This could be a saturated add and skip the SNE. */ 7960161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, 7970161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 7980161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 7990161515c395c44233529c8d51f823b60050bc7baEric Anholt 8000161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 8010161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8020161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 8034380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8044380099c98119611ceee684669d00be26195c7d7Eric Anholt 8054380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 8064380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 8070161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 8080161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8090161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 8104380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8114380099c98119611ceee684669d00be26195c7d7Eric Anholt 81284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 81384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (ir->operands[0]->type == vec4_type) { 81484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec4_type); 8150161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP4, 8160161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8170161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 81884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec3_type) { 81984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec3_type); 8200161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP3, 8210161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8220161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec2_type) { 82484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec2_type); 8250161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP2, 8260161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8270161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 82884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 82984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 8309be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 8319be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt case ir_binop_cross: 8329be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]); 8339be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt break; 8349be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 83584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 8360161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 8378f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src); 8388f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt /* For incoming channels < 0, set the result to 0. */ 8398f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst, 8408f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt op[0], src_reg_for_float(0.0), result_src); 84184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 842878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 8430161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 844878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 84550ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 846d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 847d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 848423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 8490161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 85050ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 851423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 8520161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 853423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 8541d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 855411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 8560161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, 8570161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 8581d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 859c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 8600161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 861c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 862c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 8630161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 8640161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 8650161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 866c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 867c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 8680161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 869c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 870d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 871d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]); 872d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 873d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 874c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 8750161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]); 876c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 877c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 8780161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]); 879c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 880904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 881904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]); 882904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 883e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 884e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_bit_not: 885e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_u2f: 886e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 887e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 888e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 889e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 890e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 891e64a4aaacbc682f24180dff3627b84861844476dEric Anholt assert(!"GLSL 1.30 features unsupported"); 892e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 89384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 894b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 8950161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 89684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 89784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 89884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 89984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 90084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 90184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 9020161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 90384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 90484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 90584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 906b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 907b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 908b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 909b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 91084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 91184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 9124006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt src_reg = this->result; 9134006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt assert(src_reg.file != PROGRAM_UNDEFINED); 91484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 91584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 91684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 91784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 91884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 919698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x); 92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 92184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 922698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y); 92384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 92484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 925698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z); 92684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 92784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 928698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w); 92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 93184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 93284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 93384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 93484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 935698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 93684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 93784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 93884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9390161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], 9400161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[1], 9410161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[2], 9420161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[3]); 94384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9440161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 94684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 94776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int 94876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens) 94976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{ 95076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 95176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int i; 95276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 95376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt /* Add a ref for each column. It looks like the reason we do 95476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * it this way is that _mesa_add_state_reference doesn't work 95576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * for things that aren't vec4s, so the tokens[2]/tokens[3] 95676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * range has to be equal. 95776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt */ 95876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < 4; i++) { 95976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[2] = i; 96076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[3] = i; 96176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = _mesa_add_state_reference(prog->Parameters, 96276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt (gl_state_index *)tokens); 96376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 96476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 96576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 96676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + i == pos); 96776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 96876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 96976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return base_pos; 97076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt} 97176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 972b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage * 97376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var, 97476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_rvalue *array_index) 975bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{ 976bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* 977bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * NOTE: The ARB_vertex_program extension specified that matrices get 978bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * loaded in registers in row-major order. With GLSL, we want column- 979bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * major order. So, we need to transpose all matrices here... 980bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 981bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt static const struct { 982bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt const char *name; 983bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int matrix; 984bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int modifier; 985bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } matrices[] = { 986bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, 987bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS }, 988bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, 989bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 990bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 991bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE }, 992bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS }, 993bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 }, 994bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE }, 995bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 996bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE }, 997bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS }, 998bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 }, 999bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE }, 1000bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1001bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE }, 1002bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS }, 1003bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 }, 1004bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, 1005bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1006bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 1007bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1008bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt }; 1009bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt unsigned int i; 1010b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 1011bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1012bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* C++ gets angry when we try to use an int as a gl_state_index, so we use 1013bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * ints for gl_state_index. Make sure they're compatible. 1014bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 1015bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt assert(sizeof(gl_state_index) == sizeof(int)); 1016bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1017bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt for (i = 0; i < Elements(matrices); i++) { 1018bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (strcmp(var->name, matrices[i].name) == 0) { 1019bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int tokens[STATE_LENGTH]; 102076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 1021bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1022bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[0] = matrices[i].matrix; 1023bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[4] = matrices[i].modifier; 102476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (matrices[i].matrix == STATE_TEXTURE_MATRIX) { 102576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_constant *index = array_index->constant_expression_value(); 102676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 102776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = index->value.i[0]; 102876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 102976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 103076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < var->type->length; i++) { 103176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = i; 103276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = add_matrix_ref(prog, tokens); 103376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 103476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 103576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 103676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + (int)i * 4 == pos); 103776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 103876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 103976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 104076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = 0; /* unused array index */ 104176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 1042bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 104376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[4] = matrices[i].modifier; 1044bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1045b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(var, 1046b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_STATE_VAR, 1047b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt base_pos); 1048bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1049bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return entry; 1050bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1051bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1052bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1053bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return NULL; 1054bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt} 1055bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 105684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 105784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 105884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 10590161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 1060b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 1061a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt unsigned int loc; 106284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 10638364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 10648364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt switch (ir->var->mode) { 10658364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 106676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var, 106776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt NULL); 1068bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (entry) 1069bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt break; 1070bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 107185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt /* FINISHME: Fix up uniform name for arrays and things */ 1072d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) { 1073d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* FINISHME: we whack the location of the var here, which 1074d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * is probably not expected. But we need to communicate 1075d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * mesa's sampler number to the tex instruction. 1076d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1077d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler = _mesa_add_sampler(this->prog->Parameters, 1078d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->var->name, 1079d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->var->type->gl_type); 1080d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt map_sampler(ir->var->location, sampler); 1081d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1082b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER, 1083b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt sampler); 1084b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1085d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1086d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1087d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 108885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt assert(ir->var->type->gl_type != 0 && 108985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt ir->var->type->gl_type != GL_INVALID_ENUM); 109085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt loc = _mesa_add_uniform(this->prog->Parameters, 109185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt ir->var->name, 109285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt type_size(ir->var->type) * 4, 109385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt ir->var->type->gl_type, 109485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt NULL); 1095d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 109685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt /* Always mark the uniform used at this point. If it isn't 109785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * used, dead code elimination should have nuked the decl already. 109885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 109985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt this->prog->Parameters->Parameters[loc].Used = GL_TRUE; 1100224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 1101b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc); 1102b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 11038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 11048364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 11058364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_out: 11068364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1107a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1108a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * including deprecated builtins (like gl_Color), user-assign 1109a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * generic attributes (glBindVertexLocation), and 1110a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * user-defined varyings. 1111a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1112a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1113f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1114f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt assert(ir->var->location != -1); 1115a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt if (ir->var->mode == ir_var_in || 1116a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt ir->var->mode == ir_var_inout) { 1117b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1118b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_INPUT, 1119b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1120edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt 1121edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && 1122edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->location >= VERT_ATTRIB_GENERIC0) { 1123edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt _mesa_add_attribute(prog->Attributes, 1124edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->name, 1125edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt type_size(ir->var->type) * 4, 1126edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->type->gl_type, 1127c64da87611823b4b53e93188f861f748a69936a3Eric Anholt ir->var->location - VERT_ATTRIB_GENERIC0); 1128edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt } 1129f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } else { 1130b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1131b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_OUTPUT, 1132b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1133f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } 1134f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt 11358364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 11368364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 11377e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1138b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY, 1139b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1140b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1141224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 11428364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt next_temp += type_size(ir->var->type); 11438364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 114484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 11458364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 11468364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 11478364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt printf("Failed to make storage for %s\n", ir->var->name); 11488364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1149224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 115084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 115184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 11528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt src_reg.file = entry->file; 11538364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt src_reg.index = entry->index; 115484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 115585e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 115685e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements); 115785e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 115885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = SWIZZLE_NOOP; 1159f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 11600161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.negate = 0; 116184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 11620161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 116384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 116484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 116584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 116684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 116784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1168ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 11690161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 117076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_dereference_variable *deref_var = ir->array->as_dereference_variable(); 11718258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1172ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1173ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 11744e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 117576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (deref_var && strncmp(deref_var->var->name, 117676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt "gl_TextureMatrix", 117776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt strlen("gl_TextureMatrix")) == 0) { 117876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_src_reg src_reg; 1179b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt struct variable_storage *entry; 118076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 118176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var, 118276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index); 118376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(entry); 118476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 118576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.file = entry->file; 118676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.index = entry->index; 118776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); 118876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.negate = 0; 118976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 119076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 1191f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 119276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 119376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type); 119476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 119576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index->accept(this); 119676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 119776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 11988258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt this->result, src_reg_for_float(element_size)); 119976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1200f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 1201f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 120276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 120376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 120476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt this->result = src_reg; 120576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return; 120676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 120776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1208ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 12090161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg = this->result; 12104e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 12114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 12124d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.index += index->value.i[0] * element_size; 12134e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 12144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg array_base = this->result; 12154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 12164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 12174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 12184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 12194d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 12208258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 12214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg index_reg; 12228258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 12234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 12244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 12254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 12264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1227f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 12284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 12294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 12304d5da50b94115d055ba8d0ff8717054582665384Eric Anholt this->result, src_reg_for_float(element_size)); 1231bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 12324d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 12334d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 12344d5da50b94115d055ba8d0ff8717054582665384Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 12354e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 123684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 123784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 123885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 123985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); 124085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 124185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = SWIZZLE_NOOP; 124284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 12430161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 124484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 124584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 12462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 12472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 12482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 12492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 12500161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 12512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 12522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 12530161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 12542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 12552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 12560161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 12572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 12582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 12592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 126085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 12610161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 12622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 12632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 12642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 12652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 12662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 12672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 12682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * 12692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we 12702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector, 12712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage. So handle 12722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest. 12732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 12740161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg 127518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v, 127618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt ir_to_mesa_src_reg *r) 1277b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 12780161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg dst_reg; 1279b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_swizzle *swiz; 1280b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 1281ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1282ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt /* This should have been handled by ir_vec_index_to_cond_assign */ 1283ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1284ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1285ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1286ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 12870161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 12880161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 12890161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 12902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 12910161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg = ir_to_mesa_dst_reg_from_src(v->result); 12922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 1293ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if ((swiz = ir->as_swizzle())) { 129418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int swizzles[4] = { 129518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.x, 129618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.y, 129718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.z, 129818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.w 129918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt }; 130018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int new_r_swizzle[4]; 130118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int orig_r_swizzle = r->swizzle; 130218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int i; 130318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt 130418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt for (i = 0; i < 4; i++) { 130518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[i] = GET_SWZ(orig_r_swizzle, 0); 130618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt } 1307cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 130818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt dst_reg.writemask = 0; 130918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt for (i = 0; i < 4; i++) { 131018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt if (i < swiz->mask.num_components) { 131118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt dst_reg.writemask |= 1 << swizzles[i]; 131218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[swizzles[i]] = GET_SWZ(orig_r_swizzle, i); 131318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt } 1314cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt } 131518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt 131618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt r->swizzle = MAKE_SWIZZLE4(new_r_swizzle[0], 131718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[1], 131818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[2], 131918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[3]); 1320cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt } 1321cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 132218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt return dst_reg; 1323cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1324cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 132584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 132684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 132784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 13280161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg l; 13290161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg r; 13307d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 133184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 13322c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(!ir->lhs->type->is_array()); 13332c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 133484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 133584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1336cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 133718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt l = get_assignment_lhs(ir->lhs, this, &r); 1338cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 13390161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 13400161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 134184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1342346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 13432d1789e667c4180777829f96856daf91326721b9Eric Anholt ir_to_mesa_src_reg condition; 13442d1789e667c4180777829f96856daf91326721b9Eric Anholt 13452d1789e667c4180777829f96856daf91326721b9Eric Anholt ir->condition->accept(this); 13462d1789e667c4180777829f96856daf91326721b9Eric Anholt condition = this->result; 13472d1789e667c4180777829f96856daf91326721b9Eric Anholt 13482d1789e667c4180777829f96856daf91326721b9Eric Anholt /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, 13492d1789e667c4180777829f96856daf91326721b9Eric Anholt * and the condition we produced is 0.0 or 1.0. By flipping the 13502d1789e667c4180777829f96856daf91326721b9Eric Anholt * sign, we can choose which value OPCODE_CMP produces without 13512d1789e667c4180777829f96856daf91326721b9Eric Anholt * an extra computing the condition. 13522d1789e667c4180777829f96856daf91326721b9Eric Anholt */ 13532d1789e667c4180777829f96856daf91326721b9Eric Anholt condition.negate = ~condition.negate; 13547d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 13557d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, 13567d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt condition, r, ir_to_mesa_src_reg_from_dst(l)); 13577d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 13587d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 13597d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 13602d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 13617d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 13627d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 13637d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 13647d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 13657d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1366346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 136784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 136884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 136984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 137084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 137184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 137284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 13730161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 13740bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat stack_vals[4]; 13750bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 13760bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 137784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1378ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_array()) { 1379ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir->print(); 1380ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt printf("\n"); 1381ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(!"FINISHME: array constants"); 1382ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1383ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 13845b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt /* Unfortunately, 4 floats is all we can get into 13855b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store an 13865b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * aggregate constant and move each constant value into it. If we 13875b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * get lucky, copy propagation will eliminate the extra moves. 13885b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt */ 13895b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 13905b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt if (ir->type->base_type == GLSL_TYPE_STRUCT) { 13915b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_src_reg temp_base = get_temp(ir->type); 13925b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); 13935b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 13945b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt foreach_iter(exec_list_iterator, iter, ir->components) { 13955b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_constant *field_value = (ir_constant *)iter.get(); 13965b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt int size = type_size(field_value->type); 13975b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 13985b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt assert(size > 0); 13995b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 14005b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt field_value->accept(this); 14015b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg = this->result; 14025b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 14035b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt for (i = 0; i < (unsigned int)size; i++) { 14045b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); 14055b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 14065b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg.index++; 14075b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt temp.index++; 14085b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 14095b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 14105b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt this->result = temp_base; 14115b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt return; 14125b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 14135b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 1414ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1415ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_src_reg mat = get_temp(glsl_type::vec4_type); 1416ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat); 1417ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1418ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1419ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.file = PROGRAM_CONSTANT; 1420ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1421ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1422ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1423ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1424ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 1425ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values, 1426ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir->type->vector_elements, 1427ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt &src_reg.swizzle); 1428f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 1429ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.negate = 0; 1430ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg); 1431ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1432ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1433ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1434ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1435ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1436582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 14370bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 14380bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt src_reg.file = PROGRAM_CONSTANT; 14390bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 14400bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 14410bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 14420bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14430bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 14440bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 14450bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 14460bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14470bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14480bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 14490bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 14500bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 14510bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14520bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14530bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 14540bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 14550bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 14560bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14570bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14580bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 14590bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 14600bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14610bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 14620bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 14630bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values, ir->type->vector_elements, 14640bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt &src_reg.swizzle); 1465f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 14660161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.negate = 0; 146784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14680161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 146984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 147084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry * 14727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) 14737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{ 14747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry; 14757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, this->function_signatures) { 14777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = (function_entry *)iter.get(); 14787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig == sig) 14807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 14817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 14827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = talloc(mem_ctx, function_entry); 14847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig = sig; 14857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig_id = this->next_signature_id++; 14867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = NULL; 14877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Allocate storage for all the parameters. */ 14897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, sig->parameters) { 14907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)iter.get(); 1491b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage; 14927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt storage = find_variable_storage(param); 14947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!storage); 14957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1496b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 1497b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1498b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(storage); 14997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->next_temp += type_size(param->type); 15017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 15027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (sig->return_type) { 15057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = get_temp(sig->return_type); 15067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } else { 15077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = ir_to_mesa_undef; 15087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->function_signatures.push_tail(entry); 15117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 15127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt} 151384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 151484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 151584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 151684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 15177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *call_inst; 15187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig = ir->get_callee(); 15197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = get_function_signature(sig); 15207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 15217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process in parameters. */ 15237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list_iterator sig_iter = sig->parameters.iterator(); 15247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 15257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 15267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 15277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_in || 15297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1530b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 15317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 15327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 15347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 15357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 15377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.file = storage->file; 15387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index = storage->index; 15397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.reladdr = NULL; 15407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.writemask = WRITEMASK_XYZW; 15417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.cond_mask = COND_TR; 15427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 15447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 15457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 15467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 15477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 15517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 15537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit call instruction */ 15557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL, 15567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 15577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst->function = entry; 15587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process out parameters. */ 15607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter = sig->parameters.iterator(); 15617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 15627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 15637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 15647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_out || 15667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1567b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 15687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 15697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r; 15717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.file = storage->file; 15727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index = storage->index; 15737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.reladdr = NULL; 15747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.swizzle = SWIZZLE_NOOP; 15757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.negate = 0; 15767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 15787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result); 15797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 15817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 15827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 15837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 15847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 15887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 15907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process return value. */ 15927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->result = entry->return_reg; 159384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 159484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 159584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 159684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 159784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 159884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 159956d33f8e2be1695c951a811fac1800117c2ca406Carl Worth ir_to_mesa_src_reg result_src, coord, lod_info = { 0 }, projector; 1600d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_dst_reg result_dst, coord_dst; 1601d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 1602d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 160384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 160484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->coordinate->accept(this); 1605d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1606d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 1607d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 1608d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 1609d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 1610d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1611d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 1612d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst = ir_to_mesa_dst_reg_from_src(coord); 1613d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, 1614d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt this->result); 1615d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1616de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 1617de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 1618de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 1619de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 1620de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 1621d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 1622d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 1623d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1624d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 1625d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 1626d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1627d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 1628d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 1629d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 1630d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1631d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 1632d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 1633d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 1634d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1635d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1636d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 1637d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 1638d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 1639d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1640d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1641d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 1642d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txf: 1643d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"GLSL 1.30 features unsupported"); 1644d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1645d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1646d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1647d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 1648d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 1649d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 1650d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1651d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector); 1652d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1653d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 1654d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 1655d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_src_reg coord_w = coord; 1656d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 1657d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1658d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 1659d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 1660d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 1661d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1662d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1663d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector); 1664d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1665d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 1666d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w); 1667d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1668d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1669d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 1670d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1671d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1672d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1673b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) { 1674b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 1675b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 1676b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 1677b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 1678b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_Z; 1679b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result); 1680b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1681b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 1682b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 1683d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 1684d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 1685d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1686d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info); 1687d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1688d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1689d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1690d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord); 1691d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1692b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 1693b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 1694b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 1695d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_dereference_variable *sampler = ir->sampler->as_dereference_variable(); 1696d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(sampler); /* FINISHME: sampler arrays */ 1697d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* generate the mapping, remove when we generate storage at 1698d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * declaration time 1699d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1700d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler->accept(this); 1701d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1702d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->sampler = get_sampler_number(sampler->var->location); 1703d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1704d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (sampler->type->sampler_dimensionality) { 1705d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 1706d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_1D_INDEX; 1707d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1708d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 1709d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_2D_INDEX; 1710d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1711d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 1712d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 1713d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1714d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 1715d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 1716d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1717d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 1718d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"FINISHME: other texture targets"); 1719d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1720d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1721d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 172284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 172384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 172484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 172584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 172684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 17277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(current_function); 17287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (ir->get_value()) { 17307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 17317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 17327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir->get_value()->accept(this); 17347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 173584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 17367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l = ir_to_mesa_dst_reg_from_src(current_function->return_reg); 17377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(current_function->sig->return_type); i++) { 17397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 17407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 17417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 17427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op0(ir, OPCODE_RET); 174684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 174784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 174816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 174916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 175016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 17515e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt assert(ir->condition == NULL); /* FINISHME */ 175216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 1753021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV); 175416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 175584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 175684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 175784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 175884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1759854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL; 1760cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 1761cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 1762cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 1763c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1764c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 17650161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 1766c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1767854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if (ctx->Shader.EmitCondCodes) { 1768854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 1769cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 1770cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 1771cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 1772cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 1773cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 1774cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 1775cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type); 1776cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV, 1777cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_dst_reg_from_src(temp), 1778cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt result); 1779cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 1780854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 1781854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 1782021222c6a872ca2eef770ebadb8754f659775204Eric Anholt if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF); 1783854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst->dst_reg.cond_mask = COND_NE; 1784854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 1785854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, 1786854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt OPCODE_IF, ir_to_mesa_undef_dst, 1787854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt this->result); 1788854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 1789c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1790c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 1791c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1792c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 1793c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1794c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 1795021222c6a872ca2eef770ebadb8754f659775204Eric Anholt else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE); 17960a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 1797c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1798c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 17990161515c395c44233529c8d51f823b60050bc7baEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF, 18000161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 180184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 180284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1803ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 1804ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 18050161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 1806ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 18077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 1808d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler_map = NULL; 1809d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler_map_size = 0; 18107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 1811ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 1812ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 181384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 181484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) 181584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 181684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 181784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 181884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 1819aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt assert(reg.index < (1 << INST_INDEX_BITS) - 1); 182084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 182134195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 1822f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 1823ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 1824285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 182584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 182684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 182784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 182884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1829c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 18307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 18317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 1832c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 1833c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 1834e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 183564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 183664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 183764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 1838c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1839c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 184064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 184164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 1842c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 184364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 184464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 184564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 184664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 184764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 184864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 184964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 185064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 185164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 185264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 185364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 1854c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1855c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 185664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack = (int *)calloc(if_count, sizeof(*if_stack)); 185764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack)); 1858c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1859c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 1860c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 1861c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 186264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 1863c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 1864c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 1865c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 186664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 186764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 1868c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 1869c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 187064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 1871c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 1872c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 187364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 187464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 187564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 187664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 187764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 187864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 187964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 188064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 188164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 188264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 188364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 188464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 188564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 188664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 188764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 188864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 188964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 189064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 189164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 189264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 189364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 18947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 18957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 18967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 18977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 18987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 19007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 19017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 19027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 19047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 1905c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 1906c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 1907c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1908c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1909c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1910c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt free(if_stack); 1911c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 1912c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1913c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 1914c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 1915c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 1916c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 1917c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 1918c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 1919c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 1920748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 1921c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1922c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 1923c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 1924c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 1925c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1926748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 1927748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 192864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 1929748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 1930748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 1931748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 1932748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 1933748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 1934748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 1935c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 1936c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 1937748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 1938748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 1939c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1940c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1941748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 1942748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 1943c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1944c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 1945c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1946ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void 19474d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_input(struct gl_program *prog, 19484d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int index, 19494d5da50b94115d055ba8d0ff8717054582665384Eric Anholt GLboolean reladdr) 19504d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{ 19514d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->InputsRead |= BITFIELD64_BIT(index); 19524d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int i; 19534d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19544d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (reladdr) { 19554d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) { 19564d5da50b94115d055ba8d0ff8717054582665384Eric Anholt for (i = 0; i < 8; i++) { 19574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i); 19584d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19594d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 19604d5da50b94115d055ba8d0ff8717054582665384Eric Anholt assert(!"FINISHME: Mark InputsRead for varying arrays"); 19614d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19624d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19634d5da50b94115d055ba8d0ff8717054582665384Eric Anholt} 19644d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19654d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void 19664d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_output(struct gl_program *prog, 19674d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int index, 19684d5da50b94115d055ba8d0ff8717054582665384Eric Anholt GLboolean reladdr) 19694d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{ 19704d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->OutputsWritten |= BITFIELD64_BIT(index); 19714d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int i; 19724d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19734d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (reladdr) { 19744d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) { 19754d5da50b94115d055ba8d0ff8717054582665384Eric Anholt for (i = 0; i < 8; i++) { 19764d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i); 19774d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19784d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 19794d5da50b94115d055ba8d0ff8717054582665384Eric Anholt assert(!"FINISHME: Mark OutputsWritten for varying arrays"); 19804d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19814d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19824d5da50b94115d055ba8d0ff8717054582665384Eric Anholt} 19834d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19844d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void 1985ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog) 1986ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{ 1987d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt unsigned int i; 1988d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1989ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt prog->InputsRead = 0; 1990ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt prog->OutputsWritten = 0; 1991d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed = 0; 1992ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 1993ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (i = 0; i < prog->NumInstructions; i++) { 1994ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt struct prog_instruction *inst = &prog->Instructions[i]; 1995ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt unsigned int reg; 1996ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 1997ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt switch (inst->DstReg.File) { 1998ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_OUTPUT: 19994d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr); 2000ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2001ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_INPUT: 20024d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr); 2003ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2004ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt default: 2005ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2006ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2007ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2008ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) { 2009ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt switch (inst->SrcReg[reg].File) { 2010ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_OUTPUT: 20114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_output(prog, inst->SrcReg[reg].Index, 20124d5da50b94115d055ba8d0ff8717054582665384Eric Anholt inst->SrcReg[reg].RelAddr); 2013ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2014ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_INPUT: 20154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr); 2016ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2017ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt default: 2018ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 2019ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2020ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2021d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2022d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Instead of just using the uniform's value to map to a 2023d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * sampler, Mesa first allocates a separate number for the 2024d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * sampler (_mesa_add_sampler), then we reindex it down to a 2025d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * small integer (sampler_map[], SamplersUsed), then that gets 2026d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * mapped to the uniform's value, and we get an actual sampler. 2027d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 2028d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (_mesa_is_tex_instruction(inst->Opcode)) { 2029d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplerTargets[inst->TexSrcUnit] = 2030d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt (gl_texture_index)inst->TexSrcTarget; 2031d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed |= 1 << inst->TexSrcUnit; 2032d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (inst->TexShadow) { 2033d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->ShadowSamplers |= 1 << inst->TexSrcUnit; 2034d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2035d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2036ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2037d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2038d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt _mesa_update_shader_textures_used(prog); 2039ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt} 2040ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 204185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt/* Each stage has some uniforms in its Parameters list. The Uniforms 204285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * list for the linked shader program has a pointer to these uniforms 204385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * in each of the stage's Parameters list, so that their values can be 204485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * updated when a uniform is set. 204585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 204685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void 204785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtlink_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms, 204885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt struct gl_program *prog) 204985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 205085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt unsigned int i; 205185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 205285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt for (i = 0; i < prog->Parameters->NumParameters; i++) { 205385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt const struct gl_program_parameter *p = prog->Parameters->Parameters + i; 205485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 205585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) { 205685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt struct gl_uniform *uniform = 205785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt _mesa_append_uniform(uniforms, p->Name, prog->Target, i); 205885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt if (uniform) 205985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt uniform->Initialized = p->Initialized; 206085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 206185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 206285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 206385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2064364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program * 206595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, 206695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 206784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 206895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt void *mem_ctx = shader_program; 206984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 207084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2071c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 2072c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2073364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 2074364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 2075c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 20767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt GLboolean progress; 2077364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2078364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 2079c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 2080c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 2081c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 2082c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2083c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 2084c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 2085c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 2086c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2087c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 2088c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 2089c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2090364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 209184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 20921124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 20931124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 2094364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, 1); 2095364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 2096364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 2097364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 2098364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2099364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Attributes = _mesa_new_parameter_list(); 2100364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 2101364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 2102364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2103364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.mem_ctx = talloc_new(NULL); 21047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 210616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 2107021222c6a872ca2eef770ebadb8754f659775204Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_END); 210884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 21097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Now emit bodies for any functions that were used. */ 21107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt do { 21117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_FALSE; 21127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v.function_signatures) { 21147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 21157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (!entry->bgn_inst) { 21177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt v.current_function = entry; 21187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB); 21207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst->function = entry; 21217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt visit_exec_list(&entry->sig->body, &v); 21237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_RET); 21257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB); 21267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_TRUE; 21277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } while (progress); 21307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2131364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 2132364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 213384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 213484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 213584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 213684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 213784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 213884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 213984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 214084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 2141364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *, 2142364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 214384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 214484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 2145c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 214684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 214784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 2148b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 214984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 2150854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 215184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.File = inst->dst_reg.file; 215284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.Index = inst->dst_reg.index; 2153854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask; 215412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; 2155f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL; 215684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); 215784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); 215884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); 2159d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 2160d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 2161b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 2162c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 2163aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 216495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { 216595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->InfoLog = 216695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt talloc_asprintf_append(shader_program->InfoLog, 216795c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt "Couldn't flatten if statement\n"); 216895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->LinkStatus = false; 216995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt } 217095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt 21717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (mesa_inst->Opcode == OPCODE_BGNSUB) 21727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function->inst = i; 21737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt else if (mesa_inst->Opcode == OPCODE_CAL) 21747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ 2175d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt else if (mesa_inst->Opcode == OPCODE_ARL) 2176d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 21777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 217884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 2179c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 218084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 2181c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 21827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 2183c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2184c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt printf("Mesa %s program:\n", target_string); 2185364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 2186364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 2187364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2188364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2189364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 2190364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 2191364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 219216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 2193364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 219428faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 219528faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 219628faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 219728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 2198364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 2199364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2200364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 220116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 220216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 220316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 220416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) 2205364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 22062462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 22072462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 22085e18b051c039564d1998818d08caf1bff3983630Ian Romanick 2209153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 221006143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick state->error = preprocess(state, &source, &state->info_log, 221106143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick &ctx->Extensions); 2212153eca98064252be4daad9cc27746f37c245b627Ian Romanick 2213153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 2214153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 2215153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 2216153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 2217153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 2218364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 221916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 2220364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 222116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 2222364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 222316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 2224ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2225ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 22264802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt /* Lowering */ 22274802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_mat_op_to_vec(shader->ir); 22284802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_mod_to_fract(shader->ir); 22294802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_div_to_mul_rcp(shader->ir); 22304802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt 22314802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt /* Optimization passes */ 2232364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt bool progress; 2233364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt do { 2234364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt progress = false; 2235364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 223616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_function_inlining(shader->ir) || progress; 223716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_if_simplification(shader->ir) || progress; 223816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_copy_propagation(shader->ir) || progress; 223916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_dead_code_local(shader->ir) || progress; 224016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_dead_code_unlinked(state, shader->ir) || progress; 224116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_constant_variable_unlinked(shader->ir) || progress; 224216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_constant_folding(shader->ir) || progress; 2243d674ebcee0d2731e50d6530502cefcebc39dcdb6Eric Anholt progress = do_if_return(shader->ir) || progress; 224495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt if (ctx->Shader.EmitNoIfs) 224595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt progress = do_if_to_cond_assign(shader->ir) || progress; 2246a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 224716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_vec_index_to_swizzle(shader->ir) || progress; 2248a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Do this one after the previous to let the easier pass handle 2249a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * constant vector indexing. 2250a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 2251a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt progress = do_vec_index_to_cond_assign(shader->ir) || progress; 2252a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 225316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_swizzle_swizzle(shader->ir) || progress; 2254364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } while (progress); 2255ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 2256ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2257364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2258364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2259364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 2260364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2261364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 2262364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 226325f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 2264d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 2265d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 2266d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 2267c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2268116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 226960e2d06d1ccc66ad00cd7ab81c418853f21be291Ian Romanick reparent_ir(shader->ir, shader); 2270116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 2271364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt talloc_free(state); 2272364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2273364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2274364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 2275364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog) 2276364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 2277364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 2278849e18153cd91d812f694b806a84008498860bc3Eric Anholt 2279364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 2280364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2281849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 2282364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2283364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 2284849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 2285849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->InfoLog = 2286849e18153cd91d812f694b806a84008498860bc3Eric Anholt talloc_asprintf_append(prog->InfoLog, 2287364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt "linking with uncompiled shader"); 2288849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 2289364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2290364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2291364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2292364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2293364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); 2294364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); 2295364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2296849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 2297849e18153cd91d812f694b806a84008498860bc3Eric Anholt link_shaders(prog); 2298849e18153cd91d812f694b806a84008498860bc3Eric Anholt 2299849e18153cd91d812f694b806a84008498860bc3Eric Anholt /* We don't use the linker's uniforms list, and cook up our own at 2300849e18153cd91d812f694b806a84008498860bc3Eric Anholt * generate time. 2301849e18153cd91d812f694b806a84008498860bc3Eric Anholt */ 2302849e18153cd91d812f694b806a84008498860bc3Eric Anholt free(prog->Uniforms); 2303849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->Uniforms = _mesa_new_uniform_list(); 2304849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 2305364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2306364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 23073fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick for (i = 0; i < prog->_NumLinkedShaders; i++) { 2308364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *linked_prog; 2309364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2310849e18153cd91d812f694b806a84008498860bc3Eric Anholt linked_prog = get_mesa_program(ctx, prog, 23113fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick prog->_LinkedShaders[i]); 2312ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt count_resources(linked_prog); 2313364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 231485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog); 231585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 23163fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick switch (prog->_LinkedShaders[i]->Type) { 2317364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt case GL_VERTEX_SHADER: 2318364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, 2319364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt (struct gl_vertex_program *)linked_prog); 23207dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 23217dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt linked_prog); 2322364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt break; 2323364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt case GL_FRAGMENT_SHADER: 2324364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, 2325364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt (struct gl_fragment_program *)linked_prog); 23267dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 23277dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt linked_prog); 2328364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt break; 2329364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2330364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2331364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2332364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2333364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2334364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 2335