ir_to_mesa.cpp revision 698b84444343189357ad252856d3c5493e47e4fa
184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/*
2bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
3bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Copyright © 2010 Intel Corporation
584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * copy of this software and associated documentation files (the "Software"),
884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to deal in the Software without restriction, including without limitation
984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
1184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software is furnished to do so, subject to the following conditions:
1284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * The above copyright notice and this permission notice (including the next
1484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * paragraph) shall be included in all copies or substantial portions of the
1584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software.
1684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * DEALINGS IN THE SOFTWARE.
2484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
2584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/**
2784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * \file ir_to_mesa.cpp
2884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
2984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Translates the IR to ARB_fragment_program text if possible,
3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * printing the result
3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
3284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
330161515c395c44233529c8d51f823b60050bc7baEric Anholt#include <stdio.h>
3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h"
3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h"
3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h"
3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h"
3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h"
39364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h"
40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h"
41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h"
42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h"
4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
44aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" {
450a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h"
4684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "shader/prog_instruction.h"
47aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt#include "shader/prog_print.h"
48364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/program.h"
49364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/prog_uniform.h"
50364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/prog_parameter.h"
51364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/shader_api.h"
52aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt}
5384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
54554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/**
55554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with
56554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields.
57554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */
58554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg {
59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
61582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int negate; /**< NEGATE_XYZW mask from mesa */
63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   bool reladdr; /**< Register index should be offset by address reg. */
64554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg;
65554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
66554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg {
67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
68554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
69554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
70854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLuint cond_mask:4;
71554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg;
72554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
73554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef;
74554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
75554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node {
76554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
77554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   enum prog_opcode op;
78554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_dst_reg dst_reg;
79554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_src_reg src_reg[3];
80554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** Pointer to the ir source this tree came from for debugging */
81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_instruction *ir;
82854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLboolean cond_update;
83d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler; /**< sampler index */
84d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int tex_target; /**< One of TEXTURE_*_INDEX */
85554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
86554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
87554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass temp_entry : public exec_node {
88554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
89554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   temp_entry(ir_variable *var, int file, int index)
90554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      : file(file), index(index), var(var)
91554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   {
92554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      /* empty */
93554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   }
94554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
95554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file;
96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index;
97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_variable *var; /* variable that maps to this, if any */
98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor {
101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_visitor();
103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
104364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLcontext *ctx;
105364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
106364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
107554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int next_temp;
108a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
109a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   temp_entry *find_variable_storage(ir_variable *var);
110554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1118364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   ir_to_mesa_src_reg get_temp(const glsl_type *type);
112554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
113554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg src_reg_for_float(float val);
114554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
115554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /**
116554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * \name Visit methods
117554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    *
118554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * As typical for the visitor pattern, there must be one \c visit method for
119554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * each concrete subclass of \c ir_instruction.  Virtual base classes within
120554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * the hierarchy should not have \c visit methods.
121554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    */
122554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@{*/
123554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_variable *);
124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop *);
125554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop_jump *);
126554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function_signature *);
127554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function *);
128554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_expression *);
129554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_swizzle *);
130554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_variable  *);
131554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_array *);
132554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_record *);
133554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_assignment *);
134554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_constant *);
135554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_call *);
136554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_return *);
13716efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke   virtual void visit(ir_discard *);
138554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_texture *);
139554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_if *);
140554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@}*/
141554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
142554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg result;
143554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
144554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of temp_entry */
145554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list variable_storage;
146554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
147554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of ir_to_mesa_instruction */
148554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list instructions;
149554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
150554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
151554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
152554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
153554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0);
154554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
155554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
156554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
157554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
158554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
159554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1);
160554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
161554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
162554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
164554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1,
166554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src2);
167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   enum prog_opcode op,
170554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_dst_reg dst,
171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_src_reg src0);
1720ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt
173904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
174904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   enum prog_opcode op,
175904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_dst_reg dst,
176904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src0,
177904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src1);
178904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
179d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int *sampler_map;
180d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler_map_size;
181d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
182d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   void map_sampler(int location, int sampler);
183d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int get_sampler_number(int location);
184d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
185364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   void *mem_ctx;
186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
18884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = {
189c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
19084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt};
19184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
192c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
193c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
194c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt};
195c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1960161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = {
1970161515c395c44233529c8d51f823b60050bc7baEric Anholt   PROGRAM_ADDRESS, 0, WRITEMASK_X
1980161515c395c44233529c8d51f823b60050bc7baEric Anholt};
1990161515c395c44233529c8d51f823b60050bc7baEric Anholt
2000161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size)
2010161515c395c44233529c8d51f823b60050bc7baEric Anholt{
2020161515c395c44233529c8d51f823b60050bc7baEric Anholt   int size_swizzles[4] = {
2030161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
2040161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
2050161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
2060161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
2070161515c395c44233529c8d51f823b60050bc7baEric Anholt   };
2080161515c395c44233529c8d51f823b60050bc7baEric Anholt
2090161515c395c44233529c8d51f823b60050bc7baEric Anholt   return size_swizzles[size - 1];
2100161515c395c44233529c8d51f823b60050bc7baEric Anholt}
2110161515c395c44233529c8d51f823b60050bc7baEric Anholt
2128364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt/* This list should match up with builtin_variables.h */
2138364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholtstatic const struct {
2148364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   const char *name;
2158364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   int file;
2168364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   int index;
2178364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt} builtin_var_to_mesa_reg[] = {
2188364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* core_vs */
2198364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS},
2208364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ},
2218364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2228364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* core_fs */
2238364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS},
2248364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE},
2258364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FragColor", PROGRAM_OUTPUT, FRAG_ATTRIB_COL0},
22688c20c46b8f708e89adef28f341c51ea7883b6a0Eric Anholt   {"gl_FragDepth", PROGRAM_OUTPUT, FRAG_RESULT_DEPTH},
2278364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2288364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* 110_deprecated_fs */
2298364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
2308364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1},
2318364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC},
2328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_TexCoord", PROGRAM_INPUT, FRAG_ATTRIB_TEX0}, /* array */
2338364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2348364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* 110_deprecated_vs */
2358364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS},
2368364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL},
2378364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0},
2388364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1},
2398364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0},
2408364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1},
2418364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2},
2428364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3},
2438364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4},
2448364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5},
2458364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6},
2468364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7},
2478364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */
2488364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC},
2498364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
2508364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0},
2518364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0},
2528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1},
2538364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1},
2548364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC},
2558364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2568364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /* 130_vs */
2578364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
2588364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
2598364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */
2608364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt};
2618364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
26284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2630161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
2640161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2650161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2660161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
2670161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1,
2680161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src2)
26984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
270364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
27184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
27284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->op = op;
27384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->dst_reg = dst;
27484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[0] = src0;
27584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[1] = src1;
27684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[2] = src2;
277c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   inst->ir = ir;
27884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2790161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->instructions.push_tail(inst);
28084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
28184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return inst;
28284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
28384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
28484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
28584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2860161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
2870161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2880161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2890161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
2900161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1)
29184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
2920161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
29384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
29484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
29584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2960161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
2970161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2980161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2990161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0)
300bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
3010161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst,
3020161515c395c44233529c8d51f823b60050bc7baEric Anholt			      src0, ir_to_mesa_undef, ir_to_mesa_undef);
303bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
304bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
305d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtvoid
306d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::map_sampler(int location, int sampler)
307d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
308d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   if (this->sampler_map_size <= location) {
309d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map,
310d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					 int, location + 1);
311d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      this->sampler_map_size = location + 1;
312d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
313d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
314d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->sampler_map[location] = sampler;
315d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
316d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
317d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtint
318d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::get_sampler_number(int location)
319d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
320d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(location < this->sampler_map_size);
321d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   return this->sampler_map[location];
322d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
323d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
3240161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg
3250161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
32684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3270161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_dst_reg dst_reg;
32884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3290161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.file = reg.file;
3300161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.index = reg.index;
3310161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.writemask = WRITEMASK_XYZW;
332854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   dst_reg.cond_mask = COND_TR;
3330161515c395c44233529c8d51f823b60050bc7baEric Anholt
3340161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
335bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
336bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
33712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/**
33812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels.
33912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt *
34012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
34112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels.  So to do a vec4
34212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used
34312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels.
34412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */
34512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid
346904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
3470161515c395c44233529c8d51f823b60050bc7baEric Anholt					       enum prog_opcode op,
3480161515c395c44233529c8d51f823b60050bc7baEric Anholt					       ir_to_mesa_dst_reg dst,
349904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src0,
350904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src1)
35112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{
35212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   int i, j;
353315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int done_mask = ~dst.writemask;
35412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
35512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   /* Mesa RCP is a scalar operation splatting results to all channels,
35612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
35712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * dst channels.
35812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    */
35912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   for (i = 0; i < 4; i++) {
360582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt      GLuint this_mask = (1 << i);
36112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_instruction *inst;
362904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src0 = orig_src0;
363904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src1 = orig_src1;
36412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
36512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      if (done_mask & this_mask)
36612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 continue;
36712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
368904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
369904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
37012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      for (j = i + 1; j < 4; j++) {
371904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	 if (!(done_mask & (1 << j)) &&
372904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src0.swizzle, j) == src0_swiz &&
373904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src1.swizzle, j) == src1_swiz) {
37412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	    this_mask |= (1 << j);
37512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 }
37612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      }
377904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
378904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   src0_swiz, src0_swiz);
379904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
380904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				  src1_swiz, src1_swiz);
38112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
382904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      inst = ir_to_mesa_emit_op2(ir, op,
3830161515c395c44233529c8d51f823b60050bc7baEric Anholt				 dst,
384904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src0,
385904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src1);
38612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      inst->dst_reg.writemask = this_mask;
38712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      done_mask |= this_mask;
38812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   }
38912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt}
39012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
391904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid
392904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
393904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       enum prog_opcode op,
394904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_dst_reg dst,
395904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg src0)
396904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{
39759a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt   ir_to_mesa_src_reg undef = ir_to_mesa_undef;
398904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
399904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   undef.swizzle = SWIZZLE_XXXX;
400904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
401904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
402904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt}
403904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
4040161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg
4050161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val)
406b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
4070161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
4081d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4090161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.file = PROGRAM_CONSTANT;
410582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
411582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt					      &val, 1, &src_reg.swizzle);
4121d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4130161515c395c44233529c8d51f823b60050bc7baEric Anholt   return src_reg;
4141d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt}
4151d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int
4172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type)
4182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
4192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
4202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int size;
4212c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
4222c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   switch (type->base_type) {
4232c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_UINT:
4242c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_INT:
4252c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_FLOAT:
4262c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_BOOL:
427a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      if (type->is_matrix()) {
428a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 4; /* FINISHME: Not all matrices are 4x4. */
429a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      } else {
430a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 /* Regardless of size of vector, it gets a vec4. This is bad
431a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * packing for things like floats, but otherwise arrays become a
432a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * mess.  Hopefully a later pass over the code can pack scalars
433a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * down if appropriate.
434a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  */
435a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 1;
436a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      }
4372c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_ARRAY:
4382c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return type_size(type->fields.array) * type->length;
4392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_STRUCT:
4402c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      size = 0;
4412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      for (i = 0; i < type->length; i++) {
4422c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 size += type_size(type->fields.structure[i].type);
4432c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      }
4442c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return size;
4452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   default:
4462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(0);
4472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
4482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
4492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
450d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/**
451d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to
452d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results.  (not SSA -- variable assignments will reuse
453d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage).  Actual register allocation for the Mesa VM occurs in a
454d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later.
455d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */
456d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg
457d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type)
458d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{
459d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   ir_to_mesa_src_reg src_reg;
460d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int swizzle[4];
461d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int i;
462d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
463d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   assert(!type->is_array());
464d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
465d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.file = PROGRAM_TEMPORARY;
466d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.index = next_temp;
467d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.reladdr = false;
468d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   next_temp += type_size(type);
469d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
470d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   for (i = 0; i < type->vector_elements; i++)
471d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt      swizzle[i] = i;
472d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   for (; i < 4; i++)
473d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt      swizzle[i] = type->vector_elements - 1;
474d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
475d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt				   swizzle[2], swizzle[3]);
476d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
477d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   return src_reg;
478d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt}
479d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
480a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholttemp_entry *
481a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var)
48284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
483a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
48484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   temp_entry *entry;
48584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
48684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, this->variable_storage) {
48784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      entry = (temp_entry *)iter.get();
48884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
4890161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (entry->var == var)
490a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return entry;
49184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
49284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
493a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   return NULL;
494a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt}
49584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
49684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
49784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir)
49884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
4998364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   (void)ir;
50084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
50184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
50284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
50384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir)
50484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
50564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->from);
50664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->to);
50764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->increment);
50864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->counter);
50984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
5100161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_emit_op1(NULL, OPCODE_BGNLOOP,
5110161515c395c44233529c8d51f823b60050bc7baEric Anholt		       ir_to_mesa_undef_dst, ir_to_mesa_undef);
51264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt
51364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   visit_exec_list(&ir->body_instructions, this);
51464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt
5150161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_emit_op1(NULL, OPCODE_ENDLOOP,
5160161515c395c44233529c8d51f823b60050bc7baEric Anholt		       ir_to_mesa_undef_dst, ir_to_mesa_undef);
51784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
51884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
51984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
52084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir)
52184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
52264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   switch (ir->mode) {
52364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_break:
5240161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(NULL, OPCODE_BRK,
5250161515c395c44233529c8d51f823b60050bc7baEric Anholt			  ir_to_mesa_undef_dst, ir_to_mesa_undef);
52664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
52764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_continue:
5280161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(NULL, OPCODE_CONT,
5290161515c395c44233529c8d51f823b60050bc7baEric Anholt			  ir_to_mesa_undef_dst, ir_to_mesa_undef);
53064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
53164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   }
53284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
53384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
53484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
53584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
53684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir)
53784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
53884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
53984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
54084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
54184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
54284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
54384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir)
54484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
54584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
54684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
54784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
54884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strcmp(ir->name, "main") == 0) {
54984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      const ir_function_signature *sig;
55084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exec_list empty;
55184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      sig = ir->matching_signature(&empty);
55384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      assert(sig);
55584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      foreach_iter(exec_list_iterator, iter, sig->body) {
55784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
55884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->accept(this);
56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
56184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
56284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
56384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
56484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
56584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir)
56684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
56784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   unsigned int operand;
568f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt   struct ir_to_mesa_src_reg op[2];
5690161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg result_src;
5700161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg result_dst;
57184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
5760161515c395c44233529c8d51f823b60050bc7baEric Anholt      this->result.file = PROGRAM_UNDEFINED;
57784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->operands[operand]->accept(this);
5780161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (this->result.file == PROGRAM_UNDEFINED) {
57984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_print_visitor v;
58084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("Failed to get tree for expression operand:\n");
58184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->operands[operand]->accept(&v);
58284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
58384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
58484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      op[operand] = this->result;
5858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
5868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      /* Only expression implemented for matrices yet */
5878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      assert(!ir->operands[operand]->type->is_matrix() ||
5888364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	     ir->operation == ir_binop_mul);
58984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
59084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
5910161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.file = PROGRAM_UNDEFINED;
5920161515c395c44233529c8d51f823b60050bc7baEric Anholt
5930161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
5940161515c395c44233529c8d51f823b60050bc7baEric Anholt    * the actual storage for the result here, instead.
5950161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
5968364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   result_src = get_temp(ir->type);
5970161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* convenience for the emit functions below. */
5980161515c395c44233529c8d51f823b60050bc7baEric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
5999cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   /* Limit writes to the channels that will be used by result_src later.
6009cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * This does limit this temp's use as a temporary for multi-instruction
6019cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * sequences.
6029cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    */
6039cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
60484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   switch (ir->operation) {
6061d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_logic_not:
607f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
608f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt			  op[0], src_reg_for_float(0.0));
6091d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
610c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   case ir_unop_neg:
6110161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
6120161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
613c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      break;
614524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt   case ir_unop_abs:
615524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
616524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      break;
617524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt
6188c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp:
6190161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EXP, result_dst, op[0]);
6208c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
6218c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp2:
6220161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
6238c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
6248c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log:
6250161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
6268c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
6278c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log2:
6280161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
6298c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
6303c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_sin:
6310161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
6323c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
6333c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_cos:
6340161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
6353c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
636ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
637ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdx:
638ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
639ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
640ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdy:
641ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
642ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
643ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
64484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_add:
6450161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
64684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
64784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_sub:
6480161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
64984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
65084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_mul:
6518364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (ir->operands[0]->type->is_matrix() &&
6528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	  !ir->operands[1]->type->is_matrix()) {
653ad2dc740b95f91f66d57dffe2840dffdefce1c1aEric Anholt	 if (ir->operands[1]->type->is_scalar()) {
6548364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_dst_reg dst_column = result_dst;
6558364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_src_reg src_column = op[0];
6568364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
6578364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       ir_to_mesa_emit_op2(ir, OPCODE_MUL,
6588364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt				   dst_column, src_column, op[1]);
6598364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       dst_column.index++;
6608364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       src_column.index++;
6618364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    }
6628364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 } else {
6638364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_src_reg src_column = op[0];
6648364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    ir_to_mesa_src_reg src_chan = op[1];
6653f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt	    assert(!ir->operands[1]->type->is_matrix() ||
6663f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		    !"FINISHME: matrix * matrix");
6673f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt	     for (int i = 0; i < ir->operands[0]->type->matrix_columns; i++) {
6683f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		src_chan.swizzle = MAKE_SWIZZLE4(i, i, i, i);
6693f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		if (i == 0) {
6703f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		   ir_to_mesa_emit_op2(ir, OPCODE_MUL,
6713f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt				       result_dst, src_column, src_chan);
6723f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		} else {
6733f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		   ir_to_mesa_emit_op3(ir, OPCODE_MAD,
6743f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt				       result_dst, src_column, src_chan,
6753f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt				       result_src);
6763f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		}
6773f3f41357d33893d01213b37c6d92bcb435b0eebEric Anholt		src_column.index++;
6788364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    }
6798364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 }
6808364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      } else {
6818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 assert(!ir->operands[0]->type->is_matrix());
6828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 assert(!ir->operands[1]->type->is_matrix());
6838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
6848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      }
68584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_div:
6870161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[1]);
6889d2b8e0b70acce2678bea2cb6a990e0dee380b37Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], result_src);
68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
69038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
69138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_less:
692f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
69338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
69438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_greater:
695f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
69638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
69738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_lequal:
698f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
69938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
70038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_gequal:
701f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
70238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
70338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_equal:
704f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
70538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
706763cd75863ed9a16912e585887580c44d1e8109fEric Anholt   case ir_binop_logic_xor:
70738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_nequal:
708f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
70938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
71038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
7114380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_or:
7120161515c395c44233529c8d51f823b60050bc7baEric Anholt      /* This could be a saturated add and skip the SNE. */
7130161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
7140161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
7150161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
7160161515c395c44233529c8d51f823b60050bc7baEric Anholt
7170161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
7180161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
7190161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
7204380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
7214380099c98119611ceee684669d00be26195c7d7Eric Anholt
7224380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_and:
7234380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
7240161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
7250161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
7260161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
7274380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
7284380099c98119611ceee684669d00be26195c7d7Eric Anholt
72984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_dot:
73084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (ir->operands[0]->type == vec4_type) {
73184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec4_type);
7320161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
7330161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
7340161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
73584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec3_type) {
73684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec3_type);
7370161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
7380161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
7390161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
74084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec2_type) {
74184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec2_type);
7420161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
7430161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
7440161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
74584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
74684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
74784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_unop_sqrt:
7480161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
7498f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
7508f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      /* For incoming channels < 0, set the result to 0. */
7518f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
7528f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt			  op[0], src_reg_for_float(0.0), result_src);
75384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
754878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt   case ir_unop_rsq:
7550161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
756878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      break;
75750ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   case ir_unop_i2f:
758423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      /* Mesa IR lacks types, ints are stored as truncated floats. */
7590161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
76050ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      break;
761423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt   case ir_unop_f2i:
7620161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
763423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      break;
7641d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_f2b:
7650161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
7660161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
7671d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
768c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_trunc:
7690161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
770c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
771c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_ceil:
7720161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
7730161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
7740161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src.negate = ~result_src.negate;
775c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
776c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_floor:
7770161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
778c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
779c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_min:
7800161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
781c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
782c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_max:
7830161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
784c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
785904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   case ir_binop_pow:
786904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
787904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      break;
78884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   default:
78984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_print_visitor v;
79084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      printf("Failed to get tree for expression:\n");
79184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->accept(&v);
79284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exit(1);
7930161515c395c44233529c8d51f823b60050bc7baEric Anholt      break;
79484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
795b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt
7960161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = result_src;
79784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
79884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
79984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
80084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
80184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir)
80284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
8030161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
80484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
80584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int swizzle[4];
80684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
807b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   /* Note that this is only swizzles in expressions, not those on the left
808b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * hand side of an assignment, which do write masking.  See ir_assignment
809b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * for that.
810b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    */
81184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
81284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->val->accept(this);
8134006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   src_reg = this->result;
8144006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   assert(src_reg.file != PROGRAM_UNDEFINED);
81584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
81684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; i < 4; i++) {
81784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (i < ir->type->vector_elements) {
81884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 switch (i) {
81984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 0:
820698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
82184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
82284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 1:
823698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
82484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
82584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 2:
826698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
82784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
82884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 3:
829698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
83084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
83184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 }
83284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
83384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 /* If the type is smaller than a vec4, replicate the last
83484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  * channel out.
83584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  */
836698b84444343189357ad252856d3c5493e47e4faEric Anholt	 swizzle[i] = swizzle[ir->type->vector_elements - 1];
83784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
83884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
83984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8400161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
8410161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[1],
8420161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[2],
8430161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[3]);
84484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8450161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
84684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
84784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
848bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholtstatic temp_entry *
849bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var)
850bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{
851bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /*
852bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * NOTE: The ARB_vertex_program extension specified that matrices get
853bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * loaded in registers in row-major order.  With GLSL, we want column-
854bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * major order.  So, we need to transpose all matrices here...
855bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
856bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   static const struct {
857bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      const char *name;
858bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int matrix;
859bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int modifier;
860bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   } matrices[] = {
861bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
862bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
863bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
864bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
865bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
866bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
867bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
868bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
869bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
870bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
871bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
872bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
873bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
874bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
875bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
876bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
877bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
878bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
879bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
880bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
881bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
882bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
883bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   };
884bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   unsigned int i;
885bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   temp_entry *entry;
886bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
887bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /* C++ gets angry when we try to use an int as a gl_state_index, so we use
888bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * ints for gl_state_index.  Make sure they're compatible.
889bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
890bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   assert(sizeof(gl_state_index) == sizeof(int));
891bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
892bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   for (i = 0; i < Elements(matrices); i++) {
893bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      if (strcmp(var->name, matrices[i].name) == 0) {
894bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 int j;
895bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 int last_pos = -1, base_pos = -1;
896bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 int tokens[STATE_LENGTH];
897bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
898bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[0] = matrices[i].matrix;
899bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[1] = 0; /* array index! */
900bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[4] = matrices[i].modifier;
901bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
902bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 /* Add a ref for each column.  It looks like the reason we do
903bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	  * it this way is that _mesa_add_state_reference doesn't work
904bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	  * for things that aren't vec4s, so the tokens[2]/tokens[3]
905bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	  * range has to be equal.
906bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	  */
907bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 for (j = 0; j < 4; j++) {
908bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    tokens[2] = j;
909bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    tokens[3] = j;
910bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    int pos = _mesa_add_state_reference(prog->Parameters,
911bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt						(gl_state_index *)tokens);
912bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    assert(last_pos == -1 || last_pos == base_pos + j);
913bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    if (base_pos == -1)
914bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	       base_pos = pos;
915bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 }
916bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
917bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 entry = new(mem_ctx) temp_entry(var,
918bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt					 PROGRAM_STATE_VAR,
919bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt					 base_pos);
920bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
921bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 return entry;
922bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      }
923bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   }
924bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
925bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   return NULL;
926bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt}
927bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir)
93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
9310161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
9328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   temp_entry *entry = find_variable_storage(ir->var);
93385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   unsigned int i, loc;
9348364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   bool var_in;
93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9368364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   if (!entry) {
9378364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      switch (ir->var->mode) {
9388364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_uniform:
939bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var);
940bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 if (entry)
941bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    break;
942bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
94385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* FINISHME: Fix up uniform name for arrays and things */
944d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
945d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    /* FINISHME: we whack the location of the var here, which
946d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     * is probably not expected.  But we need to communicate
947d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     * mesa's sampler number to the tex instruction.
948d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     */
949d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    int sampler = _mesa_add_sampler(this->prog->Parameters,
950d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->name,
951d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->type->gl_type);
952d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    map_sampler(ir->var->location, sampler);
953d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
954d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_SAMPLER, sampler);
955d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    this->variable_storage.push_tail(entry);
956d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    break;
957d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
958d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
95985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 assert(ir->var->type->gl_type != 0 &&
96085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt		ir->var->type->gl_type != GL_INVALID_ENUM);
96185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 loc = _mesa_add_uniform(this->prog->Parameters,
96285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 ir->var->name,
96385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 type_size(ir->var->type) * 4,
96485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 ir->var->type->gl_type,
96585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 NULL);
966d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
96785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* Always mark the uniform used at this point.  If it isn't
96885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  * used, dead code elimination should have nuked the decl already.
96985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  */
97085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
971224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
97285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_UNIFORM, loc);
97385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 this->variable_storage.push_tail(entry);
9748364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
9758364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_in:
9768364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_out:
9778364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_inout:
9788364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 var_in = (ir->var->mode == ir_var_in ||
9798364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt		   ir->var->mode == ir_var_inout);
9808364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
9818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
9828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    bool in = builtin_var_to_mesa_reg[i].file == PROGRAM_INPUT;
9838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
9848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	    if (strcmp(ir->var->name, builtin_var_to_mesa_reg[i].name) == 0 &&
9858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt		!(var_in ^ in))
9868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	       break;
9878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 }
988f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 if (i != ARRAY_SIZE(builtin_var_to_mesa_reg)) {
989f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	    entry = new(mem_ctx) temp_entry(ir->var,
990f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt					    builtin_var_to_mesa_reg[i].file,
991f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt					    builtin_var_to_mesa_reg[i].index);
992f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	    break;
9938364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 }
994f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt
995f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 /* If no builtin, then it's a user-generated varying
996f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	  * (FINISHME: or a function argument!)
997f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	  */
998f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 /* The linker-assigned location is VERT_RESULT_* or FRAG_ATTRIB*
999f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	  */
1000f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 assert(ir->var->location != -1);
1001f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 if (var_in) {
1002f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	    entry = new(mem_ctx) temp_entry(ir->var,
1003f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt					    PROGRAM_INPUT,
1004f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt					    ir->var->location);
1005edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt
1006edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1007edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt		ir->var->location >= VERT_ATTRIB_GENERIC0) {
1008edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	       _mesa_add_attribute(prog->Attributes,
1009edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->name,
1010edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   type_size(ir->var->type) * 4,
1011edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->type->gl_type,
1012c64da87611823b4b53e93188f861f748a69936a3Eric Anholt				   ir->var->location - VERT_ATTRIB_GENERIC0);
1013edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    }
1014f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 } else {
1015f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	    entry = new(mem_ctx) temp_entry(ir->var,
1016f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt					    PROGRAM_OUTPUT,
1017f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt					    ir->var->location);
1018f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 }
1019f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt
10208364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
10218364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_auto:
1022364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 entry = new(mem_ctx) temp_entry(ir->var, PROGRAM_TEMPORARY,
1023364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt					 this->next_temp);
10248364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 this->variable_storage.push_tail(entry);
1025224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
10268364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 next_temp += type_size(ir->var->type);
10278364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
102884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
10298364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
10308364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (!entry) {
10318364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 printf("Failed to make storage for %s\n", ir->var->name);
10328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 exit(1);
1033224f712950494730c76b48864f2ca19acde1c8cfEric Anholt      }
103484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
103584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
10368364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.file = entry->file;
10378364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.index = entry->index;
103884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
10398364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
10400161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.reladdr = false;
10410161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
104284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
10430161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
104484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
104584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
104684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
104784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir)
104884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1049ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir_constant *index;
10500161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
1051ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt
1052ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   index = ir->array_index->constant_expression_value();
10534e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
10544e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   /* By the time we make it to this stage, matrices should be broken down
10554e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt    * to vectors.
10564e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt    */
1057ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   assert(!ir->type->is_matrix());
10584e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
1059ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir->array->accept(this);
10600161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg = this->result;
10614e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
10620161515c395c44233529c8d51f823b60050bc7baEric Anholt   if (src_reg.file == PROGRAM_INPUT ||
10630161515c395c44233529c8d51f823b60050bc7baEric Anholt       src_reg.file == PROGRAM_OUTPUT) {
1064ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt      assert(index); /* FINISHME: Handle variable indexing of builtins. */
10654e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
10660161515c395c44233529c8d51f823b60050bc7baEric Anholt      src_reg.index += index->value.i[0];
10674e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   } else {
1068bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      if (index) {
10690161515c395c44233529c8d51f823b60050bc7baEric Anholt	 src_reg.index += index->value.i[0];
1070bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      } else {
10710161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_src_reg array_base = this->result;
1072bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 /* Variable index array dereference.  It eats the "vec4" of the
1073bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  * base of the array and an index that offsets the Mesa register
1074bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  * index.
1075bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  */
1076bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 ir->array_index->accept(this);
1077bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt
10780161515c395c44233529c8d51f823b60050bc7baEric Anholt	 /* FINISHME: This doesn't work when we're trying to do the LHS
10790161515c395c44233529c8d51f823b60050bc7baEric Anholt	  * of an assignment.
10800161515c395c44233529c8d51f823b60050bc7baEric Anholt	  */
10810161515c395c44233529c8d51f823b60050bc7baEric Anholt	 src_reg.reladdr = true;
10820161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
10830161515c395c44233529c8d51f823b60050bc7baEric Anholt			     this->result);
10840161515c395c44233529c8d51f823b60050bc7baEric Anholt
10858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 this->result = get_temp(ir->type);
10860161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV,
10870161515c395c44233529c8d51f823b60050bc7baEric Anholt			     ir_to_mesa_dst_reg_from_src(this->result),
10880161515c395c44233529c8d51f823b60050bc7baEric Anholt			     src_reg);
1089bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      }
10904e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   }
109184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
109284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
10930161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
109484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
10950161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
109684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
109784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
10982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid
10992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir)
11002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
11012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
11020161515c395c44233529c8d51f823b60050bc7baEric Anholt   const glsl_type *struct_type = ir->record->type;
11032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int offset = 0;
11042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
11050161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir->record->accept(this);
11062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
11072c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   for (i = 0; i < struct_type->length; i++) {
11080161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
11092c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 break;
11102c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
11112c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
11120161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.index += offset;
11132c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
11142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
11152c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/**
11162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage
11172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the
11182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler.
11192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt *
11202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
11212c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector,
11222c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage.  So handle
11232c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest.
11242c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */
11250161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg
1126b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
1127b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
11280161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg dst_reg;
1129b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_dereference *deref;
1130b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_swizzle *swiz;
1131b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
11320161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Use the rvalue deref handler for the most part.  We'll ignore
11330161515c395c44233529c8d51f823b60050bc7baEric Anholt    * swizzles in it and write swizzles using writemask, though.
11340161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
11352c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir->accept(v);
11360161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
11372c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
1138b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   if ((deref = ir->as_dereference())) {
11392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      ir_dereference_array *deref_array = ir->as_dereference_array();
11402c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(!deref_array || deref_array->array->type->is_array());
11412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
1142b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      ir->accept(v);
1143b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   } else if ((swiz = ir->as_swizzle())) {
11440161515c395c44233529c8d51f823b60050bc7baEric Anholt      dst_reg.writemask = 0;
1145b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 1)
11460161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.x);
1147b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 2)
11480161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.y);
1149b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 3)
11500161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.z);
1151b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 4)
11520161515c395c44233529c8d51f823b60050bc7baEric Anholt	 dst_reg.writemask |= (1 << swiz->mask.w);
1153b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   }
1154b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
11550161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
1156b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt}
1157b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
115884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
115984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir)
116084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
11610161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg l;
11620161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg r;
116384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_matrix());
11652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_array());
11662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
11672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
1168b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   l = get_assignment_lhs(ir->lhs, this);
1169b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
117084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->rhs->accept(this);
117184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   r = this->result;
11720161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(l.file != PROGRAM_UNDEFINED);
11730161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(r.file != PROGRAM_UNDEFINED);
117484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1175346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   if (ir->condition) {
1176346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 ir_constant *condition_constant;
1177346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt
1178346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 condition_constant = ir->condition->constant_expression_value();
1179346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt
1180346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 assert(condition_constant && condition_constant->value.b[0]);
1181346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   }
118284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11830161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
118484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
118584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
118684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
118784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
118884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir)
118984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
11900161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
11910bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat stack_vals[4];
11920bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat *values = stack_vals;
11930bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   unsigned int i;
119484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11950bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   if (ir->type->is_matrix() || ir->type->is_array()) {
11960bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      assert(!"FINISHME: array/matrix constants");
1197582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   }
11980bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
11990bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.file = PROGRAM_CONSTANT;
12000bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   switch (ir->type->base_type) {
12010bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_FLOAT:
12020bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      values = &ir->value.f[0];
12030bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
12040bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_UINT:
12050bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
12060bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.u[i];
12070bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
12080bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
12090bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_INT:
12100bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
12110bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.i[i];
12120bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
12130bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
12140bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_BOOL:
12150bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
12160bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.b[i];
12170bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
12180bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
12190bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   default:
12200bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      assert(!"Non-float/uint/int/bool constant");
12210bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   }
12220bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
12230bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
12240bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt					      values, ir->type->vector_elements,
12250bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt					      &src_reg.swizzle);
12260161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.reladdr = false;
12270161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
122884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
12290161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
123084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
123184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
123284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
123384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
123484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir)
123584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
123684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   printf("Can't support call to %s\n", ir->callee_name());
123784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   exit(1);
123884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
123984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
124084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
124184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
124284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir)
124384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1244d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_to_mesa_src_reg result_src, coord;
1245d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_to_mesa_dst_reg result_dst, lod_info;
1246d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_to_mesa_instruction *inst = NULL;
124784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
124884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->coordinate->accept(this);
1249d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   coord = this->result;
1250d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1251d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
1252d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * the actual storage for the result here, instead.
1253d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1254d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_src = get_temp(glsl_type::vec4_type);
1255d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1256d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1257d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (ir->op) {
1258d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_tex:
1259d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst = ir_to_mesa_emit_op1(ir, OPCODE_TEX, result_dst, coord);
1260d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1261d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txb:
1262d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      /* Mesa IR stores bias in the last channel of the coords. */
1263d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      lod_info = ir_to_mesa_dst_reg_from_src(coord);
1264d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      lod_info.writemask = WRITEMASK_W;
1265d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.bias->accept(this);
1266d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, lod_info, this->result);
1267d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1268d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst = ir_to_mesa_emit_op1(ir, OPCODE_TXB, result_dst, coord);
1269d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1270d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txl:
1271d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      /* Mesa IR stores lod in the last channel of the coords. */
1272d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      lod_info = ir_to_mesa_dst_reg_from_src(coord);
1273d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      lod_info.writemask = WRITEMASK_W;
1274d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.lod->accept(this);
1275d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, lod_info, this->result);
1276d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1277d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst = ir_to_mesa_emit_op1(ir, OPCODE_TXL, result_dst, coord);
1278d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1279d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txd:
1280d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txf:
1281d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"GLSL 1.30 features unsupported");
1282d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1283d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1284d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1285d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
1286d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(sampler); /* FINISHME: sampler arrays */
1287d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* generate the mapping, remove when we generate storage at
1288d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * declaration time
1289d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1290d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler->accept(this);
1291d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1292d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   inst->sampler = get_sampler_number(sampler->var->location);
1293d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1294d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (sampler->type->sampler_dimensionality) {
1295d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_1D:
1296d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_1D_INDEX;
1297d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1298d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_2D:
1299d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_2D_INDEX;
1300d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1301d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_3D:
1302d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_3D_INDEX;
1303d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1304d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_CUBE:
1305d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_CUBE_INDEX;
1306d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1307d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   default:
1308d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"FINISHME: other texture targets");
1309d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1310d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1311d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(!ir->projector); /* FINISHME */
1312d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(!ir->shadow_comparitor); /* FINISHME */
1313d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1314d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->result = result_src;
131584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
131684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
131784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
131884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir)
131984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
132084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
132184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
132284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->get_value()->accept(this);
132384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
132484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
132516efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid
132616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir)
132716efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{
132816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke   assert(0);
132916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
133016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke   ir->condition->accept(this);
133116efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke}
133284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
133384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
133484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir)
133584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1336854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
1337cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   ir_to_mesa_instruction *prev_inst;
1338cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
1339cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1340c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1341c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir->condition->accept(this);
13420161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(this->result.file != PROGRAM_UNDEFINED);
1343c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1344854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   if (ctx->Shader.EmitCondCodes) {
1345854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1346cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
1347cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      /* See if we actually generated any instruction for generating
1348cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * the condition.  If not, then cook up a move to a temp so we
1349cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * have something to set cond_update on.
1350cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       */
1351cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      if (cond_inst == prev_inst) {
1352cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
1353cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
1354cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 ir_to_mesa_dst_reg_from_src(temp),
1355cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 result);
1356cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      }
1357854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst->cond_update = GL_TRUE;
1358854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt
1359854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst = ir_to_mesa_emit_op1(ir->condition,
1360854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    OPCODE_IF, ir_to_mesa_undef_dst,
1361854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    ir_to_mesa_undef);
1362854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst->dst_reg.cond_mask = COND_NE;
1363854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   } else {
1364854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst = ir_to_mesa_emit_op1(ir->condition,
1365854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    OPCODE_IF, ir_to_mesa_undef_dst,
1366854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    this->result);
1367854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   }
1368c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1369c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   this->instructions.push_tail(if_inst);
1370c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1371c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   visit_exec_list(&ir->then_instructions, this);
1372c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1373c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if (!ir->else_instructions.is_empty()) {
13740161515c395c44233529c8d51f823b60050bc7baEric Anholt      else_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ELSE,
13750161515c395c44233529c8d51f823b60050bc7baEric Anholt				      ir_to_mesa_undef_dst,
13760161515c395c44233529c8d51f823b60050bc7baEric Anholt				      ir_to_mesa_undef);
13770a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt      visit_exec_list(&ir->else_instructions, this);
1378c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1379c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
13800161515c395c44233529c8d51f823b60050bc7baEric Anholt   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
13810161515c395c44233529c8d51f823b60050bc7baEric Anholt				 ir_to_mesa_undef_dst, ir_to_mesa_undef);
138284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
138384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1384ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor()
1385ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{
13860161515c395c44233529c8d51f823b60050bc7baEric Anholt   result.file = PROGRAM_UNDEFINED;
1387ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_temp = 1;
1388d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler_map = NULL;
1389d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler_map_size = 0;
1390ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt}
1391ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt
139284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register
139384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
139484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
139584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_src_register mesa_reg;
139684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
139784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.File = reg.file;
1398aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
139984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.Index = reg.index;
140034195832669f0eb7c4a80997cc524f8d10319307Eric Anholt   mesa_reg.Swizzle = reg.swizzle;
1401bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt   mesa_reg.RelAddr = reg.reladdr;
140284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
140384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return mesa_reg;
140484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
140584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1406c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
1407c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtset_branchtargets(struct prog_instruction *mesa_instructions,
1408c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		  int num_instructions)
1409c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
141064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_count = 0, loop_count;
141164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int *if_stack, *loop_stack;
141264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_stack_pos = 0, loop_stack_pos = 0;
141364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int i, j;
1414c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1415c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
141664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      switch (mesa_instructions[i].Opcode) {
141764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_IF:
1418c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_count++;
141964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
142064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
142164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_count++;
142264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
142364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BRK:
142464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_CONT:
142564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = -1;
142664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
142764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      default:
142864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
142964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      }
1430c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1431c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
143264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
143364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
1434c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1435c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1436c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      switch (mesa_instructions[i].Opcode) {
1437c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_IF:
143864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos] = i;
1439c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos++;
1440c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1441c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ELSE:
144264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
144364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos - 1] = i;
1444c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1445c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ENDIF:
144664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1447c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos--;
1448c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
144964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
145064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack[loop_stack_pos] = i;
145164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos++;
145264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
145364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_ENDLOOP:
145464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos--;
145564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* Rewrite any breaks/conts at this nesting level (haven't
145664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * already had a BranchTarget assigned) to point to the end
145764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * of the loop.
145864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  */
145964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
146064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    if (mesa_instructions[j].Opcode == OPCODE_BRK ||
146164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		mesa_instructions[j].Opcode == OPCODE_CONT) {
146264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       if (mesa_instructions[j].BranchTarget == -1) {
146364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		  mesa_instructions[j].BranchTarget = i;
146464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       }
146564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    }
146664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 }
146764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* The loop ends point at each other. */
146864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
146964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
1470c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      default:
1471c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1472c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1473c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1474c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1475c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(if_stack);
1476c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1477c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1478c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
1479c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions,
1480c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      ir_instruction **mesa_instruction_annotation,
1481c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      int num_instructions)
1482c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
1483c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction *last_ir = NULL;
1484c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
1485c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1486c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1487c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      struct prog_instruction *mesa_inst = mesa_instructions + i;
1488c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      ir_instruction *ir = mesa_instruction_annotation[i];
1489c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
149064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      if (last_ir != ir && ir) {
1491c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 ir_print_visitor print;
1492c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 ir->accept(&print);
1493c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 printf("\n");
1494c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 last_ir = ir;
1495c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1496c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1497c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      _mesa_print_instruction(mesa_inst);
1498c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1499c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1500c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1501ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void
1502ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog)
1503ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{
1504d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   unsigned int i;
1505d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1506ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->InputsRead = 0;
1507ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->OutputsWritten = 0;
1508d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   prog->SamplersUsed = 0;
1509ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1510ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   for (i = 0; i < prog->NumInstructions; i++) {
1511ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      struct prog_instruction *inst = &prog->Instructions[i];
1512ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      unsigned int reg;
1513ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1514ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      switch (inst->DstReg.File) {
1515ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_OUTPUT:
1516ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
1517ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
1518ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_INPUT:
1519ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 prog->InputsRead |= BITFIELD64_BIT(inst->DstReg.Index);
1520ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
1521ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      default:
1522ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
1523ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
1524ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1525ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
1526ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 switch (inst->SrcReg[reg].File) {
1527ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_OUTPUT:
152881b7b79c472cbc15cb044656bd37b101a941f358Eric Anholt	    prog->OutputsWritten |= BITFIELD64_BIT(inst->SrcReg[reg].Index);
1529ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
1530ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_INPUT:
153181b7b79c472cbc15cb044656bd37b101a941f358Eric Anholt	    prog->InputsRead |= BITFIELD64_BIT(inst->SrcReg[reg].Index);
1532ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
1533ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 default:
1534ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
1535ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 }
1536ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
1537d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1538d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      /* Instead of just using the uniform's value to map to a
1539d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler, Mesa first allocates a separate number for the
1540d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler (_mesa_add_sampler), then we reindex it down to a
1541d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * small integer (sampler_map[], SamplersUsed), then that gets
1542d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * mapped to the uniform's value, and we get an actual sampler.
1543d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       */
1544d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      if (_mesa_is_tex_instruction(inst->Opcode)) {
1545d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplerTargets[inst->TexSrcUnit] =
1546d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    (gl_texture_index)inst->TexSrcTarget;
1547d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
1548d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (inst->TexShadow) {
1549d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
1550d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
1551d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      }
1552ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   }
1553d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1554d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   _mesa_update_shader_textures_used(prog);
1555ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt}
1556ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
155785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt/* Each stage has some uniforms in its Parameters list.  The Uniforms
155885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * list for the linked shader program has a pointer to these uniforms
155985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * in each of the stage's Parameters list, so that their values can be
156085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * updated when a uniform is set.
156185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */
156285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void
156385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtlink_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
156485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				     struct gl_program *prog)
156585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{
156685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   unsigned int i;
156785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
156885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   for (i = 0; i < prog->Parameters->NumParameters; i++) {
156985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
157085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
157185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
157285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 struct gl_uniform *uniform =
157385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
157485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 if (uniform)
157585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    uniform->Initialized = p->Initialized;
157685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      }
157785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   }
157885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt}
157985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
1580364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program *
158116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtget_mesa_program(GLcontext *ctx, void *mem_ctx, struct gl_shader *shader)
158284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
158384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_visitor v;
158484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_instruction *mesa_instructions, *mesa_inst;
1585c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction **mesa_instruction_annotation;
1586c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
1587364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
1588364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLenum target;
1589364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1590364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   switch (shader->Type) {
1591364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   case GL_VERTEX_SHADER:   target = GL_VERTEX_PROGRAM_ARB; break;
1592364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   case GL_FRAGMENT_SHADER: target = GL_FRAGMENT_PROGRAM_ARB; break;
1593364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   default: assert(!"should not be reached"); break;
1594364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
159584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1596364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog = ctx->Driver.NewProgram(ctx, target, 1);
1597364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!prog)
1598364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      return NULL;
1599364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Parameters = _mesa_new_parameter_list();
1600364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
1601364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Attributes = _mesa_new_parameter_list();
1602364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.ctx = ctx;
1603364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.prog = prog;
1604364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1605364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.mem_ctx = talloc_new(NULL);
160616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   visit_exec_list(shader->ir, &v);
1607abc4e52992c53ee6b6895480b47e6a6e27ef9bd0Eric Anholt   v.ir_to_mesa_emit_op1(NULL, OPCODE_END,
1608abc4e52992c53ee6b6895480b47e6a6e27ef9bd0Eric Anholt			 ir_to_mesa_undef_dst, ir_to_mesa_undef);
160984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1610364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumTemporaries = v.next_temp;
1611364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
161284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int num_instructions = 0;
161384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
161484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      num_instructions++;
161584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
161684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
161784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_instructions =
161884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      (struct prog_instruction *)calloc(num_instructions,
161984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					sizeof(*mesa_instructions));
1620364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
1621364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt					      num_instructions);
162284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
162384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_inst = mesa_instructions;
1624c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   i = 0;
162584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
162684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
1627b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
162884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->Opcode = inst->op;
1629854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->CondUpdate = inst->cond_update;
163084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.File = inst->dst_reg.file;
163184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.Index = inst->dst_reg.index;
1632854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
163312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
163484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
163584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
163684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
1637d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcUnit = inst->sampler;
1638d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcTarget = inst->tex_target;
1639c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      mesa_instruction_annotation[i] = inst->ir;
1640aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt
164184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst++;
1642c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      i++;
164384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
1644c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1645c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   set_branchtargets(mesa_instructions, num_instructions);
1646364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (0) {
1647364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      print_program(mesa_instructions, mesa_instruction_annotation,
1648364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt		    num_instructions);
1649364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
1650364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1651364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Instructions = mesa_instructions;
1652364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumInstructions = num_instructions;
1653364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
165416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   _mesa_reference_program(ctx, &shader->Program, prog);
1655364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1656364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   return prog;
1657364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
1658364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
165916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" {
166016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt
1661116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunkestatic void
1662116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunkesteal_memory(ir_instruction *ir, void *new_ctx)
1663116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke{
1664116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   talloc_steal(new_ctx, ir);
1665116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke}
1666116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke
166716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid
166816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
1669364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
1670364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct _mesa_glsl_parse_state *state;
1671364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1672364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state = talloc_zero(shader, struct _mesa_glsl_parse_state);
1673364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   switch (shader->Type) {
1674364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   case GL_VERTEX_SHADER:   state->target = vertex_shader; break;
1675364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   case GL_FRAGMENT_SHADER: state->target = fragment_shader; break;
1676364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   case GL_GEOMETRY_SHADER: state->target = geometry_shader; break;
1677364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
1678364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1679364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state->scanner = NULL;
1680364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state->translation_unit.make_empty();
168116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   state->symbols = new(shader) glsl_symbol_table;
1682364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state->info_log = talloc_strdup(shader, "");
1683364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state->error = false;
1684364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state->temp_index = 0;
1685364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state->loop_or_switch_nesting = NULL;
1686364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   state->ARB_texture_rectangle_enable = true;
1687364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
16885e18b051c039564d1998818d08caf1bff3983630Ian Romanick   state->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
16895e18b051c039564d1998818d08caf1bff3983630Ian Romanick
1690153eca98064252be4daad9cc27746f37c245b627Ian Romanick   const char *source = shader->Source;
1691629198b96a8f471c48932d6af56184b6c33b5fe5Kenneth Graunke   state->error = preprocess(state, &source, &state->info_log);
1692153eca98064252be4daad9cc27746f37c245b627Ian Romanick
1693153eca98064252be4daad9cc27746f37c245b627Ian Romanick   if (!state->error) {
1694153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_ctor(state, source);
1695153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_parse(state);
1696153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_dtor(state);
1697153eca98064252be4daad9cc27746f37c245b627Ian Romanick   }
1698364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
169916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   shader->ir = new(shader) exec_list;
1700364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!state->error && !state->translation_unit.is_empty())
170116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt      _mesa_ast_to_hir(shader->ir, state);
1702364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1703364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   /* Optimization passes */
170416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   if (!state->error && !shader->ir->is_empty()) {
1705364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      bool progress;
1706364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      do {
1707364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 progress = false;
1708364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
170916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_function_inlining(shader->ir) || progress;
171016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_if_simplification(shader->ir) || progress;
171116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_copy_propagation(shader->ir) || progress;
171216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_dead_code_local(shader->ir) || progress;
171316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_dead_code_unlinked(state, shader->ir) || progress;
171416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_variable_unlinked(shader->ir) || progress;
171516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_folding(shader->ir) || progress;
171616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_vec_index_to_swizzle(shader->ir) || progress;
171716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_swizzle_swizzle(shader->ir) || progress;
1718364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      } while (progress);
1719364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
1720364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1721364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->symbols = state->symbols;
1722364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1723364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->CompileStatus = !state->error;
1724364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->InfoLog = state->info_log;
1725c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1726116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   /* Retain any live IR, but trash the rest. */
1727116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   foreach_list(node, shader->ir) {
1728116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke      visit_tree((ir_instruction *) node, steal_memory, shader);
1729116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   }
1730116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke
1731364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   talloc_free(state);
1732364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt }
1733364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1734364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid
1735364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
1736364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
1737364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   unsigned int i;
1738849e18153cd91d812f694b806a84008498860bc3Eric Anholt
1739364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_clear_shader_program_data(ctx, prog);
1740364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1741849e18153cd91d812f694b806a84008498860bc3Eric Anholt   prog->LinkStatus = GL_TRUE;
1742364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1743364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   for (i = 0; i < prog->NumShaders; i++) {
1744849e18153cd91d812f694b806a84008498860bc3Eric Anholt      if (!prog->Shaders[i]->CompileStatus) {
1745849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->InfoLog =
1746849e18153cd91d812f694b806a84008498860bc3Eric Anholt	    talloc_asprintf_append(prog->InfoLog,
1747364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				   "linking with uncompiled shader");
1748849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->LinkStatus = GL_FALSE;
1749364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
1750364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
1751364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1752364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
1753364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
1754364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
1755364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1756849e18153cd91d812f694b806a84008498860bc3Eric Anholt   if (prog->LinkStatus) {
1757849e18153cd91d812f694b806a84008498860bc3Eric Anholt      link_shaders(prog);
1758849e18153cd91d812f694b806a84008498860bc3Eric Anholt
1759849e18153cd91d812f694b806a84008498860bc3Eric Anholt      /* We don't use the linker's uniforms list, and cook up our own at
1760849e18153cd91d812f694b806a84008498860bc3Eric Anholt       * generate time.
1761849e18153cd91d812f694b806a84008498860bc3Eric Anholt       */
1762849e18153cd91d812f694b806a84008498860bc3Eric Anholt      free(prog->Uniforms);
1763849e18153cd91d812f694b806a84008498860bc3Eric Anholt      prog->Uniforms = _mesa_new_uniform_list();
1764849e18153cd91d812f694b806a84008498860bc3Eric Anholt   }
1765364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1766849e18153cd91d812f694b806a84008498860bc3Eric Anholt   prog->LinkStatus = prog->LinkStatus;
1767364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1768364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   /* FINISHME: This should use the linker-generated code */
1769364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (prog->LinkStatus) {
1770364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      for (i = 0; i < prog->NumShaders; i++) {
1771364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 struct gl_program *linked_prog;
1772364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1773849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 linked_prog = get_mesa_program(ctx, prog,
1774849e18153cd91d812f694b806a84008498860bc3Eric Anholt					prog->Shaders[i]);
1775ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 count_resources(linked_prog);
1776364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
177785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
177885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
1779849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 switch (prog->Shaders[i]->Type) {
1780364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_VERTEX_SHADER:
1781364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_vertprog(ctx, &prog->VertexProgram,
1782364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_vertex_program *)linked_prog);
17837dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt	    ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
17847dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt					    linked_prog);
1785364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
1786364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_FRAGMENT_SHADER:
1787364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
1788364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_fragment_program *)linked_prog);
17897dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt	    ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
17907dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt					    linked_prog);
1791364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
1792364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 }
1793364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
1794364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
1795364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
1796364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
1797364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */
1798