ir_to_mesa.cpp revision 0a46497a4ee3325fab47929cb17cfe2525e1fc33
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>
34261bbc011d11ab9e390cd5fe9f5151821eefaffaIan Romanick#include "main/compiler.h"
3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h"
3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h"
3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h"
3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h"
3984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h"
40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h"
41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h"
42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h"
43364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h"
4484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
45aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" {
460a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h"
47658e25987fbec3b826f500baa6d4d936b9552b13Eric Anholt#include "main/shaderapi.h"
48afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h"
49afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/uniforms.h"
50fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h"
51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h"
52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h"
53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h"
54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h"
55afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h"
56afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h"
57aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt}
5884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
599c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtstatic int swizzle_for_size(int size);
609c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt
61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/**
62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with
63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields.
64554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */
65554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg {
669c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg(int file, int index, const glsl_type *type)
679c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   {
689c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->file = file;
699c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->index = index;
709c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      if (type && (type->is_scalar() || type->is_vector() || type->is_matrix()))
719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt	 this->swizzle = swizzle_for_size(type->vector_elements);
729c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      else
739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt	 this->swizzle = SWIZZLE_XYZW;
749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->negate = 0;
759c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->reladdr = NULL;
769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   }
779c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt
789c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg()
799c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   {
809c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->file = PROGRAM_UNDEFINED;
8148c289fb552a3d363b505514b6ea22467f00e318Vinson Lee      this->index = 0;
8248c289fb552a3d363b505514b6ea22467f00e318Vinson Lee      this->swizzle = 0;
8348c289fb552a3d363b505514b6ea22467f00e318Vinson Lee      this->negate = 0;
8448c289fb552a3d363b505514b6ea22467f00e318Vinson Lee      this->reladdr = NULL;
859c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   }
869c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt
87554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
88554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
89582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
90554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int negate; /**< NEGATE_XYZW mask from mesa */
91f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
92f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
93554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg;
94554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
95554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg {
96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
99854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLuint cond_mask:4;
100f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
101f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg;
103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef;
105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node {
107554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
108554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   enum prog_opcode op;
109554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_dst_reg dst_reg;
110554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_src_reg src_reg[3];
111554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** Pointer to the ir source this tree came from for debugging */
112554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_instruction *ir;
113854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLboolean cond_update;
114d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler; /**< sampler index */
115d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int tex_target; /**< One of TEXTURE_*_INDEX */
116b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   GLboolean tex_shadow;
1177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
119554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
120554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
121b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node {
122554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
123b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage(ir_variable *var, int file, int index)
124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      : file(file), index(index), var(var)
125554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   {
126554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      /* empty */
127554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   }
128554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
129554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file;
130554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index;
131554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_variable *var; /* variable that maps to this, if any */
132554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
133554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node {
1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic:
1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig;
1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * identifier of this function signature used by the program.
1407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * At the point that Mesa instructions for function calls are
1427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * generated, we don't know the address of the first instruction of
1437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * the function body.  So we make the BranchTarget that is called a
1447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * small integer and rewrite them during set_branchtargets().
1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int sig_id;
1477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Pointer to first instruction of the function body.
1507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set during function body emits after main() is processed.
1527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *bgn_inst;
1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Index of the first instruction of the function body in actual
1577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Mesa IR.
1587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set after convertion from ir_to_mesa_instruction to prog_instruction.
1607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int inst;
1627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** Storage for the return value. */
1647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_src_reg return_reg;
1657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt};
1667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor {
168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_visitor();
170fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   ~ir_to_mesa_visitor();
171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *current_function;
1737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
174364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLcontext *ctx;
175364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
176aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   struct gl_shader_program *shader_program;
177364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int next_temp;
179a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
180b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *find_variable_storage(ir_variable *var);
181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *get_function_signature(ir_function_signature *sig);
1837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   ir_to_mesa_src_reg get_temp(const glsl_type *type);
185f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   void reladdr_to_temp(ir_instruction *ir,
186f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			ir_to_mesa_src_reg *reg, int *num_reladdr);
187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg src_reg_for_float(float val);
189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
190554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /**
191554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * \name Visit methods
192554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    *
193554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * As typical for the visitor pattern, there must be one \c visit method for
194554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * each concrete subclass of \c ir_instruction.  Virtual base classes within
195554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * the hierarchy should not have \c visit methods.
196554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    */
197554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@{*/
198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_variable *);
199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop *);
200554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop_jump *);
201554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function_signature *);
202554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function *);
203554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_expression *);
204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_swizzle *);
205554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_variable  *);
206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_array *);
207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_record *);
208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_assignment *);
209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_constant *);
210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_call *);
211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_return *);
21216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke   virtual void visit(ir_discard *);
213554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_texture *);
214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_if *);
215554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@}*/
216554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
217554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg result;
218554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
219b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   /** List of variable_storage */
220b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   exec_list variables;
221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
2227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** List of function_entry */
2237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list function_signatures;
2247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int next_signature_id;
2257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
226554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of ir_to_mesa_instruction */
227554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list instructions;
228554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
229021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
230021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					       enum prog_opcode op);
231021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
232554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
233554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
234554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
235554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0);
236554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
237554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
238554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
239554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
240554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
241554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1);
242554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
244554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
245554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
246554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
247554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1,
248554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src2);
249554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
250554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
251554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   enum prog_opcode op,
252554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_dst_reg dst,
253554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_src_reg src0);
2540ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt
255904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
256904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   enum prog_opcode op,
257904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_dst_reg dst,
258904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src0,
259904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src1);
260904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
2613f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   GLboolean try_emit_mad(ir_expression *ir,
2623f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt			  int mul_operand);
2633f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
264aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   int get_sampler_uniform_value(ir_dereference *deref);
265d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
266364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   void *mem_ctx;
267554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
268554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
2699c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL);
27084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
271c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
272f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
273c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt};
274c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2750161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = {
276f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
2770161515c395c44233529c8d51f823b60050bc7baEric Anholt};
2780161515c395c44233529c8d51f823b60050bc7baEric Anholt
2790161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size)
2800161515c395c44233529c8d51f823b60050bc7baEric Anholt{
2810161515c395c44233529c8d51f823b60050bc7baEric Anholt   int size_swizzles[4] = {
2820161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
2830161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
2840161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
2850161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
2860161515c395c44233529c8d51f823b60050bc7baEric Anholt   };
2870161515c395c44233529c8d51f823b60050bc7baEric Anholt
2880161515c395c44233529c8d51f823b60050bc7baEric Anholt   return size_swizzles[size - 1];
2890161515c395c44233529c8d51f823b60050bc7baEric Anholt}
2900161515c395c44233529c8d51f823b60050bc7baEric Anholt
29184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2920161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
2930161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2940161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2950161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
2960161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1,
2970161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src2)
29884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
299364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
300f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   int num_reladdr = 0;
301f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
302f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /* If we have to do relative addressing, we want to load the ARL
303f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * reg directly for one of the regs, and preload the other reladdr
304f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * sources into temps.
305f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    */
306f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += dst.reladdr != NULL;
307f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src0.reladdr != NULL;
308f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src1.reladdr != NULL;
309f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src2.reladdr != NULL;
310f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
311f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src2, &num_reladdr);
312f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src1, &num_reladdr);
313f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src0, &num_reladdr);
314f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
315f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (dst.reladdr) {
316f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
317f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt                          *dst.reladdr);
318f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
319f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      num_reladdr--;
320f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
321f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   assert(num_reladdr == 0);
32284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
32384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->op = op;
32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->dst_reg = dst;
32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[0] = src0;
32684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[1] = src1;
32784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[2] = src2;
328c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   inst->ir = ir;
32984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   inst->function = NULL;
3317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
3320161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->instructions.push_tail(inst);
33384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
33484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return inst;
33584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
33684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
33784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
33884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3390161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
3400161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3410161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3420161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
3430161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1)
34484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3450161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
34684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
34784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
34884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3490161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
3500161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3510161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3520161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0)
353bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
3545a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   assert(dst.writemask != 0);
3550161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst,
3560161515c395c44233529c8d51f823b60050bc7baEric Anholt			      src0, ir_to_mesa_undef, ir_to_mesa_undef);
357bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
358bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
359021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction *
360021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
361021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					enum prog_opcode op)
362021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{
363021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
364021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
365021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
366021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef);
367021222c6a872ca2eef770ebadb8754f659775204Eric Anholt}
368021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
3690161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg
3700161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
37184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3720161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_dst_reg dst_reg;
37384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3740161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.file = reg.file;
3750161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.index = reg.index;
3760161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.writemask = WRITEMASK_XYZW;
377854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   dst_reg.cond_mask = COND_TR;
378f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   dst_reg.reladdr = reg.reladdr;
3790161515c395c44233529c8d51f823b60050bc7baEric Anholt
3800161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
381bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
382bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
3832d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg
3842d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
3852d1789e667c4180777829f96856daf91326721b9Eric Anholt{
3869c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   return ir_to_mesa_src_reg(reg.file, reg.index, NULL);
3872d1789e667c4180777829f96856daf91326721b9Eric Anholt}
3882d1789e667c4180777829f96856daf91326721b9Eric Anholt
38912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/**
39012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels.
39112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt *
39212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
39312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels.  So to do a vec4
39412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used
39512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels.
39612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */
39712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid
398904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
3990161515c395c44233529c8d51f823b60050bc7baEric Anholt					       enum prog_opcode op,
4000161515c395c44233529c8d51f823b60050bc7baEric Anholt					       ir_to_mesa_dst_reg dst,
401904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src0,
402904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src1)
40312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{
40412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   int i, j;
405315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int done_mask = ~dst.writemask;
40612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
40712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   /* Mesa RCP is a scalar operation splatting results to all channels,
40812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
40912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * dst channels.
41012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    */
41112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   for (i = 0; i < 4; i++) {
412582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt      GLuint this_mask = (1 << i);
41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_instruction *inst;
414904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src0 = orig_src0;
415904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src1 = orig_src1;
41612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
41712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      if (done_mask & this_mask)
41812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 continue;
41912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
420904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
421904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
42212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      for (j = i + 1; j < 4; j++) {
423904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	 if (!(done_mask & (1 << j)) &&
424904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src0.swizzle, j) == src0_swiz &&
425904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src1.swizzle, j) == src1_swiz) {
42612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	    this_mask |= (1 << j);
42712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 }
42812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      }
429904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
430904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   src0_swiz, src0_swiz);
431904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
432904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				  src1_swiz, src1_swiz);
43312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
434904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      inst = ir_to_mesa_emit_op2(ir, op,
4350161515c395c44233529c8d51f823b60050bc7baEric Anholt				 dst,
436904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src0,
437904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src1);
43812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      inst->dst_reg.writemask = this_mask;
43912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      done_mask |= this_mask;
44012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   }
44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt}
44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
443904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid
444904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
445904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       enum prog_opcode op,
446904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_dst_reg dst,
447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg src0)
448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{
44959a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt   ir_to_mesa_src_reg undef = ir_to_mesa_undef;
450904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
451904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   undef.swizzle = SWIZZLE_XXXX;
452904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
453904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt}
455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
4560161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg
4570161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val)
458b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
4599c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL);
4601d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
461582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
462582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt					      &val, 1, &src_reg.swizzle);
4631d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4640161515c395c44233529c8d51f823b60050bc7baEric Anholt   return src_reg;
4651d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt}
4661d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int
4682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type)
4692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
4702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
4712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int size;
4722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
4732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   switch (type->base_type) {
4742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_UINT:
4752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_INT:
4762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_FLOAT:
4772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_BOOL:
478a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      if (type->is_matrix()) {
4799968f1b23c475c99139f0209c7a049ed00df01afEric Anholt	 return type->matrix_columns;
480a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      } else {
481a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 /* Regardless of size of vector, it gets a vec4. This is bad
482a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * packing for things like floats, but otherwise arrays become a
483a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * mess.  Hopefully a later pass over the code can pack scalars
484a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * down if appropriate.
485a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  */
486a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 1;
487a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      }
4882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_ARRAY:
4892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return type_size(type->fields.array) * type->length;
4902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_STRUCT:
4912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      size = 0;
4922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      for (i = 0; i < type->length; i++) {
4932c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 size += type_size(type->fields.structure[i].type);
4942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      }
4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return size;
4968d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt   case GLSL_TYPE_SAMPLER:
4970924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      /* Samplers take up one slot in UNIFORMS[], but they're baked in
4980924ba0c3496160a134d37cec800f902ae805b9cEric Anholt       * at link time.
4998d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt       */
5000924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      return 1;
5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   default:
5022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(0);
50319acfa42ed47edb63f5ec3de8051a3102e62e96bJosé Fonseca      return 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   src_reg.file = PROGRAM_TEMPORARY;
521d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.index = next_temp;
522f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
523d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   next_temp += type_size(type);
524d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
52520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   if (type->is_array() || type->is_record()) {
52620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
52720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   } else {
52820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      for (i = 0; i < type->vector_elements; i++)
52920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 swizzle[i] = i;
53020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      for (; i < 4; i++)
53120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 swizzle[i] = type->vector_elements - 1;
53220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
53320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt				      swizzle[2], swizzle[3]);
53420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   }
535ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   src_reg.negate = 0;
536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   return src_reg;
538d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt}
539d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
540b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage *
541a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var)
54284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
543a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
544b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
54584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
546b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   foreach_iter(exec_list_iterator, iter, this->variables) {
547b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      entry = (variable_storage *)iter.get();
54884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
5490161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (entry->var == var)
550a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return entry;
55184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
55284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
553a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   return NULL;
554a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt}
55584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
55784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir)
55884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
5594a962170d7cf4243d6ae156fca20a6167388925dEric Anholt   if (strcmp(ir->name, "gl_FragCoord") == 0) {
5604a962170d7cf4243d6ae156fca20a6167388925dEric Anholt      struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
5614a962170d7cf4243d6ae156fca20a6167388925dEric Anholt
5624a962170d7cf4243d6ae156fca20a6167388925dEric Anholt      fp->OriginUpperLeft = ir->origin_upper_left;
5634a962170d7cf4243d6ae156fca20a6167388925dEric Anholt      fp->PixelCenterInteger = ir->pixel_center_integer;
5644a962170d7cf4243d6ae156fca20a6167388925dEric Anholt   }
56584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
56684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
56784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
56884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir)
56984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
57064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->from);
57164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->to);
57264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->increment);
57364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->counter);
57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
575021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
57664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   visit_exec_list(&ir->body_instructions, this);
577021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
57884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
57984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
58084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
58184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir)
58284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
58364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   switch (ir->mode) {
58464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_break:
585021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
58664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
58764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_continue:
588021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
58964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
59064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   }
59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir)
59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
60284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir)
60384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
60484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
60684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
60784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strcmp(ir->name, "main") == 0) {
60884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      const ir_function_signature *sig;
60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exec_list empty;
61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      sig = ir->matching_signature(&empty);
61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      assert(sig);
61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      foreach_iter(exec_list_iterator, iter, sig->body) {
61684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
61784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->accept(this);
61984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
62084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
62184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
62284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6233f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean
6243f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
6253f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{
6263f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   int nonmul_operand = 1 - mul_operand;
6273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_src_reg a, b, c;
6283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_expression *expr = ir->operands[mul_operand]->as_expression();
6303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (!expr || expr->operation != ir_binop_mul)
6313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      return false;
6323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[0]->accept(this);
6343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   a = this->result;
6353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[1]->accept(this);
6363f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   b = this->result;
6373f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir->operands[nonmul_operand]->accept(this);
6383f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   c = this->result;
6393f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6403f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   this->result = get_temp(ir->type);
6413f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_emit_op3(ir, OPCODE_MAD,
6423f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt		       ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
6433f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6443f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   return true;
6453f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt}
6463f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
64784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
648f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
649f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt				    ir_to_mesa_src_reg *reg, int *num_reladdr)
650f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{
651f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (!reg->reladdr)
652f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      return;
653f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
654f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
655f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
656f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (*num_reladdr != 1) {
657f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
658f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
659f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV,
660f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			  ir_to_mesa_dst_reg_from_src(temp), *reg);
661f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      *reg = temp;
662f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
663f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
664f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   (*num_reladdr)--;
665f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt}
666f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
667f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid
66884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir)
66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   unsigned int operand;
671f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt   struct ir_to_mesa_src_reg op[2];
6720161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg result_src;
6730161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg result_dst;
67484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
67584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
67684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
67784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6783f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
6793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt    */
6803f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (ir->operation == ir_binop_add) {
6813f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 1))
6823f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
6833f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 0))
6843f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
6853f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   }
6863f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
6880161515c395c44233529c8d51f823b60050bc7baEric Anholt      this->result.file = PROGRAM_UNDEFINED;
68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->operands[operand]->accept(this);
6900161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (this->result.file == PROGRAM_UNDEFINED) {
69184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_print_visitor v;
69284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("Failed to get tree for expression operand:\n");
69384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->operands[operand]->accept(&v);
69484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
69584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
69684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      op[operand] = this->result;
6978364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
6984ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      /* Matrix expression operands should have been broken down to vector
6994ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       * operations already.
7004ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       */
7014ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      assert(!ir->operands[operand]->type->is_matrix());
70284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
70384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7040161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.file = PROGRAM_UNDEFINED;
7050161515c395c44233529c8d51f823b60050bc7baEric Anholt
7060161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
7070161515c395c44233529c8d51f823b60050bc7baEric Anholt    * the actual storage for the result here, instead.
7080161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
7098364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   result_src = get_temp(ir->type);
7100161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* convenience for the emit functions below. */
7110161515c395c44233529c8d51f823b60050bc7baEric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
7129cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   /* Limit writes to the channels that will be used by result_src later.
7139cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * This does limit this temp's use as a temporary for multi-instruction
7149cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * sequences.
7159cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    */
7169cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
71784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
71884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   switch (ir->operation) {
7191d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_logic_not:
720f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
721f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt			  op[0], src_reg_for_float(0.0));
7221d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
723c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   case ir_unop_neg:
7240161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
7250161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
726c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      break;
727524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt   case ir_unop_abs:
728524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
729524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      break;
7303acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt   case ir_unop_sign:
7313acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
7323acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      break;
7338761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt   case ir_unop_rcp:
7348761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
7358761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      break;
736524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt
7378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp2:
7380161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
7398c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
740bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt   case ir_unop_exp:
7418c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log:
742bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt      assert(!"not reached: should be handled by ir_explog_to_explog2");
7438c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7448c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log2:
7450161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
7468c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7473c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_sin:
7480161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
7493c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
7503c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_cos:
7510161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
7523c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
753ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
754ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdx:
755ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
756ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
757ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdy:
758ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
759ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
760ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
76184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_add:
7627b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
76384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
76484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_sub:
7657b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
76684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
7679b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt
76884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_mul:
7694ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
77084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
77184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_div:
7729a0e421983edc31371440c08687fa2bb2207924dEric Anholt      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
773411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_binop_mod:
774411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
775411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      break;
77638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
77738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_less:
778f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
77938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_greater:
781f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
78238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_lequal:
784f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
78538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_gequal:
787f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
78838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_equal:
7906992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      /* "==" operator producing a scalar boolean. */
7916992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      if (ir->operands[0]->type->is_vector() ||
7926992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	  ir->operands[1]->type->is_vector()) {
7936992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
7946992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
7956992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt			     ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
7966992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
7976992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_SEQ,
7986992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt			     result_dst, result_src, src_reg_for_float(0.0));
7996992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      } else {
8006992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
8016992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      }
80238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
80338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_nequal:
8046992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      /* "!=" operator producing a scalar boolean. */
8056992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      if (ir->operands[0]->type->is_vector() ||
8066992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	  ir->operands[1]->type->is_vector()) {
8076992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
8086992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
8096992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt			     ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
8106992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
8116992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_SNE,
8126992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt			     result_dst, result_src, src_reg_for_float(0.0));
8136992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      } else {
8146992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
8156992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      }
8166992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt      break;
8175e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt
8185e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt   case ir_unop_any:
8195e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      switch (ir->operands[0]->type->vector_elements) {
8205e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      case 4:
8215e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, op[0], op[0]);
8225e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 break;
8235e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      case 3:
8245e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, op[0], op[0]);
8255e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 break;
8265e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      case 2:
8275e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, op[0], op[0]);
8285e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 break;
8295e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      default:
8305e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 assert(!"unreached: ir_unop_any of non-bvec");
8315e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt	 break;
8325e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      }
8335e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
8345e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt			  result_dst, result_src, src_reg_for_float(0.0));
8355e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      break;
8365e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt
8376992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt   case ir_binop_logic_xor:
838f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
83938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
84038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
8414380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_or:
8420161515c395c44233529c8d51f823b60050bc7baEric Anholt      /* This could be a saturated add and skip the SNE. */
8430161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
8440161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8450161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
8460161515c395c44233529c8d51f823b60050bc7baEric Anholt
8470161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
8480161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8490161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
8504380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8514380099c98119611ceee684669d00be26195c7d7Eric Anholt
8524380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_and:
8534380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
8540161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
8550161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8560161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
8574380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8584380099c98119611ceee684669d00be26195c7d7Eric Anholt
85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_dot:
86084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (ir->operands[0]->type == vec4_type) {
86184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec4_type);
8620161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
8630161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8640161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec3_type) {
86684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec3_type);
8670161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
8680161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8690161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
87084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec2_type) {
87184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec2_type);
8720161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
8730161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8740161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
87584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
87684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
8779be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
8789be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt   case ir_binop_cross:
8799be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
8809be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      break;
8819be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
88284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_unop_sqrt:
8830161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
8848f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
8858f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      /* For incoming channels < 0, set the result to 0. */
8868f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
8878f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt			  op[0], src_reg_for_float(0.0), result_src);
88884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
889878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt   case ir_unop_rsq:
8900161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
891878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      break;
89250ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   case ir_unop_i2f:
893d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2f:
894d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2i:
895423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      /* Mesa IR lacks types, ints are stored as truncated floats. */
8960161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
89750ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      break;
898423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt   case ir_unop_f2i:
8990161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
900423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      break;
9011d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_f2b:
902411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_unop_i2b:
9030161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
90466afcb560771b6ba6ad668156e9f442e86b9a7a2Eric Anholt			  op[0], src_reg_for_float(0.0));
9051d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
906c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_trunc:
9070161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
908c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
909c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_ceil:
9100161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
9110161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
9120161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src.negate = ~result_src.negate;
913c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
914c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_floor:
9150161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
916c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
917d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt   case ir_unop_fract:
918d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
919d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      break;
920d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt
921c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_min:
9220161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
923c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
924c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_max:
9250161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
926c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
927904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   case ir_binop_pow:
928904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
929904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      break;
930e64a4aaacbc682f24180dff3627b84861844476dEric Anholt
931e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_bit_not:
932e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_u2f:
933e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_lshift:
934e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_rshift:
935e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_and:
936e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_xor:
937e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_or:
938e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      assert(!"GLSL 1.30 features unsupported");
939e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      break;
94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
941b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt
9420161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = result_src;
94384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
94684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
94784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir)
94884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
9490161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
95084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
95184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int swizzle[4];
95284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
953b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   /* Note that this is only swizzles in expressions, not those on the left
954b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * hand side of an assignment, which do write masking.  See ir_assignment
955b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * for that.
956b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    */
95784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
95884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->val->accept(this);
9594006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   src_reg = this->result;
9604006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   assert(src_reg.file != PROGRAM_UNDEFINED);
96184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
96284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; i < 4; i++) {
96384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (i < ir->type->vector_elements) {
96484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 switch (i) {
96584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 0:
966698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
96784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
96884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 1:
969698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
97084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
97184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 2:
972698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
97384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
97484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 3:
975698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
97684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
97784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 }
97884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
97984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 /* If the type is smaller than a vec4, replicate the last
98084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  * channel out.
98184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  */
982698b84444343189357ad252856d3c5493e47e4faEric Anholt	 swizzle[i] = swizzle[ir->type->vector_elements - 1];
98384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
98484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
98584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9860161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
9870161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[1],
9880161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[2],
9890161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[3]);
99084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9910161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
99284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
99384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
994dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic const struct {
995dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   const char *name;
996dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   const char *field;
997dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   int tokens[STATE_LENGTH];
998dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   int swizzle;
999dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   bool array_indexed;
1000dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt} statevars[] = {
1001dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_DepthRange", "near",
1002325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX, false},
1003dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_DepthRange", "far",
1004325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY, false},
1005dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_DepthRange", "diff",
1006325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ, false},
1007dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1008dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ClipPlane", NULL,
1009dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW, true}
1010dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt,
1011dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "size",
1012325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_POINT_SIZE}, SWIZZLE_XXXX, false},
1013dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "sizeMin",
1014325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_POINT_SIZE}, SWIZZLE_YYYY, false},
1015dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "sizeMax",
1016325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_POINT_SIZE}, SWIZZLE_ZZZZ, false},
1017dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "fadeThresholdSize",
1018325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_POINT_SIZE}, SWIZZLE_WWWW, false},
1019dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "distanceConstantAttenuation",
1020325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX, false},
1021dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "distanceLinearAttenuation",
1022325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY, false},
1023dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "distanceQuadraticAttenuation",
1024325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ, false},
1025dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1026dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "emission",
1027325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW, false},
1028dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "ambient",
1029325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW, false},
1030dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "diffuse",
1031325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, false},
1032dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "specular",
1033325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW, false},
1034dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "shininess",
1035325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX, false},
1036dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1037dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "emission",
1038325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW, false},
1039dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "ambient",
1040325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW, false},
1041dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "diffuse",
1042325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, false},
1043dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "specular",
1044325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW, false},
1045dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "shininess",
1046325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX, false},
1047dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1048dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "ambient",
1049dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1050dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "diffuse",
1051dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1052dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "specular",
1053dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1054dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "position",
1055dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW, true},
1056dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "halfVector",
1057dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW, true},
1058dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotDirection",
1059dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW, true},
1060dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotCosCutoff",
1061dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW, true},
1062dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotCutoff",
1063dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX, true},
1064dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotExponent",
1065dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW, true},
1066dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "constantAttenuation",
1067dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX, true},
1068dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "linearAttenuation",
1069dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY, true},
1070dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "quadraticAttenuation",
1071dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ, true},
1072dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1073c3e3793c325e36366165a5d1403a8c406ff200dbLuca Barbieri   {"gl_LightModel", "ambient",
1074325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW, false},
1075dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1076c108a7927d1dad9e0f641a0ec5a7387fb2626156Luca Barbieri   {"gl_FrontLightModelProduct", "sceneColor",
1077325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW, false},
1078c108a7927d1dad9e0f641a0ec5a7387fb2626156Luca Barbieri   {"gl_BackLightModelProduct", "sceneColor",
1079325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW, false},
1080dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1081dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontLightProduct", "ambient",
1082dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1083dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontLightProduct", "diffuse",
1084dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1085dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontLightProduct", "specular",
1086dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1087dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1088dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackLightProduct", "ambient",
1089dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1090dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackLightProduct", "diffuse",
1091dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1092dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackLightProduct", "specular",
1093dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1094dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1095d6cc7191daa249463b20e2965dc1006288539b1eKenneth Graunke   {"gl_TextureEnvColor", NULL,
1096dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW, true},
1097dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1098dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneS", NULL,
1099dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW, true},
1100dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneT", NULL,
1101dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW, true},
1102dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneR", NULL,
1103dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW, true},
1104dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneQ", NULL,
1105dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW, true},
1106dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1107dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneS", NULL,
1108dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW, true},
1109dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneT", NULL,
1110dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW, true},
1111dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneR", NULL,
1112dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW, true},
1113dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneQ", NULL,
1114dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW, true},
1115dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1116dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "color",
1117325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_FOG_COLOR}, SWIZZLE_XYZW, false},
1118dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "density",
1119325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_FOG_PARAMS}, SWIZZLE_XXXX, false},
1120dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "start",
1121325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_FOG_PARAMS}, SWIZZLE_YYYY, false},
1122dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "end",
1123325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ, false},
1124dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "scale",
1125325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca    {STATE_FOG_PARAMS}, SWIZZLE_WWWW, false},
1126dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt};
1127dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1128dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic ir_to_mesa_src_reg
1129dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtget_builtin_uniform_reg(struct gl_program *prog,
1130dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt			const char *name, int array_index, const char *field)
1131dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt{
1132dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   unsigned int i;
1133dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   ir_to_mesa_src_reg src_reg;
1134dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   int tokens[STATE_LENGTH];
1135dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1136dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   for (i = 0; i < Elements(statevars); i++) {
1137dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      if (strcmp(statevars[i].name, name) != 0)
1138dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 continue;
1139dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      if (!field && statevars[i].field) {
1140dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 assert(!"FINISHME: whole-structure state var dereference");
1141dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      }
1142fc76d7276393a4617f9898214bc397bb65634b02Luca Barbieri      if (field && (!statevars[i].field || strcmp(statevars[i].field, field) != 0))
1143dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 continue;
1144dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      break;
1145dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
1146dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1147dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   if (i ==  Elements(statevars)) {
1148dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      printf("builtin uniform %s%s%s not found\n",
1149dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	     name,
1150dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	     field ? "." : "",
1151dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	     field ? field : "");
1152dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      abort();
1153dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
1154dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1155dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   memcpy(&tokens, statevars[i].tokens, sizeof(tokens));
1156dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   if (statevars[i].array_indexed)
1157dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      tokens[1] = array_index;
1158dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1159dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.file = PROGRAM_STATE_VAR;
1160dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.index = _mesa_add_state_reference(prog->Parameters,
1161dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     (gl_state_index *)tokens);
1162dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.swizzle = statevars[i].swizzle;
1163dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.negate = 0;
1164dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.reladdr = false;
1165dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1166dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   return src_reg;
1167dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt}
1168dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
116976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int
117076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens)
117176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{
117276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int base_pos = -1;
117376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int i;
117476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
117576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   /* Add a ref for each column.  It looks like the reason we do
117676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * it this way is that _mesa_add_state_reference doesn't work
117776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * for things that aren't vec4s, so the tokens[2]/tokens[3]
117876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * range has to be equal.
117976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    */
118076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   for (i = 0; i < 4; i++) {
118176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[2] = i;
118276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[3] = i;
118376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      int pos = _mesa_add_state_reference(prog->Parameters,
118476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					  (gl_state_index *)tokens);
118576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (base_pos == -1)
118676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 base_pos = pos;
118776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      else
118876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 assert(base_pos + i == pos);
118976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
119076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
119176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   return base_pos;
119276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt}
119376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1194b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage *
119576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
119676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		       ir_rvalue *array_index)
1197bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{
1198bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /*
1199bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * NOTE: The ARB_vertex_program extension specified that matrices get
1200bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * loaded in registers in row-major order.  With GLSL, we want column-
1201bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * major order.  So, we need to transpose all matrices here...
1202bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
1203bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   static const struct {
1204bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      const char *name;
1205bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int matrix;
1206bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int modifier;
1207bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   } matrices[] = {
1208bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
1209bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
1210bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
1211bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1212bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1213bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
1214bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
1215bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
1216bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
1217bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1218bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
1219bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
1220bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
1221bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
1222bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1223bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
1224bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
1225bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
1226bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
1227bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1228bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1229bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1230bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   };
1231bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   unsigned int i;
1232b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
1233bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1234bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /* C++ gets angry when we try to use an int as a gl_state_index, so we use
1235bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * ints for gl_state_index.  Make sure they're compatible.
1236bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
1237bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   assert(sizeof(gl_state_index) == sizeof(int));
1238bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1239bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   for (i = 0; i < Elements(matrices); i++) {
1240bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      if (strcmp(var->name, matrices[i].name) == 0) {
1241bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 int tokens[STATE_LENGTH];
124276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 int base_pos = -1;
1243bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1244bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[0] = matrices[i].matrix;
1245bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[4] = matrices[i].modifier;
124676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
124776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    ir_constant *index = array_index->constant_expression_value();
124876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    if (index) {
124976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       tokens[1] = index->value.i[0];
125076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       base_pos = add_matrix_ref(prog, tokens);
125176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    } else {
125276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       for (i = 0; i < var->type->length; i++) {
125376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  tokens[1] = i;
125476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  int pos = add_matrix_ref(prog, tokens);
125576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  if (base_pos == -1)
125676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     base_pos = pos;
125776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  else
125876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     assert(base_pos + (int)i * 4 == pos);
125976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       }
126076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    }
126176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 } else {
126276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    tokens[1] = 0; /* unused array index */
126376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    base_pos = add_matrix_ref(prog, tokens);
1264bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 }
1265bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1266b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(var,
1267b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       PROGRAM_STATE_VAR,
1268b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       base_pos);
1269bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1270bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 return entry;
1271bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      }
1272bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   }
1273bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1274bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   return NULL;
1275bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt}
1276bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
127784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
127884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir)
127984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1280b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry = find_variable_storage(ir->var);
128184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
12828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   if (!entry) {
12838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      switch (ir->var->mode) {
12848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_uniform:
128576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
128676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					NULL);
1287bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 if (entry)
1288bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    break;
1289bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
12900924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM,
12910924ba0c3496160a134d37cec800f902ae805b9cEric Anholt					       ir->var->location);
1292b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
12938364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
12948364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_in:
12958364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_out:
12968364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_inout:
1297a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 /* The linker assigns locations for varyings and attributes,
1298a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * including deprecated builtins (like gl_Color), user-assign
1299a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * generic attributes (glBindVertexLocation), and
1300a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * user-defined varyings.
1301a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  *
1302a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * FINISHME: We would hit this path for function arguments.  Fix!
1303f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	  */
1304f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 assert(ir->var->location != -1);
1305a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 if (ir->var->mode == ir_var_in ||
1306a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	     ir->var->mode == ir_var_inout) {
1307b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1308b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_INPUT,
1309b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1310edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt
1311edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1312edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt		ir->var->location >= VERT_ATTRIB_GENERIC0) {
1313edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	       _mesa_add_attribute(prog->Attributes,
1314edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->name,
1315658e25987fbec3b826f500baa6d4d936b9552b13Eric Anholt				   _mesa_sizeof_glsl_type(ir->var->type->gl_type),
1316edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->type->gl_type,
1317c64da87611823b4b53e93188f861f748a69936a3Eric Anholt				   ir->var->location - VERT_ATTRIB_GENERIC0);
1318edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    }
1319f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 } else {
1320b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1321b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_OUTPUT,
1322b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1323f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 }
1324f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt
13258364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
13268364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_auto:
13277e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick      case ir_var_temporary:
1328b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
1329b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       this->next_temp);
1330b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
1331224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
13328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 next_temp += type_size(ir->var->type);
13338364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
133484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
13358364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
13368364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (!entry) {
13378364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 printf("Failed to make storage for %s\n", ir->var->name);
13388364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 exit(1);
1339224f712950494730c76b48864f2ca19acde1c8cfEric Anholt      }
134084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
134184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
13429c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   this->result = ir_to_mesa_src_reg(entry->file, entry->index, ir->var->type);
134384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
134484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
134584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
134684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir)
134784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1348dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   ir_variable *var = ir->variable_referenced();
1349ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir_constant *index;
13500161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
135176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
13528258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt   int element_size = type_size(ir->type);
1353ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt
1354ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   index = ir->array_index->constant_expression_value();
13554e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
135676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   if (deref_var && strncmp(deref_var->var->name,
135776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    "gl_TextureMatrix",
135876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    strlen("gl_TextureMatrix")) == 0) {
1359b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      struct variable_storage *entry;
136076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
136176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
136276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt				     ir->array_index);
136376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      assert(entry);
136476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
13659c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      ir_to_mesa_src_reg src_reg(entry->file, entry->index, ir->type);
136676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
136776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (index) {
1368f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = NULL;
136976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      } else {
137076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
137176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
137276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir->array_index->accept(this);
137376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
137476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
13758258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt			     this->result, src_reg_for_float(element_size));
137676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1377f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
1378f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
137976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      }
138076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
138176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      this->result = src_reg;
138276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      return;
138376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
138476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1385264ba1ab88f273dc92add8018f24edcdd67fa5e5Eric Anholt   if (var &&
1386264ba1ab88f273dc92add8018f24edcdd67fa5e5Eric Anholt       strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform &&
1387dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt       !var->type->is_matrix()) {
1388dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      ir_dereference_record *record = NULL;
1389dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      if (ir->array->ir_type == ir_type_dereference_record)
1390dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 record = (ir_dereference_record *)ir->array;
1391dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1392dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      assert(index || !"FINISHME: variable-indexed builtin uniform access");
1393dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1394dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      this->result = get_builtin_uniform_reg(prog,
1395dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     var->name,
1396dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     index->value.i[0],
1397dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     record ? record->field : NULL);
1398dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
1399dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1400ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir->array->accept(this);
14010161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg = this->result;
14024e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
14034d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (index) {
14044d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.index += index->value.i[0] * element_size;
14054e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   } else {
14064d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg array_base = this->result;
14074d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      /* Variable index array dereference.  It eats the "vec4" of the
14084d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * base of the array and an index that offsets the Mesa register
14094d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * index.
14104d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       */
14114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir->array_index->accept(this);
14128258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
14134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg index_reg;
14148258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
14154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (element_size == 1) {
14164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = this->result;
14174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
14184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = get_temp(glsl_type::float_type);
1419f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
14204d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
14214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
14224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     this->result, src_reg_for_float(element_size));
1423bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      }
14244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
14254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
14264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
14274e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   }
142884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
142984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
143085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   if (ir->type->is_scalar() || ir->type->is_vector())
143185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
143285e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   else
143385e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
143484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
14350161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
143684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
143784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
14382c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid
14392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir)
14402c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
14412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
14420161515c395c44233529c8d51f823b60050bc7baEric Anholt   const glsl_type *struct_type = ir->record->type;
14432c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int offset = 0;
1444dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   ir_variable *var = ir->record->variable_referenced();
1445dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1446dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform) {
1447dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      assert(var);
1448dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1449dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      this->result = get_builtin_uniform_reg(prog,
1450dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     var->name,
1451dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     0,
1452dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     ir->field);
1453dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      return;
1454dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
14552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
14560161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir->record->accept(this);
14572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
14582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   for (i = 0; i < struct_type->length; i++) {
14590161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
14602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 break;
14612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
14622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
146385e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
14640161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.index += offset;
14652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
14662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
14672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/**
14682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage
14692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the
14702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler.
14712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */
14720161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg
1473fc63e37b971b641dfdff000ba353c4810414c20eIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v)
1474b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
14755a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   /* The LHS must be a dereference.  If the LHS is a variable indexed array
14765a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * access of a vector, it must be separated into a series conditional moves
14775a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * before reaching this point (see ir_vec_index_to_cond_assign).
14785a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    */
14795a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   assert(ir->as_dereference());
1480ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   ir_dereference_array *deref_array = ir->as_dereference_array();
1481ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   if (deref_array) {
1482ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt      assert(!deref_array->array->type->is_vector());
1483ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   }
1484ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt
14850161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Use the rvalue deref handler for the most part.  We'll ignore
14860161515c395c44233529c8d51f823b60050bc7baEric Anholt    * swizzles in it and write swizzles using writemask, though.
14870161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
14882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir->accept(v);
14895a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   return ir_to_mesa_dst_reg_from_src(v->result);
1490cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt}
1491cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
149284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
149384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir)
149484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
14950161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg l;
14960161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg r;
14977d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt   int i;
149884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
149984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->rhs->accept(this);
150084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   r = this->result;
1501cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
1502fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick   l = get_assignment_lhs(ir->lhs, this);
1503cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
15045a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   /* FINISHME: This should really set to the correct maximal writemask for each
15055a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * FINISHME: component written (in the loops below).  This case can only
15065a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * FINISHME: occur for matrices, arrays, and structures.
15075a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    */
15085a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   if (ir->write_mask == 0) {
15095a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
15105a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      l.writemask = WRITEMASK_XYZW;
15115a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   } else if (ir->lhs->type->is_scalar()) {
15125a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      /* FINISHME: This hack makes writing to gl_FragData, which lives in the
15135a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick       * FINISHME: W component of fragment shader output zero, work correctly.
15145a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick       */
15155a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      l.writemask = WRITEMASK_XYZW;
15165a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   } else {
15175a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      assert(ir->lhs->type->is_vector());
15185a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      l.writemask = ir->write_mask;
15195a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   }
15205a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
15210161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(l.file != PROGRAM_UNDEFINED);
15220161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(r.file != PROGRAM_UNDEFINED);
152384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1524346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   if (ir->condition) {
15252d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir_to_mesa_src_reg condition;
15262d1789e667c4180777829f96856daf91326721b9Eric Anholt
15272d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir->condition->accept(this);
15282d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition = this->result;
15292d1789e667c4180777829f96856daf91326721b9Eric Anholt
15302d1789e667c4180777829f96856daf91326721b9Eric Anholt      /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
15312d1789e667c4180777829f96856daf91326721b9Eric Anholt       * and the condition we produced is 0.0 or 1.0.  By flipping the
15322d1789e667c4180777829f96856daf91326721b9Eric Anholt       * sign, we can choose which value OPCODE_CMP produces without
15332d1789e667c4180777829f96856daf91326721b9Eric Anholt       * an extra computing the condition.
15342d1789e667c4180777829f96856daf91326721b9Eric Anholt       */
15352d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition.negate = ~condition.negate;
15367d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
15377d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
15387d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt			     condition, r, ir_to_mesa_src_reg_from_dst(l));
15397d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
15407d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
15417d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
15422d1789e667c4180777829f96856daf91326721b9Eric Anholt   } else {
15437d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
15447d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
15457d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
15467d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
15477d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
1548346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   }
154984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
155084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
155184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
155284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
155384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir)
155484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
15550161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
15560a46497a4ee3325fab47929cb17cfe2525e1fc33Vinson Lee   GLfloat stack_vals[4] = { 0 };
15570bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat *values = stack_vals;
15580bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   unsigned int i;
155984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
15605b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   /* Unfortunately, 4 floats is all we can get into
15615b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * _mesa_add_unnamed_constant.  So, make a temp to store an
15625b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * aggregate constant and move each constant value into it.  If we
15635b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * get lucky, copy propagation will eliminate the extra moves.
15645b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    */
15655b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
15665b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   if (ir->type->base_type == GLSL_TYPE_STRUCT) {
15675b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      ir_to_mesa_src_reg temp_base = get_temp(ir->type);
15685b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
15695b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
15705b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      foreach_iter(exec_list_iterator, iter, ir->components) {
15715b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 ir_constant *field_value = (ir_constant *)iter.get();
15725b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 int size = type_size(field_value->type);
15735b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
15745b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 assert(size > 0);
15755b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
15765b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 field_value->accept(this);
15775b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 src_reg = this->result;
15785b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
15795b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 for (i = 0; i < (unsigned int)size; i++) {
15805b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
15815b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
15825b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    src_reg.index++;
15835b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    temp.index++;
15845b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 }
15855b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      }
15865b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      this->result = temp_base;
15875b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      return;
15885b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   }
15895b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
159020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   if (ir->type->is_array()) {
159120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      ir_to_mesa_src_reg temp_base = get_temp(ir->type);
159220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
159320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      int size = type_size(ir->type->fields.array);
159420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
159520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      assert(size > 0);
159620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
159720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      for (i = 0; i < ir->type->length; i++) {
159820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 ir->array_elements[i]->accept(this);
159920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 src_reg = this->result;
160020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 for (int j = 0; j < size; j++) {
160120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
160220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
160320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	    src_reg.index++;
160420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	    temp.index++;
160520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 }
160620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      }
160720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      this->result = temp_base;
160820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      return;
160920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   }
161020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
1611ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   if (ir->type->is_matrix()) {
1612c91809e1e4a4fa8884e6588159368ea32431ee0eEric Anholt      ir_to_mesa_src_reg mat = get_temp(ir->type);
1613ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
1614ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1615ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      for (i = 0; i < ir->type->matrix_columns; i++) {
1616ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 assert(ir->type->base_type == GLSL_TYPE_FLOAT);
1617ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 values = &ir->value.f[i * ir->type->vector_elements];
1618ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
16199c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt	 src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL);
1620ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
16219c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						values,
16229c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						ir->type->vector_elements,
16239c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						&src_reg.swizzle);
1624ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
1625ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1626ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 mat_column.index++;
1627ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      }
1628ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1629ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      this->result = mat;
1630ebef04011736ea8e13692fed87623d425c4d1b08Eric Anholt      return;
1631582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   }
16320bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
16330bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.file = PROGRAM_CONSTANT;
16340bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   switch (ir->type->base_type) {
16350bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_FLOAT:
16360bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      values = &ir->value.f[0];
16370bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
16380bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_UINT:
16390bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
16400bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.u[i];
16410bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
16420bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
16430bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_INT:
16440bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
16450bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.i[i];
16460bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
16470bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
16480bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_BOOL:
16490bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
16500bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.b[i];
16510bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
16520bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
16530bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   default:
16540bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      assert(!"Non-float/uint/int/bool constant");
16550bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   }
16560bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
16579c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type);
16589c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters,
16599c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						   values,
16609c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						   ir->type->vector_elements,
16619c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						   &this->result.swizzle);
166284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
166384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
16647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry *
16657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
16667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{
16677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry;
16687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
16697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, this->function_signatures) {
16707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry = (function_entry *)iter.get();
16717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
16727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (entry->sig == sig)
16737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 return entry;
16747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
16757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
16767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry = talloc(mem_ctx, function_entry);
16777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig = sig;
16787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig_id = this->next_signature_id++;
16797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->bgn_inst = NULL;
16807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
16817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Allocate storage for all the parameters. */
16827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, sig->parameters) {
16837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)iter.get();
1684b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      variable_storage *storage;
16857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
16867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      storage = find_variable_storage(param);
16877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      assert(!storage);
16887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1689b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
1690b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					      this->next_temp);
1691b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      this->variables.push_tail(storage);
16927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
16937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      this->next_temp += type_size(param->type);
16947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
16957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1696576d01ad8c8b8aa57b4711c98d8e004d4f20fc0bEric Anholt   if (!sig->return_type->is_void()) {
16977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = get_temp(sig->return_type);
16987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } else {
16997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = ir_to_mesa_undef;
17007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
17017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->function_signatures.push_tail(entry);
17037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   return entry;
17047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}
170584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
170684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
170784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir)
170884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
17097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *call_inst;
17107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig = ir->get_callee();
17117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry = get_function_signature(sig);
17127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int i;
17137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process in parameters. */
17157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list_iterator sig_iter = sig->parameters.iterator();
17167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
17177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
17187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
17197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_in ||
17217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1722b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
17237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
17247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
17267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r = this->result;
17277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l;
17297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.file = storage->file;
17307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index = storage->index;
17317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.reladdr = NULL;
17327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.writemask = WRITEMASK_XYZW;
17337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.cond_mask = COND_TR;
17347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
17367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
17377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
17387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
17397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
17407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
17417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
17437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
17447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
17457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit call instruction */
17477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
17487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt				   ir_to_mesa_undef_dst, ir_to_mesa_undef);
17497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst->function = entry;
17507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process out parameters. */
17527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   sig_iter = sig->parameters.iterator();
17537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
17547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
17557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
17567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_out ||
17587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1759b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
17607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
17617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r;
17637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.file = storage->file;
17647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index = storage->index;
17657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.reladdr = NULL;
17667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.swizzle = SWIZZLE_NOOP;
17677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.negate = 0;
17687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
17707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
17717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
17737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
17747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
17757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
17767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
17777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
17787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
17807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
17817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
17827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process return value. */
17847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->result = entry->return_reg;
178584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
178684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1787aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtclass get_sampler_name : public ir_hierarchical_visitor
1788aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt{
1789aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtpublic:
1790aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   get_sampler_name(ir_to_mesa_visitor *mesa, ir_dereference *last)
1791aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   {
1792aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->mem_ctx = mesa->mem_ctx;
1793aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->mesa = mesa;
1794aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->name = NULL;
1795aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->offset = 0;
1796aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->last = last;
1797aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   }
1798aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1799aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   virtual ir_visitor_status visit(ir_dereference_variable *ir)
1800aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   {
1801aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->name = ir->var->name;
1802aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      return visit_continue;
1803aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   }
1804aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1805aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
1806aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   {
1807aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->name = talloc_asprintf(mem_ctx, "%s.%s", name, ir->field);
1808aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      return visit_continue;
1809aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   }
1810aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1811aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
1812aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   {
1813aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      ir_constant *index = ir->array_index->as_constant();
1814aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      int i;
1815aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1816aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      if (index) {
1817aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 i = index->value.i[0];
1818aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      } else {
1819aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
1820aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * while GLSL 1.30 requires that the array indices be
1821aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * constant integer expressions.  We don't expect any driver
1822aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * to actually work with a really variable array index, so
1823aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * all that would work would be an unrolled loop counter that ends
1824aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * up being constant above.
1825aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  */
1826aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 mesa->shader_program->InfoLog =
1827aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	    talloc_asprintf_append(mesa->shader_program->InfoLog,
1828aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				   "warning: Variable sampler array index "
1829aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				   "unsupported.\nThis feature of the language "
1830aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				   "was removed in GLSL 1.20 and is unlikely "
1831aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				   "to be supported for 1.10 in Mesa.\n");
1832aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 i = 0;
1833aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      }
1834aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      if (ir != last) {
1835aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 this->name = talloc_asprintf(mem_ctx, "%s[%d]", name, i);
1836aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      } else {
1837aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 offset = i;
1838aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      }
1839aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      return visit_continue;
1840aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   }
1841aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1842aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   ir_to_mesa_visitor *mesa;
1843aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   const char *name;
1844aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   void *mem_ctx;
1845aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   int offset;
1846aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   ir_dereference *last;
1847aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt};
1848aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1849aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtint
1850aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtir_to_mesa_visitor::get_sampler_uniform_value(ir_dereference *sampler)
1851aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt{
1852aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   get_sampler_name getname(this, sampler);
1853aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1854aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   sampler->accept(&getname);
1855aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1856aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
1857aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt					      getname.name);
1858aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1859aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   if (index < 0) {
1860aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->shader_program->InfoLog =
1861aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 talloc_asprintf_append(this->shader_program->InfoLog,
1862aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				"failed to find sampler named %s.\n",
1863aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				getname.name);
1864aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      this->shader_program->LinkStatus = GL_FALSE;
1865aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      return 0;
1866aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   }
1867aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1868aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   index += getname.offset;
1869aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
1870aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   return this->prog->Parameters->ParameterValues[index][0];
1871aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt}
187284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
187384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
187484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir)
187584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
18769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg result_src, coord, lod_info, projector;
1877d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_dst_reg result_dst, coord_dst;
1878d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_to_mesa_instruction *inst = NULL;
1879d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   prog_opcode opcode = OPCODE_NOP;
188084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
188184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->coordinate->accept(this);
1882d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1883d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   /* Put our coords in a temp.  We'll need to modify them for shadow,
1884d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * projection, or LOD, so the only case we'd use it as is is if
1885d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * we're doing plain old texturing.  Mesa IR optimization should
1886d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * handle cleaning up our mess in that case.
1887d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    */
1888d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord = get_temp(glsl_type::vec4_type);
1889d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord_dst = ir_to_mesa_dst_reg_from_src(coord);
1890d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
1891d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt		       this->result);
1892d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1893de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   if (ir->projector) {
1894de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      ir->projector->accept(this);
1895de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      projector = this->result;
1896de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   }
1897de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt
1898d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
1899d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * the actual storage for the result here, instead.
1900d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1901d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_src = get_temp(glsl_type::vec4_type);
1902d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1903d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1904d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (ir->op) {
1905d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_tex:
1906d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TEX;
1907d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1908d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txb:
1909d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXB;
1910d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.bias->accept(this);
1911d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1912d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1913d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txl:
1914d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXL;
1915d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.lod->accept(this);
1916d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1917d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1918d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txd:
1919d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txf:
1920d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"GLSL 1.30 features unsupported");
1921d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1922d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1923d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1924d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (ir->projector) {
1925d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      if (opcode == OPCODE_TEX) {
1926d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* Slot the projector in as the last component of the coord. */
1927d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
1928d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
1929d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
1930d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 opcode = OPCODE_TXP;
1931d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      } else {
1932d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_src_reg coord_w = coord;
1933d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_w.swizzle = SWIZZLE_WWWW;
1934d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1935d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* For the other TEX opcodes there's no projective version
1936d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * since the last slot is taken up by lod info.  Do the
1937d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * projective divide now.
1938d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  */
1939d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
1940d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
1941d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1942d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZ;
1943d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
1944d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1945d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
1946d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord.swizzle = SWIZZLE_XYZW;
1947d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      }
1948d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
1949d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1950b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor) {
1951b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      /* Slot the shadow value in as the second to last component of the
1952b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       * coord.
1953b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       */
1954b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir->shadow_comparitor->accept(this);
1955b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_Z;
1956b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
1957b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
1958b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   }
1959b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
1960d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
1961d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      /* Mesa IR stores lod or lod bias in the last channel of the coords. */
1962d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_W;
1963d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
1964d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
1965d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
1966d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1967d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
1968d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1969b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor)
1970b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      inst->tex_shadow = GL_TRUE;
1971b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
1972aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   inst->sampler = get_sampler_uniform_value(ir->sampler);
1973c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt
1974aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   const glsl_type *sampler_type = ir->sampler->type;
1975d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1976c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt   switch (sampler_type->sampler_dimensionality) {
1977d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_1D:
1978c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt      inst->tex_target = (sampler_type->sampler_array)
19790a86d766ef0d98abd3373609a637bf137203e994Ian Romanick	 ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
1980d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1981d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_2D:
1982c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt      inst->tex_target = (sampler_type->sampler_array)
19830a86d766ef0d98abd3373609a637bf137203e994Ian Romanick	 ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
1984d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1985d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_3D:
1986d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_3D_INDEX;
1987d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1988d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_CUBE:
1989d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_CUBE_INDEX;
1990d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
19910bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick   case GLSL_SAMPLER_DIM_RECT:
19920bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick      inst->tex_target = TEXTURE_RECT_INDEX;
19930bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick      break;
199468772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick   case GLSL_SAMPLER_DIM_BUF:
199568772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick      assert(!"FINISHME: Implement ARB_texture_buffer_object");
199668772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick      break;
1997d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   default:
199868772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick      assert(!"Should not get here.");
1999d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
2000d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2001d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->result = result_src;
200284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
200384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
200484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
200584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir)
200684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
20077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   if (ir->get_value()) {
20087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_dst_reg l;
20097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      int i;
20107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
201135220fc5981045331b4f048f0fc2e1371a0673edEric Anholt      assert(current_function);
201235220fc5981045331b4f048f0fc2e1371a0673edEric Anholt
20137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir->get_value()->accept(this);
20147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_src_reg r = this->result;
201584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
20167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
20177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      for (i = 0; i < type_size(current_function->sig->return_type); i++) {
20197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
20207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index++;
20217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index++;
20227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
20237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
20247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_RET);
202684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
202784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
202816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid
202916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir)
203016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{
20315e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt   assert(ir->condition == NULL); /* FINISHME */
203216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
2033021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
203416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke}
203584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
203684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
203784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir)
203884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
2039854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
2040cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   ir_to_mesa_instruction *prev_inst;
2041cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
2042cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
2043c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2044c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir->condition->accept(this);
20450161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(this->result.file != PROGRAM_UNDEFINED);
2046c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2047854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   if (ctx->Shader.EmitCondCodes) {
2048854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
2049cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
2050cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      /* See if we actually generated any instruction for generating
2051cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * the condition.  If not, then cook up a move to a temp so we
2052cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * have something to set cond_update on.
2053cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       */
2054cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      if (cond_inst == prev_inst) {
2055cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
2056cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
2057cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 ir_to_mesa_dst_reg_from_src(temp),
2058cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 result);
2059cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      }
2060854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst->cond_update = GL_TRUE;
2061854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt
2062021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
2063854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst->dst_reg.cond_mask = COND_NE;
2064854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   } else {
2065854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst = ir_to_mesa_emit_op1(ir->condition,
2066854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    OPCODE_IF, ir_to_mesa_undef_dst,
2067854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    this->result);
2068854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   }
2069c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2070c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   this->instructions.push_tail(if_inst);
2071c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2072c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   visit_exec_list(&ir->then_instructions, this);
2073c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2074c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if (!ir->else_instructions.is_empty()) {
2075021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
20760a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt      visit_exec_list(&ir->else_instructions, this);
2077c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2078c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
20790161515c395c44233529c8d51f823b60050bc7baEric Anholt   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
20800161515c395c44233529c8d51f823b60050bc7baEric Anholt				 ir_to_mesa_undef_dst, ir_to_mesa_undef);
208184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
208284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2083ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor()
2084ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{
20850161515c395c44233529c8d51f823b60050bc7baEric Anholt   result.file = PROGRAM_UNDEFINED;
2086ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_temp = 1;
20877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   next_signature_id = 1;
20887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   current_function = NULL;
2089abc6d7e0b4b04c75129d24c3cb6f021b92cd46f6Eric Anholt   mem_ctx = talloc_new(NULL);
2090ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt}
2091ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt
2092fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor()
2093fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{
2094abc6d7e0b4b04c75129d24c3cb6f021b92cd46f6Eric Anholt   talloc_free(mem_ctx);
2095fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt}
2096fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt
209784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register
209884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
209984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
210084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_src_register mesa_reg;
210184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
210284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.File = reg.file;
2103aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
210484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.Index = reg.index;
210534195832669f0eb7c4a80997cc524f8d10319307Eric Anholt   mesa_reg.Swizzle = reg.swizzle;
2106f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   mesa_reg.RelAddr = reg.reladdr != NULL;
2107ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   mesa_reg.Negate = reg.negate;
2108285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt   mesa_reg.Abs = 0;
2109b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt   mesa_reg.HasIndex2 = GL_FALSE;
2110405546882a010885d342b0b40392de0da289374eVinson Lee   mesa_reg.RelAddr2 = 0;
2111405546882a010885d342b0b40392de0da289374eVinson Lee   mesa_reg.Index2 = 0;
211284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
211384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return mesa_reg;
211484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
211584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2116c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
21177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v,
21187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt		  struct prog_instruction *mesa_instructions,
2119c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		  int num_instructions)
2120c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
2121e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke   int if_count = 0, loop_count = 0;
212264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int *if_stack, *loop_stack;
212364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_stack_pos = 0, loop_stack_pos = 0;
212464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int i, j;
2125c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2126c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
212764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      switch (mesa_instructions[i].Opcode) {
212864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_IF:
2129c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_count++;
213064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
213164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
213264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_count++;
213364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
213464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BRK:
213564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_CONT:
213664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = -1;
213764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
213864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      default:
213964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
214064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      }
2141c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2142c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
21433ef83d270b2c24867a0d020b81bdc6c54cb1c9b0Eric Anholt   if_stack = talloc_zero_array(v->mem_ctx, int, if_count);
21443ef83d270b2c24867a0d020b81bdc6c54cb1c9b0Eric Anholt   loop_stack = talloc_zero_array(v->mem_ctx, int, loop_count);
2145c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2146c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
2147c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      switch (mesa_instructions[i].Opcode) {
2148c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_IF:
214964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos] = i;
2150c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos++;
2151c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
2152c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ELSE:
215364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
215464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos - 1] = i;
2155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
2156c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ENDIF:
215764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
2158c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos--;
2159c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
216064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
216164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack[loop_stack_pos] = i;
216264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos++;
216364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
216464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_ENDLOOP:
216564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos--;
216664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* Rewrite any breaks/conts at this nesting level (haven't
216764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * already had a BranchTarget assigned) to point to the end
216864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * of the loop.
216964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  */
217064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
217164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    if (mesa_instructions[j].Opcode == OPCODE_BRK ||
217264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		mesa_instructions[j].Opcode == OPCODE_CONT) {
217364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       if (mesa_instructions[j].BranchTarget == -1) {
217464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		  mesa_instructions[j].BranchTarget = i;
217564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       }
217664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    }
217764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 }
217864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* The loop ends point at each other. */
217964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
218064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
21817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
21827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      case OPCODE_CAL:
21837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 foreach_iter(exec_list_iterator, iter, v->function_signatures) {
21847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    function_entry *entry = (function_entry *)iter.get();
21857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
21867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    if (entry->sig_id == mesa_instructions[i].BranchTarget) {
21877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       mesa_instructions[i].BranchTarget = entry->inst;
21887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       break;
21897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    }
21907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
21917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
2192c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      default:
2193c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
2194c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
2195c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2196c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
2197c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2198c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
2199c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions,
2200c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      ir_instruction **mesa_instruction_annotation,
2201c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      int num_instructions)
2202c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
2203c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction *last_ir = NULL;
2204c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
2205748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt   int indent = 0;
2206c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2207c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
2208c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      struct prog_instruction *mesa_inst = mesa_instructions + i;
2209c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      ir_instruction *ir = mesa_instruction_annotation[i];
2210c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2211748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      fprintf(stdout, "%3d: ", i);
2212748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
221364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      if (last_ir != ir && ir) {
2214748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 int j;
2215748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
2216748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 for (j = 0; j < indent; j++) {
2217748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	    fprintf(stdout, " ");
2218748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 }
2219748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 ir->print();
2220c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 printf("\n");
2221c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 last_ir = ir;
2222748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
2223748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 fprintf(stdout, "     "); /* line number spacing. */
2224c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
2225c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2226748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
2227748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt					    PROG_PRINT_DEBUG, NULL);
2228c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2229c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
2230c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2231ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void
2232ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog)
2233ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{
2234d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   unsigned int i;
2235d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2236d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   prog->SamplersUsed = 0;
2237ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
2238ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   for (i = 0; i < prog->NumInstructions; i++) {
2239ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      struct prog_instruction *inst = &prog->Instructions[i];
2240d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2241d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      if (_mesa_is_tex_instruction(inst->Opcode)) {
2242d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplerTargets[inst->TexSrcUnit] =
2243d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    (gl_texture_index)inst->TexSrcTarget;
2244d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
2245d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (inst->TexShadow) {
2246d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
2247d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
2248d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      }
2249ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   }
2250d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2251d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   _mesa_update_shader_textures_used(prog);
2252ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt}
2253ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
22540924ba0c3496160a134d37cec800f902ae805b9cEric Anholt/* Add the uniforms to the parameters.  The linker chose locations
22550924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * in our parameters lists (which weren't created yet), which the
22560924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * uniforms code will use to poke values into our parameters list
22570924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * when uniforms are updated.
225885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */
225985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void
22600924ba0c3496160a134d37cec800f902ae805b9cEric Anholtadd_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
22610924ba0c3496160a134d37cec800f902ae805b9cEric Anholt				struct gl_shader *shader,
22620924ba0c3496160a134d37cec800f902ae805b9cEric Anholt				struct gl_program *prog)
226385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{
226485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   unsigned int i;
2265aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   unsigned int next_sampler = 0;
226685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
22670924ba0c3496160a134d37cec800f902ae805b9cEric Anholt   for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) {
22680924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i;
22690924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      const glsl_type *type = uniform->Type;
22700924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      unsigned int size;
22710924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      int parameter_index = -1;
22720924ba0c3496160a134d37cec800f902ae805b9cEric Anholt
22730924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      switch (shader->Type) {
22740924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      case GL_VERTEX_SHADER:
22750924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 parameter_index = uniform->VertPos;
22760924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 break;
22770924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      case GL_FRAGMENT_SHADER:
22780924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 parameter_index = uniform->FragPos;
22790924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 break;
22800924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      case GL_GEOMETRY_SHADER:
22810924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 parameter_index = uniform->GeomPos;
22820924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 break;
22830924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      }
22840924ba0c3496160a134d37cec800f902ae805b9cEric Anholt
22850924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      /* Only add uniforms used in our target. */
22860924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      if (parameter_index == -1)
22870924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 continue;
22880924ba0c3496160a134d37cec800f902ae805b9cEric Anholt
22890924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      if (type->is_vector() ||
22900924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	  type->is_scalar()) {
22910924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 size = type->vector_elements;
22920924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      } else {
22930924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 size = type_size(type) * 4;
22940924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      }
22950924ba0c3496160a134d37cec800f902ae805b9cEric Anholt
2296aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      gl_register_file file;
22970924ba0c3496160a134d37cec800f902ae805b9cEric Anholt      if (type->is_sampler() ||
22980924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	  (type->is_array() && type->fields.array->is_sampler())) {
2299aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 file = PROGRAM_SAMPLER;
2300aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      } else {
2301aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 file = PROGRAM_UNIFORM;
2302aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      }
230385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
2304aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
2305aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt						 uniform->Name);
23060924ba0c3496160a134d37cec800f902ae805b9cEric Anholt
2307aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt      if (index < 0) {
2308aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 index = _mesa_add_parameter(prog->Parameters, file,
2309aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				     uniform->Name, size, type->gl_type,
2310aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				     NULL, NULL, 0x0);
2311aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
2312aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 /* Sampler uniform values are stored in prog->SamplerUnits,
2313aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * and the entry in that array is selected by this index we
2314aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * store in ParameterValues[].
2315aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  */
2316aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 if (file == PROGRAM_SAMPLER) {
2317aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	    for (unsigned int j = 0; j < size / 4; j++)
2318aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	       prog->Parameters->ParameterValues[index + j][0] = next_sampler++;
2319aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 }
2320aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt
2321aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 /* The location chosen in the Parameters list here (returned
2322aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  * from _mesa_add_uniform) has to match what the linker chose.
2323aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	  */
2324aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	 if (index != parameter_index) {
2325aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	    shader_program->InfoLog =
2326aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	       talloc_asprintf_append(shader_program->InfoLog,
2327aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				      "Allocation of uniform `%s' to target "
2328aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				      "failed (%d vs %d)\n", uniform->Name,
2329aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt				      index, parameter_index);
2330aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt	    shader_program->LinkStatus = false;
23310924ba0c3496160a134d37cec800f902ae805b9cEric Anholt	 }
233285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      }
233385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   }
233485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt}
233585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
23362f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void
23372f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtset_uniform_initializer(GLcontext *ctx, void *mem_ctx,
23382f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt			struct gl_shader_program *shader_program,
23392f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt			const char *name, const glsl_type *type,
23402f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt			ir_constant *val)
23412f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{
23422f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   if (type->is_record()) {
23432f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      ir_constant *field_constant;
23442f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23452f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      field_constant = (ir_constant *)val->components.get_head();
23462f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23472f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      for (unsigned int i = 0; i < type->length; i++) {
23482f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 const glsl_type *field_type = type->fields.structure[i].type;
23492f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 const char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name,
23502f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt					    type->fields.structure[i].name);
23512f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 set_uniform_initializer(ctx, mem_ctx, shader_program, field_name,
23522f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt				 field_type, field_constant);
23532f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 field_constant = (ir_constant *)field_constant->next;
23542f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      }
23552f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      return;
23562f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   }
23572f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23582f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   int loc = _mesa_get_uniform_location(ctx, shader_program, name);
23592f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23602f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   if (loc == -1) {
23612f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      shader_program->InfoLog =
23622f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 talloc_asprintf_append(shader_program->InfoLog,
23632f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt				"Couldn't find uniform for "
23642f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt				"initializer %s\n", name);
23652f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      shader_program->LinkStatus = false;
23662f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      abort();
23672f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   }
23682f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23692f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) {
23702f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      ir_constant *element;
23712f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      const glsl_type *element_type;
23722f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      if (type->is_array()) {
23732f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 element = val->array_elements[i];
23742f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 element_type = type->fields.array;
23752f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      } else {
23762f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 element = val;
23772f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 element_type = type;
23782f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      }
23792f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23802f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      void *values;
23812f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23822f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      if (element_type->base_type == GLSL_TYPE_BOOL) {
23832f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 int *conv = talloc_array(mem_ctx, int, element_type->components());
23842f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 for (unsigned int j = 0; j < element_type->components(); j++) {
23852f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	    conv[j] = element->value.b[j];
23862f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 }
23872f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 values = (void *)conv;
23882f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 element_type = glsl_type::get_instance(GLSL_TYPE_INT,
23892f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt						element_type->vector_elements,
23902f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt						1);
23912f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      } else {
23922f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 values = &element->value;
23932f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      }
23942f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
23952f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      if (element_type->is_matrix()) {
23962f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 _mesa_uniform_matrix(ctx, shader_program,
23972f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt			      element_type->matrix_columns,
23982f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt			      element_type->vector_elements,
23992f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt			      loc, 1, GL_FALSE, (GLfloat *)values);
24002f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 loc += element_type->matrix_columns;
24012f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      } else {
24022f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
24032f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt		       values, element_type->gl_type);
24042f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 loc += type_size(element_type);
24052f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      }
24062f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   }
24072f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt}
24082f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
24092f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void
24102f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtset_uniform_initializers(GLcontext *ctx,
24112f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt			 struct gl_shader_program *shader_program)
24122f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{
24132f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   void *mem_ctx = NULL;
24142f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
24152f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   for (unsigned int i = 0; i < shader_program->_NumLinkedShaders; i++) {
24162f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      struct gl_shader *shader = shader_program->_LinkedShaders[i];
24172f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      foreach_iter(exec_list_iterator, iter, *shader->ir) {
24182f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
24192f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 ir_variable *var = ir->as_variable();
24202f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
24212f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 if (!var || var->mode != ir_var_uniform || !var->constant_value)
24222f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	    continue;
24232f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
24242f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 if (!mem_ctx)
24252f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	    mem_ctx = talloc_new(NULL);
24262f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
24272f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt	 set_uniform_initializer(ctx, mem_ctx, shader_program, var->name,
24282f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt				 var->type, var->constant_value);
24292f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt      }
24302f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   }
24312f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
24322f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   talloc_free(mem_ctx);
24332f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt}
24342f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
2435364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program *
243695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
243795c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt		 struct gl_shader *shader)
243884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
243984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_visitor v;
244084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_instruction *mesa_instructions, *mesa_inst;
2441c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction **mesa_instruction_annotation;
2442c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
2443364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
2444364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLenum target;
2445c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   const char *target_string;
24467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   GLboolean progress;
2447364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2448364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   switch (shader->Type) {
2449c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_VERTEX_SHADER:
2450c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_VERTEX_PROGRAM_ARB;
2451c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "vertex";
2452c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2453c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_FRAGMENT_SHADER:
2454c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_FRAGMENT_PROGRAM_ARB;
2455c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "fragment";
2456c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2457c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   default:
2458c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      assert(!"should not be reached");
2459c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2460364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
246184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
24621124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt   validate_ir_tree(shader->ir);
24631124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt
2464859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt   prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name);
2465364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!prog)
2466364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      return NULL;
2467364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Parameters = _mesa_new_parameter_list();
2468364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2469364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Attributes = _mesa_new_parameter_list();
2470364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.ctx = ctx;
2471364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.prog = prog;
2472aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt   v.shader_program = shader_program;
2473364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
24740924ba0c3496160a134d37cec800f902ae805b9cEric Anholt   add_uniforms_to_parameters_list(shader_program, shader, prog);
24750924ba0c3496160a134d37cec800f902ae805b9cEric Anholt
24767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit Mesa IR for main(). */
247716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   visit_exec_list(shader->ir, &v);
2478021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
247984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
24807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Now emit bodies for any functions that were used. */
24817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   do {
24827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      progress = GL_FALSE;
24837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      foreach_iter(exec_list_iterator, iter, v.function_signatures) {
24857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 function_entry *entry = (function_entry *)iter.get();
24867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 if (!entry->bgn_inst) {
24887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    v.current_function = entry;
24897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
24917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst->function = entry;
24927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    visit_exec_list(&entry->sig->body, &v);
24947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
2495806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	    ir_to_mesa_instruction *last;
2496806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	    last = (ir_to_mesa_instruction *)v.instructions.get_tail();
2497806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	    if (last->op != OPCODE_RET)
2498806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	       v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
2499806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt
250040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	    ir_to_mesa_instruction *end;
250140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	    end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
250240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	    end->function = entry;
250340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt
25047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    progress = GL_TRUE;
25057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
25067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
25077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } while (progress);
25087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
2509364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumTemporaries = v.next_temp;
2510364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
251184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int num_instructions = 0;
251284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
251384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      num_instructions++;
251484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
251584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
251684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_instructions =
251784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      (struct prog_instruction *)calloc(num_instructions,
251884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					sizeof(*mesa_instructions));
2519850c659044d081c53713800cacf8d518fae6cd70Eric Anholt   mesa_instruction_annotation = talloc_array(v.mem_ctx, ir_instruction *,
2520364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt					      num_instructions);
252184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
252284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_inst = mesa_instructions;
2523c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   i = 0;
252484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
252584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
2526b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
252784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->Opcode = inst->op;
2528854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->CondUpdate = inst->cond_update;
252984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.File = inst->dst_reg.file;
253084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.Index = inst->dst_reg.index;
2531854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
253212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
2533f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
253484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
253584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
253684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
2537d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcUnit = inst->sampler;
2538d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcTarget = inst->tex_target;
2539b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      mesa_inst->TexShadow = inst->tex_shadow;
2540c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      mesa_instruction_annotation[i] = inst->ir;
2541aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt
25425755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák      /* Set IndirectRegisterFiles. */
25435755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák      if (mesa_inst->DstReg.RelAddr)
25445755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák         prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File;
25455755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák
25465755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák      for (unsigned src = 0; src < 3; src++)
25475755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák         if (mesa_inst->SrcReg[src].RelAddr)
25485755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák            prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File;
25495755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák
255095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
255195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->InfoLog =
255295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	    talloc_asprintf_append(shader_program->InfoLog,
255395c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt				   "Couldn't flatten if statement\n");
255495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->LinkStatus = false;
255595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      }
255695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt
255740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      switch (mesa_inst->Opcode) {
255840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_BGNSUB:
25597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 inst->function->inst = i;
256040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 mesa_inst->Comment = strdup(inst->function->sig->function_name());
256140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
256240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_ENDSUB:
256340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 mesa_inst->Comment = strdup(inst->function->sig->function_name());
256440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
256540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_CAL:
25667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
256740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
256840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_ARL:
2569d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt	 prog->NumAddressRegs = 1;
257040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
257140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      default:
257240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
257340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      }
25747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
257584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst++;
2576c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      i++;
257784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
2578c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
25797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   set_branchtargets(&v, mesa_instructions, num_instructions);
2580925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt
2581c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
2582455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("\n");
2583455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("GLSL IR for linked %s program %d:\n", target_string,
2584455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt	     shader_program->Name);
2585455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      _mesa_print_ir(shader->ir, NULL);
2586455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("\n");
2587455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("\n");
2588455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("Mesa IR for linked %s program %d:\n", target_string,
2589455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt	     shader_program->Name);
2590364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      print_program(mesa_instructions, mesa_instruction_annotation,
2591364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt		    num_instructions);
2592364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2593364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2594364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Instructions = mesa_instructions;
2595364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumInstructions = num_instructions;
2596364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2597925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt   do_set_program_inouts(shader->ir, prog);
2598925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt   count_resources(prog);
2599925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt
260016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   _mesa_reference_program(ctx, &shader->Program, prog);
2601364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
260228faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
260328faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt      _mesa_optimize_program(ctx, prog);
260428faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   }
260528faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt
2606364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   return prog;
2607364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2608364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
260916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" {
2610d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean
2611d19eecef54384c163af27a470496ed885a5a271bEric Anholt_mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader)
2612d19eecef54384c163af27a470496ed885a5a271bEric Anholt{
2613d19eecef54384c163af27a470496ed885a5a271bEric Anholt   assert(shader->CompileStatus);
2614fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick   (void) ctx;
2615d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2616d19eecef54384c163af27a470496ed885a5a271bEric Anholt   return GL_TRUE;
2617d19eecef54384c163af27a470496ed885a5a271bEric Anholt}
2618d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2619d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean
2620d19eecef54384c163af27a470496ed885a5a271bEric Anholt_mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
2621d19eecef54384c163af27a470496ed885a5a271bEric Anholt{
2622d19eecef54384c163af27a470496ed885a5a271bEric Anholt   assert(prog->LinkStatus);
2623d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2624d19eecef54384c163af27a470496ed885a5a271bEric Anholt   for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
2625d19eecef54384c163af27a470496ed885a5a271bEric Anholt      bool progress;
2626d19eecef54384c163af27a470496ed885a5a271bEric Anholt      exec_list *ir = prog->_LinkedShaders[i]->ir;
2627d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2628d19eecef54384c163af27a470496ed885a5a271bEric Anholt      do {
2629d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 progress = false;
2630d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2631d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 /* Lowering */
2632d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 do_mat_op_to_vec(ir);
2633d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 do_mod_to_fract(ir);
2634d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 do_div_to_mul_rcp(ir);
2635d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 do_explog_to_explog2(ir);
2636d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2637d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 progress = do_common_optimization(ir, true) || progress;
2638d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2639d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 if (ctx->Shader.EmitNoIfs)
2640d19eecef54384c163af27a470496ed885a5a271bEric Anholt	    progress = do_if_to_cond_assign(ir) || progress;
2641d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2642d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 progress = do_vec_index_to_cond_assign(ir) || progress;
2643d19eecef54384c163af27a470496ed885a5a271bEric Anholt      } while (progress);
2644d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2645d19eecef54384c163af27a470496ed885a5a271bEric Anholt      validate_ir_tree(ir);
2646d19eecef54384c163af27a470496ed885a5a271bEric Anholt   }
2647d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2648d19eecef54384c163af27a470496ed885a5a271bEric Anholt   for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
2649d19eecef54384c163af27a470496ed885a5a271bEric Anholt      struct gl_program *linked_prog;
2650d19eecef54384c163af27a470496ed885a5a271bEric Anholt      bool ok = true;
2651d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2652d19eecef54384c163af27a470496ed885a5a271bEric Anholt      linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
2653d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2654d19eecef54384c163af27a470496ed885a5a271bEric Anholt      switch (prog->_LinkedShaders[i]->Type) {
2655d19eecef54384c163af27a470496ed885a5a271bEric Anholt      case GL_VERTEX_SHADER:
2656d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 _mesa_reference_vertprog(ctx, &prog->VertexProgram,
2657d19eecef54384c163af27a470496ed885a5a271bEric Anholt				  (struct gl_vertex_program *)linked_prog);
2658d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
2659d19eecef54384c163af27a470496ed885a5a271bEric Anholt					      linked_prog);
2660d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 break;
2661d19eecef54384c163af27a470496ed885a5a271bEric Anholt      case GL_FRAGMENT_SHADER:
2662d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
2663d19eecef54384c163af27a470496ed885a5a271bEric Anholt				  (struct gl_fragment_program *)linked_prog);
2664d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
2665d19eecef54384c163af27a470496ed885a5a271bEric Anholt					      linked_prog);
2666d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 break;
2667d19eecef54384c163af27a470496ed885a5a271bEric Anholt      }
2668d19eecef54384c163af27a470496ed885a5a271bEric Anholt      if (!ok) {
2669d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 return GL_FALSE;
2670d19eecef54384c163af27a470496ed885a5a271bEric Anholt      }
26713cd233eb5714137dccb6218ad78005511bcc02bdEric Anholt      _mesa_reference_program(ctx, &linked_prog, NULL);
2672d19eecef54384c163af27a470496ed885a5a271bEric Anholt   }
2673d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2674d19eecef54384c163af27a470496ed885a5a271bEric Anholt   return GL_TRUE;
2675d19eecef54384c163af27a470496ed885a5a271bEric Anholt}
267616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt
267716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid
267816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
2679364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
26802462a536ea5c98867296905e3da127eba7c7bdffIan Romanick   struct _mesa_glsl_parse_state *state =
26812462a536ea5c98867296905e3da127eba7c7bdffIan Romanick      new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
26825e18b051c039564d1998818d08caf1bff3983630Ian Romanick
2683153eca98064252be4daad9cc27746f37c245b627Ian Romanick   const char *source = shader->Source;
268406143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick   state->error = preprocess(state, &source, &state->info_log,
268506143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick			     &ctx->Extensions);
2686153eca98064252be4daad9cc27746f37c245b627Ian Romanick
26871b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
26881b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt      printf("GLSL source for shader %d:\n", shader->Name);
26891b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt      printf("%s\n", shader->Source);
26901b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt   }
26911b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt
2692153eca98064252be4daad9cc27746f37c245b627Ian Romanick   if (!state->error) {
2693153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_ctor(state, source);
2694153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_parse(state);
2695153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_dtor(state);
2696153eca98064252be4daad9cc27746f37c245b627Ian Romanick   }
2697364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
26984a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt   talloc_free(shader->ir);
269916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   shader->ir = new(shader) exec_list;
2700364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!state->error && !state->translation_unit.is_empty())
270116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt      _mesa_ast_to_hir(shader->ir, state);
2702364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
270316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   if (!state->error && !shader->ir->is_empty()) {
2704ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2705ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
27062f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt      /* Do some optimization at compile time to reduce shader IR size
27072f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt       * and reduce later work if the same shader is linked multiple times
27082f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt       */
27092f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt      while (do_common_optimization(shader->ir, false))
27102f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt	 ;
2711ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
2712ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2713364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2714364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2715364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->symbols = state->symbols;
2716364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2717364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->CompileStatus = !state->error;
2718364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->InfoLog = state->info_log;
271925f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick   shader->Version = state->language_version;
2720d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   memcpy(shader->builtins_to_link, state->builtins_to_link,
2721d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick	  sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
2722d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   shader->num_builtins_to_link = state->num_builtins_to_link;
2723c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2724b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt   if (ctx->Shader.Flags & GLSL_LOG) {
2725b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt      _mesa_write_shader_to_file(shader);
2726b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt   }
2727b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt
27280df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
27290df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      if (shader->CompileStatus) {
27300df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("GLSL IR for shader %d:\n", shader->Name);
27310df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 _mesa_print_ir(shader->ir, NULL);
27320df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("\n\n");
27330df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      } else {
27340df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("GLSL shader %d failed to compile.\n", shader->Name);
27350df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      }
27360df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      if (shader->InfoLog && shader->InfoLog[0] != 0) {
27370df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("GLSL shader %d info log:\n", shader->Name);
27380df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("%s\n", shader->InfoLog);
27390df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      }
2740455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt   }
2741455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt
2742116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   /* Retain any live IR, but trash the rest. */
27434a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt   reparent_ir(shader->ir, shader->ir);
2744116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke
2745364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   talloc_free(state);
2746d19eecef54384c163af27a470496ed885a5a271bEric Anholt
2747d19eecef54384c163af27a470496ed885a5a271bEric Anholt   if (shader->CompileStatus) {
2748d19eecef54384c163af27a470496ed885a5a271bEric Anholt      if (!ctx->Driver.CompileShader(ctx, shader))
2749d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 shader->CompileStatus = GL_FALSE;
2750d19eecef54384c163af27a470496ed885a5a271bEric Anholt   }
2751d19eecef54384c163af27a470496ed885a5a271bEric Anholt}
2752364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2753364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid
2754364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
2755364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
2756364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   unsigned int i;
2757849e18153cd91d812f694b806a84008498860bc3Eric Anholt
2758364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_clear_shader_program_data(ctx, prog);
2759364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2760849e18153cd91d812f694b806a84008498860bc3Eric Anholt   prog->LinkStatus = GL_TRUE;
2761364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2762364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   for (i = 0; i < prog->NumShaders; i++) {
2763849e18153cd91d812f694b806a84008498860bc3Eric Anholt      if (!prog->Shaders[i]->CompileStatus) {
2764849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->InfoLog =
2765849e18153cd91d812f694b806a84008498860bc3Eric Anholt	    talloc_asprintf_append(prog->InfoLog,
2766364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				   "linking with uncompiled shader");
2767849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->LinkStatus = GL_FALSE;
2768364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
2769364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2770364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2771364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2772364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
2773364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
2774364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2775849e18153cd91d812f694b806a84008498860bc3Eric Anholt   if (prog->LinkStatus) {
27765d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt      link_shaders(ctx, prog);
2777849e18153cd91d812f694b806a84008498860bc3Eric Anholt   }
2778364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2779364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (prog->LinkStatus) {
27800df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      if (!ctx->Driver.LinkShader(ctx, prog)) {
2781d19eecef54384c163af27a470496ed885a5a271bEric Anholt	 prog->LinkStatus = GL_FALSE;
2782af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt      }
2783af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt   }
2784af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt
27852f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt   set_uniform_initializers(ctx, prog);
27862f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt
2787af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
2788af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt      if (!prog->LinkStatus) {
27890df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("GLSL shader program %d failed to link\n", prog->Name);
27900df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      }
27910df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt
27920df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      if (prog->InfoLog && prog->InfoLog[0] != 0) {
27930df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("GLSL shader program %d info log:\n", prog->Name);
27940df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt	 printf("%s\n", prog->InfoLog);
27950df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt      }
2796364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2797364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2798364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2799364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */
2800