ir_to_mesa.cpp revision d64343f1ae84979bd154475badf11af8a9bfc2eb
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" 4684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "shader/prog_instruction.h" 4728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt#include "shader/prog_optimize.h" 48aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt#include "shader/prog_print.h" 49364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/program.h" 50364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/prog_uniform.h" 51364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/prog_parameter.h" 52364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/shader_api.h" 53aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt} 5484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 55554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/** 56554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with 57554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields. 58554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg { 60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 62582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int negate; /**< NEGATE_XYZW mask from mesa */ 64f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 65f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 66554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg; 67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 68554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg { 69554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 70554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 71554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 72854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLuint cond_mask:4; 73f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 74f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 75554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg; 76554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 77554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef; 78554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 79554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node { 80554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op; 82554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst_reg; 83554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src_reg[3]; 84554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** Pointer to the ir source this tree came from for debugging */ 85554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_instruction *ir; 86854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLboolean cond_update; 87d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler; /**< sampler index */ 88d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int tex_target; /**< One of TEXTURE_*_INDEX */ 89b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt GLboolean tex_shadow; 907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ 92554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 93554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 94b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node { 95554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 96b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage(ir_variable *var, int file, int index) 97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt : file(file), index(index), var(var) 98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt { 99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /* empty */ 100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt } 101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; 103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; 104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_variable *var; /* variable that maps to this, if any */ 105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node { 1087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic: 1097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig; 1107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * identifier of this function signature used by the program. 1137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * At the point that Mesa instructions for function calls are 1157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * generated, we don't know the address of the first instruction of 1167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * the function body. So we make the BranchTarget that is called a 1177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * small integer and rewrite them during set_branchtargets(). 1187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int sig_id; 1207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Pointer to first instruction of the function body. 1237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set during function body emits after main() is processed. 1257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *bgn_inst; 1277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Index of the first instruction of the function body in actual 1307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Mesa IR. 1317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set after convertion from ir_to_mesa_instruction to prog_instruction. 1337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int inst; 1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** Storage for the return value. */ 1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg return_reg; 1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}; 1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 140554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor { 141554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 142554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_visitor(); 143554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *current_function; 1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 146364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLcontext *ctx; 147364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 148364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 149554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int next_temp; 150a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 151b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *find_variable_storage(ir_variable *var); 152554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *get_function_signature(ir_function_signature *sig); 1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1558364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt ir_to_mesa_src_reg get_temp(const glsl_type *type); 156f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt void reladdr_to_temp(ir_instruction *ir, 157f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr); 158554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 159554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg src_reg_for_float(float val); 160554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 161554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 162554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 164554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 166554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 170554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 172554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 173554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 174554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 175554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 176554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 177554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 179554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 18316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 184554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 185554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg result; 189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 190b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 191b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 192554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 1947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 1957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 1967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 197554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 200021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir, 201021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op); 202021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 203554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir, 204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 205554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir, 209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 212554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1); 213554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir, 215554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 216554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 217554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 218554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1, 219554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src2); 220554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt void ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 222554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 223554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 224554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 2250ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt 226904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt void ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 227904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 228904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 229904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0, 230904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1); 231904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 2323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt GLboolean try_emit_mad(ir_expression *ir, 2333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 2343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 235d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int *sampler_map; 236d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler_map_size; 237d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 238d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt void map_sampler(int location, int sampler); 239d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int get_sampler_number(int location); 240d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 241364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 242554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 24484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = { 245f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, NULL, 24684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}; 24784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 248c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = { 249f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL, 250c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}; 251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2520161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = { 253f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL 2540161515c395c44233529c8d51f823b60050bc7baEric Anholt}; 2550161515c395c44233529c8d51f823b60050bc7baEric Anholt 2560161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size) 2570161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 2580161515c395c44233529c8d51f823b60050bc7baEric Anholt int size_swizzles[4] = { 2590161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 2600161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 2610161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 2620161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 2630161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 2640161515c395c44233529c8d51f823b60050bc7baEric Anholt 2650161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 2660161515c395c44233529c8d51f823b60050bc7baEric Anholt} 2670161515c395c44233529c8d51f823b60050bc7baEric Anholt 26884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 2690161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir, 2700161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 2710161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 2720161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 2730161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1, 2740161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src2) 27584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 276364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 277f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 278f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 279f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 280f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 281f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 282f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 283f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 284f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 285f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 286f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 287f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 288f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 289f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 290f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 291f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 292f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 293f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, 294f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *dst.reladdr); 295f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 296f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 297f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 298f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 29984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 30084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 30184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->dst_reg = dst; 30284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[0] = src0; 30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[1] = src1; 30484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[2] = src2; 305c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 30684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function = NULL; 3087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3090161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 31084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 31184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 31284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 31384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 31484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 31584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3160161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir, 3170161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3180161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3190161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 3200161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1) 32184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3220161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef); 32384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3260161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir, 3270161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3280161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3290161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0) 330bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 3310161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, 3320161515c395c44233529c8d51f823b60050bc7baEric Anholt src0, ir_to_mesa_undef, ir_to_mesa_undef); 333bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 334bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 335021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 336021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir, 337021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op) 338021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 339021222c6a872ca2eef770ebadb8754f659775204Eric Anholt return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst, 340021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 341021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 342021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef); 343021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 344021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 345d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtvoid 346d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::map_sampler(int location, int sampler) 347d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{ 348d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (this->sampler_map_size <= location) { 349d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map, 350d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int, location + 1); 351d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->sampler_map_size = location + 1; 352d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 353d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 354d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->sampler_map[location] = sampler; 355d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt} 356d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 357d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtint 358d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::get_sampler_number(int location) 359d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{ 360d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(location < this->sampler_map_size); 361d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt return this->sampler_map[location]; 362d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt} 363d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 3640161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg 3650161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg) 36684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3670161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst_reg; 36884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3690161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.file = reg.file; 3700161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.index = reg.index; 3710161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.writemask = WRITEMASK_XYZW; 372854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt dst_reg.cond_mask = COND_TR; 373f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt dst_reg.reladdr = reg.reladdr; 3740161515c395c44233529c8d51f823b60050bc7baEric Anholt 3750161515c395c44233529c8d51f823b60050bc7baEric Anholt return dst_reg; 376bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 377bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 3782d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg 3792d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg) 3802d1789e667c4180777829f96856daf91326721b9Eric Anholt{ 3812d1789e667c4180777829f96856daf91326721b9Eric Anholt ir_to_mesa_src_reg src_reg; 3822d1789e667c4180777829f96856daf91326721b9Eric Anholt 3832d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.file = reg.file; 3842d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.index = reg.index; 3852d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.swizzle = SWIZZLE_XYZW; 3862d1789e667c4180777829f96856daf91326721b9Eric Anholt src_reg.negate = 0; 387f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = reg.reladdr; 3882d1789e667c4180777829f96856daf91326721b9Eric Anholt 3892d1789e667c4180777829f96856daf91326721b9Eric Anholt return src_reg; 3902d1789e667c4180777829f96856daf91326721b9Eric Anholt} 3912d1789e667c4180777829f96856daf91326721b9Eric Anholt 39212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 39312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 39412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 39512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 39612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 39712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 39812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 39912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 40012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 401904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 4020161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 4030161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 404904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src0, 405904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src1) 40612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 40712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 408315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 40912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 41012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 41112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 41212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 41412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 415582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 41612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 417904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0 = orig_src0; 418904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1 = orig_src1; 41912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 42012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 42112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 42212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 423904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 424904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 42512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 426904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 427904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 428904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 42912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 432904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 433904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 434904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 435904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 43612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 437904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt inst = ir_to_mesa_emit_op2(ir, op, 4380161515c395c44233529c8d51f823b60050bc7baEric Anholt dst, 439904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0, 440904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1); 44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt inst->dst_reg.writemask = this_mask; 44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 44412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 44512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 446904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 449904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 450904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0) 451904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 45259a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt ir_to_mesa_src_reg undef = ir_to_mesa_undef; 453904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 456904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef); 457904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 458904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 4590161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg 4600161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 461b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 4620161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 4631d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4640161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.file = PROGRAM_CONSTANT; 465582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 466582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt &val, 1, &src_reg.swizzle); 467f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 4688bb15c1ed55eb71533d2af94a6afbf01e3d23610Eric Anholt src_reg.negate = 0; 4691d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4700161515c395c44233529c8d51f823b60050bc7baEric Anholt return src_reg; 4711d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 4721d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 4742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 4752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 4762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 4772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 4782c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 4792c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 4802c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 4812c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 4822c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 4832c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 484a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 4859968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 486a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 487a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 488a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 489a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 490a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 491a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 492a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 493a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 4942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 4962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 4972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 4982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 4992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 5002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 5022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 5032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 5042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 5052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 5062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 507d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 508d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 509d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 510d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 511d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 512d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 513d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg 514d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 515d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 516d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt ir_to_mesa_src_reg src_reg; 517d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int swizzle[4]; 518d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int i; 519d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 520d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt assert(!type->is_array()); 521d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 522d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.file = PROGRAM_TEMPORARY; 523d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.index = next_temp; 524f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 525d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 526d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 527d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt for (i = 0; i < type->vector_elements; i++) 528d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt swizzle[i] = i; 529d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt for (; i < 4; i++) 530d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt swizzle[i] = type->vector_elements - 1; 531d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], 532d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt swizzle[2], swizzle[3]); 533ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt src_reg.negate = 0; 534d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 535d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt return src_reg; 536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 538b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 539a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 54084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 541a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 542b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 54384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 544b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 545b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 54684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 5470161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 548a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 54984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 55084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 551a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 552a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 55384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 55484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 55584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 55684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 5578364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt (void)ir; 55884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 55984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 56184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 56284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 56364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->from); 56464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->to); 56564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->increment); 56664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->counter); 56784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 568021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); 56964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 570021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); 57184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 57664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 57764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 578021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BRK); 57964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 58064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 581021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_CONT); 58264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 58364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 58484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 58884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 58984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 59084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 60184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 60284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 60384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 60484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 60684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 60784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 60884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6163f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean 6173f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 6183f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 6193f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 6203f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_src_reg a, b, c; 6213f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6223f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 6233f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 6243f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 6253f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6263f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 6273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 6283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 6293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 6303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 6313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 6323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 6343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_emit_op3(ir, OPCODE_MAD, 6353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_dst_reg_from_src(this->result), a, b, c); 6363f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6373f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 6383f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 6393f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 64084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 641f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 642f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr) 643f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 644f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 645f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 646f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 647f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr); 648f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 649f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 650f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 651f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 652f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, 653f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_dst_reg_from_src(temp), *reg); 654f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 655f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 656f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 657f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 658f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 659f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 660f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 66184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 66284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 66384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 664f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt struct ir_to_mesa_src_reg op[2]; 6650161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg result_src; 6660161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg result_dst; 66784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1); 66884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1); 66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1); 67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6713f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 6723f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 6733f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 6743f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 6753f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 6763f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 6773f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 6783f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 6793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 68084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 6810161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 68284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 6830161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 68484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 68584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 6908364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 6914ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 6924ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 6934ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 6944ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 69584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 69684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6970161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 6980161515c395c44233529c8d51f823b60050bc7baEric Anholt 6990161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 7000161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 7010161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 7028364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 7030161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 7040161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 7059cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 7069cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 7079cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 7089cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 7099cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 71084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 7121d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 713f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, 714f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt op[0], src_reg_for_float(0.0)); 7151d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 716c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 7170161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 7180161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 719c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 720524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 721524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]); 722524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 7233acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 7243acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]); 7253acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 7268761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 7278761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]); 7288761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 729524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 7308c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp: 731b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, 732b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt src_reg_for_float(M_E), op[0]); 7338c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7348c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 7350161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]); 7368c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 7380161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]); 7398c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7408c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 7410161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]); 7428c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7433c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 7440161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]); 7453c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 7463c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 7470161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]); 7483c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 749ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 750ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 751ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]); 752ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 753ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 754ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]); 755ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 756ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 75784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 7587b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]); 75984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 76084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 7617b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]); 76284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 7639b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 76484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 7654ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]); 76684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 76784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 7689a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 769411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 770411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 771411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 77238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 77338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 774f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]); 77538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 77638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 777f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]); 77838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 77938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 780f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]); 78138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 783f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); 78438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 786f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 78738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 788763cd75863ed9a16912e585887580c44d1e8109fEric Anholt case ir_binop_logic_xor: 78938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_nequal: 790f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 79138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 79238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 7934380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_or: 7940161515c395c44233529c8d51f823b60050bc7baEric Anholt /* This could be a saturated add and skip the SNE. */ 7950161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, 7960161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 7970161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 7980161515c395c44233529c8d51f823b60050bc7baEric Anholt 7990161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 8000161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8010161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 8024380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8034380099c98119611ceee684669d00be26195c7d7Eric Anholt 8044380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 8054380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 8060161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 8070161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8080161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 8094380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8104380099c98119611ceee684669d00be26195c7d7Eric Anholt 81184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 81284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (ir->operands[0]->type == vec4_type) { 81384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec4_type); 8140161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP4, 8150161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8160161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 81784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec3_type) { 81884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec3_type); 8190161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP3, 8200161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8210161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 82284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec2_type) { 82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec2_type); 8240161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP2, 8250161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8260161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 82784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 82884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 8299be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 8309be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt case ir_binop_cross: 8319be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]); 8329be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt break; 8339be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 83484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 8350161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 8368f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src); 8378f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt /* For incoming channels < 0, set the result to 0. */ 8388f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst, 8398f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt op[0], src_reg_for_float(0.0), result_src); 84084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 841878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 8420161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 843878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 84450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 845d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 846d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 847423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 8480161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 84950ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 850423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 8510161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 852423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 8531d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 854411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 8550161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, 8560161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 8571d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 858c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 8590161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 860c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 861c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 8620161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 8630161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 8640161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 865c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 866c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 8670161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 868c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 869d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 870d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]); 871d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 872d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 873c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 8740161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]); 875c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 876c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 8770161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]); 878c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 879904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 880904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]); 881904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 882e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 883e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_bit_not: 884e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_u2f: 885e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 886e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 887e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 888e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 889e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 890e64a4aaacbc682f24180dff3627b84861844476dEric Anholt assert(!"GLSL 1.30 features unsupported"); 891e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 89284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 893b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 8940161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 89584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 89684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 89784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 89884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 89984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 90084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 9010161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 90284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 90384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 90484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 905b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 906b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 907b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 908b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 90984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 91084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 9114006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt src_reg = this->result; 9124006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt assert(src_reg.file != PROGRAM_UNDEFINED); 91384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 91484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 91584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 91684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 91784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 918698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x); 91984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 921698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y); 92284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 92384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 924698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z); 92584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 92684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 927698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w); 92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 93184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 93284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 93384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 934698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 93684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 93784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9380161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], 9390161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[1], 9400161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[2], 9410161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[3]); 94284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9430161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 94676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int 94776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens) 94876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{ 94976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 95076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int i; 95176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 95276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt /* Add a ref for each column. It looks like the reason we do 95376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * it this way is that _mesa_add_state_reference doesn't work 95476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * for things that aren't vec4s, so the tokens[2]/tokens[3] 95576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * range has to be equal. 95676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt */ 95776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < 4; i++) { 95876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[2] = i; 95976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[3] = i; 96076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = _mesa_add_state_reference(prog->Parameters, 96176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt (gl_state_index *)tokens); 96276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 96376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 96476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 96576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + i == pos); 96676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 96776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 96876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return base_pos; 96976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt} 97076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 971b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage * 97276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var, 97376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_rvalue *array_index) 974bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{ 975bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* 976bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * NOTE: The ARB_vertex_program extension specified that matrices get 977bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * loaded in registers in row-major order. With GLSL, we want column- 978bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * major order. So, we need to transpose all matrices here... 979bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 980bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt static const struct { 981bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt const char *name; 982bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int matrix; 983bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int modifier; 984bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } matrices[] = { 985bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, 986bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS }, 987bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, 988bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 989bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 990bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE }, 991bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS }, 992bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 }, 993bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE }, 994bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 995bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE }, 996bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS }, 997bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 }, 998bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE }, 999bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1000bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE }, 1001bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS }, 1002bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 }, 1003bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, 1004bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1005bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 1006bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1007bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt }; 1008bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt unsigned int i; 1009b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 1010bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1011bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* C++ gets angry when we try to use an int as a gl_state_index, so we use 1012bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * ints for gl_state_index. Make sure they're compatible. 1013bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 1014bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt assert(sizeof(gl_state_index) == sizeof(int)); 1015bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1016bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt for (i = 0; i < Elements(matrices); i++) { 1017bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (strcmp(var->name, matrices[i].name) == 0) { 1018bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int tokens[STATE_LENGTH]; 101976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 1020bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1021bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[0] = matrices[i].matrix; 1022bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[4] = matrices[i].modifier; 102376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (matrices[i].matrix == STATE_TEXTURE_MATRIX) { 102476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_constant *index = array_index->constant_expression_value(); 102576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 102676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = index->value.i[0]; 102776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 102876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 102976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < var->type->length; i++) { 103076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = i; 103176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = add_matrix_ref(prog, tokens); 103276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 103376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 103476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 103576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + (int)i * 4 == pos); 103676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 103776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 103876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 103976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = 0; /* unused array index */ 104076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 1041bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 104276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[4] = matrices[i].modifier; 1043bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1044b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(var, 1045b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_STATE_VAR, 1046b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt base_pos); 1047bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1048bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return entry; 1049bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1050bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1051bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1052bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return NULL; 1053bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt} 1054bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 105584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 105684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 105784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 10580161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 1059b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 1060a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt unsigned int loc; 106184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 10628364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 10638364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt switch (ir->var->mode) { 10648364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 106576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var, 106676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt NULL); 1067bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (entry) 1068bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt break; 1069bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 107085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt /* FINISHME: Fix up uniform name for arrays and things */ 1071d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) { 1072d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* FINISHME: we whack the location of the var here, which 1073d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * is probably not expected. But we need to communicate 1074d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * mesa's sampler number to the tex instruction. 1075d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1076d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler = _mesa_add_sampler(this->prog->Parameters, 1077d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->var->name, 1078d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->var->type->gl_type); 1079d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt map_sampler(ir->var->location, sampler); 1080d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1081b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER, 1082b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt sampler); 1083b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1084d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1085d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1086d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 108785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt assert(ir->var->type->gl_type != 0 && 108885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt ir->var->type->gl_type != GL_INVALID_ENUM); 108985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt loc = _mesa_add_uniform(this->prog->Parameters, 109085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt ir->var->name, 109185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt type_size(ir->var->type) * 4, 109285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt ir->var->type->gl_type, 109385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt NULL); 1094d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 109585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt /* Always mark the uniform used at this point. If it isn't 109685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * used, dead code elimination should have nuked the decl already. 109785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 109885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt this->prog->Parameters->Parameters[loc].Used = GL_TRUE; 1099224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 1100b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc); 1101b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 11028364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 11038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 11048364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_out: 11058364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1106a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1107a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * including deprecated builtins (like gl_Color), user-assign 1108a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * generic attributes (glBindVertexLocation), and 1109a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * user-defined varyings. 1110a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1111a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1112f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1113f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt assert(ir->var->location != -1); 1114a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt if (ir->var->mode == ir_var_in || 1115a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt ir->var->mode == ir_var_inout) { 1116b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1117b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_INPUT, 1118b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1119edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt 1120edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && 1121edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->location >= VERT_ATTRIB_GENERIC0) { 1122edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt _mesa_add_attribute(prog->Attributes, 1123edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->name, 1124edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt type_size(ir->var->type) * 4, 1125edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->type->gl_type, 1126c64da87611823b4b53e93188f861f748a69936a3Eric Anholt ir->var->location - VERT_ATTRIB_GENERIC0); 1127edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt } 1128f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } else { 1129b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1130b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_OUTPUT, 1131b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1132f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } 1133f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt 11348364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 11358364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 11367e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1137b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY, 1138b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1139b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1140224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 11418364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt next_temp += type_size(ir->var->type); 11428364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 114384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 11448364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 11458364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 11468364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt printf("Failed to make storage for %s\n", ir->var->name); 11478364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1148224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 114984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 115084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 11518364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt src_reg.file = entry->file; 11528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt src_reg.index = entry->index; 115384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 115485e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 115585e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements); 115685e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 115785e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = SWIZZLE_NOOP; 1158f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 11590161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.negate = 0; 116084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 11610161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 116284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 116384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 116484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 116584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 116684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1167ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 11680161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 116976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_dereference_variable *deref_var = ir->array->as_dereference_variable(); 11708258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1171ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1172ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 11734e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 117476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (deref_var && strncmp(deref_var->var->name, 117576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt "gl_TextureMatrix", 117676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt strlen("gl_TextureMatrix")) == 0) { 117776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_src_reg src_reg; 1178b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt struct variable_storage *entry; 117976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 118076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var, 118176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index); 118276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(entry); 118376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 118476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.file = entry->file; 118576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.index = entry->index; 118676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); 118776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt src_reg.negate = 0; 118876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 118976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 1190f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 119176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 119276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type); 119376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 119476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index->accept(this); 119576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 119676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 11978258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt this->result, src_reg_for_float(element_size)); 119876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1199f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 1200f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 120176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 120276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 120376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt this->result = src_reg; 120476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return; 120576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 120676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1207ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 12080161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg = this->result; 12094e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 12104d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 12114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.index += index->value.i[0] * element_size; 12124e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 12134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg array_base = this->result; 12144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 12154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 12164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 12174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 12184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 12198258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 12204d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg index_reg; 12218258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 12224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 12234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 12244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 12254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1226f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 12274d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 12284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 12294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt this->result, src_reg_for_float(element_size)); 1230bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 12314d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 12324d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 12334d5da50b94115d055ba8d0ff8717054582665384Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 12344e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 123584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 123684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 123785e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 123885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); 123985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 124085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = SWIZZLE_NOOP; 124184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 12420161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 124384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 124484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 12452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 12462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 12472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 12482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 12490161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 12502c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 12512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 12520161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 12532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 12542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 12550161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 12562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 12572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 12582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 125985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 12600161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 12612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 12622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 12632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 12642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 12652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 12662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 12672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * 12682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we 12692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector, 12702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage. So handle 12712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest. 12722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 12730161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg 127418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v, 127518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt ir_to_mesa_src_reg *r) 1276b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 12770161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg dst_reg; 1278b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt ir_swizzle *swiz; 1279b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt 1280ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1281ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt /* This should have been handled by ir_vec_index_to_cond_assign */ 1282ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1283ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1284ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1285ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 12860161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 12870161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 12880161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 12892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 12900161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg = ir_to_mesa_dst_reg_from_src(v->result); 12912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 1292ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if ((swiz = ir->as_swizzle())) { 129318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int swizzles[4] = { 129418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.x, 129518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.y, 129618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.z, 129718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt swiz->mask.w 129818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt }; 129918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int new_r_swizzle[4]; 130018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int orig_r_swizzle = r->swizzle; 130118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt int i; 130218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt 130318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt for (i = 0; i < 4; i++) { 130418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[i] = GET_SWZ(orig_r_swizzle, 0); 130518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt } 1306cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 130718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt dst_reg.writemask = 0; 130818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt for (i = 0; i < 4; i++) { 130918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt if (i < swiz->mask.num_components) { 131018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt dst_reg.writemask |= 1 << swizzles[i]; 131118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[swizzles[i]] = GET_SWZ(orig_r_swizzle, i); 131218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt } 1313cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt } 131418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt 131518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt r->swizzle = MAKE_SWIZZLE4(new_r_swizzle[0], 131618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[1], 131718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[2], 131818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt new_r_swizzle[3]); 1319cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt } 1320cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 132118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt return dst_reg; 1322cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1323cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 132484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 132584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 132684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 13270161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg l; 13280161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg r; 13297d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 133084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 13312c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(!ir->lhs->type->is_array()); 13322c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 133384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 133484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1335cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 133618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt l = get_assignment_lhs(ir->lhs, this, &r); 1337cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 13380161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 13390161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 134084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1341346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 13422d1789e667c4180777829f96856daf91326721b9Eric Anholt ir_to_mesa_src_reg condition; 13432d1789e667c4180777829f96856daf91326721b9Eric Anholt 13442d1789e667c4180777829f96856daf91326721b9Eric Anholt ir->condition->accept(this); 13452d1789e667c4180777829f96856daf91326721b9Eric Anholt condition = this->result; 13462d1789e667c4180777829f96856daf91326721b9Eric Anholt 13472d1789e667c4180777829f96856daf91326721b9Eric Anholt /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, 13482d1789e667c4180777829f96856daf91326721b9Eric Anholt * and the condition we produced is 0.0 or 1.0. By flipping the 13492d1789e667c4180777829f96856daf91326721b9Eric Anholt * sign, we can choose which value OPCODE_CMP produces without 13502d1789e667c4180777829f96856daf91326721b9Eric Anholt * an extra computing the condition. 13512d1789e667c4180777829f96856daf91326721b9Eric Anholt */ 13522d1789e667c4180777829f96856daf91326721b9Eric Anholt condition.negate = ~condition.negate; 13537d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 13547d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, 13557d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt condition, r, ir_to_mesa_src_reg_from_dst(l)); 13567d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 13577d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 13587d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 13592d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 13607d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 13617d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 13627d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 13637d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 13647d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1365346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 136684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 136784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 136884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 136984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 137084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 137184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 13720161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 13730bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat stack_vals[4]; 13740bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 13750bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 137684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1377ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_array()) { 1378ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir->print(); 1379ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt printf("\n"); 1380ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(!"FINISHME: array constants"); 1381ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1382ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1383ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1384ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt /* Unfortunately, 4 floats is all we can get into 1385ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store the 1386ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt * matrix and move each constant value into it. If we get 1387ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt * lucky, copy propagation will eliminate the extra moves. 1388ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt */ 1389ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_src_reg mat = get_temp(glsl_type::vec4_type); 1390ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat); 1391ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1392ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1393ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.file = PROGRAM_CONSTANT; 1394ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1395ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1396ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1397ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1398ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 1399ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values, 1400ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir->type->vector_elements, 1401ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt &src_reg.swizzle); 1402f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 1403ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.negate = 0; 1404ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg); 1405ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1406ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1407ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1408ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1409ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1410582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 14110bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 14120bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt src_reg.file = PROGRAM_CONSTANT; 14130bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 14140bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 14150bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 14160bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14170bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 14180bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 14190bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 14200bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14210bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14220bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 14230bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 14240bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 14250bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14260bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14270bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 14280bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 14290bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 14300bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14310bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 14320bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 14330bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 14340bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 14350bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 14360bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 14370bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values, ir->type->vector_elements, 14380bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt &src_reg.swizzle); 1439f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 14400161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.negate = 0; 144184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14420161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 144384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 144484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry * 14467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) 14477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{ 14487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry; 14497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, this->function_signatures) { 14517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = (function_entry *)iter.get(); 14527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig == sig) 14547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 14557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 14567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = talloc(mem_ctx, function_entry); 14587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig = sig; 14597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig_id = this->next_signature_id++; 14607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = NULL; 14617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Allocate storage for all the parameters. */ 14637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, sig->parameters) { 14647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)iter.get(); 1465b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage; 14667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt storage = find_variable_storage(param); 14687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!storage); 14697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1470b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 1471b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1472b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(storage); 14737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->next_temp += type_size(param->type); 14757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 14767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 14777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (sig->return_type) { 14797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = get_temp(sig->return_type); 14807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } else { 14817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = ir_to_mesa_undef; 14827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 14837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->function_signatures.push_tail(entry); 14857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 14867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt} 148784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 148884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 148984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 149084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 14917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *call_inst; 14927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig = ir->get_callee(); 14937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = get_function_signature(sig); 14947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 14957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 14967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process in parameters. */ 14977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list_iterator sig_iter = sig->parameters.iterator(); 14987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 14997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 15007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 15017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_in || 15037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1504b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 15057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 15067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 15087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 15097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 15117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.file = storage->file; 15127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index = storage->index; 15137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.reladdr = NULL; 15147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.writemask = WRITEMASK_XYZW; 15157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.cond_mask = COND_TR; 15167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 15187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 15197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 15207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 15217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 15257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 15277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit call instruction */ 15297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL, 15307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 15317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst->function = entry; 15327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process out parameters. */ 15347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter = sig->parameters.iterator(); 15357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 15367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 15377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 15387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_out || 15407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1541b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 15427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 15437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r; 15457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.file = storage->file; 15467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index = storage->index; 15477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.reladdr = NULL; 15487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.swizzle = SWIZZLE_NOOP; 15497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.negate = 0; 15507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 15527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result); 15537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 15557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 15567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 15577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 15587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 15627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 15637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 15647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 15657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process return value. */ 15667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->result = entry->return_reg; 156784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 156884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 156984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 157084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 157184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 157284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 157356d33f8e2be1695c951a811fac1800117c2ca406Carl Worth ir_to_mesa_src_reg result_src, coord, lod_info = { 0 }, projector; 1574d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_dst_reg result_dst, coord_dst; 1575d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 1576d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 157784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 157884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->coordinate->accept(this); 1579d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1580d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 1581d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 1582d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 1583d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 1584d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1585d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 1586d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst = ir_to_mesa_dst_reg_from_src(coord); 1587d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, 1588d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt this->result); 1589d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1590de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 1591de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 1592de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 1593de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 1594de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 1595d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 1596d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 1597d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1598d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 1599d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 1600d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1601d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 1602d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 1603d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 1604d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1605d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 1606d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 1607d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 1608d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1609d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1610d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 1611d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 1612d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 1613d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1614d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1615d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 1616d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txf: 1617d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"GLSL 1.30 features unsupported"); 1618d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1619d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1620d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1621d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 1622d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 1623d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 1624d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1625d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector); 1626d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1627d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 1628d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 1629d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_src_reg coord_w = coord; 1630d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 1631d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1632d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 1633d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 1634d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 1635d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1636d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1637d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector); 1638d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1639d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 1640d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w); 1641d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1642d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1643d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 1644d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1645d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1646d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1647b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) { 1648b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 1649b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 1650b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 1651b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 1652b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_Z; 1653b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result); 1654b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1655b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 1656b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 1657d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 1658d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 1659d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1660d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info); 1661d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1662d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1663d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1664d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord); 1665d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1666b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 1667b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 1668b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 1669d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_dereference_variable *sampler = ir->sampler->as_dereference_variable(); 1670d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(sampler); /* FINISHME: sampler arrays */ 1671d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* generate the mapping, remove when we generate storage at 1672d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * declaration time 1673d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1674d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler->accept(this); 1675d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1676d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->sampler = get_sampler_number(sampler->var->location); 1677d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1678d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (sampler->type->sampler_dimensionality) { 1679d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 1680d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_1D_INDEX; 1681d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1682d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 1683d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_2D_INDEX; 1684d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1685d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 1686d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 1687d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1688d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 1689d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 1690d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1691d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 1692d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"FINISHME: other texture targets"); 1693d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1694d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1695d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 169684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 169784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 169884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 169984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 170084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 17017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(current_function); 17027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (ir->get_value()) { 17047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 17057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 17067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir->get_value()->accept(this); 17087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 170984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 17107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l = ir_to_mesa_dst_reg_from_src(current_function->return_reg); 17117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(current_function->sig->return_type); i++) { 17137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 17147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 17157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 17167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op0(ir, OPCODE_RET); 172084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 172184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 172216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 172316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 172416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 17255e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt assert(ir->condition == NULL); /* FINISHME */ 172616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 1727021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV); 172816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 172984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 173084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 173184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 173284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1733854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL; 1734cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 1735cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 1736cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 1737c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1738c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 17390161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 1740c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1741854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if (ctx->Shader.EmitCondCodes) { 1742854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 1743cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 1744cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 1745cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 1746cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 1747cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 1748cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 1749cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type); 1750cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV, 1751cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_dst_reg_from_src(temp), 1752cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt result); 1753cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 1754854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 1755854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 1756021222c6a872ca2eef770ebadb8754f659775204Eric Anholt if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF); 1757854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst->dst_reg.cond_mask = COND_NE; 1758854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 1759854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, 1760854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt OPCODE_IF, ir_to_mesa_undef_dst, 1761854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt this->result); 1762854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 1763c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1764c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 1765c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1766c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 1767c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1768c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 1769021222c6a872ca2eef770ebadb8754f659775204Eric Anholt else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE); 17700a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 1771c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1772c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 17730161515c395c44233529c8d51f823b60050bc7baEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF, 17740161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 177584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 177684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1777ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 1778ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 17790161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 1780ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 17817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 1782d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler_map = NULL; 1783d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt sampler_map_size = 0; 17847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 1785ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 1786ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 178784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 178884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) 178984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 179084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 179184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 179284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 1793aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt assert(reg.index < (1 << INST_INDEX_BITS) - 1); 179484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 179534195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 1796f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 1797ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 1798285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 179984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 180084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 180184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 180284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1803c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 18047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 18057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 1806c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 1807c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 1808e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 180964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 181064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 181164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 1812c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1813c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 181464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 181564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 1816c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 181764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 181864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 181964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 182064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 182164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 182264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 182364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 182464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 182564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 182664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 182764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 1828c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1829c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 183064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack = (int *)calloc(if_count, sizeof(*if_stack)); 183164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack)); 1832c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1833c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 1834c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 1835c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 183664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 1837c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 1838c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 1839c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 184064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 184164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 1842c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 1843c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 184464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 1845c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 1846c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 184764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 184864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 184964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 185064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 185164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 185264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 185364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 185464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 185564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 185664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 185764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 185864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 185964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 186064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 186164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 186264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 186364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 186464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 186564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 186664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 186764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 18687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 18697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 18707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 18717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 18727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 18737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 18747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 18757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 18767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 18787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 1879c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 1880c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 1881c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1882c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1883c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1884c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt free(if_stack); 1885c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 1886c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1887c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 1888c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 1889c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 1890c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 1891c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 1892c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 1893c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 1894748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 1895c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1896c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 1897c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 1898c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 1899c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1900748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 1901748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 190264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 1903748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 1904748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 1905748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 1906748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 1907748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 1908748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 1909c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 1910c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 1911748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 1912748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 1913c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1914c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1915748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 1916748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 1917c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 1918c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 1919c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 1920ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void 19214d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_input(struct gl_program *prog, 19224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int index, 19234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt GLboolean reladdr) 19244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{ 19254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->InputsRead |= BITFIELD64_BIT(index); 19264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int i; 19274d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (reladdr) { 19294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) { 19304d5da50b94115d055ba8d0ff8717054582665384Eric Anholt for (i = 0; i < 8; i++) { 19314d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i); 19324d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19334d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 19344d5da50b94115d055ba8d0ff8717054582665384Eric Anholt assert(!"FINISHME: Mark InputsRead for varying arrays"); 19354d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19364d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19374d5da50b94115d055ba8d0ff8717054582665384Eric Anholt} 19384d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19394d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void 19404d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_output(struct gl_program *prog, 19414d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int index, 19424d5da50b94115d055ba8d0ff8717054582665384Eric Anholt GLboolean reladdr) 19434d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{ 19444d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->OutputsWritten |= BITFIELD64_BIT(index); 19454d5da50b94115d055ba8d0ff8717054582665384Eric Anholt int i; 19464d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19474d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (reladdr) { 19484d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) { 19494d5da50b94115d055ba8d0ff8717054582665384Eric Anholt for (i = 0; i < 8; i++) { 19504d5da50b94115d055ba8d0ff8717054582665384Eric Anholt prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i); 19514d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19524d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 19534d5da50b94115d055ba8d0ff8717054582665384Eric Anholt assert(!"FINISHME: Mark OutputsWritten for varying arrays"); 19544d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19554d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } 19564d5da50b94115d055ba8d0ff8717054582665384Eric Anholt} 19574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 19584d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void 1959ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog) 1960ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{ 1961d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt unsigned int i; 1962d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1963ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt prog->InputsRead = 0; 1964ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt prog->OutputsWritten = 0; 1965d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed = 0; 1966ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 1967ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (i = 0; i < prog->NumInstructions; i++) { 1968ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt struct prog_instruction *inst = &prog->Instructions[i]; 1969ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt unsigned int reg; 1970ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 1971ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt switch (inst->DstReg.File) { 1972ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_OUTPUT: 19734d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr); 1974ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 1975ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_INPUT: 19764d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr); 1977ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 1978ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt default: 1979ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 1980ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 1981ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 1982ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) { 1983ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt switch (inst->SrcReg[reg].File) { 1984ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_OUTPUT: 19854d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_output(prog, inst->SrcReg[reg].Index, 19864d5da50b94115d055ba8d0ff8717054582665384Eric Anholt inst->SrcReg[reg].RelAddr); 1987ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 1988ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt case PROGRAM_INPUT: 19894d5da50b94115d055ba8d0ff8717054582665384Eric Anholt mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr); 1990ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 1991ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt default: 1992ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt break; 1993ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 1994ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 1995d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1996d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Instead of just using the uniform's value to map to a 1997d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * sampler, Mesa first allocates a separate number for the 1998d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * sampler (_mesa_add_sampler), then we reindex it down to a 1999d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * small integer (sampler_map[], SamplersUsed), then that gets 2000d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * mapped to the uniform's value, and we get an actual sampler. 2001d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 2002d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (_mesa_is_tex_instruction(inst->Opcode)) { 2003d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplerTargets[inst->TexSrcUnit] = 2004d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt (gl_texture_index)inst->TexSrcTarget; 2005d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed |= 1 << inst->TexSrcUnit; 2006d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (inst->TexShadow) { 2007d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->ShadowSamplers |= 1 << inst->TexSrcUnit; 2008d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2009d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2010ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2011d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2012d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt _mesa_update_shader_textures_used(prog); 2013ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt} 2014ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 201585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt/* Each stage has some uniforms in its Parameters list. The Uniforms 201685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * list for the linked shader program has a pointer to these uniforms 201785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * in each of the stage's Parameters list, so that their values can be 201885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * updated when a uniform is set. 201985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 202085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void 202185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtlink_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms, 202285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt struct gl_program *prog) 202385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 202485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt unsigned int i; 202585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 202685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt for (i = 0; i < prog->Parameters->NumParameters; i++) { 202785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt const struct gl_program_parameter *p = prog->Parameters->Parameters + i; 202885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 202985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) { 203085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt struct gl_uniform *uniform = 203185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt _mesa_append_uniform(uniforms, p->Name, prog->Target, i); 203285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt if (uniform) 203385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt uniform->Initialized = p->Initialized; 203485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 203585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 203685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 203785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2038364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program * 203995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, 204095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 204184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 204295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt void *mem_ctx = shader_program; 204384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 204484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2045c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 2046c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2047364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 2048364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 2049c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 20507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt GLboolean progress; 2051364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2052364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 2053c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 2054c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 2055c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 2056c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2057c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 2058c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 2059c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 2060c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2061c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 2062c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 2063c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2064364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 206584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 20661124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 20671124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 2068364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, 1); 2069364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 2070364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 2071364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 2072364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2073364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Attributes = _mesa_new_parameter_list(); 2074364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 2075364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 2076364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2077364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.mem_ctx = talloc_new(NULL); 20787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 208016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 2081021222c6a872ca2eef770ebadb8754f659775204Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_END); 208284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 20837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Now emit bodies for any functions that were used. */ 20847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt do { 20857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_FALSE; 20867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v.function_signatures) { 20887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 20897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (!entry->bgn_inst) { 20917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt v.current_function = entry; 20927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB); 20947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst->function = entry; 20957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt visit_exec_list(&entry->sig->body, &v); 20977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_RET); 20997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB); 21007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_TRUE; 21017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } while (progress); 21047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2105364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 2106364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 210784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 210884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 210984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 211084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 211184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 211284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 211384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 211484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 2115364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *, 2116364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 211784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 211884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 2119c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 212084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 212184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 2122b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 212384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 2124854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 212584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.File = inst->dst_reg.file; 212684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.Index = inst->dst_reg.index; 2127854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask; 212812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; 2129f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL; 213084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); 213184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); 213284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); 2133d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 2134d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 2135b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 2136c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 2137aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 213895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { 213995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->InfoLog = 214095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt talloc_asprintf_append(shader_program->InfoLog, 214195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt "Couldn't flatten if statement\n"); 214295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->LinkStatus = false; 214395c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt } 214495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt 21457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (mesa_inst->Opcode == OPCODE_BGNSUB) 21467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function->inst = i; 21477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt else if (mesa_inst->Opcode == OPCODE_CAL) 21487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ 2149d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt else if (mesa_inst->Opcode == OPCODE_ARL) 2150d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 21517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 215284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 2153c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 215484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 2155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 21567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 2157c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2158c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt printf("Mesa %s program:\n", target_string); 2159364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 2160364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 2161364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2162364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2163364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 2164364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 2165364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 216616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 2167364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 216828faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 216928faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 217028faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 217128faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 2172364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 2173364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2174364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 217516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 217616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 217716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 217816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) 2179364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 21802462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 21812462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 21825e18b051c039564d1998818d08caf1bff3983630Ian Romanick 2183153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 218406143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick state->error = preprocess(state, &source, &state->info_log, 218506143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick &ctx->Extensions); 2186153eca98064252be4daad9cc27746f37c245b627Ian Romanick 2187153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 2188153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 2189153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 2190153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 2191153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 2192364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 219316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 2194364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 219516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 2196364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 219716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 2198ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2199ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 22004802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt /* Lowering */ 22014802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_mat_op_to_vec(shader->ir); 22024802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_mod_to_fract(shader->ir); 22034802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt do_div_to_mul_rcp(shader->ir); 22044802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt 22054802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt /* Optimization passes */ 2206364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt bool progress; 2207364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt do { 2208364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt progress = false; 2209364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 221016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_function_inlining(shader->ir) || progress; 221116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_if_simplification(shader->ir) || progress; 221216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_copy_propagation(shader->ir) || progress; 221316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_dead_code_local(shader->ir) || progress; 221416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_dead_code_unlinked(state, shader->ir) || progress; 221516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_constant_variable_unlinked(shader->ir) || progress; 221616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_constant_folding(shader->ir) || progress; 2217d674ebcee0d2731e50d6530502cefcebc39dcdb6Eric Anholt progress = do_if_return(shader->ir) || progress; 221895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt if (ctx->Shader.EmitNoIfs) 221995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt progress = do_if_to_cond_assign(shader->ir) || progress; 2220a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 222116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_vec_index_to_swizzle(shader->ir) || progress; 2222a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt /* Do this one after the previous to let the easier pass handle 2223a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt * constant vector indexing. 2224a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt */ 2225a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt progress = do_vec_index_to_cond_assign(shader->ir) || progress; 2226a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt 222716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt progress = do_swizzle_swizzle(shader->ir) || progress; 2228364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } while (progress); 2229ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 2230ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2231364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2232364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2233364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 2234364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2235364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 2236364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 223725f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 2238d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 2239d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 2240d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 2241c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2242116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 224360e2d06d1ccc66ad00cd7ab81c418853f21be291Ian Romanick reparent_ir(shader->ir, shader); 2244116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 2245364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt talloc_free(state); 2246364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2247364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2248364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 2249364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog) 2250364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 2251364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 2252849e18153cd91d812f694b806a84008498860bc3Eric Anholt 2253364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 2254364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2255849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 2256364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2257364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 2258849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 2259849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->InfoLog = 2260849e18153cd91d812f694b806a84008498860bc3Eric Anholt talloc_asprintf_append(prog->InfoLog, 2261364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt "linking with uncompiled shader"); 2262849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 2263364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2264364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2265364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2266364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2267364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); 2268364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); 2269364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2270849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 2271849e18153cd91d812f694b806a84008498860bc3Eric Anholt link_shaders(prog); 2272849e18153cd91d812f694b806a84008498860bc3Eric Anholt 2273849e18153cd91d812f694b806a84008498860bc3Eric Anholt /* We don't use the linker's uniforms list, and cook up our own at 2274849e18153cd91d812f694b806a84008498860bc3Eric Anholt * generate time. 2275849e18153cd91d812f694b806a84008498860bc3Eric Anholt */ 2276849e18153cd91d812f694b806a84008498860bc3Eric Anholt free(prog->Uniforms); 2277849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->Uniforms = _mesa_new_uniform_list(); 2278849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 2279364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2280364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 22813fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick for (i = 0; i < prog->_NumLinkedShaders; i++) { 2282364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *linked_prog; 2283364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2284849e18153cd91d812f694b806a84008498860bc3Eric Anholt linked_prog = get_mesa_program(ctx, prog, 22853fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick prog->_LinkedShaders[i]); 2286ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt count_resources(linked_prog); 2287364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 228885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog); 228985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 22903fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick switch (prog->_LinkedShaders[i]->Type) { 2291364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt case GL_VERTEX_SHADER: 2292364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, 2293364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt (struct gl_vertex_program *)linked_prog); 22947dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 22957dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt linked_prog); 2296364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt break; 2297364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt case GL_FRAGMENT_SHADER: 2298364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, 2299364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt (struct gl_fragment_program *)linked_prog); 23007dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 23017dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt linked_prog); 2302364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt break; 2303364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2304364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2305364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2306364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2307364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2308364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 2309